From: Jeremy Hylton Date: Tue, 24 Feb 2004 19:40:35 +0000 (+0000) Subject: Fix two bugs in the new do_open() implementation for HTTPHandler. X-Git-Tag: v2.4a1~775 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b3ee6f9921a0979b77a64b83f2f3a267ae66916e;p=python Fix two bugs in the new do_open() implementation for HTTPHandler. Invoke the standard error handlers for non-200 responses. Always supply a "Connection: close" header to prevent the server from leaving the connection open. Downstream users of the socket may attempt recv()/read() with no arguments, which would block if the connection were kept open. --- diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index 87de229768..f38a4a3f40 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -461,7 +461,8 @@ class HandlerTests(unittest.TestCase): self.assertEqual(http.method, method) self.assertEqual(http.selector, "/") self.assertEqual(http.req_headers, - [("Foo", "bar"), ("Spam", "eggs")]) + [("Connection", "close"), + ("Foo", "bar"), ("Spam", "eggs")]) self.assertEqual(http.data, data) # check socket.error converted to URLError diff --git a/Lib/urllib2.py b/Lib/urllib2.py index 9f6dc6309f..cd0cfc18e1 100644 --- a/Lib/urllib2.py +++ b/Lib/urllib2.py @@ -957,18 +957,29 @@ class AbstractHTTPHandler(BaseHandler): headers = dict(req.headers) headers.update(req.unredirected_hdrs) + # We want to make an HTTP/1.1 request, but the addinfourl + # class isn't prepared to deal with a persistent connection. + # It will try to read all remaining data from the socket, + # which will block while the server waits for the next request. + # So make sure the connection gets closed after the (only) + # request. + headers["Connection"] = "close" try: h.request(req.get_method(), req.get_selector(), req.data, headers) r = h.getresponse() except socket.error, err: # XXX what error? raise URLError(err) - # Pick apart the HTTPResponse object to get the various pieces - # of the - resp = addinfourl(r.fp, r.msg, req.get_full_url()) - resp.code = r.status - resp.msg = r.reason - return resp + if r.status == 200: + # Pick apart the HTTPResponse object to get the addinfourl + # object initialized properly + resp = addinfourl(r.fp, r.msg, req.get_full_url()) + resp.code = r.status + resp.msg = r.reason + return resp + else: + return self.parent.error("http", req, r.fp, r.status, r.msg, + r.msg.dict) class HTTPHandler(AbstractHTTPHandler):