summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Petrov <shazow@gmail.com>2015-04-28 14:25:07 -0400
committerAndrey Petrov <shazow@gmail.com>2015-04-28 14:25:07 -0400
commit22a9713fab2ed831204711906a974c3beba3319e (patch)
tree3276272e8659ef01961cd66f68d8f11d110305bf
parent7906b5f166da93c61ddd41608cd64d920953a9cd (diff)
parent697362076d23983744602d8682f6fc6b10188e80 (diff)
downloadurllib3-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.py30
-rw-r--r--urllib3/response.py10
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: