Make sure the HTTP socket is closed when the urlopen() response object is closed --- /lib/python3.3/urllib/request.py 2013-12-06 12:19:39.497101991 +0000 +++ /lib/python3.3/urllib/request.py 2013-12-06 12:15:51.926917269 +0000 @@ -1245,12 +1245,19 @@ class AbstractHTTPHandler(BaseHandler): h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: - h.request(req.get_method(), req.selector, req.data, headers) - except socket.error as err: # timeout error - h.close() - raise URLError(err) - else: + try: + h.request(req.get_method(), req.selector, req.data, headers) + except socket.error as err: # timeout error + raise URLError(err) r = h.getresponse() + except: + h.close() + raise + # Explicitly close the original socket object now + # to guarantee that the connection closes + # when the response closes its socket.makefile() object + if h.sock: + h.sock.close() r.url = req.get_full_url() # This line replaces the .msg attribute of the HTTPResponse --- /lib/python3.3/test/test_urllib2.py 2013-12-06 12:21:23.378709619 +0000 +++ /lib/python3.3/test/test_urllib2.py 2013-12-06 12:01:38.850391435 +0000 @@ -284,6 +285,7 @@ class MockHTTPClass: self.data = None self.raise_on_endheaders = False self._tunnel_headers = {} + self.sock = None def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): self.host = host