Allow HTTPS long poll requests#3372
Conversation
|
Good find– for TLS I think we should be listening for |
|
@devinivy Interesting! I'm not clear where you mean, though…in the |
|
I mean in connection.js, where connections are added to @dahjelle while it's not my decision and I think that your fix works, I'm guessing hapi wont take this particular fix because it relies on the undocumented |
Definitely makes sense! My objective was to clearly communicate the issue as much as anything—I figured that actually fixing it was rather out of the scope of my expertise. :-)
I tried replacing in line 155 with (…and then the matching set of code down in While my new test passes just fine that way, it causes another test failure: …which I haven't dug into yet.
Hopefully! :-) |
|
I think there is more subtlety here than I'm figuring out. :-/ |
0f96fe9 to
b4ba28a
Compare
|
|
||
| expect(err).to.not.exist(); | ||
| expect(count1).to.equal(2); | ||
| expect(Object.keys(server.connections[0]._connections).length).to.equal(2); |
There was a problem hiding this comment.
The way this test is written doesn't take into account the handshake that happens before the secureConnection event is fired. I removed this part of the test to account for that—is that a correct way to fix it?
There was a problem hiding this comment.
Try the following,
const socket1 = new Net.Socket();
const socket2 = new Net.Socket();
socket1.on('error', () => { });
socket2.on('error', () => { });
socket1.connect(server.info.port, '127.0.0.1');
socket2.connect(server.info.port, '127.0.0.1');
TLS.connect({ socket: socket1, rejectUnauthorized: false }, () => {
TLS.connect({ socket: socket2, rejectUnauthorized: false }, () => {
server.listener.getConnections((err, count1) => {
expect(err).to.not.exist();
expect(count1).to.equal(2);
expect(Object.keys(server.connections[0]._connections).length).to.equal(2);
// ...There was a problem hiding this comment.
You should actually create the socket and TLS.connect() one at a time to be safe (rather than creating/connecting both at the same time then calling TLS.connect() in series).
There was a problem hiding this comment.
Might look like,
const socket1 = new Net.Socket();
const socket2 = new Net.Socket();
socket1.on('error', () => { });
socket2.on('error', () => { });
socket1.connect(server.info.port, '127.0.0.1');
TLS.connect({ socket: socket1, rejectUnauthorized: false }, () => {
socket2.connect(server.info.port, '127.0.0.1');
TLS.connect({ socket: socket2, rejectUnauthorized: false }, () => {
server.listener.getConnections((err, count1) => {
expect(err).to.not.exist();
expect(count1).to.equal(2);
expect(Object.keys(server.connections[0]._connections).length).to.equal(2);|
I pushed up new changes using listening for either Otherwise, this PR gets away from using the private Comments/suggestions very welcome! |
b4ba28a to
0e868ca
Compare
0e868ca to
375a9a7
Compare
|
Thanks for your comments, @devinivy ! I adjusted the PR. |
|
What's next for this PR? Further suggestions? |
|
Looks good to me. Want to get @hueniverse's impression. I would be curious now if today's HTTP2 implementations use the |
|
This patch seems to be working for us in production for the past week or so, for whatever that's worth. |
|
This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions. |
This is a possible fix for outmoded/discuss#395, where longpoll HTTPS requests were getting cancelled before the timeout value passed to
server.stop().Fair warning: I'm not very familiar with Hapi internals nor low-level Node HTTP & socket handling, so I don't have any idea if this fix is appropriate. Any and all suggestions—or a complete rewrite!—more than welcome! My real goal is simply to get this particular issue fixed in whatever manner is fastest. :-D
Issue Description
Expected behavior
server.stop({timeout}, callback)should wait for the provided timeout before forcibly closing any pending requests.Observed behavior
For HTTPS requests only,
server.stopimmediately forcibly closes pending requests, without waiting for either a response to the request or for the timeout.Analysis
It looks like
connection.jslooks for the_isHapiProcessingflag. However, in an HTTPS connection, that flag isundefined.I think what is happening is that the
_dispatchfunction sets the flag on aTLSSocketinstance. But, by the time we are handling the stop in the_stopfunction, we no longer have access to the TLSSocket, but rather have just aSocket.(As far as I can tell, a TLSSocket is created from a Socket originally? as some sort of wrapper?)
It appears that we can set the flag on the socket by using the
_parentproperty of a TLSsocket. It's private and undocumented, so I hope there is a better way to do this, but that's all I could find.