-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
Description
Description
While reviewing the close method in (
Lines 1015 to 1028 in 5e73ece
| def close(self): | |
| """Close the connection to the HTTP server.""" | |
| self.__state = _CS_IDLE | |
| try: | |
| sock = self.sock | |
| if sock: | |
| self.sock = None | |
| sock.close() # close it manually... there may be other refs | |
| finally: | |
| response = self.__response | |
| if response: | |
| self.__response = None | |
| response.close() | |
close() (line 1022), without first calling shutdown().
This is similar to what I previously reported in issue #130850, where _close_self_pipe in asyncio.selector_events also closes sockets without calling shutdown() first.
Code Reference
Currently, the code is as follows:
def close(self):
"""Close the connection to the HTTP server."""
self.__state = _CS_IDLE
try:
sock = self.sock
if sock:
self.sock = None
sock.close() # close it manually... there may be other refs
finally:
response = self.__response
if response:
self.__response = None
response.close()Question
Would there be any potential downsides or benefits to adding a shutdown(socket.SHUT_RDWR) call before close() in this case?
Possible Benefits
- Ensures that all pending data is properly discarded before closing, particularly in scenarios where data might still be buffered.
- Prevents potential issues with lingering resources in some edge cases.
- Aligns with best practices for socket cleanup.
- Can help avoid RST (reset by peer) issues in some network conditions.
Possible Change
def close(self):
"""Close the connection to the HTTP server."""
self.__state = _CS_IDLE
try:
sock = self.sock
if sock:
self.sock = None
try:
sock.shutdown(socket.SHUT_RDWR) # Gracefully terminate the connection
except OSError:
pass # Ignore errors if the socket is already closed
sock.close() # Close it manually... there may be other refs
finally:
response = self.__response
if response:
self.__response = None
response.close()Reference
The Python socket documentation states:
"close() releases the resource associated with a connection but does not necessarily close the connection immediately. If you want to close the connection in a timely fashion, call shutdown() before close()."
π Python socket documentation
Since a similar discussion is happening in #130850, I wanted to bring attention to this case in http.client as well.
Looking forward to your thoughts!