Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hhhrrrttt222111
GitHub Repository: hhhrrrttt222111/Dorkify
Path: blob/master/venv/Lib/site-packages/urllib3/contrib/socks.py
811 views
1
# -*- coding: utf-8 -*-
2
"""
3
This module contains provisional support for SOCKS proxies from within
4
urllib3. This module supports SOCKS4, SOCKS4A (an extension of SOCKS4), and
5
SOCKS5. To enable its functionality, either install PySocks or install this
6
module with the ``socks`` extra.
7
8
The SOCKS implementation supports the full range of urllib3 features. It also
9
supports the following SOCKS features:
10
11
- SOCKS4A (``proxy_url='socks4a://...``)
12
- SOCKS4 (``proxy_url='socks4://...``)
13
- SOCKS5 with remote DNS (``proxy_url='socks5h://...``)
14
- SOCKS5 with local DNS (``proxy_url='socks5://...``)
15
- Usernames and passwords for the SOCKS proxy
16
17
.. note::
18
It is recommended to use ``socks5h://`` or ``socks4a://`` schemes in
19
your ``proxy_url`` to ensure that DNS resolution is done from the remote
20
server instead of client-side when connecting to a domain name.
21
22
SOCKS4 supports IPv4 and domain names with the SOCKS4A extension. SOCKS5
23
supports IPv4, IPv6, and domain names.
24
25
When connecting to a SOCKS4 proxy the ``username`` portion of the ``proxy_url``
26
will be sent as the ``userid`` section of the SOCKS request::
27
28
proxy_url="socks4a://<userid>@proxy-host"
29
30
When connecting to a SOCKS5 proxy the ``username`` and ``password`` portion
31
of the ``proxy_url`` will be sent as the username/password to authenticate
32
with the proxy::
33
34
proxy_url="socks5h://<username>:<password>@proxy-host"
35
36
"""
37
from __future__ import absolute_import
38
39
try:
40
import socks
41
except ImportError:
42
import warnings
43
from ..exceptions import DependencyWarning
44
45
warnings.warn(
46
(
47
"SOCKS support in urllib3 requires the installation of optional "
48
"dependencies: specifically, PySocks. For more information, see "
49
"https://urllib3.readthedocs.io/en/latest/contrib.html#socks-proxies"
50
),
51
DependencyWarning,
52
)
53
raise
54
55
from socket import error as SocketError, timeout as SocketTimeout
56
57
from ..connection import HTTPConnection, HTTPSConnection
58
from ..connectionpool import HTTPConnectionPool, HTTPSConnectionPool
59
from ..exceptions import ConnectTimeoutError, NewConnectionError
60
from ..poolmanager import PoolManager
61
from ..util.url import parse_url
62
63
try:
64
import ssl
65
except ImportError:
66
ssl = None
67
68
69
class SOCKSConnection(HTTPConnection):
70
"""
71
A plain-text HTTP connection that connects via a SOCKS proxy.
72
"""
73
74
def __init__(self, *args, **kwargs):
75
self._socks_options = kwargs.pop("_socks_options")
76
super(SOCKSConnection, self).__init__(*args, **kwargs)
77
78
def _new_conn(self):
79
"""
80
Establish a new connection via the SOCKS proxy.
81
"""
82
extra_kw = {}
83
if self.source_address:
84
extra_kw["source_address"] = self.source_address
85
86
if self.socket_options:
87
extra_kw["socket_options"] = self.socket_options
88
89
try:
90
conn = socks.create_connection(
91
(self.host, self.port),
92
proxy_type=self._socks_options["socks_version"],
93
proxy_addr=self._socks_options["proxy_host"],
94
proxy_port=self._socks_options["proxy_port"],
95
proxy_username=self._socks_options["username"],
96
proxy_password=self._socks_options["password"],
97
proxy_rdns=self._socks_options["rdns"],
98
timeout=self.timeout,
99
**extra_kw
100
)
101
102
except SocketTimeout:
103
raise ConnectTimeoutError(
104
self,
105
"Connection to %s timed out. (connect timeout=%s)"
106
% (self.host, self.timeout),
107
)
108
109
except socks.ProxyError as e:
110
# This is fragile as hell, but it seems to be the only way to raise
111
# useful errors here.
112
if e.socket_err:
113
error = e.socket_err
114
if isinstance(error, SocketTimeout):
115
raise ConnectTimeoutError(
116
self,
117
"Connection to %s timed out. (connect timeout=%s)"
118
% (self.host, self.timeout),
119
)
120
else:
121
raise NewConnectionError(
122
self, "Failed to establish a new connection: %s" % error
123
)
124
else:
125
raise NewConnectionError(
126
self, "Failed to establish a new connection: %s" % e
127
)
128
129
except SocketError as e: # Defensive: PySocks should catch all these.
130
raise NewConnectionError(
131
self, "Failed to establish a new connection: %s" % e
132
)
133
134
return conn
135
136
137
# We don't need to duplicate the Verified/Unverified distinction from
138
# urllib3/connection.py here because the HTTPSConnection will already have been
139
# correctly set to either the Verified or Unverified form by that module. This
140
# means the SOCKSHTTPSConnection will automatically be the correct type.
141
class SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection):
142
pass
143
144
145
class SOCKSHTTPConnectionPool(HTTPConnectionPool):
146
ConnectionCls = SOCKSConnection
147
148
149
class SOCKSHTTPSConnectionPool(HTTPSConnectionPool):
150
ConnectionCls = SOCKSHTTPSConnection
151
152
153
class SOCKSProxyManager(PoolManager):
154
"""
155
A version of the urllib3 ProxyManager that routes connections via the
156
defined SOCKS proxy.
157
"""
158
159
pool_classes_by_scheme = {
160
"http": SOCKSHTTPConnectionPool,
161
"https": SOCKSHTTPSConnectionPool,
162
}
163
164
def __init__(
165
self,
166
proxy_url,
167
username=None,
168
password=None,
169
num_pools=10,
170
headers=None,
171
**connection_pool_kw
172
):
173
parsed = parse_url(proxy_url)
174
175
if username is None and password is None and parsed.auth is not None:
176
split = parsed.auth.split(":")
177
if len(split) == 2:
178
username, password = split
179
if parsed.scheme == "socks5":
180
socks_version = socks.PROXY_TYPE_SOCKS5
181
rdns = False
182
elif parsed.scheme == "socks5h":
183
socks_version = socks.PROXY_TYPE_SOCKS5
184
rdns = True
185
elif parsed.scheme == "socks4":
186
socks_version = socks.PROXY_TYPE_SOCKS4
187
rdns = False
188
elif parsed.scheme == "socks4a":
189
socks_version = socks.PROXY_TYPE_SOCKS4
190
rdns = True
191
else:
192
raise ValueError("Unable to determine SOCKS version from %s" % proxy_url)
193
194
self.proxy_url = proxy_url
195
196
socks_options = {
197
"socks_version": socks_version,
198
"proxy_host": parsed.host,
199
"proxy_port": parsed.port,
200
"username": username,
201
"password": password,
202
"rdns": rdns,
203
}
204
connection_pool_kw["_socks_options"] = socks_options
205
206
super(SOCKSProxyManager, self).__init__(
207
num_pools, headers, **connection_pool_kw
208
)
209
210
self.pool_classes_by_scheme = SOCKSProxyManager.pool_classes_by_scheme
211
212