python-socks 2.8.2__py3-none-any.whl → 3.1.0__py3-none-any.whl
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.
- python_socks/__init__.py +11 -13
- python_socks/_abc.py +35 -22
- python_socks/_connectors/abc.py +5 -3
- python_socks/_connectors/factory_async.py +8 -8
- python_socks/_connectors/factory_sync.py +8 -8
- python_socks/_connectors/http_async.py +7 -7
- python_socks/_connectors/http_sync.py +7 -7
- python_socks/_connectors/socks4_async.py +10 -10
- python_socks/_connectors/socks4_sync.py +10 -10
- python_socks/_connectors/socks5_async.py +29 -26
- python_socks/_connectors/socks5_sync.py +36 -28
- python_socks/_errors.py +15 -2
- python_socks/_helpers.py +35 -32
- python_socks/_protocols/errors.py +10 -1
- python_socks/_protocols/http.py +55 -60
- python_socks/_protocols/socks4.py +22 -26
- python_socks/_protocols/socks5.py +77 -70
- python_socks/_types.py +4 -0
- python_socks/_version.py +2 -2
- python_socks/async_/__init__.py +0 -3
- python_socks/async_/anyio/__init__.py +1 -2
- python_socks/async_/anyio/_connect.py +6 -4
- python_socks/async_/anyio/_proxy.py +85 -92
- python_socks/async_/anyio/_resolver.py +10 -3
- python_socks/async_/anyio/_stream.py +11 -26
- python_socks/async_/anyio/v2/__init__.py +1 -5
- python_socks/async_/anyio/v2/_connect.py +7 -4
- python_socks/async_/anyio/v2/_proxy.py +36 -26
- python_socks/async_/anyio/v2/_stream.py +11 -11
- python_socks/async_/asyncio/__init__.py +1 -2
- python_socks/async_/asyncio/_connect.py +12 -7
- python_socks/async_/asyncio/_proxy.py +48 -49
- python_socks/async_/asyncio/_resolver.py +11 -4
- python_socks/async_/asyncio/_stream.py +9 -13
- python_socks/async_/asyncio/v2/__init__.py +1 -2
- python_socks/async_/asyncio/v2/_connect.py +8 -5
- python_socks/async_/asyncio/v2/_proxy.py +38 -28
- python_socks/async_/asyncio/v2/_stream.py +20 -18
- python_socks/async_/trio/__init__.py +1 -1
- python_socks/async_/trio/_connect.py +5 -4
- python_socks/async_/trio/_proxy.py +46 -48
- python_socks/async_/trio/_resolver.py +11 -3
- python_socks/async_/trio/_stream.py +9 -9
- python_socks/async_/trio/v2/__init__.py +1 -5
- python_socks/async_/trio/v2/_connect.py +3 -2
- python_socks/async_/trio/v2/_proxy.py +34 -24
- python_socks/async_/trio/v2/_stream.py +13 -13
- python_socks/sync/__init__.py +1 -3
- python_socks/sync/_connect.py +4 -3
- python_socks/sync/_proxy.py +42 -43
- python_socks/sync/_resolver.py +17 -5
- python_socks/sync/_stream.py +9 -9
- python_socks/sync/v2/__init__.py +1 -5
- python_socks/sync/v2/_connect.py +5 -3
- python_socks/sync/v2/_proxy.py +35 -26
- python_socks/sync/v2/_ssl_transport.py +3 -0
- python_socks/sync/v2/_stream.py +19 -14
- python_socks-3.1.0.dist-info/METADATA +346 -0
- python_socks-3.1.0.dist-info/RECORD +65 -0
- {python_socks-2.8.2.dist-info → python_socks-3.1.0.dist-info}/WHEEL +1 -1
- python_socks/async_/_proxy_chain.py +0 -34
- python_socks/async_/anyio/_chain.py +0 -42
- python_socks/async_/anyio/v2/_chain.py +0 -32
- python_socks/async_/asyncio/v2/_chain.py +0 -32
- python_socks/async_/curio/__init__.py +0 -4
- python_socks/async_/curio/_connect.py +0 -17
- python_socks/async_/curio/_proxy.py +0 -132
- python_socks/async_/curio/_resolver.py +0 -25
- python_socks/async_/curio/_stream.py +0 -32
- python_socks/async_/trio/v2/_chain.py +0 -32
- python_socks/sync/_chain.py +0 -32
- python_socks/sync/v2/_chain.py +0 -26
- python_socks-2.8.2.dist-info/METADATA +0 -295
- python_socks-2.8.2.dist-info/RECORD +0 -77
- {python_socks-2.8.2.dist-info → python_socks-3.1.0.dist-info}/licenses/LICENSE.txt +0 -0
- {python_socks-2.8.2.dist-info → python_socks-3.1.0.dist-info}/top_level.txt +0 -0
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
from typing import Any, Optional
|
|
2
|
-
import warnings
|
|
3
|
-
import curio
|
|
4
|
-
import curio.io
|
|
5
|
-
|
|
6
|
-
from ..._types import ProxyType
|
|
7
|
-
from ..._helpers import parse_proxy_url
|
|
8
|
-
from ..._errors import ProxyConnectionError, ProxyTimeoutError, ProxyError
|
|
9
|
-
|
|
10
|
-
from ._stream import CurioSocketStream
|
|
11
|
-
from ._resolver import Resolver
|
|
12
|
-
from ._connect import connect_tcp
|
|
13
|
-
|
|
14
|
-
from ..._protocols.errors import ReplyError
|
|
15
|
-
from ..._connectors.factory_async import create_connector
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
DEFAULT_TIMEOUT = 60
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class CurioProxy:
|
|
22
|
-
def __init__(
|
|
23
|
-
self,
|
|
24
|
-
proxy_type: ProxyType,
|
|
25
|
-
host: str,
|
|
26
|
-
port: int,
|
|
27
|
-
username: Optional[str] = None,
|
|
28
|
-
password: Optional[str] = None,
|
|
29
|
-
rdns: Optional[bool] = None,
|
|
30
|
-
):
|
|
31
|
-
self._proxy_type = proxy_type
|
|
32
|
-
self._proxy_host = host
|
|
33
|
-
self._proxy_port = port
|
|
34
|
-
self._password = password
|
|
35
|
-
self._username = username
|
|
36
|
-
self._rdns = rdns
|
|
37
|
-
|
|
38
|
-
self._resolver = Resolver()
|
|
39
|
-
|
|
40
|
-
async def connect(
|
|
41
|
-
self,
|
|
42
|
-
dest_host: str,
|
|
43
|
-
dest_port: int,
|
|
44
|
-
timeout: Optional[float] = None,
|
|
45
|
-
**kwargs: Any,
|
|
46
|
-
) -> curio.io.Socket:
|
|
47
|
-
if timeout is None:
|
|
48
|
-
timeout = DEFAULT_TIMEOUT
|
|
49
|
-
|
|
50
|
-
_socket = kwargs.get('_socket')
|
|
51
|
-
if _socket is not None:
|
|
52
|
-
warnings.warn(
|
|
53
|
-
"The '_socket' argument is deprecated and will be removed in the future",
|
|
54
|
-
DeprecationWarning,
|
|
55
|
-
stacklevel=2,
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
local_addr = kwargs.get('local_addr')
|
|
59
|
-
try:
|
|
60
|
-
return await curio.timeout_after(
|
|
61
|
-
timeout,
|
|
62
|
-
self._connect,
|
|
63
|
-
dest_host,
|
|
64
|
-
dest_port,
|
|
65
|
-
_socket,
|
|
66
|
-
local_addr,
|
|
67
|
-
)
|
|
68
|
-
except curio.TaskTimeout as e:
|
|
69
|
-
raise ProxyTimeoutError(f'Proxy connection timed out: {timeout}') from e
|
|
70
|
-
|
|
71
|
-
async def _connect(
|
|
72
|
-
self,
|
|
73
|
-
dest_host: str,
|
|
74
|
-
dest_port: int,
|
|
75
|
-
_socket=None,
|
|
76
|
-
local_addr=None,
|
|
77
|
-
):
|
|
78
|
-
if _socket is None:
|
|
79
|
-
try:
|
|
80
|
-
_socket = await connect_tcp(
|
|
81
|
-
host=self._proxy_host,
|
|
82
|
-
port=self._proxy_port,
|
|
83
|
-
local_addr=local_addr,
|
|
84
|
-
)
|
|
85
|
-
except OSError as e:
|
|
86
|
-
msg = 'Could not connect to proxy {}:{} [{}]'.format(
|
|
87
|
-
self._proxy_host,
|
|
88
|
-
self._proxy_port,
|
|
89
|
-
e.strerror,
|
|
90
|
-
)
|
|
91
|
-
raise ProxyConnectionError(e.errno, msg) from e
|
|
92
|
-
|
|
93
|
-
stream = CurioSocketStream(_socket)
|
|
94
|
-
|
|
95
|
-
try:
|
|
96
|
-
connector = create_connector(
|
|
97
|
-
proxy_type=self._proxy_type,
|
|
98
|
-
username=self._username,
|
|
99
|
-
password=self._password,
|
|
100
|
-
rdns=self._rdns,
|
|
101
|
-
resolver=self._resolver,
|
|
102
|
-
)
|
|
103
|
-
await connector.connect(
|
|
104
|
-
stream=stream,
|
|
105
|
-
host=dest_host,
|
|
106
|
-
port=dest_port,
|
|
107
|
-
)
|
|
108
|
-
return _socket
|
|
109
|
-
|
|
110
|
-
except ReplyError as e:
|
|
111
|
-
await stream.close()
|
|
112
|
-
raise ProxyError(e, error_code=e.error_code)
|
|
113
|
-
except BaseException:
|
|
114
|
-
await stream.close()
|
|
115
|
-
raise
|
|
116
|
-
|
|
117
|
-
@property
|
|
118
|
-
def proxy_host(self):
|
|
119
|
-
return self._proxy_host
|
|
120
|
-
|
|
121
|
-
@property
|
|
122
|
-
def proxy_port(self):
|
|
123
|
-
return self._proxy_port
|
|
124
|
-
|
|
125
|
-
@classmethod
|
|
126
|
-
def create(cls, *args, **kwargs): # for backward compatibility
|
|
127
|
-
return cls(*args, **kwargs)
|
|
128
|
-
|
|
129
|
-
@classmethod
|
|
130
|
-
def from_url(cls, url: str, **kwargs) -> 'CurioProxy':
|
|
131
|
-
url_args = parse_proxy_url(url)
|
|
132
|
-
return cls(*url_args, **kwargs)
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import socket
|
|
2
|
-
from curio.socket import getaddrinfo
|
|
3
|
-
|
|
4
|
-
from ... import _abc as abc
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class Resolver(abc.AsyncResolver):
|
|
8
|
-
async def resolve(self, host, port=0, family=socket.AF_UNSPEC):
|
|
9
|
-
try:
|
|
10
|
-
infos = await getaddrinfo(
|
|
11
|
-
host=host,
|
|
12
|
-
port=port,
|
|
13
|
-
family=family,
|
|
14
|
-
type=socket.SOCK_STREAM,
|
|
15
|
-
)
|
|
16
|
-
except socket.gaierror: # pragma: no cover
|
|
17
|
-
infos = None
|
|
18
|
-
|
|
19
|
-
if not infos: # pragma: no cover
|
|
20
|
-
raise OSError('Can`t resolve address {}:{} [{}]'.format(host, port, family))
|
|
21
|
-
|
|
22
|
-
infos = sorted(infos, key=lambda info: info[0])
|
|
23
|
-
|
|
24
|
-
family, _, _, _, address = infos[0]
|
|
25
|
-
return family, address[0]
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import curio.io
|
|
2
|
-
import curio.socket
|
|
3
|
-
|
|
4
|
-
from ... import _abc as abc
|
|
5
|
-
from ..._errors import ProxyError
|
|
6
|
-
|
|
7
|
-
DEFAULT_RECEIVE_SIZE = 65536
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class CurioSocketStream(abc.AsyncSocketStream):
|
|
11
|
-
_socket: curio.io.Socket = None
|
|
12
|
-
|
|
13
|
-
def __init__(self, sock: curio.io.Socket):
|
|
14
|
-
self._socket = sock
|
|
15
|
-
|
|
16
|
-
async def write_all(self, data):
|
|
17
|
-
await self._socket.sendall(data)
|
|
18
|
-
|
|
19
|
-
async def read(self, max_bytes=DEFAULT_RECEIVE_SIZE):
|
|
20
|
-
return await self._socket.recv(max_bytes)
|
|
21
|
-
|
|
22
|
-
async def read_exact(self, n):
|
|
23
|
-
data = bytearray()
|
|
24
|
-
while len(data) < n:
|
|
25
|
-
packet = await self._socket.recv(n - len(data))
|
|
26
|
-
if not packet: # pragma: no cover
|
|
27
|
-
raise ProxyError('Connection closed unexpectedly')
|
|
28
|
-
data += packet
|
|
29
|
-
return data
|
|
30
|
-
|
|
31
|
-
async def close(self):
|
|
32
|
-
await self._socket.close()
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
from typing import Sequence
|
|
2
|
-
import warnings
|
|
3
|
-
from ._proxy import TrioProxy
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class ProxyChain:
|
|
7
|
-
def __init__(self, proxies: Sequence[TrioProxy]):
|
|
8
|
-
warnings.warn(
|
|
9
|
-
'This implementation of ProxyChain is deprecated and will be removed in the future',
|
|
10
|
-
DeprecationWarning,
|
|
11
|
-
stacklevel=2,
|
|
12
|
-
)
|
|
13
|
-
self._proxies = proxies
|
|
14
|
-
|
|
15
|
-
async def connect(
|
|
16
|
-
self,
|
|
17
|
-
dest_host,
|
|
18
|
-
dest_port,
|
|
19
|
-
dest_ssl=None,
|
|
20
|
-
timeout=None,
|
|
21
|
-
):
|
|
22
|
-
forward = None
|
|
23
|
-
for proxy in self._proxies:
|
|
24
|
-
proxy._forward = forward
|
|
25
|
-
forward = proxy
|
|
26
|
-
|
|
27
|
-
return await forward.connect(
|
|
28
|
-
dest_host=dest_host,
|
|
29
|
-
dest_port=dest_port,
|
|
30
|
-
dest_ssl=dest_ssl,
|
|
31
|
-
timeout=timeout,
|
|
32
|
-
)
|
python_socks/sync/_chain.py
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
from typing import Iterable
|
|
2
|
-
import warnings
|
|
3
|
-
from ._proxy import SyncProxy
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class ProxyChain:
|
|
7
|
-
def __init__(self, proxies: Iterable[SyncProxy]):
|
|
8
|
-
warnings.warn(
|
|
9
|
-
'This implementation of ProxyChain is deprecated and will be removed in the future',
|
|
10
|
-
DeprecationWarning,
|
|
11
|
-
stacklevel=2,
|
|
12
|
-
)
|
|
13
|
-
self._proxies = proxies
|
|
14
|
-
|
|
15
|
-
def connect(self, dest_host, dest_port, timeout=None):
|
|
16
|
-
curr_socket = None
|
|
17
|
-
proxies = list(self._proxies)
|
|
18
|
-
|
|
19
|
-
length = len(proxies) - 1
|
|
20
|
-
for i in range(length):
|
|
21
|
-
curr_socket = proxies[i].connect(
|
|
22
|
-
dest_host=proxies[i + 1].proxy_host,
|
|
23
|
-
dest_port=proxies[i + 1].proxy_port,
|
|
24
|
-
timeout=timeout,
|
|
25
|
-
_socket=curr_socket,
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
curr_socket = proxies[length].connect(
|
|
29
|
-
dest_host=dest_host, dest_port=dest_port, timeout=timeout, _socket=curr_socket
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
return curr_socket
|
python_socks/sync/v2/_chain.py
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
from typing import Iterable
|
|
2
|
-
from ._proxy import SyncProxy
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class ProxyChain:
|
|
6
|
-
def __init__(self, proxies: Iterable[SyncProxy]):
|
|
7
|
-
self._proxies = proxies
|
|
8
|
-
|
|
9
|
-
def connect(
|
|
10
|
-
self,
|
|
11
|
-
dest_host,
|
|
12
|
-
dest_port,
|
|
13
|
-
dest_ssl=None,
|
|
14
|
-
timeout=None,
|
|
15
|
-
):
|
|
16
|
-
forward = None
|
|
17
|
-
for proxy in self._proxies:
|
|
18
|
-
proxy._forward = forward
|
|
19
|
-
forward = proxy
|
|
20
|
-
|
|
21
|
-
return forward.connect(
|
|
22
|
-
dest_host=dest_host,
|
|
23
|
-
dest_port=dest_port,
|
|
24
|
-
dest_ssl=dest_ssl,
|
|
25
|
-
timeout=timeout,
|
|
26
|
-
)
|
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: python-socks
|
|
3
|
-
Version: 2.8.2
|
|
4
|
-
Summary: Proxy (SOCKS4, SOCKS5, HTTP CONNECT) client for Python
|
|
5
|
-
Author-email: Roman Snegirev <snegiryev@gmail.com>
|
|
6
|
-
License: Apache-2.0
|
|
7
|
-
Project-URL: homepage, https://github.com/romis2012/python-socks
|
|
8
|
-
Project-URL: repository, https://github.com/romis2012/python-socks
|
|
9
|
-
Keywords: socks,socks5,socks4,http,proxy,asyncio,trio,curio,anyio
|
|
10
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
-
Classifier: Programming Language :: Python
|
|
12
|
-
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
-
Classifier: Operating System :: MacOS
|
|
22
|
-
Classifier: Operating System :: Microsoft
|
|
23
|
-
Classifier: Operating System :: POSIX :: Linux
|
|
24
|
-
Classifier: Topic :: Internet :: WWW/HTTP
|
|
25
|
-
Classifier: Intended Audience :: Developers
|
|
26
|
-
Classifier: Framework :: AsyncIO
|
|
27
|
-
Classifier: Framework :: Trio
|
|
28
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
29
|
-
Requires-Python: >=3.8.0
|
|
30
|
-
Description-Content-Type: text/markdown
|
|
31
|
-
License-File: LICENSE.txt
|
|
32
|
-
Provides-Extra: asyncio
|
|
33
|
-
Requires-Dist: async-timeout>=4.0; python_version < "3.11" and extra == "asyncio"
|
|
34
|
-
Provides-Extra: trio
|
|
35
|
-
Requires-Dist: trio>=0.24; extra == "trio"
|
|
36
|
-
Provides-Extra: curio
|
|
37
|
-
Requires-Dist: curio>=1.4; extra == "curio"
|
|
38
|
-
Provides-Extra: anyio
|
|
39
|
-
Requires-Dist: anyio<5.0.0,>=3.3.4; extra == "anyio"
|
|
40
|
-
Dynamic: license-file
|
|
41
|
-
|
|
42
|
-
## python-socks
|
|
43
|
-
|
|
44
|
-
[](https://github.com/romis2012/python-socks/actions/workflows/ci.yml)
|
|
45
|
-
[](https://codecov.io/gh/romis2012/python-socks)
|
|
46
|
-
[](https://pypi.python.org/pypi/python-socks)
|
|
47
|
-
[](https://github.com/romis2012/python-socks)
|
|
48
|
-
<!--
|
|
49
|
-
[](https://pepy.tech/project/python-socks)
|
|
50
|
-
-->
|
|
51
|
-
|
|
52
|
-
The `python-socks` package provides a core proxy client functionality for Python.
|
|
53
|
-
Supports `SOCKS4(a)`, `SOCKS5(h)`, `HTTP CONNECT` proxy and provides sync and async (asyncio, trio, curio, anyio) APIs.
|
|
54
|
-
You probably don't need to use `python-socks` directly.
|
|
55
|
-
It is used internally by
|
|
56
|
-
[aiohttp-socks](https://github.com/romis2012/aiohttp-socks) and [httpx-socks](https://github.com/romis2012/httpx-socks) packages.
|
|
57
|
-
|
|
58
|
-
## Requirements
|
|
59
|
-
- Python >= 3.8
|
|
60
|
-
- async-timeout >= 4.0 (optional)
|
|
61
|
-
- trio >= 0.24 (optional)
|
|
62
|
-
- curio >= 1.4 (optional)
|
|
63
|
-
- anyio >= 3.3.4 (optional)
|
|
64
|
-
|
|
65
|
-
## Installation
|
|
66
|
-
|
|
67
|
-
only sync proxy support:
|
|
68
|
-
```
|
|
69
|
-
pip install python-socks
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
to include optional asyncio support:
|
|
73
|
-
```
|
|
74
|
-
pip install python-socks[asyncio]
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
to include optional trio support:
|
|
78
|
-
```
|
|
79
|
-
pip install python-socks[trio]
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
to include optional curio support:
|
|
83
|
-
```
|
|
84
|
-
pip install python-socks[curio]
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
to include optional anyio support:
|
|
88
|
-
```
|
|
89
|
-
pip install python-socks[anyio]
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
## Simple usage
|
|
93
|
-
We are making secure HTTP GET request via SOCKS5 proxy
|
|
94
|
-
|
|
95
|
-
#### Sync
|
|
96
|
-
```python
|
|
97
|
-
import ssl
|
|
98
|
-
from python_socks.sync import Proxy
|
|
99
|
-
|
|
100
|
-
proxy = Proxy.from_url('socks5://user:password@127.0.0.1:1080')
|
|
101
|
-
|
|
102
|
-
# `connect` returns standard Python socket in blocking mode
|
|
103
|
-
sock = proxy.connect(dest_host='check-host.net', dest_port=443)
|
|
104
|
-
|
|
105
|
-
sock = ssl.create_default_context().wrap_socket(
|
|
106
|
-
sock=sock,
|
|
107
|
-
server_hostname='check-host.net'
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
request = (
|
|
111
|
-
b'GET /ip HTTP/1.1\r\n'
|
|
112
|
-
b'Host: check-host.net\r\n'
|
|
113
|
-
b'Connection: close\r\n\r\n'
|
|
114
|
-
)
|
|
115
|
-
sock.sendall(request)
|
|
116
|
-
response = sock.recv(4096)
|
|
117
|
-
print(response)
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
#### Async (asyncio)
|
|
121
|
-
```python
|
|
122
|
-
import ssl
|
|
123
|
-
import asyncio
|
|
124
|
-
from python_socks.async_.asyncio import Proxy
|
|
125
|
-
|
|
126
|
-
proxy = Proxy.from_url('socks5://user:password@127.0.0.1:1080')
|
|
127
|
-
|
|
128
|
-
# `connect` returns standard Python socket in non-blocking mode
|
|
129
|
-
# so we can pass it to asyncio.open_connection(...)
|
|
130
|
-
sock = await proxy.connect(dest_host='check-host.net', dest_port=443)
|
|
131
|
-
|
|
132
|
-
reader, writer = await asyncio.open_connection(
|
|
133
|
-
host=None,
|
|
134
|
-
port=None,
|
|
135
|
-
sock=sock,
|
|
136
|
-
ssl=ssl.create_default_context(),
|
|
137
|
-
server_hostname='check-host.net',
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
request = (
|
|
141
|
-
b'GET /ip HTTP/1.1\r\n'
|
|
142
|
-
b'Host: check-host.net\r\n'
|
|
143
|
-
b'Connection: close\r\n\r\n'
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
writer.write(request)
|
|
147
|
-
response = await reader.read(-1)
|
|
148
|
-
print(response)
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
#### Async (trio)
|
|
152
|
-
```python
|
|
153
|
-
import ssl
|
|
154
|
-
import trio
|
|
155
|
-
from python_socks.async_.trio import Proxy
|
|
156
|
-
|
|
157
|
-
proxy = Proxy.from_url('socks5://user:password@127.0.0.1:1080')
|
|
158
|
-
|
|
159
|
-
# `connect` returns trio socket
|
|
160
|
-
# so we can pass it to trio.SocketStream
|
|
161
|
-
sock = await proxy.connect(dest_host='check-host.net', dest_port=443)
|
|
162
|
-
|
|
163
|
-
stream = trio.SocketStream(sock)
|
|
164
|
-
|
|
165
|
-
stream = trio.SSLStream(
|
|
166
|
-
stream, ssl.create_default_context(),
|
|
167
|
-
server_hostname='check-host.net'
|
|
168
|
-
)
|
|
169
|
-
await stream.do_handshake()
|
|
170
|
-
|
|
171
|
-
request = (
|
|
172
|
-
b'GET /ip HTTP/1.1\r\n'
|
|
173
|
-
b'Host: check-host.net\r\n'
|
|
174
|
-
b'Connection: close\r\n\r\n'
|
|
175
|
-
)
|
|
176
|
-
|
|
177
|
-
await stream.send_all(request)
|
|
178
|
-
response = await stream.receive_some(4096)
|
|
179
|
-
print(response)
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
#### Async (curio)
|
|
183
|
-
```python
|
|
184
|
-
import curio.ssl as curiossl
|
|
185
|
-
from python_socks.async_.curio import Proxy
|
|
186
|
-
|
|
187
|
-
proxy = Proxy.from_url('socks5://user:password@127.0.0.1:1080')
|
|
188
|
-
# `connect` returns curio.io.Socket
|
|
189
|
-
sock = await proxy.connect(
|
|
190
|
-
dest_host='check-host.net',
|
|
191
|
-
dest_port=443
|
|
192
|
-
)
|
|
193
|
-
|
|
194
|
-
request = (
|
|
195
|
-
b'GET /ip HTTP/1.1\r\n'
|
|
196
|
-
b'Host: check-host.net\r\n'
|
|
197
|
-
b'Connection: close\r\n\r\n'
|
|
198
|
-
)
|
|
199
|
-
|
|
200
|
-
ssl_context = curiossl.create_default_context()
|
|
201
|
-
sock = await ssl_context.wrap_socket(
|
|
202
|
-
sock, do_handshake_on_connect=False, server_hostname='check-host.net'
|
|
203
|
-
)
|
|
204
|
-
|
|
205
|
-
await sock.do_handshake()
|
|
206
|
-
|
|
207
|
-
stream = sock.as_stream()
|
|
208
|
-
|
|
209
|
-
await stream.write(request)
|
|
210
|
-
response = await stream.read(1024)
|
|
211
|
-
print(response)
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
#### Async (anyio)
|
|
215
|
-
```python
|
|
216
|
-
import ssl
|
|
217
|
-
from python_socks.async_.anyio import Proxy
|
|
218
|
-
|
|
219
|
-
proxy = Proxy.from_url('socks5://user:password@127.0.0.1:1080')
|
|
220
|
-
|
|
221
|
-
# `connect` returns AnyioSocketStream
|
|
222
|
-
stream = await proxy.connect(
|
|
223
|
-
dest_host='check-host.net',
|
|
224
|
-
dest_port=443,
|
|
225
|
-
dest_ssl=ssl.create_default_context(),
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
request = (
|
|
229
|
-
b'GET /ip HTTP/1.1\r\n'
|
|
230
|
-
b'Host: check-host.net\r\n'
|
|
231
|
-
b'Connection: close\r\n\r\n'
|
|
232
|
-
)
|
|
233
|
-
|
|
234
|
-
await stream.write_all(request)
|
|
235
|
-
response = await stream.read()
|
|
236
|
-
print(response)
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
## More complex example
|
|
240
|
-
|
|
241
|
-
#### A urllib3 PoolManager that routes connections via the proxy
|
|
242
|
-
|
|
243
|
-
```python
|
|
244
|
-
from urllib3 import PoolManager, HTTPConnectionPool, HTTPSConnectionPool
|
|
245
|
-
from urllib3.connection import HTTPConnection, HTTPSConnection
|
|
246
|
-
from python_socks.sync import Proxy
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
class ProxyHTTPConnection(HTTPConnection):
|
|
250
|
-
def __init__(self, *args, **kwargs):
|
|
251
|
-
socks_options = kwargs.pop('_socks_options')
|
|
252
|
-
self._proxy_url = socks_options['proxy_url']
|
|
253
|
-
super().__init__(*args, **kwargs)
|
|
254
|
-
|
|
255
|
-
def _new_conn(self):
|
|
256
|
-
proxy = Proxy.from_url(self._proxy_url)
|
|
257
|
-
return proxy.connect(
|
|
258
|
-
dest_host=self.host,
|
|
259
|
-
dest_port=self.port,
|
|
260
|
-
timeout=self.timeout
|
|
261
|
-
)
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
class ProxyHTTPSConnection(ProxyHTTPConnection, HTTPSConnection):
|
|
265
|
-
pass
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
class ProxyHTTPConnectionPool(HTTPConnectionPool):
|
|
269
|
-
ConnectionCls = ProxyHTTPConnection
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
class ProxyHTTPSConnectionPool(HTTPSConnectionPool):
|
|
273
|
-
ConnectionCls = ProxyHTTPSConnection
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
class ProxyPoolManager(PoolManager):
|
|
277
|
-
def __init__(self, proxy_url, timeout=5, num_pools=10, headers=None,
|
|
278
|
-
**connection_pool_kw):
|
|
279
|
-
|
|
280
|
-
connection_pool_kw['_socks_options'] = {'proxy_url': proxy_url}
|
|
281
|
-
connection_pool_kw['timeout'] = timeout
|
|
282
|
-
|
|
283
|
-
super().__init__(num_pools, headers, **connection_pool_kw)
|
|
284
|
-
|
|
285
|
-
self.pool_classes_by_scheme = {
|
|
286
|
-
'http': ProxyHTTPConnectionPool,
|
|
287
|
-
'https': ProxyHTTPSConnectionPool,
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
### and how to use it
|
|
292
|
-
manager = ProxyPoolManager('socks5://user:password@127.0.0.1:1080')
|
|
293
|
-
response = manager.request('GET', 'https://check-host.net/ip')
|
|
294
|
-
print(response.data)
|
|
295
|
-
```
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
python_socks/__init__.py,sha256=gKywvwx_x4_0hWJEa2eif1dPzP9YeFXJdrNlHuvFmC8,367
|
|
2
|
-
python_socks/_abc.py,sha256=_juTZE0iqoTChE53IHjBKEYFO-fxYZfPhdUc6EgFlwE,909
|
|
3
|
-
python_socks/_errors.py,sha256=M2KkgCrFy_ebEqw7JoxCWMjIIQ5Zu_B7YlXYhsLo-gk,329
|
|
4
|
-
python_socks/_helpers.py,sha256=UacO07M9i8G8CfqzBYWnehgCTFbZTlwJWAsFoXR3mVk,2708
|
|
5
|
-
python_socks/_types.py,sha256=dgQifNf2mIwdKoX7YmI91H_lUsW9-Y0ZkZGlIV6_NNw,90
|
|
6
|
-
python_socks/_version.py,sha256=60qSCLD6nICI7tW_gU87eg-E18vmyw7k12UWh4OVy7g,49
|
|
7
|
-
python_socks/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
python_socks/_connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
python_socks/_connectors/abc.py,sha256=1fgjPiv64UAMiJDsJXYr-GofPGhuHTwTzaodQfrzf7Q,397
|
|
10
|
-
python_socks/_connectors/factory_async.py,sha256=X63hJuhpr8iDdAxwrUlsbyXfHewZJtgKQRdSZs41RS4,1055
|
|
11
|
-
python_socks/_connectors/factory_sync.py,sha256=QVaNbUXSEPZW9Cv43gRFF3kwVwU64moQR1BEtE4VOiE,1042
|
|
12
|
-
python_socks/_connectors/http_async.py,sha256=vo8QhluTYEqnIoxL2XPcj9vSl8yhu9Tvm4KI-gMyJGM,951
|
|
13
|
-
python_socks/_connectors/http_sync.py,sha256=Q6DRrUCljokQe2veoJJ6G8SZ7QEmq8x4_Q-faSADLEY,926
|
|
14
|
-
python_socks/_connectors/socks4_async.py,sha256=QGoB1are0qU-uoPCUvanFBUvSCyFxgKN_XVMKSrDoYY,1179
|
|
15
|
-
python_socks/_connectors/socks4_sync.py,sha256=yX4e3xMOHH1OzVPTYROeQDBf8gcZcXODFOxBHyRtVOc,1148
|
|
16
|
-
python_socks/_connectors/socks5_async.py,sha256=qniozb0P8gtXF_vK3b7kjRmoGNMHmYAb9eIZg-heI8k,2829
|
|
17
|
-
python_socks/_connectors/socks5_sync.py,sha256=G_FW1XsiaMDbzR7vcBMtRpD3R9LpO5V5zu9pltpo7xI,2602
|
|
18
|
-
python_socks/_protocols/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
-
python_socks/_protocols/errors.py,sha256=4XqU4AqgrWaedmUVGMjd6TvQKXv3mV0H76s5lf8aazY,150
|
|
20
|
-
python_socks/_protocols/http.py,sha256=T8hxXJnxApF2dxMC89jajeE66v7rtjmHcnrHICKTY0s,5175
|
|
21
|
-
python_socks/_protocols/socks4.py,sha256=j1Psqi3PDiKAF19g_Mh3sf_RwXu7o-8X7BqWOaoTbKE,3061
|
|
22
|
-
python_socks/_protocols/socks5.py,sha256=7AhzpKYM6ZBdGEoTD5ynKdApTKz4Q1l7LcHxhHfgRVw,9931
|
|
23
|
-
python_socks/async_/__init__.py,sha256=TeBn5oirLy6aPoWcTc3OW9OxXh5Uv5LADwF_Y7f7HjY,64
|
|
24
|
-
python_socks/async_/_proxy_chain.py,sha256=TiG1Uu45anONWi2ZFj11w4-LrNbja8SbG27bWCX9Et4,987
|
|
25
|
-
python_socks/async_/anyio/__init__.py,sha256=pZnrND4Qd-pIGg7KI1ML41kZNkWHmkd3vrvwZZIJyk4,106
|
|
26
|
-
python_socks/async_/anyio/_chain.py,sha256=-d4sR-JM8Agh73rB8nK7DBcB9oqDgtx2GOTAx-SMslU,1099
|
|
27
|
-
python_socks/async_/anyio/_connect.py,sha256=dYx-X2rDDTe-mtLm6DTpV-gFB7Vt_OYS1Xs_4Ea9JZ4,306
|
|
28
|
-
python_socks/async_/anyio/_proxy.py,sha256=nWHzIFPYPXatmuVITdDWN6uoQe_P2Xm6NomgfgYm5UA,4322
|
|
29
|
-
python_socks/async_/anyio/_resolver.py,sha256=LPRLmEzgKPGCqAbEMmLSMVtFkNVKha_2u08MhrZZ-CY,590
|
|
30
|
-
python_socks/async_/anyio/_stream.py,sha256=OcCl4YkccA0-5hZh90CP4YmsBDLPwHpS3B0wCLytnAY,1614
|
|
31
|
-
python_socks/async_/anyio/v2/__init__.py,sha256=4xgyAJHDGpRANYVNfpUdn3Zo8Ib_gREWH8bH4APycK4,117
|
|
32
|
-
python_socks/async_/anyio/v2/_chain.py,sha256=NZ_9dA1AQrG3pBOnYBszbtD-Kse85bQ_dT33VtmGx3o,797
|
|
33
|
-
python_socks/async_/anyio/v2/_connect.py,sha256=_LF1f_cYJbfdSqkq-xEK4nF4l-bP5I1VWRFFyX1RH3Y,368
|
|
34
|
-
python_socks/async_/anyio/v2/_proxy.py,sha256=7F-Y_xhVcqGnKjUDVnjYNkyz5VEFJjzZhkl0Xklyj9U,4085
|
|
35
|
-
python_socks/async_/anyio/v2/_stream.py,sha256=40D3Pmb0rryk9gaQlmjpAMdiJi5H5O0xbBseblGG1FY,1616
|
|
36
|
-
python_socks/async_/asyncio/__init__.py,sha256=0WAM07vy0YvI8IhKGmaUA0GaNLHaG3l-4mnJVbfoqHE,65
|
|
37
|
-
python_socks/async_/asyncio/_connect.py,sha256=K4qqOwXI-1uVleSwf-mQ2ZPO5LwKeSr50Wr3jWImEng,1110
|
|
38
|
-
python_socks/async_/asyncio/_proxy.py,sha256=HS1NfXZCYOZ2b4qUee01CwH4NF1OcXPzqYxEJXYJeT8,4120
|
|
39
|
-
python_socks/async_/asyncio/_resolver.py,sha256=ROqOncuIub87J9_nMdvRTG_5zYOh8uafk265z0s2ORQ,681
|
|
40
|
-
python_socks/async_/asyncio/_stream.py,sha256=RP7BIP9iFFy5nLRf9kHH7s1h_zPfo0yoEVKNpExqFcI,1021
|
|
41
|
-
python_socks/async_/asyncio/v2/__init__.py,sha256=v9eJQeZ2yGJHeBQ0FYqNmIMCRrB547QqoAANHVBitxY,108
|
|
42
|
-
python_socks/async_/asyncio/v2/_chain.py,sha256=KCtmKg0halaCIEqBY6JB-KGVNNiaa4APBb5l5z8kVPk,811
|
|
43
|
-
python_socks/async_/asyncio/v2/_connect.py,sha256=3yPmPCNmMKlCCZZCnNvydER3ilnfE5gTevzBN7IoGEE,603
|
|
44
|
-
python_socks/async_/asyncio/v2/_proxy.py,sha256=QPMx2nFeHCKObBkDqzONkgf2VLXdhuP-aMsBWAgdf-I,4714
|
|
45
|
-
python_socks/async_/asyncio/v2/_stream.py,sha256=YdpJap_Ax-7tJnA-AJ7nayZmD5lpem2UIPbUepnzqxM,2753
|
|
46
|
-
python_socks/async_/curio/__init__.py,sha256=1OyhLhvLJ23iDROgyxGqQACice66SrIYCMqmwjw_dqY,63
|
|
47
|
-
python_socks/async_/curio/_connect.py,sha256=u1HRJ8n3OZbux-wETO9HuqZv9By2LGhhSsM78gnxr_0,328
|
|
48
|
-
python_socks/async_/curio/_proxy.py,sha256=_Qgodw62VPvt-5j1T34l7P52R5Bk4Crq97QJ0f1Qf10,3644
|
|
49
|
-
python_socks/async_/curio/_resolver.py,sha256=_jDZq_lzTl_QihxH2HNEY_7_ELo-qmzG6IO5PNNEOek,722
|
|
50
|
-
python_socks/async_/curio/_stream.py,sha256=sIAbwkPuiFF4c8cEs7exVdGb7cfFgoggKTV4LYqDcm0,855
|
|
51
|
-
python_socks/async_/trio/__init__.py,sha256=Y68xwGqkXGKXHcwM6nvev6n2ChbFpBUFW0RzBrsIrug,61
|
|
52
|
-
python_socks/async_/trio/_connect.py,sha256=qVfK4jz3h1Tjwnr8sX0DNazASdg3DDXNHjMopaHGY0I,851
|
|
53
|
-
python_socks/async_/trio/_proxy.py,sha256=yp3NJOTAaw2ReXlPt4fBRY51Xqc1C3tf16H3v0XvlCg,3786
|
|
54
|
-
python_socks/async_/trio/_resolver.py,sha256=uqBoTkbYpwwESoph2SmXRUUHM_DsT7dALQDmKqp-sco,591
|
|
55
|
-
python_socks/async_/trio/_stream.py,sha256=xunx_XUiwH1pBLQjWbkqq3P92SeXaRypPMPRYwHOsPg,1003
|
|
56
|
-
python_socks/async_/trio/v2/__init__.py,sha256=cd8Sc6NLmrUZewkqeDvnxmQqGZBKNuwYEEb4NMW2qo0,116
|
|
57
|
-
python_socks/async_/trio/v2/_chain.py,sha256=g9atl9HcWYrCHLCI8GtLR9GZC67sKiXEjcvGwZVGhDw,795
|
|
58
|
-
python_socks/async_/trio/v2/_connect.py,sha256=Nk0ipvuFFnzH-NPfXkX57I74-sbT6ks--ZgbfN3r42o,360
|
|
59
|
-
python_socks/async_/trio/v2/_proxy.py,sha256=9118wyv9SthZNVlvECfb3OfhrPMOFyyJSHhl7lG0TbI,4094
|
|
60
|
-
python_socks/async_/trio/v2/_stream.py,sha256=wGB7sDjRO1ywVNjF_DFgdF2orjD3zrh8dPSmW9aBEV0,1475
|
|
61
|
-
python_socks/sync/__init__.py,sha256=Dslh61MLGktjBK50UVGYjAQ-iGl8tjoLR93_-cvddWM,106
|
|
62
|
-
python_socks/sync/_chain.py,sha256=do_WtGenqKAG7B50nNZdltFqEQV8t-mSlGnMACNIwgE,973
|
|
63
|
-
python_socks/sync/_connect.py,sha256=N1Y-uQXkOiJ_dxkwWHw1fBliIQlTL47ydql7IvaSqm8,344
|
|
64
|
-
python_socks/sync/_proxy.py,sha256=Ny2QA8GI2aCUm0JL8IfY2j2IaXKzAZNp6bZeF7OmwYA,3287
|
|
65
|
-
python_socks/sync/_resolver.py,sha256=2rf9-NdjRktYrab1Oyv9ZJLKByP95ysFmRE3TgjRCSA,547
|
|
66
|
-
python_socks/sync/_stream.py,sha256=VeR-_ERvn5x_PjxFsPy88llEiNfTuejvXoZkAxlqOuY,811
|
|
67
|
-
python_socks/sync/v2/__init__.py,sha256=eVZc6zh0pLhNMf_uSPZiH_1vNGEvedwzX5gObUSkRT8,116
|
|
68
|
-
python_socks/sync/v2/_chain.py,sha256=IRVMioTVWwxylZ8maD5Gqxhhgw4VyrG5vo_hAOuEn8Q,579
|
|
69
|
-
python_socks/sync/v2/_connect.py,sha256=QrZ1CZimYCUMUuaD8JdUblwlqlzIbqFrbsPwMzoxGkM,420
|
|
70
|
-
python_socks/sync/v2/_proxy.py,sha256=7FuO6wML0DkEonoGAprhTlVd8fazOgNeNrJyxABmP1Q,3621
|
|
71
|
-
python_socks/sync/v2/_ssl_transport.py,sha256=MURwzvKu-S2-MI7o8KaZTvvBFOiiKIu5R0ERVIMvERE,6088
|
|
72
|
-
python_socks/sync/v2/_stream.py,sha256=Jq89x1xmIX3L_v-WyS1nRTItjTnYTcDcfDblsANxfJI,1544
|
|
73
|
-
python_socks-2.8.2.dist-info/licenses/LICENSE.txt,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
|
|
74
|
-
python_socks-2.8.2.dist-info/METADATA,sha256=QZw-g2v-tBl8fXCKS9nO_wsICjCR5TJG53-hzdFODpU,8151
|
|
75
|
-
python_socks-2.8.2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
76
|
-
python_socks-2.8.2.dist-info/top_level.txt,sha256=7qyDAVwjTZ0sIYG1iatFbE-SLpWhONjaoMQ0Ib2DX0Q,13
|
|
77
|
-
python_socks-2.8.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|