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
|
Binary file
|
Binary file
|
Binary file
|
File without changes
|
Binary file
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""
|
3
|
+
backports.makefile
|
4
|
+
~~~~~~~~~~~~~~~~~~
|
5
|
+
|
6
|
+
Backports the Python 3 ``socket.makefile`` method for use with anything that
|
7
|
+
wants to create a "fake" socket object.
|
8
|
+
"""
|
9
|
+
import io
|
10
|
+
|
11
|
+
from socket import SocketIO
|
12
|
+
|
13
|
+
|
14
|
+
def backport_makefile(self, mode="r", buffering=None, encoding=None,
|
15
|
+
errors=None, newline=None):
|
16
|
+
"""
|
17
|
+
Backport of ``socket.makefile`` from Python 3.5.
|
18
|
+
"""
|
19
|
+
if not set(mode) <= set(["r", "w", "b"]):
|
20
|
+
raise ValueError(
|
21
|
+
"invalid mode %r (only r, w, b allowed)" % (mode,)
|
22
|
+
)
|
23
|
+
writing = "w" in mode
|
24
|
+
reading = "r" in mode or not writing
|
25
|
+
assert reading or writing
|
26
|
+
binary = "b" in mode
|
27
|
+
rawmode = ""
|
28
|
+
if reading:
|
29
|
+
rawmode += "r"
|
30
|
+
if writing:
|
31
|
+
rawmode += "w"
|
32
|
+
raw = SocketIO(self, rawmode)
|
33
|
+
self._makefile_refs += 1
|
34
|
+
if buffering is None:
|
35
|
+
buffering = -1
|
36
|
+
if buffering < 0:
|
37
|
+
buffering = io.DEFAULT_BUFFER_SIZE
|
38
|
+
if buffering == 0:
|
39
|
+
if not binary:
|
40
|
+
raise ValueError("unbuffered streams must be binary")
|
41
|
+
return raw
|
42
|
+
if reading and writing:
|
43
|
+
buffer = io.BufferedRWPair(raw, raw, buffering)
|
44
|
+
elif reading:
|
45
|
+
buffer = io.BufferedReader(raw, buffering)
|
46
|
+
else:
|
47
|
+
assert writing
|
48
|
+
buffer = io.BufferedWriter(raw, buffering)
|
49
|
+
if binary:
|
50
|
+
return buffer
|
51
|
+
text = io.TextIOWrapper(buffer, encoding, errors, newline)
|
52
|
+
text.mode = mode
|
53
|
+
return text
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,5 +1,11 @@
|
|
1
|
+
import sys
|
2
|
+
|
1
3
|
try:
|
2
|
-
#
|
4
|
+
# Our match_hostname function is the same as 3.5's, so we only want to
|
5
|
+
# import the match_hostname function if it's at least that good.
|
6
|
+
if sys.version_info < (3, 5):
|
7
|
+
raise ImportError("Fallback to vendored code")
|
8
|
+
|
3
9
|
from ssl import CertificateError, match_hostname
|
4
10
|
except ImportError:
|
5
11
|
try:
|
Binary file
|
@@ -4,8 +4,20 @@
|
|
4
4
|
# stdlib. http://docs.python.org/3/license.html
|
5
5
|
|
6
6
|
import re
|
7
|
+
import sys
|
8
|
+
|
9
|
+
# ipaddress has been backported to 2.6+ in pypi. If it is installed on the
|
10
|
+
# system, use it to handle IPAddress ServerAltnames (this was added in
|
11
|
+
# python-3.5) otherwise only do DNS matching. This allows
|
12
|
+
# backports.ssl_match_hostname to continue to be used all the way back to
|
13
|
+
# python-2.4.
|
14
|
+
try:
|
15
|
+
import ipaddress
|
16
|
+
except ImportError:
|
17
|
+
ipaddress = None
|
18
|
+
|
19
|
+
__version__ = '3.5.0.1'
|
7
20
|
|
8
|
-
__version__ = '3.4.0.2'
|
9
21
|
|
10
22
|
class CertificateError(ValueError):
|
11
23
|
pass
|
@@ -64,6 +76,23 @@ def _dnsname_match(dn, hostname, max_wildcards=1):
|
|
64
76
|
return pat.match(hostname)
|
65
77
|
|
66
78
|
|
79
|
+
def _to_unicode(obj):
|
80
|
+
if isinstance(obj, str) and sys.version_info < (3,):
|
81
|
+
obj = unicode(obj, encoding='ascii', errors='strict')
|
82
|
+
return obj
|
83
|
+
|
84
|
+
def _ipaddress_match(ipname, host_ip):
|
85
|
+
"""Exact matching of IP addresses.
|
86
|
+
|
87
|
+
RFC 6125 explicitly doesn't define an algorithm for this
|
88
|
+
(section 1.7.2 - "Out of Scope").
|
89
|
+
"""
|
90
|
+
# OpenSSL may add a trailing newline to a subjectAltName's IP address
|
91
|
+
# Divergence from upstream: ipaddress can't handle byte str
|
92
|
+
ip = ipaddress.ip_address(_to_unicode(ipname).rstrip())
|
93
|
+
return ip == host_ip
|
94
|
+
|
95
|
+
|
67
96
|
def match_hostname(cert, hostname):
|
68
97
|
"""Verify that *cert* (in decoded format as returned by
|
69
98
|
SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
|
@@ -73,12 +102,35 @@ def match_hostname(cert, hostname):
|
|
73
102
|
returns nothing.
|
74
103
|
"""
|
75
104
|
if not cert:
|
76
|
-
raise ValueError("empty or no certificate"
|
105
|
+
raise ValueError("empty or no certificate, match_hostname needs a "
|
106
|
+
"SSL socket or SSL context with either "
|
107
|
+
"CERT_OPTIONAL or CERT_REQUIRED")
|
108
|
+
try:
|
109
|
+
# Divergence from upstream: ipaddress can't handle byte str
|
110
|
+
host_ip = ipaddress.ip_address(_to_unicode(hostname))
|
111
|
+
except ValueError:
|
112
|
+
# Not an IP address (common case)
|
113
|
+
host_ip = None
|
114
|
+
except UnicodeError:
|
115
|
+
# Divergence from upstream: Have to deal with ipaddress not taking
|
116
|
+
# byte strings. addresses should be all ascii, so we consider it not
|
117
|
+
# an ipaddress in this case
|
118
|
+
host_ip = None
|
119
|
+
except AttributeError:
|
120
|
+
# Divergence from upstream: Make ipaddress library optional
|
121
|
+
if ipaddress is None:
|
122
|
+
host_ip = None
|
123
|
+
else:
|
124
|
+
raise
|
77
125
|
dnsnames = []
|
78
126
|
san = cert.get('subjectAltName', ())
|
79
127
|
for key, value in san:
|
80
128
|
if key == 'DNS':
|
81
|
-
if _dnsname_match(value, hostname):
|
129
|
+
if host_ip is None and _dnsname_match(value, hostname):
|
130
|
+
return
|
131
|
+
dnsnames.append(value)
|
132
|
+
elif key == 'IP Address':
|
133
|
+
if host_ip is not None and _ipaddress_match(value, host_ip):
|
82
134
|
return
|
83
135
|
dnsnames.append(value)
|
84
136
|
if not dnsnames:
|
Binary file
|
@@ -3,15 +3,11 @@ import collections
|
|
3
3
|
import functools
|
4
4
|
import logging
|
5
5
|
|
6
|
-
try: # Python 3
|
7
|
-
from urllib.parse import urljoin
|
8
|
-
except ImportError:
|
9
|
-
from urlparse import urljoin
|
10
|
-
|
11
6
|
from ._collections import RecentlyUsedContainer
|
12
7
|
from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool
|
13
8
|
from .connectionpool import port_by_scheme
|
14
9
|
from .exceptions import LocationValueError, MaxRetryError, ProxySchemeUnknown
|
10
|
+
from .packages.six.moves.urllib.parse import urljoin
|
15
11
|
from .request import RequestMethods
|
16
12
|
from .util.url import parse_url
|
17
13
|
from .util.retry import Retry
|
@@ -23,7 +19,7 @@ __all__ = ['PoolManager', 'ProxyManager', 'proxy_from_url']
|
|
23
19
|
log = logging.getLogger(__name__)
|
24
20
|
|
25
21
|
SSL_KEYWORDS = ('key_file', 'cert_file', 'cert_reqs', 'ca_certs',
|
26
|
-
'ssl_version', 'ca_cert_dir')
|
22
|
+
'ssl_version', 'ca_cert_dir', 'ssl_context')
|
27
23
|
|
28
24
|
# The base fields to use when determining what pool to get a connection from;
|
29
25
|
# these do not rely on the ``connection_pool_kw`` and can be determined by the
|
Binary file
|
@@ -1,10 +1,7 @@
|
|
1
1
|
from __future__ import absolute_import
|
2
|
-
try:
|
3
|
-
from urllib.parse import urlencode
|
4
|
-
except ImportError:
|
5
|
-
from urllib import urlencode
|
6
2
|
|
7
3
|
from .filepost import encode_multipart_formdata
|
4
|
+
from .packages.six.moves.urllib.parse import urlencode
|
8
5
|
|
9
6
|
|
10
7
|
__all__ = ['RequestMethods']
|
Binary file
|
@@ -2,18 +2,22 @@ from __future__ import absolute_import
|
|
2
2
|
from contextlib import contextmanager
|
3
3
|
import zlib
|
4
4
|
import io
|
5
|
+
import logging
|
5
6
|
from socket import timeout as SocketTimeout
|
6
7
|
from socket import error as SocketError
|
7
8
|
|
8
9
|
from ._collections import HTTPHeaderDict
|
9
10
|
from .exceptions import (
|
10
|
-
ProtocolError, DecodeError, ReadTimeoutError,
|
11
|
+
BodyNotHttplibCompatible, ProtocolError, DecodeError, ReadTimeoutError,
|
12
|
+
ResponseNotChunked, IncompleteRead, InvalidHeader
|
11
13
|
)
|
12
14
|
from .packages.six import string_types as basestring, binary_type, PY3
|
13
15
|
from .packages.six.moves import http_client as httplib
|
14
16
|
from .connection import HTTPException, BaseSSLError
|
15
17
|
from .util.response import is_fp_closed, is_response_to_head
|
16
18
|
|
19
|
+
log = logging.getLogger(__name__)
|
20
|
+
|
17
21
|
|
18
22
|
class DeflateDecoder(object):
|
19
23
|
|
@@ -89,6 +93,14 @@ class HTTPResponse(io.IOBase):
|
|
89
93
|
When this HTTPResponse wrapper is generated from an httplib.HTTPResponse
|
90
94
|
object, it's convenient to include the original for debug purposes. It's
|
91
95
|
otherwise unused.
|
96
|
+
|
97
|
+
:param retries:
|
98
|
+
The retries contains the last :class:`~urllib3.util.retry.Retry` that
|
99
|
+
was used during the request.
|
100
|
+
|
101
|
+
:param enforce_content_length:
|
102
|
+
Enforce content length checking. Body returned by server must match
|
103
|
+
value of Content-Length header, if present. Otherwise, raise error.
|
92
104
|
"""
|
93
105
|
|
94
106
|
CONTENT_DECODERS = ['gzip', 'deflate']
|
@@ -96,7 +108,8 @@ class HTTPResponse(io.IOBase):
|
|
96
108
|
|
97
109
|
def __init__(self, body='', headers=None, status=0, version=0, reason=None,
|
98
110
|
strict=0, preload_content=True, decode_content=True,
|
99
|
-
original_response=None, pool=None, connection=None
|
111
|
+
original_response=None, pool=None, connection=None,
|
112
|
+
retries=None, enforce_content_length=False, request_method=None):
|
100
113
|
|
101
114
|
if isinstance(headers, HTTPHeaderDict):
|
102
115
|
self.headers = headers
|
@@ -107,6 +120,8 @@ class HTTPResponse(io.IOBase):
|
|
107
120
|
self.reason = reason
|
108
121
|
self.strict = strict
|
109
122
|
self.decode_content = decode_content
|
123
|
+
self.retries = retries
|
124
|
+
self.enforce_content_length = enforce_content_length
|
110
125
|
|
111
126
|
self._decoder = None
|
112
127
|
self._body = None
|
@@ -132,6 +147,9 @@ class HTTPResponse(io.IOBase):
|
|
132
147
|
if "chunked" in encodings:
|
133
148
|
self.chunked = True
|
134
149
|
|
150
|
+
# Determine length of response
|
151
|
+
self.length_remaining = self._init_length(request_method)
|
152
|
+
|
135
153
|
# If requested, preload the body.
|
136
154
|
if preload_content and not self._body:
|
137
155
|
self._body = self.read(decode_content=decode_content)
|
@@ -177,9 +195,57 @@ class HTTPResponse(io.IOBase):
|
|
177
195
|
"""
|
178
196
|
return self._fp_bytes_read
|
179
197
|
|
198
|
+
def _init_length(self, request_method):
|
199
|
+
"""
|
200
|
+
Set initial length value for Response content if available.
|
201
|
+
"""
|
202
|
+
length = self.headers.get('content-length')
|
203
|
+
|
204
|
+
if length is not None and self.chunked:
|
205
|
+
# This Response will fail with an IncompleteRead if it can't be
|
206
|
+
# received as chunked. This method falls back to attempt reading
|
207
|
+
# the response before raising an exception.
|
208
|
+
log.warning("Received response with both Content-Length and "
|
209
|
+
"Transfer-Encoding set. This is expressly forbidden "
|
210
|
+
"by RFC 7230 sec 3.3.2. Ignoring Content-Length and "
|
211
|
+
"attempting to process response as Transfer-Encoding: "
|
212
|
+
"chunked.")
|
213
|
+
return None
|
214
|
+
|
215
|
+
elif length is not None:
|
216
|
+
try:
|
217
|
+
# RFC 7230 section 3.3.2 specifies multiple content lengths can
|
218
|
+
# be sent in a single Content-Length header
|
219
|
+
# (e.g. Content-Length: 42, 42). This line ensures the values
|
220
|
+
# are all valid ints and that as long as the `set` length is 1,
|
221
|
+
# all values are the same. Otherwise, the header is invalid.
|
222
|
+
lengths = set([int(val) for val in length.split(',')])
|
223
|
+
if len(lengths) > 1:
|
224
|
+
raise InvalidHeader("Content-Length contained multiple "
|
225
|
+
"unmatching values (%s)" % length)
|
226
|
+
length = lengths.pop()
|
227
|
+
except ValueError:
|
228
|
+
length = None
|
229
|
+
else:
|
230
|
+
if length < 0:
|
231
|
+
length = None
|
232
|
+
|
233
|
+
# Convert status to int for comparison
|
234
|
+
# In some cases, httplib returns a status of "_UNKNOWN"
|
235
|
+
try:
|
236
|
+
status = int(self.status)
|
237
|
+
except ValueError:
|
238
|
+
status = 0
|
239
|
+
|
240
|
+
# Check for responses that shouldn't include a body
|
241
|
+
if status in (204, 304) or 100 <= status < 200 or request_method == 'HEAD':
|
242
|
+
length = 0
|
243
|
+
|
244
|
+
return length
|
245
|
+
|
180
246
|
def _init_decoder(self):
|
181
247
|
"""
|
182
|
-
Set-up the _decoder attribute if
|
248
|
+
Set-up the _decoder attribute if necessary.
|
183
249
|
"""
|
184
250
|
# Note: content-encoding value should be case-insensitive, per RFC 7230
|
185
251
|
# Section 3.2
|
@@ -322,9 +388,18 @@ class HTTPResponse(io.IOBase):
|
|
322
388
|
# no harm in redundantly calling close.
|
323
389
|
self._fp.close()
|
324
390
|
flush_decoder = True
|
391
|
+
if self.enforce_content_length and self.length_remaining not in (0, None):
|
392
|
+
# This is an edge case that httplib failed to cover due
|
393
|
+
# to concerns of backward compatibility. We're
|
394
|
+
# addressing it here to make sure IncompleteRead is
|
395
|
+
# raised during streaming, so all calls with incorrect
|
396
|
+
# Content-Length are caught.
|
397
|
+
raise IncompleteRead(self._fp_bytes_read, self.length_remaining)
|
325
398
|
|
326
399
|
if data:
|
327
400
|
self._fp_bytes_read += len(data)
|
401
|
+
if self.length_remaining is not None:
|
402
|
+
self.length_remaining -= len(data)
|
328
403
|
|
329
404
|
data = self._decode(data, decode_content, flush_decoder)
|
330
405
|
|
@@ -349,7 +424,7 @@ class HTTPResponse(io.IOBase):
|
|
349
424
|
If True, will attempt to decode the body based on the
|
350
425
|
'content-encoding' header.
|
351
426
|
"""
|
352
|
-
if self.chunked:
|
427
|
+
if self.chunked and self.supports_chunked_reads():
|
353
428
|
for line in self.read_chunked(amt, decode_content=decode_content):
|
354
429
|
yield line
|
355
430
|
else:
|
@@ -407,10 +482,10 @@ class HTTPResponse(io.IOBase):
|
|
407
482
|
def closed(self):
|
408
483
|
if self._fp is None:
|
409
484
|
return True
|
485
|
+
elif hasattr(self._fp, 'isclosed'):
|
486
|
+
return self._fp.isclosed()
|
410
487
|
elif hasattr(self._fp, 'closed'):
|
411
488
|
return self._fp.closed
|
412
|
-
elif hasattr(self._fp, 'isclosed'): # Python 2
|
413
|
-
return self._fp.isclosed()
|
414
489
|
else:
|
415
490
|
return True
|
416
491
|
|
@@ -440,6 +515,15 @@ class HTTPResponse(io.IOBase):
|
|
440
515
|
b[:len(temp)] = temp
|
441
516
|
return len(temp)
|
442
517
|
|
518
|
+
def supports_chunked_reads(self):
|
519
|
+
"""
|
520
|
+
Checks if the underlying file-like object looks like a
|
521
|
+
httplib.HTTPResponse object. We do this by testing for the fp
|
522
|
+
attribute. If it is present we assume it returns raw chunks as
|
523
|
+
processed by read_chunked().
|
524
|
+
"""
|
525
|
+
return hasattr(self._fp, 'fp')
|
526
|
+
|
443
527
|
def _update_chunk_length(self):
|
444
528
|
# First, we'll figure out length of a chunk and then
|
445
529
|
# we'll try to read it from socket.
|
@@ -491,6 +575,10 @@ class HTTPResponse(io.IOBase):
|
|
491
575
|
raise ResponseNotChunked(
|
492
576
|
"Response is not chunked. "
|
493
577
|
"Header 'transfer-encoding: chunked' is missing.")
|
578
|
+
if not self.supports_chunked_reads():
|
579
|
+
raise BodyNotHttplibCompatible(
|
580
|
+
"Body should be httplib.HTTPResponse like. "
|
581
|
+
"It should have have an fp attribute which returns raw chunks.")
|
494
582
|
|
495
583
|
# Don't bother reading the body of a HEAD request.
|
496
584
|
if self._original_response and is_response_to_head(self._original_response):
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -12,6 +12,13 @@ def is_fp_closed(obj):
|
|
12
12
|
The file-like object to check.
|
13
13
|
"""
|
14
14
|
|
15
|
+
try:
|
16
|
+
# Check `isclosed()` first, in case Python3 doesn't set `closed`.
|
17
|
+
# GH Issue #928
|
18
|
+
return obj.isclosed()
|
19
|
+
except AttributeError:
|
20
|
+
pass
|
21
|
+
|
15
22
|
try:
|
16
23
|
# Check via the official file-like-object way.
|
17
24
|
return obj.closed
|