rigid 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/vendor/click/__init__.pyc +0 -0
- data/vendor/click/_bashcomplete.pyc +0 -0
- data/vendor/click/_compat.pyc +0 -0
- data/vendor/click/_termui_impl.pyc +0 -0
- data/vendor/click/_textwrap.pyc +0 -0
- data/vendor/click/_unicodefun.pyc +0 -0
- data/vendor/click/_winconsole.pyc +0 -0
- data/vendor/click/core.pyc +0 -0
- data/vendor/click/decorators.pyc +0 -0
- data/vendor/click/exceptions.pyc +0 -0
- data/vendor/click/formatting.pyc +0 -0
- data/vendor/click/globals.pyc +0 -0
- data/vendor/click/parser.pyc +0 -0
- data/vendor/click/termui.pyc +0 -0
- data/vendor/click/testing.pyc +0 -0
- data/vendor/click/types.pyc +0 -0
- data/vendor/click/utils.pyc +0 -0
- data/vendor/easy_install.pyc +0 -0
- data/vendor/pkg_resources/__init__.pyc +0 -0
- data/vendor/pkg_resources/_vendor/__init__.pyc +0 -0
- data/vendor/pkg_resources/_vendor/appdirs.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/__about__.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/__init__.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/_compat.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/_structures.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/markers.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/requirements.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/specifiers.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/utils.pyc +0 -0
- data/vendor/pkg_resources/_vendor/packaging/version.pyc +0 -0
- data/vendor/pkg_resources/_vendor/pyparsing.pyc +0 -0
- data/vendor/pkg_resources/_vendor/six.pyc +0 -0
- data/vendor/pkg_resources/extern/__init__.pyc +0 -0
- data/vendor/{requests-2.11.1.dist-info/METADATA → requests-2.12.1.dist-info/DESCRIPTION.rst} +51 -30
- data/vendor/{requests-2.11.1.dist-info → requests-2.12.1.dist-info}/INSTALLER +0 -0
- data/vendor/{requests-2.11.1.dist-info/DESCRIPTION.rst → requests-2.12.1.dist-info/METADATA} +80 -1
- data/vendor/{requests-2.11.1.dist-info → requests-2.12.1.dist-info}/RECORD +61 -41
- data/vendor/{requests-2.11.1.dist-info → requests-2.12.1.dist-info}/WHEEL +1 -1
- data/vendor/requests-2.12.1.dist-info/metadata.json +1 -0
- data/vendor/{requests-2.11.1.dist-info → requests-2.12.1.dist-info}/top_level.txt +0 -0
- data/vendor/requests/__init__.py +2 -2
- data/vendor/requests/__init__.pyc +0 -0
- data/vendor/requests/_internal_utils.py +27 -0
- data/vendor/requests/_internal_utils.pyc +0 -0
- data/vendor/requests/adapters.py +1 -1
- data/vendor/requests/adapters.pyc +0 -0
- data/vendor/requests/api.py +3 -1
- data/vendor/requests/api.pyc +0 -0
- data/vendor/requests/auth.py +2 -1
- data/vendor/requests/auth.pyc +0 -0
- data/vendor/requests/cacert.pem +448 -375
- data/vendor/requests/certs.pyc +0 -0
- data/vendor/requests/compat.py +2 -0
- data/vendor/requests/compat.pyc +0 -0
- data/vendor/requests/cookies.py +3 -1
- data/vendor/requests/cookies.pyc +0 -0
- data/vendor/requests/exceptions.py +2 -0
- data/vendor/requests/exceptions.pyc +0 -0
- data/vendor/requests/hooks.pyc +0 -0
- data/vendor/requests/models.py +53 -29
- data/vendor/requests/models.pyc +0 -0
- data/vendor/requests/packages/__init__.py +6 -0
- data/vendor/requests/packages/__init__.pyc +0 -0
- data/vendor/requests/packages/chardet/__init__.pyc +0 -0
- data/vendor/requests/packages/chardet/big5freq.pyc +0 -0
- data/vendor/requests/packages/chardet/big5prober.pyc +0 -0
- data/vendor/requests/packages/chardet/chardetect.pyc +0 -0
- data/vendor/requests/packages/chardet/chardistribution.pyc +0 -0
- data/vendor/requests/packages/chardet/charsetgroupprober.pyc +0 -0
- data/vendor/requests/packages/chardet/charsetprober.pyc +0 -0
- data/vendor/requests/packages/chardet/codingstatemachine.pyc +0 -0
- data/vendor/requests/packages/chardet/compat.pyc +0 -0
- data/vendor/requests/packages/chardet/constants.pyc +0 -0
- data/vendor/requests/packages/chardet/cp949prober.pyc +0 -0
- data/vendor/requests/packages/chardet/escprober.pyc +0 -0
- data/vendor/requests/packages/chardet/escsm.pyc +0 -0
- data/vendor/requests/packages/chardet/eucjpprober.pyc +0 -0
- data/vendor/requests/packages/chardet/euckrfreq.pyc +0 -0
- data/vendor/requests/packages/chardet/euckrprober.pyc +0 -0
- data/vendor/requests/packages/chardet/euctwfreq.pyc +0 -0
- data/vendor/requests/packages/chardet/euctwprober.pyc +0 -0
- data/vendor/requests/packages/chardet/gb2312freq.pyc +0 -0
- data/vendor/requests/packages/chardet/gb2312prober.pyc +0 -0
- data/vendor/requests/packages/chardet/hebrewprober.pyc +0 -0
- data/vendor/requests/packages/chardet/jisfreq.pyc +0 -0
- data/vendor/requests/packages/chardet/jpcntx.pyc +0 -0
- data/vendor/requests/packages/chardet/langbulgarianmodel.pyc +0 -0
- data/vendor/requests/packages/chardet/langcyrillicmodel.pyc +0 -0
- data/vendor/requests/packages/chardet/langgreekmodel.pyc +0 -0
- data/vendor/requests/packages/chardet/langhebrewmodel.pyc +0 -0
- data/vendor/requests/packages/chardet/langhungarianmodel.pyc +0 -0
- data/vendor/requests/packages/chardet/langthaimodel.pyc +0 -0
- data/vendor/requests/packages/chardet/latin1prober.pyc +0 -0
- data/vendor/requests/packages/chardet/mbcharsetprober.pyc +0 -0
- data/vendor/requests/packages/chardet/mbcsgroupprober.pyc +0 -0
- data/vendor/requests/packages/chardet/mbcssm.pyc +0 -0
- data/vendor/requests/packages/chardet/sbcharsetprober.pyc +0 -0
- data/vendor/requests/packages/chardet/sbcsgroupprober.pyc +0 -0
- data/vendor/requests/packages/chardet/sjisprober.pyc +0 -0
- data/vendor/requests/packages/chardet/universaldetector.pyc +0 -0
- data/vendor/requests/packages/chardet/utf8prober.pyc +0 -0
- data/vendor/requests/packages/idna/__init__.py +1 -0
- data/vendor/requests/packages/idna/__init__.pyc +0 -0
- data/vendor/requests/packages/idna/codec.py +118 -0
- data/vendor/requests/packages/idna/codec.pyc +0 -0
- data/vendor/requests/packages/idna/compat.py +12 -0
- data/vendor/requests/packages/idna/compat.pyc +0 -0
- data/vendor/requests/packages/idna/core.py +387 -0
- data/vendor/requests/packages/idna/core.pyc +0 -0
- data/vendor/requests/packages/idna/idnadata.py +1584 -0
- data/vendor/requests/packages/idna/idnadata.pyc +0 -0
- data/vendor/requests/packages/idna/intranges.py +46 -0
- data/vendor/requests/packages/idna/intranges.pyc +0 -0
- data/vendor/requests/packages/idna/uts46data.py +7267 -0
- data/vendor/requests/packages/idna/uts46data.pyc +0 -0
- data/vendor/requests/packages/urllib3/__init__.py +2 -1
- data/vendor/requests/packages/urllib3/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/_collections.pyc +0 -0
- data/vendor/requests/packages/urllib3/connection.py +62 -26
- data/vendor/requests/packages/urllib3/connection.pyc +0 -0
- data/vendor/requests/packages/urllib3/connectionpool.py +25 -20
- data/vendor/requests/packages/urllib3/connectionpool.pyc +0 -0
- data/vendor/requests/packages/urllib3/contrib/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/contrib/appengine.py +87 -22
- data/vendor/requests/packages/urllib3/contrib/appengine.pyc +0 -0
- data/vendor/requests/packages/urllib3/contrib/ntlmpool.py +2 -5
- data/vendor/requests/packages/urllib3/contrib/ntlmpool.pyc +0 -0
- data/vendor/requests/packages/urllib3/contrib/pyopenssl.py +191 -118
- data/vendor/requests/packages/urllib3/contrib/pyopenssl.pyc +0 -0
- data/vendor/requests/packages/urllib3/contrib/socks.py +11 -5
- data/vendor/requests/packages/urllib3/contrib/socks.pyc +0 -0
- data/vendor/requests/packages/urllib3/exceptions.py +32 -0
- data/vendor/requests/packages/urllib3/exceptions.pyc +0 -0
- data/vendor/requests/packages/urllib3/fields.py +1 -1
- data/vendor/requests/packages/urllib3/fields.pyc +0 -0
- data/vendor/requests/packages/urllib3/filepost.py +1 -1
- data/vendor/requests/packages/urllib3/filepost.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/backports/__init__.py +0 -0
- data/vendor/requests/packages/urllib3/packages/backports/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/backports/makefile.py +53 -0
- data/vendor/requests/packages/urllib3/packages/backports/makefile.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/ordered_dict.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/six.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py +7 -1
- data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.py +55 -3
- data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.pyc +0 -0
- data/vendor/requests/packages/urllib3/poolmanager.py +2 -6
- data/vendor/requests/packages/urllib3/poolmanager.pyc +0 -0
- data/vendor/requests/packages/urllib3/request.py +1 -4
- data/vendor/requests/packages/urllib3/request.pyc +0 -0
- data/vendor/requests/packages/urllib3/response.py +94 -6
- data/vendor/requests/packages/urllib3/response.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/__init__.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/connection.py +1 -0
- data/vendor/requests/packages/urllib3/util/connection.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/request.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/response.py +7 -0
- data/vendor/requests/packages/urllib3/util/response.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/retry.py +93 -17
- data/vendor/requests/packages/urllib3/util/retry.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/ssl_.py +28 -12
- data/vendor/requests/packages/urllib3/util/ssl_.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/timeout.py +9 -6
- data/vendor/requests/packages/urllib3/util/timeout.pyc +0 -0
- data/vendor/requests/packages/urllib3/util/url.py +14 -5
- data/vendor/requests/packages/urllib3/util/url.pyc +0 -0
- data/vendor/requests/sessions.py +18 -5
- data/vendor/requests/sessions.pyc +0 -0
- data/vendor/requests/status_codes.pyc +0 -0
- data/vendor/requests/structures.pyc +0 -0
- data/vendor/requests/utils.py +42 -32
- data/vendor/requests/utils.pyc +0 -0
- data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/DESCRIPTION.rst +0 -0
- data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/INSTALLER +0 -0
- data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/METADATA +2 -2
- data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/RECORD +18 -18
- data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/WHEEL +0 -0
- data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/entry_points.txt +0 -0
- data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/metadata.json +1 -1
- data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/top_level.txt +0 -0
- data/vendor/rigid/__init__.pyc +0 -0
- data/vendor/rigid/api.py +39 -2
- data/vendor/rigid/api.pyc +0 -0
- data/vendor/rigid/commands/__init__.py +71 -11
- data/vendor/rigid/commands/__init__.pyc +0 -0
- data/vendor/rigid/commands/deploy.pyc +0 -0
- data/vendor/rigid/deploy.py +1 -1
- data/vendor/rigid/deploy.pyc +0 -0
- data/vendor/rigid/file_scanner.py +1 -1
- data/vendor/rigid/file_scanner.pyc +0 -0
- data/vendor/rigid/utils.pyc +0 -0
- data/vendor/tests/__init__.pyc +0 -0
- data/vendor/tests/integration/__init__.pyc +0 -0
- data/vendor/tests/integration/test_app.py +12 -0
- data/vendor/tests/integration/test_app.pyc +0 -0
- data/vendor/tests/integration/test_apps.pyc +0 -0
- data/vendor/tests/integration/test_deploy.pyc +0 -0
- data/vendor/tests/integration/test_domains.pyc +0 -0
- data/vendor/tests/integration/test_login.pyc +0 -0
- data/vendor/tests/integration/test_promote.py +2 -2
- data/vendor/tests/integration/test_promote.pyc +0 -0
- data/vendor/tests/integration/test_token.pyc +0 -0
- data/vendor/tests/integration/test_whoami.pyc +0 -0
- data/vendor/tests/test_deploy.pyc +0 -0
- data/vendor/tests/test_file_scanner.pyc +0 -0
- data/vendor/tests/utils.py +5 -2
- data/vendor/tests/utils.pyc +0 -0
- data/vendor/yaml/__init__.pyc +0 -0
- data/vendor/yaml/composer.pyc +0 -0
- data/vendor/yaml/constructor.pyc +0 -0
- data/vendor/yaml/cyaml.pyc +0 -0
- data/vendor/yaml/dumper.pyc +0 -0
- data/vendor/yaml/emitter.pyc +0 -0
- data/vendor/yaml/error.pyc +0 -0
- data/vendor/yaml/events.pyc +0 -0
- data/vendor/yaml/loader.pyc +0 -0
- data/vendor/yaml/nodes.pyc +0 -0
- data/vendor/yaml/parser.pyc +0 -0
- data/vendor/yaml/reader.pyc +0 -0
- data/vendor/yaml/representer.pyc +0 -0
- data/vendor/yaml/resolver.pyc +0 -0
- data/vendor/yaml/scanner.pyc +0 -0
- data/vendor/yaml/serializer.pyc +0 -0
- data/vendor/yaml/tokens.pyc +0 -0
- metadata +37 -17
- data/vendor/requests-2.11.1.dist-info/metadata.json +0 -1
Binary file
|
@@ -1,6 +1,10 @@
|
|
1
1
|
from __future__ import absolute_import
|
2
2
|
import time
|
3
3
|
import logging
|
4
|
+
from collections import namedtuple
|
5
|
+
from itertools import takewhile
|
6
|
+
import email
|
7
|
+
import re
|
4
8
|
|
5
9
|
from ..exceptions import (
|
6
10
|
ConnectTimeoutError,
|
@@ -8,12 +12,17 @@ from ..exceptions import (
|
|
8
12
|
ProtocolError,
|
9
13
|
ReadTimeoutError,
|
10
14
|
ResponseError,
|
15
|
+
InvalidHeader,
|
11
16
|
)
|
12
17
|
from ..packages import six
|
13
18
|
|
14
19
|
|
15
20
|
log = logging.getLogger(__name__)
|
16
21
|
|
22
|
+
# Data structure for representing the metadata of requests that result in a retry.
|
23
|
+
RequestHistory = namedtuple('RequestHistory', ["method", "url", "error",
|
24
|
+
"status", "redirect_location"])
|
25
|
+
|
17
26
|
|
18
27
|
class Retry(object):
|
19
28
|
""" Retry configuration.
|
@@ -113,18 +122,29 @@ class Retry(object):
|
|
113
122
|
whether we should raise an exception, or return a response,
|
114
123
|
if status falls in ``status_forcelist`` range and retries have
|
115
124
|
been exhausted.
|
125
|
+
|
126
|
+
:param tuple history: The history of the request encountered during
|
127
|
+
each call to :meth:`~Retry.increment`. The list is in the order
|
128
|
+
the requests occurred. Each list item is of class :class:`RequestHistory`.
|
129
|
+
|
130
|
+
:param bool respect_retry_after_header:
|
131
|
+
Whether to respect Retry-After header on status codes defined as
|
132
|
+
:attr:`Retry.RETRY_AFTER_STATUS_CODES` or not.
|
133
|
+
|
116
134
|
"""
|
117
135
|
|
118
136
|
DEFAULT_METHOD_WHITELIST = frozenset([
|
119
137
|
'HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS', 'TRACE'])
|
120
138
|
|
139
|
+
RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503])
|
140
|
+
|
121
141
|
#: Maximum backoff time.
|
122
142
|
BACKOFF_MAX = 120
|
123
143
|
|
124
144
|
def __init__(self, total=10, connect=None, read=None, redirect=None,
|
125
145
|
method_whitelist=DEFAULT_METHOD_WHITELIST, status_forcelist=None,
|
126
146
|
backoff_factor=0, raise_on_redirect=True, raise_on_status=True,
|
127
|
-
|
147
|
+
history=None, respect_retry_after_header=True):
|
128
148
|
|
129
149
|
self.total = total
|
130
150
|
self.connect = connect
|
@@ -140,7 +160,8 @@ class Retry(object):
|
|
140
160
|
self.backoff_factor = backoff_factor
|
141
161
|
self.raise_on_redirect = raise_on_redirect
|
142
162
|
self.raise_on_status = raise_on_status
|
143
|
-
self.
|
163
|
+
self.history = history or tuple()
|
164
|
+
self.respect_retry_after_header = respect_retry_after_header
|
144
165
|
|
145
166
|
def new(self, **kw):
|
146
167
|
params = dict(
|
@@ -151,7 +172,7 @@ class Retry(object):
|
|
151
172
|
backoff_factor=self.backoff_factor,
|
152
173
|
raise_on_redirect=self.raise_on_redirect,
|
153
174
|
raise_on_status=self.raise_on_status,
|
154
|
-
|
175
|
+
history=self.history,
|
155
176
|
)
|
156
177
|
params.update(kw)
|
157
178
|
return type(self)(**params)
|
@@ -175,23 +196,71 @@ class Retry(object):
|
|
175
196
|
|
176
197
|
:rtype: float
|
177
198
|
"""
|
178
|
-
|
199
|
+
# We want to consider only the last consecutive errors sequence (Ignore redirects).
|
200
|
+
consecutive_errors_len = len(list(takewhile(lambda x: x.redirect_location is None,
|
201
|
+
reversed(self.history))))
|
202
|
+
if consecutive_errors_len <= 1:
|
179
203
|
return 0
|
180
204
|
|
181
|
-
backoff_value = self.backoff_factor * (2 ** (
|
205
|
+
backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1))
|
182
206
|
return min(self.BACKOFF_MAX, backoff_value)
|
183
207
|
|
184
|
-
def
|
185
|
-
|
208
|
+
def parse_retry_after(self, retry_after):
|
209
|
+
# Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4
|
210
|
+
if re.match(r"^\s*[0-9]+\s*$", retry_after):
|
211
|
+
seconds = int(retry_after)
|
212
|
+
else:
|
213
|
+
retry_date_tuple = email.utils.parsedate(retry_after)
|
214
|
+
if retry_date_tuple is None:
|
215
|
+
raise InvalidHeader("Invalid Retry-After header: %s" % retry_after)
|
216
|
+
retry_date = time.mktime(retry_date_tuple)
|
217
|
+
seconds = retry_date - time.time()
|
186
218
|
|
187
|
-
|
188
|
-
|
189
|
-
|
219
|
+
if seconds < 0:
|
220
|
+
seconds = 0
|
221
|
+
|
222
|
+
return seconds
|
223
|
+
|
224
|
+
def get_retry_after(self, response):
|
225
|
+
""" Get the value of Retry-After in seconds. """
|
226
|
+
|
227
|
+
retry_after = response.getheader("Retry-After")
|
228
|
+
|
229
|
+
if retry_after is None:
|
230
|
+
return None
|
231
|
+
|
232
|
+
return self.parse_retry_after(retry_after)
|
233
|
+
|
234
|
+
def sleep_for_retry(self, response=None):
|
235
|
+
retry_after = self.get_retry_after(response)
|
236
|
+
if retry_after:
|
237
|
+
time.sleep(retry_after)
|
238
|
+
return True
|
239
|
+
|
240
|
+
return False
|
241
|
+
|
242
|
+
def _sleep_backoff(self):
|
190
243
|
backoff = self.get_backoff_time()
|
191
244
|
if backoff <= 0:
|
192
245
|
return
|
193
246
|
time.sleep(backoff)
|
194
247
|
|
248
|
+
def sleep(self, response=None):
|
249
|
+
""" Sleep between retry attempts.
|
250
|
+
|
251
|
+
This method will respect a server's ``Retry-After`` response header
|
252
|
+
and sleep the duration of the time requested. If that is not present, it
|
253
|
+
will use an exponential backoff. By default, the backoff factor is 0 and
|
254
|
+
this method will return immediately.
|
255
|
+
"""
|
256
|
+
|
257
|
+
if response:
|
258
|
+
slept = self.sleep_for_retry(response)
|
259
|
+
if slept:
|
260
|
+
return
|
261
|
+
|
262
|
+
self._sleep_backoff()
|
263
|
+
|
195
264
|
def _is_connection_error(self, err):
|
196
265
|
""" Errors when we're fairly sure that the server did not receive the
|
197
266
|
request, so it should be safe to retry.
|
@@ -204,13 +273,17 @@ class Retry(object):
|
|
204
273
|
"""
|
205
274
|
return isinstance(err, (ReadTimeoutError, ProtocolError))
|
206
275
|
|
207
|
-
def
|
276
|
+
def is_retry(self, method, status_code, has_retry_after=False):
|
208
277
|
""" Is this method/status code retryable? (Based on method/codes whitelists)
|
209
278
|
"""
|
210
279
|
if self.method_whitelist and method.upper() not in self.method_whitelist:
|
211
280
|
return False
|
212
281
|
|
213
|
-
|
282
|
+
if self.status_forcelist and status_code in self.status_forcelist:
|
283
|
+
return True
|
284
|
+
|
285
|
+
return (self.total and self.respect_retry_after_header and
|
286
|
+
has_retry_after and (status_code in self.RETRY_AFTER_STATUS_CODES))
|
214
287
|
|
215
288
|
def is_exhausted(self):
|
216
289
|
""" Are we out of retries? """
|
@@ -241,11 +314,12 @@ class Retry(object):
|
|
241
314
|
if total is not None:
|
242
315
|
total -= 1
|
243
316
|
|
244
|
-
_observed_errors = self._observed_errors
|
245
317
|
connect = self.connect
|
246
318
|
read = self.read
|
247
319
|
redirect = self.redirect
|
248
320
|
cause = 'unknown'
|
321
|
+
status = None
|
322
|
+
redirect_location = None
|
249
323
|
|
250
324
|
if error and self._is_connection_error(error):
|
251
325
|
# Connect retry?
|
@@ -253,7 +327,6 @@ class Retry(object):
|
|
253
327
|
raise six.reraise(type(error), error, _stacktrace)
|
254
328
|
elif connect is not None:
|
255
329
|
connect -= 1
|
256
|
-
_observed_errors += 1
|
257
330
|
|
258
331
|
elif error and self._is_read_error(error):
|
259
332
|
# Read retry?
|
@@ -261,27 +334,30 @@ class Retry(object):
|
|
261
334
|
raise six.reraise(type(error), error, _stacktrace)
|
262
335
|
elif read is not None:
|
263
336
|
read -= 1
|
264
|
-
_observed_errors += 1
|
265
337
|
|
266
338
|
elif response and response.get_redirect_location():
|
267
339
|
# Redirect retry?
|
268
340
|
if redirect is not None:
|
269
341
|
redirect -= 1
|
270
342
|
cause = 'too many redirects'
|
343
|
+
redirect_location = response.get_redirect_location()
|
344
|
+
status = response.status
|
271
345
|
|
272
346
|
else:
|
273
347
|
# Incrementing because of a server error like a 500 in
|
274
348
|
# status_forcelist and a the given method is in the whitelist
|
275
|
-
_observed_errors += 1
|
276
349
|
cause = ResponseError.GENERIC_ERROR
|
277
350
|
if response and response.status:
|
278
351
|
cause = ResponseError.SPECIFIC_ERROR.format(
|
279
352
|
status_code=response.status)
|
353
|
+
status = response.status
|
354
|
+
|
355
|
+
history = self.history + (RequestHistory(method, url, error, status, redirect_location),)
|
280
356
|
|
281
357
|
new_retry = self.new(
|
282
358
|
total=total,
|
283
359
|
connect=connect, read=read, redirect=redirect,
|
284
|
-
|
360
|
+
history=history)
|
285
361
|
|
286
362
|
if new_retry.is_exhausted():
|
287
363
|
raise MaxRetryError(_pool, url, error or ResponseError(cause))
|
Binary file
|
@@ -11,7 +11,6 @@ from ..exceptions import SSLError, InsecurePlatformWarning, SNIMissingWarning
|
|
11
11
|
|
12
12
|
SSLContext = None
|
13
13
|
HAS_SNI = False
|
14
|
-
create_default_context = None
|
15
14
|
IS_PYOPENSSL = False
|
16
15
|
|
17
16
|
# Maps the length of a digest to a possible hash function producing this digest
|
@@ -63,14 +62,25 @@ except ImportError:
|
|
63
62
|
# The general intent is:
|
64
63
|
# - Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE),
|
65
64
|
# - prefer ECDHE over DHE for better performance,
|
66
|
-
# - prefer any AES-GCM over any AES-CBC for better performance and
|
67
|
-
#
|
65
|
+
# - prefer any AES-GCM and ChaCha20 over any AES-CBC for better performance and
|
66
|
+
# security,
|
67
|
+
# - prefer AES-GCM over ChaCha20 because hardware-accelerated AES is common,
|
68
68
|
# - disable NULL authentication, MD5 MACs and DSS for security reasons.
|
69
|
-
DEFAULT_CIPHERS = (
|
70
|
-
'ECDH+AESGCM
|
71
|
-
'
|
72
|
-
'
|
73
|
-
|
69
|
+
DEFAULT_CIPHERS = ':'.join([
|
70
|
+
'ECDH+AESGCM',
|
71
|
+
'ECDH+CHACHA20',
|
72
|
+
'DH+AESGCM',
|
73
|
+
'DH+CHACHA20',
|
74
|
+
'ECDH+AES256',
|
75
|
+
'DH+AES256',
|
76
|
+
'ECDH+AES128',
|
77
|
+
'DH+AES',
|
78
|
+
'RSA+AESGCM',
|
79
|
+
'RSA+AES',
|
80
|
+
'!aNULL',
|
81
|
+
'!eNULL',
|
82
|
+
'!MD5',
|
83
|
+
])
|
74
84
|
|
75
85
|
try:
|
76
86
|
from ssl import SSLContext # Modern SSL?
|
@@ -117,8 +127,8 @@ except ImportError:
|
|
117
127
|
'urllib3 from configuring SSL appropriately and may cause '
|
118
128
|
'certain SSL connections to fail. You can upgrade to a newer '
|
119
129
|
'version of Python to solve this. For more information, see '
|
120
|
-
'https://urllib3.readthedocs.io/en/latest/
|
121
|
-
'#
|
130
|
+
'https://urllib3.readthedocs.io/en/latest/advanced-usage.html'
|
131
|
+
'#ssl-warnings',
|
122
132
|
InsecurePlatformWarning
|
123
133
|
)
|
124
134
|
kwargs = {
|
@@ -287,6 +297,9 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
|
|
287
297
|
"""
|
288
298
|
context = ssl_context
|
289
299
|
if context is None:
|
300
|
+
# Note: This branch of code and all the variables in it are no longer
|
301
|
+
# used by urllib3 itself. We should consider deprecating and removing
|
302
|
+
# this code.
|
290
303
|
context = create_urllib3_context(ssl_version, cert_reqs,
|
291
304
|
ciphers=ciphers)
|
292
305
|
|
@@ -301,6 +314,9 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
|
|
301
314
|
if e.errno == errno.ENOENT:
|
302
315
|
raise SSLError(e)
|
303
316
|
raise
|
317
|
+
elif getattr(context, 'load_default_certs', None) is not None:
|
318
|
+
# try to load OS default certs; works well on Windows (require Python3.4+)
|
319
|
+
context.load_default_certs()
|
304
320
|
|
305
321
|
if certfile:
|
306
322
|
context.load_cert_chain(certfile, keyfile)
|
@@ -313,8 +329,8 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
|
|
313
329
|
'This may cause the server to present an incorrect TLS '
|
314
330
|
'certificate, which can cause validation failures. You can upgrade to '
|
315
331
|
'a newer version of Python to solve this. For more information, see '
|
316
|
-
'https://urllib3.readthedocs.io/en/latest/
|
317
|
-
'#
|
332
|
+
'https://urllib3.readthedocs.io/en/latest/advanced-usage.html'
|
333
|
+
'#ssl-warnings',
|
318
334
|
SNIMissingWarning
|
319
335
|
)
|
320
336
|
return context.wrap_socket(sock)
|
Binary file
|
@@ -111,8 +111,8 @@ class Timeout(object):
|
|
111
111
|
:param name: The name of the timeout attribute to validate. This is
|
112
112
|
used to specify in error messages.
|
113
113
|
:return: The validated and casted version of the given value.
|
114
|
-
:raises ValueError: If
|
115
|
-
is
|
114
|
+
:raises ValueError: If it is a numeric value less than or equal to
|
115
|
+
zero, or the type is not an integer, float, or None.
|
116
116
|
"""
|
117
117
|
if value is _Default:
|
118
118
|
return cls.DEFAULT_TIMEOUT
|
@@ -120,20 +120,23 @@ class Timeout(object):
|
|
120
120
|
if value is None or value is cls.DEFAULT_TIMEOUT:
|
121
121
|
return value
|
122
122
|
|
123
|
+
if isinstance(value, bool):
|
124
|
+
raise ValueError("Timeout cannot be a boolean value. It must "
|
125
|
+
"be an int, float or None.")
|
123
126
|
try:
|
124
127
|
float(value)
|
125
128
|
except (TypeError, ValueError):
|
126
129
|
raise ValueError("Timeout value %s was %s, but it must be an "
|
127
|
-
"int or
|
130
|
+
"int, float or None." % (name, value))
|
128
131
|
|
129
132
|
try:
|
130
|
-
if value
|
133
|
+
if value <= 0:
|
131
134
|
raise ValueError("Attempted to set %s timeout to %s, but the "
|
132
135
|
"timeout cannot be set to a value less "
|
133
|
-
"than 0." % (name, value))
|
136
|
+
"than or equal to 0." % (name, value))
|
134
137
|
except TypeError: # Python 3
|
135
138
|
raise ValueError("Timeout value %s was %s, but it must be an "
|
136
|
-
"int or
|
139
|
+
"int, float or None." % (name, value))
|
137
140
|
|
138
141
|
return value
|
139
142
|
|
Binary file
|
@@ -10,14 +10,19 @@ url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment']
|
|
10
10
|
class Url(namedtuple('Url', url_attrs)):
|
11
11
|
"""
|
12
12
|
Datastructure for representing an HTTP URL. Used as a return value for
|
13
|
-
:func:`parse_url`.
|
13
|
+
:func:`parse_url`. Both the scheme and host are normalized as they are
|
14
|
+
both case-insensitive according to RFC 3986.
|
14
15
|
"""
|
15
|
-
|
16
|
+
__slots__ = ()
|
16
17
|
|
17
18
|
def __new__(cls, scheme=None, auth=None, host=None, port=None, path=None,
|
18
19
|
query=None, fragment=None):
|
19
20
|
if path and not path.startswith('/'):
|
20
21
|
path = '/' + path
|
22
|
+
if scheme:
|
23
|
+
scheme = scheme.lower()
|
24
|
+
if host:
|
25
|
+
host = host.lower()
|
21
26
|
return super(Url, cls).__new__(cls, scheme, auth, host, port, path,
|
22
27
|
query, fragment)
|
23
28
|
|
@@ -184,10 +189,14 @@ def parse_url(url):
|
|
184
189
|
host = _host
|
185
190
|
|
186
191
|
if port:
|
187
|
-
# If given, ports must be integers.
|
192
|
+
# If given, ports must be integers. No whitespace, no plus or
|
193
|
+
# minus prefixes, no non-integer digits such as ^2 (superscript).
|
188
194
|
if not port.isdigit():
|
189
195
|
raise LocationParseError(url)
|
190
|
-
|
196
|
+
try:
|
197
|
+
port = int(port)
|
198
|
+
except ValueError:
|
199
|
+
raise LocationParseError(url)
|
191
200
|
else:
|
192
201
|
# Blank ports are cool, too. (rfc3986#section-3.2.3)
|
193
202
|
port = None
|
@@ -211,7 +220,7 @@ def parse_url(url):
|
|
211
220
|
|
212
221
|
def get_host(url):
|
213
222
|
"""
|
214
|
-
Deprecated. Use :func
|
223
|
+
Deprecated. Use :func:`parse_url` instead.
|
215
224
|
"""
|
216
225
|
p = parse_url(url)
|
217
226
|
return p.scheme or 'http', p.hostname, p.port
|
Binary file
|
data/vendor/requests/sessions.py
CHANGED
@@ -17,7 +17,8 @@ from .cookies import (
|
|
17
17
|
cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies)
|
18
18
|
from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT
|
19
19
|
from .hooks import default_hooks, dispatch_hook
|
20
|
-
from .
|
20
|
+
from ._internal_utils import to_native_string
|
21
|
+
from .utils import to_key_val_list, default_headers
|
21
22
|
from .exceptions import (
|
22
23
|
TooManyRedirects, InvalidSchema, ChunkedEncodingError, ContentDecodingError)
|
23
24
|
from .packages.urllib3._collections import RecentlyUsedContainer
|
@@ -27,7 +28,7 @@ from .adapters import HTTPAdapter
|
|
27
28
|
|
28
29
|
from .utils import (
|
29
30
|
requote_uri, get_environ_proxies, get_netrc_auth, should_bypass_proxies,
|
30
|
-
get_auth_from_url
|
31
|
+
get_auth_from_url, rewind_body
|
31
32
|
)
|
32
33
|
|
33
34
|
from .status_codes import codes
|
@@ -156,13 +157,25 @@ class SessionRedirectMixin(object):
|
|
156
157
|
# in the new request. Because we've mutated our copied prepared
|
157
158
|
# request, use the old one that we haven't yet touched.
|
158
159
|
extract_cookies_to_jar(prepared_request._cookies, req, resp.raw)
|
159
|
-
prepared_request._cookies
|
160
|
+
merge_cookies(prepared_request._cookies, self.cookies)
|
160
161
|
prepared_request.prepare_cookies(prepared_request._cookies)
|
161
162
|
|
162
163
|
# Rebuild auth and proxy information.
|
163
164
|
proxies = self.rebuild_proxies(prepared_request, proxies)
|
164
165
|
self.rebuild_auth(prepared_request, resp)
|
165
166
|
|
167
|
+
# A failed tell() sets `_body_position` to `object()`. This non-None
|
168
|
+
# value ensures `rewindable` will be True, allowing us to raise an
|
169
|
+
# UnrewindableBodyError, instead of hanging the connection.
|
170
|
+
rewindable = (
|
171
|
+
prepared_request._body_position is not None and
|
172
|
+
('Content-Length' in headers or 'Transfer-Encoding' in headers)
|
173
|
+
)
|
174
|
+
|
175
|
+
# Attempt to rewind consumed file-like object.
|
176
|
+
if rewindable:
|
177
|
+
rewind_body(prepared_request)
|
178
|
+
|
166
179
|
# Override the original request.
|
167
180
|
req = prepared_request
|
168
181
|
|
@@ -226,7 +239,7 @@ class SessionRedirectMixin(object):
|
|
226
239
|
if self.trust_env and not should_bypass_proxies(url):
|
227
240
|
environ_proxies = get_environ_proxies(url)
|
228
241
|
|
229
|
-
proxy = environ_proxies.get(
|
242
|
+
proxy = environ_proxies.get(scheme, environ_proxies.get('all'))
|
230
243
|
|
231
244
|
if proxy:
|
232
245
|
new_proxies.setdefault(scheme, proxy)
|
@@ -322,7 +335,7 @@ class Session(SessionRedirectMixin):
|
|
322
335
|
#: SSL Verification default.
|
323
336
|
self.verify = True
|
324
337
|
|
325
|
-
#: SSL certificate default.
|
338
|
+
#: SSL client certificate default.
|
326
339
|
self.cert = None
|
327
340
|
|
328
341
|
#: Maximum number of redirects allowed. If the request exceeds this
|