Mercurial > repos > bcclaywell > argo_navis
comparison venv/lib/python2.7/site-packages/requests/packages/urllib3/connection.py @ 0:d67268158946 draft
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
author | bcclaywell |
---|---|
date | Mon, 12 Oct 2015 17:43:33 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:d67268158946 |
---|---|
1 import datetime | |
2 import sys | |
3 import socket | |
4 from socket import error as SocketError, timeout as SocketTimeout | |
5 import warnings | |
6 from .packages import six | |
7 | |
8 try: # Python 3 | |
9 from http.client import HTTPConnection as _HTTPConnection, HTTPException | |
10 except ImportError: | |
11 from httplib import HTTPConnection as _HTTPConnection, HTTPException | |
12 | |
13 | |
14 class DummyConnection(object): | |
15 "Used to detect a failed ConnectionCls import." | |
16 pass | |
17 | |
18 | |
19 try: # Compiled with SSL? | |
20 HTTPSConnection = DummyConnection | |
21 import ssl | |
22 BaseSSLError = ssl.SSLError | |
23 except (ImportError, AttributeError): # Platform-specific: No SSL. | |
24 ssl = None | |
25 | |
26 class BaseSSLError(BaseException): | |
27 pass | |
28 | |
29 | |
30 try: # Python 3: | |
31 # Not a no-op, we're adding this to the namespace so it can be imported. | |
32 ConnectionError = ConnectionError | |
33 except NameError: # Python 2: | |
34 class ConnectionError(Exception): | |
35 pass | |
36 | |
37 | |
38 from .exceptions import ( | |
39 NewConnectionError, | |
40 ConnectTimeoutError, | |
41 SubjectAltNameWarning, | |
42 SystemTimeWarning, | |
43 ) | |
44 from .packages.ssl_match_hostname import match_hostname | |
45 | |
46 from .util.ssl_ import ( | |
47 resolve_cert_reqs, | |
48 resolve_ssl_version, | |
49 ssl_wrap_socket, | |
50 assert_fingerprint, | |
51 ) | |
52 | |
53 | |
54 from .util import connection | |
55 | |
56 port_by_scheme = { | |
57 'http': 80, | |
58 'https': 443, | |
59 } | |
60 | |
61 RECENT_DATE = datetime.date(2014, 1, 1) | |
62 | |
63 | |
64 class HTTPConnection(_HTTPConnection, object): | |
65 """ | |
66 Based on httplib.HTTPConnection but provides an extra constructor | |
67 backwards-compatibility layer between older and newer Pythons. | |
68 | |
69 Additional keyword parameters are used to configure attributes of the connection. | |
70 Accepted parameters include: | |
71 | |
72 - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool` | |
73 - ``source_address``: Set the source address for the current connection. | |
74 | |
75 .. note:: This is ignored for Python 2.6. It is only applied for 2.7 and 3.x | |
76 | |
77 - ``socket_options``: Set specific options on the underlying socket. If not specified, then | |
78 defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling | |
79 Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy. | |
80 | |
81 For example, if you wish to enable TCP Keep Alive in addition to the defaults, | |
82 you might pass:: | |
83 | |
84 HTTPConnection.default_socket_options + [ | |
85 (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), | |
86 ] | |
87 | |
88 Or you may want to disable the defaults by passing an empty list (e.g., ``[]``). | |
89 """ | |
90 | |
91 default_port = port_by_scheme['http'] | |
92 | |
93 #: Disable Nagle's algorithm by default. | |
94 #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]`` | |
95 default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)] | |
96 | |
97 #: Whether this connection verifies the host's certificate. | |
98 is_verified = False | |
99 | |
100 def __init__(self, *args, **kw): | |
101 if six.PY3: # Python 3 | |
102 kw.pop('strict', None) | |
103 | |
104 # Pre-set source_address in case we have an older Python like 2.6. | |
105 self.source_address = kw.get('source_address') | |
106 | |
107 if sys.version_info < (2, 7): # Python 2.6 | |
108 # _HTTPConnection on Python 2.6 will balk at this keyword arg, but | |
109 # not newer versions. We can still use it when creating a | |
110 # connection though, so we pop it *after* we have saved it as | |
111 # self.source_address. | |
112 kw.pop('source_address', None) | |
113 | |
114 #: The socket options provided by the user. If no options are | |
115 #: provided, we use the default options. | |
116 self.socket_options = kw.pop('socket_options', self.default_socket_options) | |
117 | |
118 # Superclass also sets self.source_address in Python 2.7+. | |
119 _HTTPConnection.__init__(self, *args, **kw) | |
120 | |
121 def _new_conn(self): | |
122 """ Establish a socket connection and set nodelay settings on it. | |
123 | |
124 :return: New socket connection. | |
125 """ | |
126 extra_kw = {} | |
127 if self.source_address: | |
128 extra_kw['source_address'] = self.source_address | |
129 | |
130 if self.socket_options: | |
131 extra_kw['socket_options'] = self.socket_options | |
132 | |
133 try: | |
134 conn = connection.create_connection( | |
135 (self.host, self.port), self.timeout, **extra_kw) | |
136 | |
137 except SocketTimeout as e: | |
138 raise ConnectTimeoutError( | |
139 self, "Connection to %s timed out. (connect timeout=%s)" % | |
140 (self.host, self.timeout)) | |
141 | |
142 except SocketError as e: | |
143 raise NewConnectionError( | |
144 self, "Failed to establish a new connection: %s" % e) | |
145 | |
146 return conn | |
147 | |
148 def _prepare_conn(self, conn): | |
149 self.sock = conn | |
150 # the _tunnel_host attribute was added in python 2.6.3 (via | |
151 # http://hg.python.org/cpython/rev/0f57b30a152f) so pythons 2.6(0-2) do | |
152 # not have them. | |
153 if getattr(self, '_tunnel_host', None): | |
154 # TODO: Fix tunnel so it doesn't depend on self.sock state. | |
155 self._tunnel() | |
156 # Mark this connection as not reusable | |
157 self.auto_open = 0 | |
158 | |
159 def connect(self): | |
160 conn = self._new_conn() | |
161 self._prepare_conn(conn) | |
162 | |
163 | |
164 class HTTPSConnection(HTTPConnection): | |
165 default_port = port_by_scheme['https'] | |
166 | |
167 def __init__(self, host, port=None, key_file=None, cert_file=None, | |
168 strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, **kw): | |
169 | |
170 HTTPConnection.__init__(self, host, port, strict=strict, | |
171 timeout=timeout, **kw) | |
172 | |
173 self.key_file = key_file | |
174 self.cert_file = cert_file | |
175 | |
176 # Required property for Google AppEngine 1.9.0 which otherwise causes | |
177 # HTTPS requests to go out as HTTP. (See Issue #356) | |
178 self._protocol = 'https' | |
179 | |
180 def connect(self): | |
181 conn = self._new_conn() | |
182 self._prepare_conn(conn) | |
183 self.sock = ssl.wrap_socket(conn, self.key_file, self.cert_file) | |
184 | |
185 | |
186 class VerifiedHTTPSConnection(HTTPSConnection): | |
187 """ | |
188 Based on httplib.HTTPSConnection but wraps the socket with | |
189 SSL certification. | |
190 """ | |
191 cert_reqs = None | |
192 ca_certs = None | |
193 ca_cert_dir = None | |
194 ssl_version = None | |
195 assert_fingerprint = None | |
196 | |
197 def set_cert(self, key_file=None, cert_file=None, | |
198 cert_reqs=None, ca_certs=None, | |
199 assert_hostname=None, assert_fingerprint=None, | |
200 ca_cert_dir=None): | |
201 | |
202 if (ca_certs or ca_cert_dir) and cert_reqs is None: | |
203 cert_reqs = 'CERT_REQUIRED' | |
204 | |
205 self.key_file = key_file | |
206 self.cert_file = cert_file | |
207 self.cert_reqs = cert_reqs | |
208 self.ca_certs = ca_certs | |
209 self.ca_cert_dir = ca_cert_dir | |
210 self.assert_hostname = assert_hostname | |
211 self.assert_fingerprint = assert_fingerprint | |
212 | |
213 def connect(self): | |
214 # Add certificate verification | |
215 conn = self._new_conn() | |
216 | |
217 resolved_cert_reqs = resolve_cert_reqs(self.cert_reqs) | |
218 resolved_ssl_version = resolve_ssl_version(self.ssl_version) | |
219 | |
220 hostname = self.host | |
221 if getattr(self, '_tunnel_host', None): | |
222 # _tunnel_host was added in Python 2.6.3 | |
223 # (See: http://hg.python.org/cpython/rev/0f57b30a152f) | |
224 | |
225 self.sock = conn | |
226 # Calls self._set_hostport(), so self.host is | |
227 # self._tunnel_host below. | |
228 self._tunnel() | |
229 # Mark this connection as not reusable | |
230 self.auto_open = 0 | |
231 | |
232 # Override the host with the one we're requesting data from. | |
233 hostname = self._tunnel_host | |
234 | |
235 is_time_off = datetime.date.today() < RECENT_DATE | |
236 if is_time_off: | |
237 warnings.warn(( | |
238 'System time is way off (before {0}). This will probably ' | |
239 'lead to SSL verification errors').format(RECENT_DATE), | |
240 SystemTimeWarning | |
241 ) | |
242 | |
243 # Wrap socket using verification with the root certs in | |
244 # trusted_root_certs | |
245 self.sock = ssl_wrap_socket(conn, self.key_file, self.cert_file, | |
246 cert_reqs=resolved_cert_reqs, | |
247 ca_certs=self.ca_certs, | |
248 ca_cert_dir=self.ca_cert_dir, | |
249 server_hostname=hostname, | |
250 ssl_version=resolved_ssl_version) | |
251 | |
252 if self.assert_fingerprint: | |
253 assert_fingerprint(self.sock.getpeercert(binary_form=True), | |
254 self.assert_fingerprint) | |
255 elif resolved_cert_reqs != ssl.CERT_NONE \ | |
256 and self.assert_hostname is not False: | |
257 cert = self.sock.getpeercert() | |
258 if not cert.get('subjectAltName', ()): | |
259 warnings.warn(( | |
260 'Certificate for {0} has no `subjectAltName`, falling back to check for a ' | |
261 '`commonName` for now. This feature is being removed by major browsers and ' | |
262 'deprecated by RFC 2818. (See https://github.com/shazow/urllib3/issues/497 ' | |
263 'for details.)'.format(hostname)), | |
264 SubjectAltNameWarning | |
265 ) | |
266 match_hostname(cert, self.assert_hostname or hostname) | |
267 | |
268 self.is_verified = (resolved_cert_reqs == ssl.CERT_REQUIRED | |
269 or self.assert_fingerprint is not None) | |
270 | |
271 | |
272 if ssl: | |
273 # Make a copy for testing. | |
274 UnverifiedHTTPSConnection = HTTPSConnection | |
275 HTTPSConnection = VerifiedHTTPSConnection | |
276 else: | |
277 HTTPSConnection = DummyConnection |