1from __future__
import absolute_import
9from socket
import error
as SocketError
10from socket
import timeout
as SocketTimeout
12from .packages
import six
15from .
util.proxy import create_proxy_ssl_context
21except (ImportError, AttributeError):
30 ConnectionError = ConnectionError
39 BrokenPipeError = BrokenPipeError
46from ._collections
import HTTPHeaderDict
47from ._version
import __version__
48from .exceptions
import (
51 SubjectAltNameWarning,
54from .util
import SKIP_HEADER, SKIPPABLE_HEADERS, connection
57 create_urllib3_context,
67port_by_scheme = {
"http": 80,
"https": 443}
73_CONTAINS_CONTROL_CHAR_RE =
re.compile(
r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]")
78 Based on :class:`http.client.HTTPConnection` but provides an extra constructor
79 backwards-compatibility layer between older and newer Pythons.
81 Additional keyword parameters are used to configure attributes of the connection.
82 Accepted parameters include:
84 - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool`
85 - ``source_address``: Set the source address for the current connection.
86 - ``socket_options``: Set specific options on the underlying socket. If not specified, then
87 defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling
88 Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy.
90 For example, if you wish to enable TCP Keep Alive in addition to the defaults,
93 .. code-block:: python
95 HTTPConnection.default_socket_options + [
96 (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
99 Or you may want to disable the defaults by passing an empty list (e.g., ``[]``).
102 default_port = port_by_scheme[
"http"]
113 proxy_is_verified =
None
135 Getter method to remove any trailing dots that indicate the hostname is an FQDN.
137 In general, SSL certificates don't include the trailing dot indicating a
138 fully-qualified domain name, and thus, they don't validate properly when
139 checked against a domain name that includes the dot. In addition, some
140 servers may not expect to receive the trailing dot when provided.
142 However, the hostname with trailing dot is critical to DNS resolution; doing a
143 lookup with the trailing dot will properly only resolve the appropriate FQDN,
144 whereas a lookup without a trailing dot will search the system's search domain
145 list. Thus, it's important to keep the original host around for use only in
146 those cases where it's appropriate (i.e., when doing DNS lookup to establish the
147 actual TCP connection across which we're going to send HTTP requests).
154 Setter for the `host` property.
156 We assume that only urllib3 uses the _dns_host attribute; httplib itself
157 only uses `host`, and it seems reasonable that other libraries follow suit.
162 """Establish a socket connection and set nodelay settings on it.
164 :return: New socket connection.
178 except SocketTimeout:
181 "Connection to %s timed out. (connect timeout=%s)"
185 except SocketError
as e:
187 self,
"Failed to establish a new connection: %s" % e
194 return getattr(self,
"_tunnel_host",
None)
215 "Method cannot contain non-token characters %r (found at least %r)"
223 if not any(
isinstance(v, str)
and v == SKIP_HEADER
for v
in values):
227 "urllib3.util.SKIP_HEADER only supports '%s'"
228 % (
"', '".join(map(
str.title, sorted(SKIPPABLE_HEADERS))),)
231 def request(self, method, url, body=None, headers=None):
234 if getattr(self,
"sock",
None)
is not None:
244 super(HTTPConnection, self).request(method, url, body=body, headers=headers)
248 Alternative to the common request method, which sends the
249 body with chunked encoding and not as one block
251 headers = headers
or {}
253 skip_accept_encoding =
"accept-encoding" in header_keys
254 skip_host =
"host" in header_keys
256 method, url, skip_accept_encoding=skip_accept_encoding, skip_host=skip_host
258 if "user-agent" not in header_keys:
262 if "transfer-encoding" not in header_keys:
263 self.
putheader(
"Transfer-Encoding",
"chunked")
275 len_str = hex(
len(chunk))[2:]
283 self.send(b
"0\r\n\r\n")
288 Many of the parameters to this constructor are passed to the underlying SSL
289 socket by means of :py:func:`urllib3.util.ssl_wrap_socket`.
292 default_port = port_by_scheme[
"https"]
299 assert_fingerprint =
None
300 tls_in_tls_required =
False
310 timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
312 server_hostname=None,
335 assert_hostname=None,
336 assert_fingerprint=None,
341 This method should only be called once, before the connection is used.
345 if cert_reqs
is None:
349 cert_reqs = resolve_cert_reqs(
None)
379 hostname = self._tunnel_host
381 server_hostname = hostname
389 "System time is way off (before {0}). This will probably "
390 "lead to SSL verification errors"
391 ).format(RECENT_DATE),
397 default_ssl_context =
False
399 default_ssl_context =
True
402 cert_reqs=resolve_cert_reqs(self.
cert_reqs),
414 and default_ssl_context
415 and hasattr(context,
"load_default_certs")
427 server_hostname=server_hostname,
429 tls_in_tls=tls_in_tls,
439 and self.
socksock.version()
in {
"TLSv1",
"TLSv1.1"}
442 "Negotiating TLSv1/TLSv1.1 by default is deprecated "
443 "and will be disabled in urllib3 v2.0.0. Connecting to "
444 "'%s' with '%s' can be enabled by explicitly opting-in "
455 and not getattr(context,
"check_hostname",
False)
462 if not cert.get(
"subjectAltName", ()):
465 "Certificate for {0} has no `subjectAltName`, falling back to check for a "
466 "`commonName` for now. This feature is being removed by major browsers and "
467 "deprecated by RFC 2818. (See https://github.com/urllib3/urllib3/issues/497 "
468 "for details.)".format(hostname)
470 SubjectAltNameWarning,
481 Establish a TLS connection to the proxy using the provided SSL context.
488 return ssl_wrap_socket(
490 server_hostname=hostname,
491 ssl_context=ssl_context,
494 ssl_context = create_proxy_ssl_context(
504 socket = ssl_wrap_socket(
509 server_hostname=hostname,
510 ssl_context=ssl_context,
514 ssl_context,
"check_hostname",
False
520 if not cert.get(
"subjectAltName", ()):
523 "Certificate for {0} has no `subjectAltName`, falling back to check for a "
524 "`commonName` for now. This feature is being removed by major browsers and "
525 "deprecated by RFC 2818. (See https://github.com/urllib3/urllib3/issues/497 "
526 "for details.)".format(hostname)
528 SubjectAltNameWarning,
541 if is_ipaddress(stripped_hostname):
542 asserted_hostname = stripped_hostname
545 match_hostname(cert, asserted_hostname)
546 except CertificateError
as e:
548 "Certificate did not match expected hostname: %s. Certificate: %s",
559 return "python-urllib3/%s" % __version__
563 """Used to detect a failed ConnectionCls import."""
569 HTTPSConnection = DummyConnection
572VerifiedHTTPSConnection = HTTPSConnection
request_chunked(self, method, url, body=None, headers=None)
__init__(self, *args, **kw)
_prepare_conn(self, conn)
putrequest(self, method, url, *args, **kwargs)
putheader(self, header, *values)
list default_socket_options
_connect_tls_proxy(self, hostname, conn)
set_cert(self, key_file=None, cert_file=None, cert_reqs=None, key_password=None, ca_certs=None, assert_hostname=None, assert_fingerprint=None, ca_cert_dir=None, ca_cert_data=None)
__init__(self, host, port=None, key_file=None, cert_file=None, key_password=None, strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, ssl_context=None, server_hostname=None, **kw)
_match_hostname(cert, asserted_hostname)
_get_default_user_agent()