diff options
author | Andrey Petrov <shazow@gmail.com> | 2015-04-28 14:25:07 -0400 |
---|---|---|
committer | Andrey Petrov <shazow@gmail.com> | 2015-04-28 14:25:07 -0400 |
commit | 22a9713fab2ed831204711906a974c3beba3319e (patch) | |
tree | 3276272e8659ef01961cd66f68d8f11d110305bf | |
parent | 7906b5f166da93c61ddd41608cd64d920953a9cd (diff) | |
parent | 697362076d23983744602d8682f6fc6b10188e80 (diff) | |
download | urllib3-22a9713fab2ed831204711906a974c3beba3319e.tar.gz |
Merge pull request #605 from sigmavirus24/bug/601
Learn from httplib how to handle chunked HEAD requests
-rw-r--r-- | test/with_dummyserver/test_socketlevel.py | 30 | ||||
-rw-r--r-- | urllib3/response.py | 10 |
2 files changed, 38 insertions, 2 deletions
diff --git a/test/with_dummyserver/test_socketlevel.py b/test/with_dummyserver/test_socketlevel.py index 9872249e..6c996538 100644 --- a/test/with_dummyserver/test_socketlevel.py +++ b/test/with_dummyserver/test_socketlevel.py @@ -616,3 +616,33 @@ class TestHeaders(SocketDummyServerTestCase): HEADERS = {'Content-Length': '0', 'Content-type': 'text/plain'} r = pool.request('GET', '/') self.assertEqual(HEADERS, dict(r.headers.items())) # to preserve case sensitivity + + +class TestHEAD(SocketDummyServerTestCase): + def test_chunked_head_response_does_not_hang(self): + handler = create_response_handler( + b'HTTP/1.1 200 OK\r\n' + b'Transfer-Encoding: chunked\r\n' + b'Content-type: text/plain\r\n' + b'\r\n' + ) + self._start_server(handler) + pool = HTTPConnectionPool(self.host, self.port, retries=False) + r = pool.request('HEAD', '/', timeout=1, preload_content=False) + + # stream will use the read_chunked method here. + self.assertEqual([], list(r.stream())) + + def test_empty_head_response_does_not_hang(self): + handler = create_response_handler( + b'HTTP/1.1 200 OK\r\n' + b'Content-Length: 256\r\n' + b'Content-type: text/plain\r\n' + b'\r\n' + ) + self._start_server(handler) + pool = HTTPConnectionPool(self.host, self.port, retries=False) + r = pool.request('HEAD', '/', timeout=1, preload_content=False) + + # stream will use the read method here. + self.assertEqual([], list(r.stream())) diff --git a/urllib3/response.py b/urllib3/response.py index e0236e5d..24140c4c 100644 --- a/urllib3/response.py +++ b/urllib3/response.py @@ -432,11 +432,17 @@ class HTTPResponse(io.IOBase): 'content-encoding' header. """ self._init_decoder() - # FIXME: Rewrite this method and make it a class with - # a better structured logic. + # FIXME: Rewrite this method and make it a class with a better structured logic. if not self.chunked: raise ResponseNotChunked("Response is not chunked. " "Header 'transfer-encoding: chunked' is missing.") + + if self._original_response and self._original_response._method.upper() == 'HEAD': + # Don't bother reading the body of a HEAD request. + # FIXME: Can we do this somehow without accessing private httplib _method? + self._original_response.close() + return + while True: self._update_chunk_length() if self.chunk_left == 0: |