Merge pull request #1944 from schlamar/redirect-decoding

Catch errors while handling redirects
This commit is contained in:
2014-05-12 16:50:33 -04:00
3 changed files with 50 additions and 9 deletions
+1 -6
View File
@@ -385,9 +385,4 @@ class HTTPAdapter(BaseAdapter):
else:
raise
r = self.build_response(request, resp)
if not stream:
r.content
return r
return self.build_response(request, resp)
+9 -2
View File
@@ -19,7 +19,8 @@ from .cookies import (
from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT
from .hooks import default_hooks, dispatch_hook
from .utils import to_key_val_list, default_headers, to_native_string
from .exceptions import TooManyRedirects, InvalidSchema
from .exceptions import (
TooManyRedirects, InvalidSchema, ChunkedEncodingError, ContentDecodingError)
from .structures import CaseInsensitiveDict
from .adapters import HTTPAdapter
@@ -94,7 +95,10 @@ class SessionRedirectMixin(object):
while resp.is_redirect:
prepared_request = req.copy()
resp.content # Consume socket so it can be released
try:
resp.content # Consume socket so it can be released
except (ChunkedEncodingError, ContentDecodingError, RuntimeError):
resp.raw.read(decode_content=False)
if i >= self.max_redirects:
raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects)
@@ -588,6 +592,9 @@ class Session(SessionRedirectMixin):
r = history.pop()
r.history = history
if not stream:
r.content
return r
def get_adapter(self, url):
+40 -1
View File
@@ -917,6 +917,45 @@ class RequestsTestCase(unittest.TestCase):
assert h1 == h2
def test_manual_redirect_with_partial_body_read(self):
s = requests.Session()
r1 = s.get(httpbin('redirect/2'), allow_redirects=False, stream=True)
assert r1.is_redirect
rg = s.resolve_redirects(r1, r1.request, stream=True)
# read only the first eight bytes of the response body,
# then follow the redirect
r1.iter_content(8)
r2 = next(rg)
assert r2.is_redirect
# read all of the response via iter_content,
# then follow the redirect
for _ in r2.iter_content():
pass
r3 = next(rg)
assert not r3.is_redirect
def _patch_adapter_gzipped_redirect(self, session, url):
adapter = session.get_adapter(url=url)
org_build_response = adapter.build_response
self._patched_response = False
def build_response(*args, **kwargs):
resp = org_build_response(*args, **kwargs)
if not self._patched_response:
resp.raw.headers['content-encoding'] = 'gzip'
self._patched_response = True
return resp
adapter.build_response = build_response
def test_redirect_with_wrong_gzipped_header(self):
s = requests.Session()
url = httpbin('redirect/1')
self._patch_adapter_gzipped_redirect(s, url)
s.get(url)
class TestContentEncodingDetection(unittest.TestCase):
@@ -1321,7 +1360,7 @@ def test_data_argument_accepts_tuples(list_of_tuples):
hooks=default_hooks()
)
assert p.body == urlencode(data)
if __name__ == '__main__':
unittest.main()