aboutsummaryrefslogtreecommitdiffstats
path: root/build/f_repos/patch/fuel-mirror/0001-Fixed-handling-http-redirects.patch
blob: b82be11280d3edc0c672bdb821d5689789e0a208 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
From: Bulat Gaifullin <bgaifullin@mirantis.com>
Date: Fri, 24 Jun 2016 15:52:41 +0200
Subject: [PATCH] Fixed handling http redirects

Override method 'redirect_request' for patching
new request, that has been created on handling
http redirect.

Change-Id: I40db406e2377bebec1113639b91a0b5262e2e9ad
Closes-Bug: 1593674
(cherry picked from commit 192a3d9f8f993afb12c5108dd9339c6688c23e11)
---
 packetary/library/connections.py    | 21 ++++++++++++++++++++-
 packetary/tests/test_connections.py | 19 +++++++++++++++++++
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/packetary/library/connections.py b/packetary/library/connections.py
index 36a7a84..49b6c9b 100644
--- a/packetary/library/connections.py
+++ b/packetary/library/connections.py
@@ -93,9 +93,23 @@ class ResumableResponse(StreamWrapper):
                 self.stream = response.stream


-class RetryHandler(urllib.BaseHandler):
+class RetryHandler(urllib.HTTPRedirectHandler):
     """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
     def http_request(request):
         """Initialises http request.
@@ -118,6 +132,11 @@ class RetryHandler(urllib.BaseHandler):
         :return: ResumableResponse if success otherwise same response
         """
         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
         if request.offset > 0 and code != 206:
             raise RangeError(msg)
diff --git a/packetary/tests/test_connections.py b/packetary/tests/test_connections.py
index a2621c8..c80b03d 100644
--- a/packetary/tests/test_connections.py
+++ b/packetary/tests/test_connections.py
@@ -268,6 +268,25 @@ class TestRetryHandler(base.TestCase):
         self.handler.http_response(request, response_mock)
         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):
     def setUp(self):