Merge "Fixed handling http redirects"
This commit is contained in:
commit
485fb77a88
|
@ -93,9 +93,23 @@ class ResumableResponse(StreamWrapper):
|
||||||
self.stream = response.stream
|
self.stream = response.stream
|
||||||
|
|
||||||
|
|
||||||
class RetryHandler(urllib.BaseHandler):
|
class RetryHandler(urllib.HTTPRedirectHandler):
|
||||||
"""urllib Handler to add ability for retrying on server errors."""
|
"""urllib Handler to add ability for retrying on server errors."""
|
||||||
|
|
||||||
|
def redirect_request(self, req, fp, code, msg, headers, newurl):
|
||||||
|
new_req = urllib.HTTPRedirectHandler.redirect_request(
|
||||||
|
self, req, fp, code, msg, headers, newurl
|
||||||
|
)
|
||||||
|
if new_req is not None:
|
||||||
|
# We use class assignment for casting new request to type
|
||||||
|
# RetryableRequest
|
||||||
|
new_req.__class__ = RetryableRequest
|
||||||
|
new_req.retries_left = req.retries_left
|
||||||
|
new_req.offset = req.offset
|
||||||
|
new_req.start_time = req.start_time
|
||||||
|
new_req.retry_interval = req.retry_interval
|
||||||
|
return new_req
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def http_request(request):
|
def http_request(request):
|
||||||
"""Initialises http request.
|
"""Initialises http request.
|
||||||
|
@ -118,6 +132,11 @@ class RetryHandler(urllib.BaseHandler):
|
||||||
:return: ResumableResponse if success otherwise same response
|
:return: ResumableResponse if success otherwise same response
|
||||||
"""
|
"""
|
||||||
code, msg = response.getcode(), response.msg
|
code, msg = response.getcode(), response.msg
|
||||||
|
|
||||||
|
if 300 <= code < 400:
|
||||||
|
# the redirect group, pass to next handler as is
|
||||||
|
return response
|
||||||
|
|
||||||
# the server should response partial content if range is specified
|
# the server should response partial content if range is specified
|
||||||
if request.offset > 0 and code != http_client.PARTIAL_CONTENT:
|
if request.offset > 0 and code != http_client.PARTIAL_CONTENT:
|
||||||
raise RangeError(msg)
|
raise RangeError(msg)
|
||||||
|
|
|
@ -268,6 +268,25 @@ class TestRetryHandler(base.TestCase):
|
||||||
self.handler.http_response(request, response_mock)
|
self.handler.http_response(request, response_mock)
|
||||||
self.handler.parent.open.assert_called_once_with(request)
|
self.handler.parent.open.assert_called_once_with(request)
|
||||||
|
|
||||||
|
@mock.patch(
|
||||||
|
'packetary.library.connections.urllib.'
|
||||||
|
'HTTPRedirectHandler.redirect_request'
|
||||||
|
)
|
||||||
|
def test_redirect_request(self, redirect_mock, _):
|
||||||
|
redirect_mock.return_value = connections.urllib.Request(
|
||||||
|
'http://localhost/'
|
||||||
|
)
|
||||||
|
req = mock.MagicMock(retries_left=10, retry_interval=5, offset=100)
|
||||||
|
new_req = self.handler.redirect_request(req, -1, 301, "", {}, "")
|
||||||
|
self.assertIsInstance(new_req, connections.RetryableRequest)
|
||||||
|
self.assertEqual(req.retries_left, new_req.retries_left)
|
||||||
|
self.assertEqual(req.retry_interval, new_req.retry_interval)
|
||||||
|
self.assertEqual(req.offset, new_req.offset)
|
||||||
|
redirect_mock.return_value = None
|
||||||
|
self.assertIsNone(
|
||||||
|
self.handler.redirect_request(req, -1, 301, "", {}, "")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestResumeableResponse(base.TestCase):
|
class TestResumeableResponse(base.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
Loading…
Reference in New Issue