Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/node_http_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ class Parser : public AsyncWrap {

stream->set_alloc_cb(parser->prev_alloc_cb_);
stream->set_read_cb(parser->prev_read_cb_);
stream->Unconsume();
}

parser->prev_alloc_cb_.clear();
Expand Down
5 changes: 5 additions & 0 deletions src/stream_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,11 @@ class StreamBase : public StreamResource {
consumed_ = true;
}

inline void Unconsume() {
CHECK_EQ(consumed_, true);
consumed_ = false;
}

template <class Outer>
inline Outer* Cast() { return static_cast<Outer*>(Cast()); }

Expand Down
29 changes: 29 additions & 0 deletions test/parallel/test-http-upgrade-reconsume-stream.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');

const tls = require('tls');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add the hasCrypto skip check.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cjihrig Thanks for pointing that out, done

const http = require('http');

// Tests that, after the HTTP parser stopped owning a socket that emits an
// 'upgrade' event, another C++ stream can start owning it (e.g. a TLSSocket).

const server = http.createServer(common.mustNotCall());

server.on('upgrade', common.mustCall((request, socket, head) => {
// This should not crash.
new tls.TLSSocket(socket);
server.close();
socket.destroy();
}));

server.listen(0, common.mustCall(() => {
http.request({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit (feel free to ignore): http.get()? so we can remove .end().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lpinca done

port: server.address().port,
headers: {
'Connection': 'Upgrade',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Even though we agreed not to lint quote-props in #14059, most people seem to prefer as-needed, so I would probably drop the quotes here. It's up to you :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the quotes for map-like objects :)

'Upgrade': 'websocket'
}
}).on('error', () => {}).end();
}));