Skip to content

Commit 6707411

Browse files
addaleaxMylesBorins
authored andcommitted
http: reset stream to unconsumed in unconsume()
Reset the underlying socket of an HTTP stream to be marked as unconsume after the HTTP parser no longer owns it. Fixes: #14407 PR-URL: #14410 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Luigi Pinca <[email protected]>
1 parent ca61f3b commit 6707411

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-0
lines changed

src/node_http_parser.cc

+1
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,7 @@ class Parser : public AsyncWrap {
503503

504504
stream->set_alloc_cb(parser->prev_alloc_cb_);
505505
stream->set_read_cb(parser->prev_read_cb_);
506+
stream->Unconsume();
506507
}
507508

508509
parser->prev_alloc_cb_.clear();

src/stream_base.h

+5
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ class StreamBase : public StreamResource {
234234
consumed_ = true;
235235
}
236236

237+
inline void Unconsume() {
238+
CHECK_EQ(consumed_, true);
239+
consumed_ = false;
240+
}
241+
237242
template <class Outer>
238243
inline Outer* Cast() { return static_cast<Outer*>(Cast()); }
239244

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict';
2+
const common = require('../common');
3+
if (!common.hasCrypto)
4+
common.skip('missing crypto');
5+
6+
const tls = require('tls');
7+
const http = require('http');
8+
9+
// Tests that, after the HTTP parser stopped owning a socket that emits an
10+
// 'upgrade' event, another C++ stream can start owning it (e.g. a TLSSocket).
11+
12+
const server = http.createServer(common.mustNotCall());
13+
14+
server.on('upgrade', common.mustCall((request, socket, head) => {
15+
// This should not crash.
16+
new tls.TLSSocket(socket);
17+
server.close();
18+
socket.destroy();
19+
}));
20+
21+
server.listen(0, common.mustCall(() => {
22+
http.get({
23+
port: server.address().port,
24+
headers: {
25+
'Connection': 'Upgrade',
26+
'Upgrade': 'websocket'
27+
}
28+
}).on('error', () => {});
29+
}));

0 commit comments

Comments
 (0)