diff --git a/.gitignore b/.gitignore index ef0234688a5..04fe8034644 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,6 @@ var/* .noseids docs/_build/ nosetests.xml -cover \ No newline at end of file +cover +.idea +pyvenv \ No newline at end of file diff --git a/aiohttp/client.py b/aiohttp/client.py index b3f3af1f88f..5f0810f84b5 100644 --- a/aiohttp/client.py +++ b/aiohttp/client.py @@ -90,6 +90,7 @@ def request(method, url, *, """ redirects = 0 + method = method.upper() if loop is None: loop = asyncio.get_event_loop() if request_class is None: @@ -120,12 +121,18 @@ def request(method, url, *, raise aiohttp.OsConnectionError(exc) # redirects - if resp.status in (301, 302) and allow_redirects: + if resp.status in (301, 302, 303, 307) and allow_redirects: redirects += 1 if max_redirects and redirects >= max_redirects: resp.close(force=True) break + # For 301 and 302, mimic IE behaviour, now changed in RFC. Details: https://github.com/kennethreitz/requests/pull/269 + if resp.status != 307: + method = 'GET' + data = None + cookies = resp.cookies + r_url = resp.headers.get('LOCATION') or resp.headers.get('URI') scheme = urllib.parse.urlsplit(r_url)[0] diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py index f862f63743f..5073b26af33 100644 --- a/tests/test_client_functional.py +++ b/tests/test_client_functional.py @@ -202,6 +202,19 @@ def test_HTTP_302_REDIRECT_POST(self): content = self.loop.run_until_complete(r.content.read()) content = content.decode() + self.assertEqual(r.status, 200) + self.assertIn('"method": "GET"', content) + self.assertEqual(2, httpd['redirects']) + r.close() + + def test_HTTP_307_REDIRECT_POST(self): + with test_utils.run_server(self.loop, router=Functional) as httpd: + r = self.loop.run_until_complete( + client.request('post', httpd.url('redirect_307', 2), + data={'some': 'data'}, loop=self.loop)) + content = self.loop.run_until_complete(r.content.read()) + content = content.decode() + self.assertEqual(r.status, 200) self.assertIn('"method": "POST"', content) self.assertEqual(2, httpd['redirects']) @@ -933,6 +946,20 @@ def redirect(self, match): self._start_response(302), headers={'Location': self._path}) + @test_utils.Router.define('/redirect_307/([0-9]+)$') + def redirect_307(self, match): + no = int(match.group(1).upper()) + rno = self._props['redirects'] = self._props.get('redirects', 0) + 1 + + if rno >= no: + self._response( + self._start_response(307), + headers={'Location': '/method/%s' % self._method.lower()}) + else: + self._response( + self._start_response(307), + headers={'Location': self._path}) + @test_utils.Router.define('/encoding/(gzip|deflate)$') def encoding(self, match): mode = match.group(1)