-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
https.request failed for certain URL after first visting #8368
Comments
Is there reason to believe it's an issue with node.js and not with the endpoints that you are trying to connect to? I infer that you are from the PRC. Is it possible the Great Firewall is blocking your connections? |
Hi @bnoordhuis It could be related to the endpoints, because when I test the request against other endpoints it works just fine. The network was not blocked, which I can confirm. But it's still confusing, since the issue only occurs if we request the second one inside the first one, if we move the second request out, to be a parallel one, the two requests are all good. With wireshark, the second request seems to be timeout and the endpoint close the connection, then the Thanks! |
I'm able to reproduce and IMHO the problem is with Node.js socket pooling agent. Looks like HTTP socket agent creates a identifier for the socket based on request options. When two identical nested requests are made, the completion (event: end) instructs agent to remove/close the socket. If both sockets are within the same agent (by default This happens only when requests are "slow" and long enough to collide, such as the one from weixin.qq.com. With faster server such as GitHub URL above, the first request gets away before its completion can interfere with the second request. If you make the requests setting const opts = {
hostname: 'weixin.qq.com',
port: 443,
path: '/zh_CN/htmledition/js/qmtool0cae9c.js',
agent: false
};
https.get(opts, function (res) { .. nested calls to with same opts here ... }); HTTP socket agent's handling of it's |
I'd like to add that my analysis above is a rough simplification of what http socket agent code does to pool and manage sockets and as such it doesn't yet exactly pinpoint the bug inside However, I think the idea is right and end result is that when connection options are identical the agent seems to errorneously close the socket of the second nested connection. Maybe someone more familiar with HTTP Agent's code could comment on this? |
I have spent quite a bit of time looking at the agent code when investigating #8279 and your explanation makes perfect sense to me!
/cc @nodejs/http :) |
Did some debugging on this and seems that the reason is not with the HTTP socket pooling agent alone, but in HTTP socket pooling agent is indirectly involved because its So, it seems that new socket is properly created after all but Alternative workaround is to disable TLS session caching. This also makes nested connections work:
|
I'm not sure if TLS session reuse is supported by all HTTPS servers when the first negotiated TLS session connection is still in progress. Does Node.js support session renegotiation if server fails when attempting to reuse TLS session? |
@imyller there is no support for this on our side, but TLS protocol has a way for server to ignore the incoming session id and generate a new one. Some servers may be faulty though. |
RFC 2246 7.2:
Chrome seems to invalidate session id (remove from cache), reconnect socket and renegotiate. Maybe Node.js should do the same. |
@imyller we invalidate sessions on error, but I believe that user code should be responsible for doing retries in case of faulty servers. Semantics differ per application, and different people have different needs. |
Thanks so much! @imyller @indutny This really makes sense to me, but I'm not sure whether I understood it correctly:) So the root cause is the TLS session cache, the second socket was created but still trying to use the previous one, and the previous one closed after the But does this just happened when the request are slow ? |
@codingfishman In my testing two connections overlap if the server if slow because the first connection's So, the sockets are indeed pooled properly and overlapping sockets are not an issue. The issue with I suggest that you disable TLS session cache if you want to make nested connections to https.globalAgent.maxCachedSessions = 0; |
…e the cache, it will hang up the following request after the cached one. refer to nodejs/node#8368
@imyller Thanks for the detail, it helps a lot! |
Tried the same but getting this issue. Could you please help me on that |
osx 15.3.0 Darwin Kernel Version 15.3.0: Thu Dec 10 18:40:58 PST 2015; root:xnu-3248.30.4~1/RELEASE_X86_64 x86_64
https.request
When visiting the specified URL with
https.request
, the first request is OK but the following request will be failed with :socket hang up
after certain timeout. To demostrate it , try the code below:The second request will be failed, while for other HTTPS resources, such as the
url2
, it works fine. And also for http request it works normally either.The text was updated successfully, but these errors were encountered: