Fix redirection error when the Location header value starts with 3 slashes (#4042)

This commit is contained in:
Amardeep Bhowmick 2019-10-30 13:39:12 +05:30 committed by Adrián Chaves
parent be2e910dd0
commit 66cbceeb0a
2 changed files with 21 additions and 2 deletions

View File

@ -1,5 +1,5 @@
import logging
from six.moves.urllib.parse import urljoin
from six.moves.urllib.parse import urljoin, urlparse
from w3lib.url import safe_url_string
@ -70,7 +70,10 @@ class RedirectMiddleware(BaseRedirectMiddleware):
if 'Location' not in response.headers or response.status not in allowed_status:
return response
location = safe_url_string(response.headers['location'])
location = safe_url_string(response.headers['Location'])
if response.headers['Location'].startswith(b'//'):
request_scheme = urlparse(request.url).scheme
location = request_scheme + '://' + location.lstrip('/')
redirected_url = urljoin(request.url, location)

View File

@ -106,6 +106,22 @@ class RedirectMiddlewareTest(unittest.TestCase):
del rsp.headers['Location']
assert self.mw.process_response(req, rsp, self.spider) is rsp
def test_redirect_302_relative(self):
url = 'http://www.example.com/302'
url2 = '///i8n.example2.com/302'
url3 = 'http://i8n.example2.com/302'
req = Request(url, method='HEAD')
rsp = Response(url, headers={'Location': url2}, status=302)
req2 = self.mw.process_response(req, rsp, self.spider)
assert isinstance(req2, Request)
self.assertEqual(req2.url, url3)
self.assertEqual(req2.method, 'HEAD')
# response without Location header but with status code is 3XX should be ignored
del rsp.headers['Location']
assert self.mw.process_response(req, rsp, self.spider) is rsp
def test_max_redirect_times(self):
self.mw.max_redirect_times = 1