-
Notifications
You must be signed in to change notification settings - Fork 125
Connections not being closed, even when server sets the "Connection: close" header #324
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
Comments
Do you have the full set of headers sent by the remote server? We do have code that should tear these down if |
Sure! This is the output of a curl to that device:
|
Given that these are plaintext, can we get a packet capture of what |
ping @0xpablo |
Yup, looks like something is going wrong here. I'll see if I can repro in an isolated environment. |
And great, ok, this is a really nasty bug: we actually leak these connections. If I spin in a loop hitting a localhost server exhibiting the same behaviour as your server, we leak connections until eventually we exhaust the FD limit and crash. This is normally not a problem because the server should be actually closing the connection after it sends
This server is failing to do that. We need to defend against that case, in any rate. The best system for us is to issue a socket closure ourselves eagerly. This addresses our own resource exhaustion issue, and also solves the problem here. I'll throw a unit test together and get this fixed. |
Motivation: Currently when either we or the server send Connection: close, we correctly do not return that connection to the pool. However, we rely on the server actually performing the connection closure: we never call close() ourselves. This is unnecessarily optimistic: a server may absolutely fail to close this connection. To protect our own file descriptors, we should make sure that any connection we do not return the pool is closed. Modifications: If we think a connection is closing when we release it, we now call close() on it defensively. Result: We no longer leak connections when the server fails to close them. Fixes swift-server#324.
Motivation: Currently when either we or the server send Connection: close, we correctly do not return that connection to the pool. However, we rely on the server actually performing the connection closure: we never call close() ourselves. This is unnecessarily optimistic: a server may absolutely fail to close this connection. To protect our own file descriptors, we should make sure that any connection we do not return the pool is closed. Modifications: If we think a connection is closing when we release it, we now call close() on it defensively. Result: We no longer leak connections when the server fails to close them. Fixes swift-server#324.
Motivation: Currently when either we or the server send Connection: close, we correctly do not return that connection to the pool. However, we rely on the server actually performing the connection closure: we never call close() ourselves. This is unnecessarily optimistic: a server may absolutely fail to close this connection. To protect our own file descriptors, we should make sure that any connection we do not return the pool is closed. Modifications: If we think a connection is closing when we release it, we now call close() on it defensively. Result: We no longer leak connections when the server fails to close them. Fixes swift-server#324.
Motivation: Currently when either we or the server send Connection: close, we correctly do not return that connection to the pool. However, we rely on the server actually performing the connection closure: we never call close() ourselves. This is unnecessarily optimistic: a server may absolutely fail to close this connection. To protect our own file descriptors, we should make sure that any connection we do not return the pool is closed. Modifications: If we think a connection is closing when we release it, we now call close() on it defensively. Result: We no longer leak connections when the server fails to close them. Fixes swift-server#324.
Great!!! Thanks for investigating and the quick fix, I will try pointing to that PR to confirm that the issue is fixed, and I will also try contacting the manufacturers of the embedded device to let them know that they should be closing the socket as well. |
Motivation: Currently when either we or the server send Connection: close, we correctly do not return that connection to the pool. However, we rely on the server actually performing the connection closure: we never call close() ourselves. This is unnecessarily optimistic: a server may absolutely fail to close this connection. To protect our own file descriptors, we should make sure that any connection we do not return the pool is closed. Modifications: If we think a connection is closing when we release it, we now call close() on it defensively. Result: We no longer leak connections when the server fails to close them. Fixes swift-server#324.
Motivation: Currently when either we or the server send Connection: close, we correctly do not return that connection to the pool. However, we rely on the server actually performing the connection closure: we never call close() ourselves. This is unnecessarily optimistic: a server may absolutely fail to close this connection. To protect our own file descriptors, we should make sure that any connection we do not return the pool is closed. Modifications: If we think a connection is closing when we release it, we now call close() on it defensively. Result: We no longer leak connections when the server fails to close them. Fixes swift-server#324.
Motivation: Currently when either we or the server send Connection: close, we correctly do not return that connection to the pool. However, we rely on the server actually performing the connection closure: we never call close() ourselves. This is unnecessarily optimistic: a server may absolutely fail to close this connection. To protect our own file descriptors, we should make sure that any connection we do not return the pool is closed. Modifications: If we think a connection is closing when we release it, we now call close() on it defensively. Result: We no longer leak connections when the server fails to close them. Fixes swift-server#324.
Motivation: Currently when either we or the server send Connection: close, we correctly do not return that connection to the pool. However, we rely on the server actually performing the connection closure: we never call close() ourselves. This is unnecessarily optimistic: a server may absolutely fail to close this connection. To protect our own file descriptors, we should make sure that any connection we do not return the pool is closed. Modifications: If we think a connection is closing when we release it, we now call close() on it defensively. Result: We no longer leak connections when the server fails to close them. Fixes #324.
Hi there,
I'm trying to perform some requests to an embedded device in my local network (by IP address). I noticed that after a few requests, the device would stop responding (requests would time out). It looks like the device supports a limited number of concurrent connections / open sockets, so after going over the limit, requests time out.
The embedded device sets the
Connection: close
header, but looking inside the Active Connections panel in Xcode, I notice that the connections are not being closed:The only workaround I found was to shutdown the
HTTPClient
used to make the request and create a new one for the next request.I'm running macOS 11, and the issue happens on both release and debug builds. My code is very similar to the sample code on the README (I don't think I'm doing anything that would cause this issue).
Any ideas?
Thanks in advance!
Environment:
The text was updated successfully, but these errors were encountered: