diff options
Diffstat (limited to 'venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/connection.py')
-rw-r--r-- | venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/connection.py | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/connection.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/connection.py new file mode 100644 index 0000000..31ecd83 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/connection.py | |||
@@ -0,0 +1,130 @@ | |||
1 | from __future__ import absolute_import | ||
2 | import socket | ||
3 | from .wait import wait_for_read | ||
4 | from .selectors import HAS_SELECT, SelectorError | ||
5 | |||
6 | |||
7 | def is_connection_dropped(conn): # Platform-specific | ||
8 | """ | ||
9 | Returns True if the connection is dropped and should be closed. | ||
10 | |||
11 | :param conn: | ||
12 | :class:`httplib.HTTPConnection` object. | ||
13 | |||
14 | Note: For platforms like AppEngine, this will always return ``False`` to | ||
15 | let the platform handle connection recycling transparently for us. | ||
16 | """ | ||
17 | sock = getattr(conn, 'sock', False) | ||
18 | if sock is False: # Platform-specific: AppEngine | ||
19 | return False | ||
20 | if sock is None: # Connection already closed (such as by httplib). | ||
21 | return True | ||
22 | |||
23 | if not HAS_SELECT: | ||
24 | return False | ||
25 | |||
26 | try: | ||
27 | return bool(wait_for_read(sock, timeout=0.0)) | ||
28 | except SelectorError: | ||
29 | return True | ||
30 | |||
31 | |||
32 | # This function is copied from socket.py in the Python 2.7 standard | ||
33 | # library test suite. Added to its signature is only `socket_options`. | ||
34 | # One additional modification is that we avoid binding to IPv6 servers | ||
35 | # discovered in DNS if the system doesn't have IPv6 functionality. | ||
36 | def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, | ||
37 | source_address=None, socket_options=None): | ||
38 | """Connect to *address* and return the socket object. | ||
39 | |||
40 | Convenience function. Connect to *address* (a 2-tuple ``(host, | ||
41 | port)``) and return the socket object. Passing the optional | ||
42 | *timeout* parameter will set the timeout on the socket instance | ||
43 | before attempting to connect. If no *timeout* is supplied, the | ||
44 | global default timeout setting returned by :func:`getdefaulttimeout` | ||
45 | is used. If *source_address* is set it must be a tuple of (host, port) | ||
46 | for the socket to bind as a source address before making the connection. | ||
47 | An host of '' or port 0 tells the OS to use the default. | ||
48 | """ | ||
49 | |||
50 | host, port = address | ||
51 | if host.startswith('['): | ||
52 | host = host.strip('[]') | ||
53 | err = None | ||
54 | |||
55 | # Using the value from allowed_gai_family() in the context of getaddrinfo lets | ||
56 | # us select whether to work with IPv4 DNS records, IPv6 records, or both. | ||
57 | # The original create_connection function always returns all records. | ||
58 | family = allowed_gai_family() | ||
59 | |||
60 | for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): | ||
61 | af, socktype, proto, canonname, sa = res | ||
62 | sock = None | ||
63 | try: | ||
64 | sock = socket.socket(af, socktype, proto) | ||
65 | |||
66 | # If provided, set socket level options before connecting. | ||
67 | _set_socket_options(sock, socket_options) | ||
68 | |||
69 | if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: | ||
70 | sock.settimeout(timeout) | ||
71 | if source_address: | ||
72 | sock.bind(source_address) | ||
73 | sock.connect(sa) | ||
74 | return sock | ||
75 | |||
76 | except socket.error as e: | ||
77 | err = e | ||
78 | if sock is not None: | ||
79 | sock.close() | ||
80 | sock = None | ||
81 | |||
82 | if err is not None: | ||
83 | raise err | ||
84 | |||
85 | raise socket.error("getaddrinfo returns an empty list") | ||
86 | |||
87 | |||
88 | def _set_socket_options(sock, options): | ||
89 | if options is None: | ||
90 | return | ||
91 | |||
92 | for opt in options: | ||
93 | sock.setsockopt(*opt) | ||
94 | |||
95 | |||
96 | def allowed_gai_family(): | ||
97 | """This function is designed to work in the context of | ||
98 | getaddrinfo, where family=socket.AF_UNSPEC is the default and | ||
99 | will perform a DNS search for both IPv6 and IPv4 records.""" | ||
100 | |||
101 | family = socket.AF_INET | ||
102 | if HAS_IPV6: | ||
103 | family = socket.AF_UNSPEC | ||
104 | return family | ||
105 | |||
106 | |||
107 | def _has_ipv6(host): | ||
108 | """ Returns True if the system can bind an IPv6 address. """ | ||
109 | sock = None | ||
110 | has_ipv6 = False | ||
111 | |||
112 | if socket.has_ipv6: | ||
113 | # has_ipv6 returns true if cPython was compiled with IPv6 support. | ||
114 | # It does not tell us if the system has IPv6 support enabled. To | ||
115 | # determine that we must bind to an IPv6 address. | ||
116 | # https://github.com/shazow/urllib3/pull/611 | ||
117 | # https://bugs.python.org/issue658327 | ||
118 | try: | ||
119 | sock = socket.socket(socket.AF_INET6) | ||
120 | sock.bind((host, 0)) | ||
121 | has_ipv6 = True | ||
122 | except Exception: | ||
123 | pass | ||
124 | |||
125 | if sock: | ||
126 | sock.close() | ||
127 | return has_ipv6 | ||
128 | |||
129 | |||
130 | HAS_IPV6 = _has_ipv6('::1') | ||