Merge ~adam-collard/simplestreams:remove-requests-read-timeout into simplestreams:master

Proposed by Adam Collard
Status: Merged
Approved by: Paride Legovini
Approved revision: 10bf9cc60f5c35a996f32a0300d831b40526e00e
Merge reported by: Server Team CI bot
Merged at revision: not available
Proposed branch: ~adam-collard/simplestreams:remove-requests-read-timeout
Merge into: simplestreams:master
Diff against target: 110 lines (+29/-10)
2 files modified
simplestreams/contentsource.py (+18/-8)
tests/unittests/test_contentsource.py (+11/-2)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve
Paride Legovini Approve
Review via email: mp+409434@code.launchpad.net

Commit message

Remove requests read timeout, whilst retaining connect timeout

Drive-by: make the negative tests actually test negative sizes

Fix for bug introduced in f37d2ed - the intention there was only
for a connect timeout and not a read timeout.

Description of the change

Changed the timeout to just over a multiple of 3s to match advice in https://docs.python-requests.org/en/master/user/advanced/#timeouts

To post a comment you must log in.
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Paride Legovini (paride) wrote :

LGTM, thanks for the pointer on why 9.05s, TIL!

review: Approve
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

Commit message lints:
- Line #4 has 36 too many characters. Line starts with: "Fix for bug introduced"...

review: Needs Fixing
Revision history for this message
Paride Legovini (paride) wrote (last edit ):

Rewrapped

review: Approve
Revision history for this message
Server Team CI bot (server-team-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/simplestreams/contentsource.py b/simplestreams/contentsource.py
2index b54e898..55028a7 100644
3--- a/simplestreams/contentsource.py
4+++ b/simplestreams/contentsource.py
5@@ -32,7 +32,7 @@ else:
6 urllib_error = urllib_request
7
8 READ_BUFFER_SIZE = 1024 * 10
9-TIMEOUT = 10
10+TIMEOUT = 9.05
11
12 try:
13 # We try to use requests because we can do gzip encoding with it.
14@@ -322,6 +322,9 @@ class FileReader(UrlReader):
15
16
17 class Urllib2UrlReader(UrlReader):
18+
19+ timeout = TIMEOUT
20+
21 def __init__(self, url, offset=None, user_agent=None):
22 (url, username, password) = parse_url_auth(url)
23 self.url = url
24@@ -339,7 +342,7 @@ class Urllib2UrlReader(UrlReader):
25 req.add_header('User-Agent', user_agent)
26 if offset is not None:
27 req.add_header('Range', 'bytes=%d-' % offset)
28- self.req = opener(req, timeout=TIMEOUT)
29+ self.req = opener(req, timeout=self.timeout)
30 except urllib_error.HTTPError as e:
31 if e.code == 404:
32 myerr = IOError("Unable to open %s" % url)
33@@ -355,11 +358,18 @@ class Urllib2UrlReader(UrlReader):
34
35
36 class RequestsUrlReader(UrlReader):
37- # This provides a url reader that supports deflate/gzip encoding
38- # but still implements 'read'.
39- # r = RequestsUrlReader(http://example.com)
40- # r.read(10)
41- # r.close()
42+ """
43+ This provides a url reader that supports deflate/gzip encoding
44+ but still implements 'read'.
45+ r = RequestsUrlReader('http://example.com')
46+ r.read(10)
47+ r.close()
48+ """
49+
50+ # requests takes a 2-tuple for timeout, the first being a
51+ # connect timeout, the second being a read timeout.
52+ timeout = (TIMEOUT, None)
53+
54 def __init__(self, url, buflen=None, offset=None, user_agent=None):
55 if requests is None:
56 raise ImportError("Attempt to use RequestsUrlReader "
57@@ -380,7 +390,7 @@ class RequestsUrlReader(UrlReader):
58 headers = None
59
60 self.req = requests.get(
61- url, stream=True, auth=auth, headers=headers, timeout=TIMEOUT
62+ url, stream=True, auth=auth, headers=headers, timeout=self.timeout
63 )
64 self.r_iter = None
65 if buflen is None:
66diff --git a/tests/unittests/test_contentsource.py b/tests/unittests/test_contentsource.py
67index 6487494..77a566d 100644
68--- a/tests/unittests/test_contentsource.py
69+++ b/tests/unittests/test_contentsource.py
70@@ -170,6 +170,11 @@ class TestUrlContentSource(BaseDirUsingTestCase):
71 self.assertEqual(data, self.fdata)
72
73 @skipIf(contentsource.requests is None, "requests not available")
74+ def test_requests_default_timeout(self):
75+ self.assertEqual(contentsource.RequestsUrlReader.timeout,
76+ (contentsource.TIMEOUT, None))
77+
78+ @skipIf(contentsource.requests is None, "requests not available")
79 def test_requests_url_read_handles_None(self):
80 scs = self.getcs(self.fpath, contentsource.RequestsUrlReader)
81 data = scs.read(None)
82@@ -178,7 +183,7 @@ class TestUrlContentSource(BaseDirUsingTestCase):
83 @skipIf(contentsource.requests is None, "requests not available")
84 def test_requests_url_read_handles_negative_size(self):
85 scs = self.getcs(self.fpath, contentsource.RequestsUrlReader)
86- data = scs.read(None)
87+ data = scs.read(-2)
88 self.assertEqual(data, self.fdata)
89
90 @skipIf(contentsource.requests is None, "requests not available")
91@@ -193,6 +198,10 @@ class TestUrlContentSource(BaseDirUsingTestCase):
92 data = scs.read(3)
93 self.assertEqual(data, self.fdata[0:3])
94
95+ def test_urllib_default_timeout(self):
96+ self.assertEqual(contentsource.Urllib2UrlReader.timeout,
97+ contentsource.TIMEOUT)
98+
99 def test_urllib_url_read_handles_None(self):
100 scs = self.getcs(self.fpath, contentsource.Urllib2UrlReader)
101 data = scs.read(None)
102@@ -200,7 +209,7 @@ class TestUrlContentSource(BaseDirUsingTestCase):
103
104 def test_urllib_url_read_handles_negative_size(self):
105 scs = self.getcs(self.fpath, contentsource.Urllib2UrlReader)
106- data = scs.read(None)
107+ data = scs.read(-2)
108 self.assertEqual(data, self.fdata)
109
110 def test_urllib_url_read_handles_no_size(self):

Subscribers

People subscribed via source and target branches