This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author martin.panter
Recipients WildCard65, berker.peksag, martin.panter, paul.moore, steve.dower, terry.reedy, tim.golden, vstinner, zach.ware
Date 2018-01-05.10:32:39
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1515148359.54.0.467229070634.issue25095@psf.upfronthosting.co.za>
In-reply-to
Content
In the server, the send_header("Connection", "close") call sets the “close_connection” flag. This shuts down the connection once “do_GET” returns. Without the flag set, the server will wait and read another request.

If you want the server to shut the connection down, I suggest to be explicit in setting “close_connection”. It should work even if no “Connection: close” appears in the HTTP protocol. The special behaviour of “send_header” I think you are relying on is not documented.

On my Linux computer with the original code, I think the client shuts the connection down. This causes the server to see an empty “raw_requestline” and return from “handle_one_request”. It returns to “serve_forever” where it polls the “__shutdown_request” flag and sees that it should stop.

The client shuts down the connection only because of subtleties in how the HTTP client manages the socket and how sockets are garbage collected. The response does not have Content-Length nor Transfer-Encoding fields, and would be terminated by the server shutting the connection down. So the HTTPConnection object cannot reuse the TCP connection and hands ownership to the HTTPResponse object returned by “getresponse”. Since this object is not saved anywhere, it gets garbage collected, which closes the socket and shuts the connection down. But perhaps on Windows the shutdown doesn’t happen, or perhaps the garbage collector is too slow.

If I am right, closing the HTTPResponse object would also fix the deadlock. It is good practice to close the underlying socket anyway:

with support.captured_stderr() as err:
    self.con.request('GET', '/')
    res = self.con.getresponse()
    
    # Shut down connection to stop the server reading from it
    res.close()
    self.con.close()
History
Date User Action Args
2018-01-05 10:32:39martin.pantersetrecipients: + martin.panter, terry.reedy, paul.moore, vstinner, tim.golden, berker.peksag, zach.ware, steve.dower, WildCard65
2018-01-05 10:32:39martin.pantersetmessageid: <1515148359.54.0.467229070634.issue25095@psf.upfronthosting.co.za>
2018-01-05 10:32:39martin.panterlinkissue25095 messages
2018-01-05 10:32:39martin.pantercreate