python-socks 2.5.2__py3-none-any.whl → 2.6.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/_abc.py +3 -26
- python_socks/_connectors/factory_async.py +4 -3
- python_socks/_connectors/factory_sync.py +4 -3
- python_socks/_connectors/http_async.py +3 -2
- python_socks/_connectors/http_sync.py +3 -2
- python_socks/_connectors/socks4_async.py +3 -2
- python_socks/_connectors/socks4_sync.py +3 -2
- python_socks/_connectors/socks5_async.py +6 -4
- python_socks/_connectors/socks5_sync.py +6 -4
- python_socks/_helpers.py +17 -10
- python_socks/_protocols/http.py +3 -2
- python_socks/_protocols/socks4.py +2 -1
- python_socks/_protocols/socks5.py +7 -7
- python_socks/_version.py +1 -1
- python_socks/async_/_proxy_chain.py +1 -2
- python_socks/async_/anyio/_proxy.py +11 -9
- python_socks/async_/anyio/v2/_proxy.py +13 -10
- python_socks/async_/asyncio/_proxy.py +24 -17
- python_socks/async_/asyncio/v2/_proxy.py +20 -16
- python_socks/async_/curio/_proxy.py +10 -8
- python_socks/async_/trio/_proxy.py +13 -9
- python_socks/async_/trio/v2/_proxy.py +10 -9
- python_socks/py.typed +0 -0
- python_socks/sync/_proxy.py +13 -9
- python_socks/sync/v2/_proxy.py +10 -10
- {python_socks-2.5.2.dist-info → python_socks-2.6.0.dist-info}/METADATA +35 -16
- {python_socks-2.5.2.dist-info → python_socks-2.6.0.dist-info}/RECORD +30 -29
- {python_socks-2.5.2.dist-info → python_socks-2.6.0.dist-info}/WHEEL +1 -1
- {python_socks-2.5.2.dist-info → python_socks-2.6.0.dist-info}/LICENSE.txt +0 -0
- {python_socks-2.5.2.dist-info → python_socks-2.6.0.dist-info}/top_level.txt +0 -0
python_socks/_abc.py
CHANGED
|
@@ -1,27 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
def connect(self, dest_host, dest_port, timeout=None, **kwargs):
|
|
3
|
-
raise NotImplementedError()
|
|
4
|
-
|
|
5
|
-
@property
|
|
6
|
-
def proxy_host(self):
|
|
7
|
-
raise NotImplementedError()
|
|
8
|
-
|
|
9
|
-
@property
|
|
10
|
-
def proxy_port(self):
|
|
11
|
-
raise NotImplementedError()
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class AsyncProxy:
|
|
15
|
-
async def connect(self, dest_host, dest_port, timeout=None, **kwargs):
|
|
16
|
-
raise NotImplementedError()
|
|
17
|
-
|
|
18
|
-
@property
|
|
19
|
-
def proxy_host(self):
|
|
20
|
-
raise NotImplementedError()
|
|
21
|
-
|
|
22
|
-
@property
|
|
23
|
-
def proxy_port(self):
|
|
24
|
-
raise NotImplementedError()
|
|
1
|
+
from typing import Optional
|
|
25
2
|
|
|
26
3
|
|
|
27
4
|
class SyncResolver:
|
|
@@ -39,7 +16,7 @@ class SyncSocketStream:
|
|
|
39
16
|
def write_all(self, data: bytes):
|
|
40
17
|
raise NotImplementedError()
|
|
41
18
|
|
|
42
|
-
def read(self, max_bytes: int = None):
|
|
19
|
+
def read(self, max_bytes: Optional[int] = None):
|
|
43
20
|
raise NotImplementedError()
|
|
44
21
|
|
|
45
22
|
def read_exact(self, n: int):
|
|
@@ -53,7 +30,7 @@ class AsyncSocketStream:
|
|
|
53
30
|
async def write_all(self, data: bytes):
|
|
54
31
|
raise NotImplementedError()
|
|
55
32
|
|
|
56
|
-
async def read(self, max_bytes: int = None):
|
|
33
|
+
async def read(self, max_bytes: Optional[int] = None):
|
|
57
34
|
raise NotImplementedError()
|
|
58
35
|
|
|
59
36
|
async def read_exact(self, n: int):
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from typing import Optional
|
|
1
2
|
from .._abc import AsyncResolver
|
|
2
3
|
from .._types import ProxyType
|
|
3
4
|
|
|
@@ -9,9 +10,9 @@ from .http_async import HttpAsyncConnector
|
|
|
9
10
|
|
|
10
11
|
def create_connector(
|
|
11
12
|
proxy_type: ProxyType,
|
|
12
|
-
username: str,
|
|
13
|
-
password: str,
|
|
14
|
-
rdns: bool,
|
|
13
|
+
username: Optional[str],
|
|
14
|
+
password: Optional[str],
|
|
15
|
+
rdns: Optional[bool],
|
|
15
16
|
resolver: AsyncResolver,
|
|
16
17
|
) -> AsyncConnector:
|
|
17
18
|
if proxy_type == ProxyType.SOCKS4:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from typing import Optional
|
|
1
2
|
from .._abc import SyncResolver
|
|
2
3
|
from .._types import ProxyType
|
|
3
4
|
|
|
@@ -9,9 +10,9 @@ from .http_sync import HttpSyncConnector
|
|
|
9
10
|
|
|
10
11
|
def create_connector(
|
|
11
12
|
proxy_type: ProxyType,
|
|
12
|
-
username: str,
|
|
13
|
-
password: str,
|
|
14
|
-
rdns: bool,
|
|
13
|
+
username: Optional[str],
|
|
14
|
+
password: Optional[str],
|
|
15
|
+
rdns: Optional[bool],
|
|
15
16
|
resolver: SyncResolver,
|
|
16
17
|
) -> SyncConnector:
|
|
17
18
|
if proxy_type == ProxyType.SOCKS4:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from typing import Optional
|
|
1
2
|
from .._abc import AsyncSocketStream, AsyncResolver
|
|
2
3
|
from .abc import AsyncConnector
|
|
3
4
|
|
|
@@ -7,8 +8,8 @@ from .._protocols import http
|
|
|
7
8
|
class HttpAsyncConnector(AsyncConnector):
|
|
8
9
|
def __init__(
|
|
9
10
|
self,
|
|
10
|
-
username: str,
|
|
11
|
-
password: str,
|
|
11
|
+
username: Optional[str],
|
|
12
|
+
password: Optional[str],
|
|
12
13
|
resolver: AsyncResolver,
|
|
13
14
|
):
|
|
14
15
|
self._username = username
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from typing import Optional
|
|
1
2
|
from .._abc import SyncSocketStream, SyncResolver
|
|
2
3
|
from .abc import SyncConnector
|
|
3
4
|
|
|
@@ -7,8 +8,8 @@ from .._protocols import http
|
|
|
7
8
|
class HttpSyncConnector(SyncConnector):
|
|
8
9
|
def __init__(
|
|
9
10
|
self,
|
|
10
|
-
username: str,
|
|
11
|
-
password: str,
|
|
11
|
+
username: Optional[str],
|
|
12
|
+
password: Optional[str],
|
|
12
13
|
resolver: SyncResolver,
|
|
13
14
|
):
|
|
14
15
|
self._username = username
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import socket
|
|
2
|
+
from typing import Optional
|
|
2
3
|
|
|
3
4
|
from .._abc import AsyncSocketStream, AsyncResolver
|
|
4
5
|
from .abc import AsyncConnector
|
|
@@ -10,8 +11,8 @@ from .._helpers import is_ip_address
|
|
|
10
11
|
class Socks4AsyncConnector(AsyncConnector):
|
|
11
12
|
def __init__(
|
|
12
13
|
self,
|
|
13
|
-
user_id: str,
|
|
14
|
-
rdns: bool,
|
|
14
|
+
user_id: Optional[str],
|
|
15
|
+
rdns: Optional[bool],
|
|
15
16
|
resolver: AsyncResolver,
|
|
16
17
|
):
|
|
17
18
|
if rdns is None:
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import socket
|
|
2
|
+
from typing import Optional
|
|
2
3
|
|
|
3
4
|
from .._abc import SyncSocketStream, SyncResolver
|
|
4
5
|
from .abc import SyncConnector
|
|
@@ -10,8 +11,8 @@ from .._helpers import is_ip_address
|
|
|
10
11
|
class Socks4SyncConnector(SyncConnector):
|
|
11
12
|
def __init__(
|
|
12
13
|
self,
|
|
13
|
-
user_id: str,
|
|
14
|
-
rdns: bool,
|
|
14
|
+
user_id: Optional[str],
|
|
15
|
+
rdns: Optional[bool],
|
|
15
16
|
resolver: SyncResolver,
|
|
16
17
|
):
|
|
17
18
|
if rdns is None:
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import socket
|
|
2
|
+
from typing import Optional
|
|
2
3
|
|
|
3
4
|
from .._abc import AsyncSocketStream, AsyncResolver
|
|
4
5
|
from .abc import AsyncConnector
|
|
@@ -10,9 +11,9 @@ from .._helpers import is_ip_address
|
|
|
10
11
|
class Socks5AsyncConnector(AsyncConnector):
|
|
11
12
|
def __init__(
|
|
12
13
|
self,
|
|
13
|
-
username: str,
|
|
14
|
-
password: str,
|
|
15
|
-
rdns: bool,
|
|
14
|
+
username: Optional[str],
|
|
15
|
+
password: Optional[str],
|
|
16
|
+
rdns: Optional[bool],
|
|
16
17
|
resolver: AsyncResolver,
|
|
17
18
|
):
|
|
18
19
|
if rdns is None:
|
|
@@ -86,7 +87,8 @@ class Socks5AsyncConnector(AsyncConnector):
|
|
|
86
87
|
elif addr_type == socks5.AddressType.IPV6:
|
|
87
88
|
data += await stream.read_exact(18)
|
|
88
89
|
elif addr_type == socks5.AddressType.DOMAIN:
|
|
89
|
-
|
|
90
|
+
data += await stream.read_exact(1)
|
|
91
|
+
host_len = data[-1]
|
|
90
92
|
data += await stream.read_exact(host_len + 2)
|
|
91
93
|
|
|
92
94
|
return data
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import socket
|
|
2
|
+
from typing import Optional
|
|
2
3
|
|
|
3
4
|
from .._abc import SyncSocketStream, SyncResolver
|
|
4
5
|
from .abc import SyncConnector
|
|
@@ -10,9 +11,9 @@ from .._helpers import is_ip_address
|
|
|
10
11
|
class Socks5SyncConnector(SyncConnector):
|
|
11
12
|
def __init__(
|
|
12
13
|
self,
|
|
13
|
-
username: str,
|
|
14
|
-
password: str,
|
|
15
|
-
rdns: bool,
|
|
14
|
+
username: Optional[str],
|
|
15
|
+
password: Optional[str],
|
|
16
|
+
rdns: Optional[bool],
|
|
16
17
|
resolver: SyncResolver,
|
|
17
18
|
):
|
|
18
19
|
if rdns is None:
|
|
@@ -77,7 +78,8 @@ class Socks5SyncConnector(SyncConnector):
|
|
|
77
78
|
elif addr_type == socks5.AddressType.IPV6:
|
|
78
79
|
data += stream.read_exact(18)
|
|
79
80
|
elif addr_type == socks5.AddressType.DOMAIN:
|
|
80
|
-
|
|
81
|
+
data += stream.read_exact(1)
|
|
82
|
+
host_len = data[-1]
|
|
81
83
|
data += stream.read_exact(host_len + 2)
|
|
82
84
|
|
|
83
85
|
return data
|
python_socks/_helpers.py
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
import re
|
|
3
|
+
from typing import Optional, Tuple
|
|
3
4
|
from urllib.parse import urlparse, unquote
|
|
4
5
|
|
|
5
6
|
from ._types import ProxyType
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
# pylint:disable-next=invalid-name
|
|
9
|
+
_ipv4_pattern = (
|
|
10
|
+
r'^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}'
|
|
11
|
+
r'(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
|
|
12
|
+
)
|
|
9
13
|
|
|
14
|
+
# pylint:disable-next=invalid-name
|
|
10
15
|
_ipv6_pattern = (
|
|
11
16
|
r'^(?:(?:(?:[A-F0-9]{1,4}:){6}|(?=(?:[A-F0-9]{0,4}:){0,6}'
|
|
12
17
|
r'(?:[0-9]{1,3}\.){3}[0-9]{1,3}$)(([0-9A-F]{1,4}:){0,5}|:)'
|
|
@@ -15,7 +20,8 @@ _ipv6_pattern = (
|
|
|
15
20
|
r'(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])|(?:[A-F0-9]{1,4}:){7}'
|
|
16
21
|
r'[A-F0-9]{1,4}|(?=(?:[A-F0-9]{0,4}:){0,7}[A-F0-9]{0,4}$)'
|
|
17
22
|
r'(([0-9A-F]{1,4}:){1,7}|:)((:[0-9A-F]{1,4}){1,7}|:)|(?:[A-F0-9]{1,4}:){7}'
|
|
18
|
-
r':|:(:[A-F0-9]{1,4}){7})$'
|
|
23
|
+
r':|:(:[A-F0-9]{1,4}){7})$'
|
|
24
|
+
)
|
|
19
25
|
|
|
20
26
|
_ipv4_regex = re.compile(_ipv4_pattern)
|
|
21
27
|
_ipv6_regex = re.compile(_ipv6_pattern, flags=re.IGNORECASE)
|
|
@@ -31,8 +37,9 @@ def _is_ip_address(regex, regexb, host):
|
|
|
31
37
|
elif isinstance(host, (bytes, bytearray, memoryview)):
|
|
32
38
|
return bool(regexb.match(host))
|
|
33
39
|
else:
|
|
34
|
-
raise TypeError(
|
|
35
|
-
|
|
40
|
+
raise TypeError(
|
|
41
|
+
'{} [{}] is not a str or bytes'.format(host, type(host)) # pragma: no cover
|
|
42
|
+
)
|
|
36
43
|
|
|
37
44
|
|
|
38
45
|
is_ipv4_address = functools.partial(_is_ip_address, _ipv4_regex, _ipv4_regexb)
|
|
@@ -43,7 +50,7 @@ def is_ip_address(host):
|
|
|
43
50
|
return is_ipv4_address(host) or is_ipv6_address(host)
|
|
44
51
|
|
|
45
52
|
|
|
46
|
-
def parse_proxy_url(url):
|
|
53
|
+
def parse_proxy_url(url: str) -> Tuple[ProxyType, str, int, Optional[str], Optional[str]]:
|
|
47
54
|
parsed = urlparse(url)
|
|
48
55
|
|
|
49
56
|
scheme = parsed.scheme
|
|
@@ -62,12 +69,12 @@ def parse_proxy_url(url):
|
|
|
62
69
|
|
|
63
70
|
try:
|
|
64
71
|
port = parsed.port
|
|
65
|
-
|
|
66
|
-
|
|
72
|
+
assert port is not None
|
|
73
|
+
except (ValueError, TypeError, AssertionError) as e: # pragma: no cover
|
|
74
|
+
raise ValueError('Invalid port component') from e
|
|
67
75
|
|
|
68
76
|
try:
|
|
69
|
-
username, password = (unquote(parsed.username),
|
|
70
|
-
unquote(parsed.password))
|
|
77
|
+
username, password = (unquote(parsed.username), unquote(parsed.password))
|
|
71
78
|
except (AttributeError, TypeError):
|
|
72
79
|
username, password = '', ''
|
|
73
80
|
|
python_socks/_protocols/http.py
CHANGED
|
@@ -3,6 +3,7 @@ from dataclasses import dataclass
|
|
|
3
3
|
import base64
|
|
4
4
|
import binascii
|
|
5
5
|
from collections import namedtuple
|
|
6
|
+
from typing import Optional
|
|
6
7
|
|
|
7
8
|
from .._version import __title__, __version__
|
|
8
9
|
|
|
@@ -88,8 +89,8 @@ class _Buffer:
|
|
|
88
89
|
class ConnectRequest:
|
|
89
90
|
host: str
|
|
90
91
|
port: int
|
|
91
|
-
username: str
|
|
92
|
-
password: str
|
|
92
|
+
username: Optional[str]
|
|
93
|
+
password: Optional[str]
|
|
93
94
|
|
|
94
95
|
def dumps(self) -> bytes:
|
|
95
96
|
buff = _Buffer()
|
|
@@ -2,6 +2,7 @@ import enum
|
|
|
2
2
|
import ipaddress
|
|
3
3
|
import socket
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
+
from typing import Optional
|
|
5
6
|
|
|
6
7
|
from .errors import ReplyError
|
|
7
8
|
from .._helpers import is_ipv4_address
|
|
@@ -38,7 +39,7 @@ ReplyMessages = {
|
|
|
38
39
|
class ConnectRequest:
|
|
39
40
|
host: str # hostname or IPv4 address
|
|
40
41
|
port: int
|
|
41
|
-
user_id: str
|
|
42
|
+
user_id: Optional[str]
|
|
42
43
|
|
|
43
44
|
def dumps(self):
|
|
44
45
|
port_bytes = self.port.to_bytes(2, 'big')
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import enum
|
|
2
2
|
import ipaddress
|
|
3
3
|
import socket
|
|
4
|
-
import
|
|
4
|
+
from typing import Optional, Union
|
|
5
5
|
from dataclasses import dataclass, field
|
|
6
6
|
|
|
7
7
|
from .errors import ReplyError
|
|
@@ -67,8 +67,8 @@ ReplyMessages = {
|
|
|
67
67
|
|
|
68
68
|
@dataclass
|
|
69
69
|
class AuthMethodsRequest:
|
|
70
|
-
username: str
|
|
71
|
-
password: str
|
|
70
|
+
username: Optional[str]
|
|
71
|
+
password: Optional[str]
|
|
72
72
|
methods: bytearray = field(init=False)
|
|
73
73
|
|
|
74
74
|
def __post_init__(self):
|
|
@@ -260,7 +260,7 @@ class StateServerWaitingForAuth:
|
|
|
260
260
|
|
|
261
261
|
@dataclass
|
|
262
262
|
class StateClientAuthenticated:
|
|
263
|
-
data:
|
|
263
|
+
data: Optional[AuthReply] = None
|
|
264
264
|
|
|
265
265
|
|
|
266
266
|
@dataclass
|
|
@@ -278,19 +278,19 @@ class StateServerConnected:
|
|
|
278
278
|
data: ConnectReply
|
|
279
279
|
|
|
280
280
|
|
|
281
|
-
Request =
|
|
281
|
+
Request = Union[
|
|
282
282
|
AuthMethodsRequest,
|
|
283
283
|
AuthRequest,
|
|
284
284
|
ConnectRequest,
|
|
285
285
|
]
|
|
286
286
|
|
|
287
|
-
Reply =
|
|
287
|
+
Reply = Union[
|
|
288
288
|
AuthMethodReply,
|
|
289
289
|
AuthReply,
|
|
290
290
|
ConnectReply,
|
|
291
291
|
]
|
|
292
292
|
|
|
293
|
-
ConnectionState =
|
|
293
|
+
ConnectionState = Union[
|
|
294
294
|
StateServerWaitingForAuthMethods,
|
|
295
295
|
StateClientSentAuthMethods,
|
|
296
296
|
StateServerWaitingForAuth,
|
python_socks/_version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
__title__ = 'python-socks'
|
|
2
|
-
__version__ = '2.
|
|
2
|
+
__version__ = '2.6.0'
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
from typing import Iterable
|
|
2
|
-
from .. import _abc as abc
|
|
3
2
|
|
|
4
3
|
|
|
5
4
|
class ProxyChain:
|
|
6
|
-
def __init__(self, proxies: Iterable
|
|
5
|
+
def __init__(self, proxies: Iterable):
|
|
7
6
|
self._proxies = proxies
|
|
8
7
|
|
|
9
8
|
async def connect(self, dest_host, dest_port, timeout=None):
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ssl
|
|
2
|
-
from typing import Optional
|
|
2
|
+
from typing import Any, Optional
|
|
3
3
|
|
|
4
4
|
import anyio
|
|
5
5
|
|
|
@@ -25,10 +25,10 @@ class AnyioProxy:
|
|
|
25
25
|
proxy_type: ProxyType,
|
|
26
26
|
host: str,
|
|
27
27
|
port: int,
|
|
28
|
-
username: str = None,
|
|
29
|
-
password: str = None,
|
|
30
|
-
rdns: bool = None,
|
|
31
|
-
proxy_ssl: ssl.SSLContext = None,
|
|
28
|
+
username: Optional[str] = None,
|
|
29
|
+
password: Optional[str] = None,
|
|
30
|
+
rdns: Optional[bool] = None,
|
|
31
|
+
proxy_ssl: Optional[ssl.SSLContext] = None,
|
|
32
32
|
):
|
|
33
33
|
self._proxy_type = proxy_type
|
|
34
34
|
self._proxy_host = host
|
|
@@ -44,13 +44,15 @@ class AnyioProxy:
|
|
|
44
44
|
self,
|
|
45
45
|
dest_host: str,
|
|
46
46
|
dest_port: int,
|
|
47
|
-
dest_ssl: ssl.SSLContext = None,
|
|
48
|
-
timeout: float = None,
|
|
49
|
-
|
|
47
|
+
dest_ssl: Optional[ssl.SSLContext] = None,
|
|
48
|
+
timeout: Optional[float] = None,
|
|
49
|
+
**kwargs: Any,
|
|
50
50
|
) -> AnyioSocketStream:
|
|
51
51
|
if timeout is None:
|
|
52
52
|
timeout = DEFAULT_TIMEOUT
|
|
53
53
|
|
|
54
|
+
_stream = kwargs.get('_stream')
|
|
55
|
+
|
|
54
56
|
try:
|
|
55
57
|
with anyio.fail_after(timeout):
|
|
56
58
|
if _stream is None:
|
|
@@ -117,7 +119,7 @@ class AnyioProxy:
|
|
|
117
119
|
return self._proxy_port
|
|
118
120
|
|
|
119
121
|
@classmethod
|
|
120
|
-
def create(cls, *args, **kwargs):
|
|
122
|
+
def create(cls, *args, **kwargs): # for backward compatibility
|
|
121
123
|
return cls(*args, **kwargs)
|
|
122
124
|
|
|
123
125
|
@classmethod
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import ssl
|
|
2
|
+
from typing import Optional
|
|
2
3
|
|
|
3
4
|
import anyio
|
|
4
5
|
|
|
@@ -22,11 +23,11 @@ class AnyioProxy:
|
|
|
22
23
|
proxy_type: ProxyType,
|
|
23
24
|
host: str,
|
|
24
25
|
port: int,
|
|
25
|
-
username: str = None,
|
|
26
|
-
password: str = None,
|
|
27
|
-
rdns: bool = None,
|
|
28
|
-
proxy_ssl: ssl.SSLContext = None,
|
|
29
|
-
forward: 'AnyioProxy' = None,
|
|
26
|
+
username: Optional[str] = None,
|
|
27
|
+
password: Optional[str] = None,
|
|
28
|
+
rdns: Optional[bool] = None,
|
|
29
|
+
proxy_ssl: Optional[ssl.SSLContext] = None,
|
|
30
|
+
forward: Optional['AnyioProxy'] = None,
|
|
30
31
|
):
|
|
31
32
|
self._proxy_type = proxy_type
|
|
32
33
|
self._proxy_host = host
|
|
@@ -44,8 +45,8 @@ class AnyioProxy:
|
|
|
44
45
|
self,
|
|
45
46
|
dest_host: str,
|
|
46
47
|
dest_port: int,
|
|
47
|
-
dest_ssl: ssl.SSLContext = None,
|
|
48
|
-
timeout: float = None,
|
|
48
|
+
dest_ssl: Optional[ssl.SSLContext] = None,
|
|
49
|
+
timeout: Optional[float] = None,
|
|
49
50
|
) -> AnyioSocketStream:
|
|
50
51
|
if timeout is None:
|
|
51
52
|
timeout = DEFAULT_TIMEOUT
|
|
@@ -58,13 +59,15 @@ class AnyioProxy:
|
|
|
58
59
|
dest_ssl=dest_ssl,
|
|
59
60
|
)
|
|
60
61
|
except TimeoutError as e:
|
|
61
|
-
raise ProxyTimeoutError(
|
|
62
|
+
raise ProxyTimeoutError(
|
|
63
|
+
'Proxy connection timed out: {}'.format(timeout)
|
|
64
|
+
) from e
|
|
62
65
|
|
|
63
66
|
async def _connect(
|
|
64
67
|
self,
|
|
65
68
|
dest_host: str,
|
|
66
69
|
dest_port: int,
|
|
67
|
-
dest_ssl: ssl.SSLContext = None,
|
|
70
|
+
dest_ssl: Optional[ssl.SSLContext] = None,
|
|
68
71
|
) -> AnyioSocketStream:
|
|
69
72
|
if self._forward is None:
|
|
70
73
|
try:
|
|
@@ -120,7 +123,7 @@ class AnyioProxy:
|
|
|
120
123
|
return stream
|
|
121
124
|
|
|
122
125
|
@classmethod
|
|
123
|
-
def create(cls, *args, **kwargs):
|
|
126
|
+
def create(cls, *args, **kwargs): # for backward compatibility
|
|
124
127
|
return cls(*args, **kwargs)
|
|
125
128
|
|
|
126
129
|
@classmethod
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import socket
|
|
3
3
|
import sys
|
|
4
|
-
|
|
5
|
-
if sys.version_info >= (3, 11):
|
|
6
|
-
import asyncio as async_timeout
|
|
7
|
-
else:
|
|
8
|
-
import async_timeout
|
|
4
|
+
from typing import Any, Optional
|
|
9
5
|
|
|
10
6
|
from ..._types import ProxyType
|
|
11
7
|
from ..._helpers import parse_proxy_url
|
|
@@ -17,21 +13,25 @@ from ..._protocols.errors import ReplyError
|
|
|
17
13
|
from ..._connectors.factory_async import create_connector
|
|
18
14
|
|
|
19
15
|
from ._connect import connect_tcp
|
|
20
|
-
|
|
16
|
+
|
|
17
|
+
if sys.version_info >= (3, 11):
|
|
18
|
+
import asyncio as async_timeout # pylint:disable=reimported
|
|
19
|
+
else:
|
|
20
|
+
import async_timeout
|
|
21
21
|
|
|
22
22
|
DEFAULT_TIMEOUT = 60
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
class AsyncioProxy
|
|
25
|
+
class AsyncioProxy:
|
|
26
26
|
def __init__(
|
|
27
27
|
self,
|
|
28
28
|
proxy_type: ProxyType,
|
|
29
29
|
host: str,
|
|
30
30
|
port: int,
|
|
31
|
-
username: str = None,
|
|
32
|
-
password: str = None,
|
|
33
|
-
rdns: bool = None,
|
|
34
|
-
loop: asyncio.AbstractEventLoop = None,
|
|
31
|
+
username: Optional[str] = None,
|
|
32
|
+
password: Optional[str] = None,
|
|
33
|
+
rdns: Optional[bool] = None,
|
|
34
|
+
loop: Optional[asyncio.AbstractEventLoop] = None,
|
|
35
35
|
):
|
|
36
36
|
if loop is None:
|
|
37
37
|
loop = asyncio.get_event_loop()
|
|
@@ -51,12 +51,13 @@ class AsyncioProxy(abc.AsyncProxy):
|
|
|
51
51
|
self,
|
|
52
52
|
dest_host: str,
|
|
53
53
|
dest_port: int,
|
|
54
|
-
timeout: float = None,
|
|
55
|
-
|
|
54
|
+
timeout: Optional[float] = None,
|
|
55
|
+
**kwargs: Any,
|
|
56
56
|
) -> socket.socket:
|
|
57
57
|
if timeout is None:
|
|
58
58
|
timeout = DEFAULT_TIMEOUT
|
|
59
59
|
|
|
60
|
+
_socket = kwargs.get('_socket')
|
|
60
61
|
try:
|
|
61
62
|
async with async_timeout.timeout(timeout):
|
|
62
63
|
return await self._connect(
|
|
@@ -116,19 +117,25 @@ class AsyncioProxy(abc.AsyncProxy):
|
|
|
116
117
|
def _can_be_closed_safely(self): # pragma: no cover
|
|
117
118
|
def is_proactor_event_loop():
|
|
118
119
|
try:
|
|
119
|
-
|
|
120
|
+
# pylint:disable-next=import-outside-toplevel
|
|
121
|
+
from asyncio import ProactorEventLoop
|
|
120
122
|
except ImportError:
|
|
121
123
|
return False
|
|
122
124
|
return isinstance(self._loop, ProactorEventLoop)
|
|
123
125
|
|
|
124
126
|
def is_uvloop_event_loop():
|
|
125
127
|
try:
|
|
126
|
-
|
|
128
|
+
# pylint:disable-next=import-outside-toplevel
|
|
129
|
+
from uvloop import Loop # type:ignore[import-not-found]
|
|
127
130
|
except ImportError:
|
|
128
131
|
return False
|
|
129
132
|
return isinstance(self._loop, Loop)
|
|
130
133
|
|
|
131
|
-
return
|
|
134
|
+
return (
|
|
135
|
+
sys.version_info[:2] >= (3, 8)
|
|
136
|
+
or is_proactor_event_loop()
|
|
137
|
+
or is_uvloop_event_loop()
|
|
138
|
+
)
|
|
132
139
|
|
|
133
140
|
@property
|
|
134
141
|
def proxy_host(self):
|
|
@@ -139,7 +146,7 @@ class AsyncioProxy(abc.AsyncProxy):
|
|
|
139
146
|
return self._proxy_port
|
|
140
147
|
|
|
141
148
|
@classmethod
|
|
142
|
-
def create(cls, *args, **kwargs):
|
|
149
|
+
def create(cls, *args, **kwargs): # for backward compatibility
|
|
143
150
|
return cls(*args, **kwargs)
|
|
144
151
|
|
|
145
152
|
@classmethod
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import ssl
|
|
3
|
+
from typing import Optional
|
|
3
4
|
import warnings
|
|
4
5
|
import sys
|
|
5
6
|
|
|
6
7
|
|
|
7
|
-
if sys.version_info >= (3, 11):
|
|
8
|
-
import asyncio as async_timeout
|
|
9
|
-
else:
|
|
10
|
-
import async_timeout
|
|
11
|
-
|
|
12
8
|
from ...._types import ProxyType
|
|
13
9
|
from ...._helpers import parse_proxy_url
|
|
14
10
|
from ...._errors import ProxyConnectionError, ProxyTimeoutError, ProxyError
|
|
@@ -20,6 +16,12 @@ from .._resolver import Resolver
|
|
|
20
16
|
from ._stream import AsyncioSocketStream
|
|
21
17
|
from ._connect import connect_tcp
|
|
22
18
|
|
|
19
|
+
if sys.version_info >= (3, 11):
|
|
20
|
+
import asyncio as async_timeout # pylint:disable=reimported
|
|
21
|
+
else:
|
|
22
|
+
import async_timeout
|
|
23
|
+
|
|
24
|
+
|
|
23
25
|
DEFAULT_TIMEOUT = 60
|
|
24
26
|
|
|
25
27
|
|
|
@@ -29,12 +31,12 @@ class AsyncioProxy:
|
|
|
29
31
|
proxy_type: ProxyType,
|
|
30
32
|
host: str,
|
|
31
33
|
port: int,
|
|
32
|
-
username: str = None,
|
|
33
|
-
password: str = None,
|
|
34
|
-
rdns: bool = None,
|
|
35
|
-
proxy_ssl: ssl.SSLContext = None,
|
|
36
|
-
forward: 'AsyncioProxy' = None,
|
|
37
|
-
loop: asyncio.AbstractEventLoop = None,
|
|
34
|
+
username: Optional[str] = None,
|
|
35
|
+
password: Optional[str] = None,
|
|
36
|
+
rdns: Optional[bool] = None,
|
|
37
|
+
proxy_ssl: Optional[ssl.SSLContext] = None,
|
|
38
|
+
forward: Optional['AsyncioProxy'] = None,
|
|
39
|
+
loop: Optional[asyncio.AbstractEventLoop] = None,
|
|
38
40
|
):
|
|
39
41
|
if loop is not None: # pragma: no cover
|
|
40
42
|
warnings.warn(
|
|
@@ -64,8 +66,8 @@ class AsyncioProxy:
|
|
|
64
66
|
self,
|
|
65
67
|
dest_host: str,
|
|
66
68
|
dest_port: int,
|
|
67
|
-
dest_ssl: ssl.SSLContext = None,
|
|
68
|
-
timeout: float = None,
|
|
69
|
+
dest_ssl: Optional[ssl.SSLContext] = None,
|
|
70
|
+
timeout: Optional[float] = None,
|
|
69
71
|
) -> AsyncioSocketStream:
|
|
70
72
|
if timeout is None:
|
|
71
73
|
timeout = DEFAULT_TIMEOUT
|
|
@@ -78,13 +80,15 @@ class AsyncioProxy:
|
|
|
78
80
|
dest_ssl=dest_ssl,
|
|
79
81
|
)
|
|
80
82
|
except asyncio.TimeoutError as e:
|
|
81
|
-
raise ProxyTimeoutError(
|
|
83
|
+
raise ProxyTimeoutError(
|
|
84
|
+
'Proxy connection timed out: {}'.format(timeout)
|
|
85
|
+
) from e
|
|
82
86
|
|
|
83
87
|
async def _connect(
|
|
84
88
|
self,
|
|
85
89
|
dest_host: str,
|
|
86
90
|
dest_port: int,
|
|
87
|
-
dest_ssl: ssl.SSLContext = None,
|
|
91
|
+
dest_ssl: Optional[ssl.SSLContext] = None,
|
|
88
92
|
) -> AsyncioSocketStream:
|
|
89
93
|
if self._forward is None:
|
|
90
94
|
try:
|
|
@@ -141,7 +145,7 @@ class AsyncioProxy:
|
|
|
141
145
|
return stream
|
|
142
146
|
|
|
143
147
|
@classmethod
|
|
144
|
-
def create(cls, *args, **kwargs):
|
|
148
|
+
def create(cls, *args, **kwargs): # for backward compatibility
|
|
145
149
|
return cls(*args, **kwargs)
|
|
146
150
|
|
|
147
151
|
@classmethod
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from typing import Any, Optional
|
|
1
2
|
import curio
|
|
2
3
|
import curio.io
|
|
3
4
|
|
|
@@ -12,20 +13,19 @@ from ._connect import connect_tcp
|
|
|
12
13
|
from ..._protocols.errors import ReplyError
|
|
13
14
|
from ..._connectors.factory_async import create_connector
|
|
14
15
|
|
|
15
|
-
from ... import _abc as abc
|
|
16
16
|
|
|
17
17
|
DEFAULT_TIMEOUT = 60
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
class CurioProxy
|
|
20
|
+
class CurioProxy:
|
|
21
21
|
def __init__(
|
|
22
22
|
self,
|
|
23
23
|
proxy_type: ProxyType,
|
|
24
24
|
host: str,
|
|
25
25
|
port: int,
|
|
26
|
-
username: str = None,
|
|
27
|
-
password: str = None,
|
|
28
|
-
rdns: bool = None,
|
|
26
|
+
username: Optional[str] = None,
|
|
27
|
+
password: Optional[str] = None,
|
|
28
|
+
rdns: Optional[bool] = None,
|
|
29
29
|
):
|
|
30
30
|
self._proxy_type = proxy_type
|
|
31
31
|
self._proxy_host = host
|
|
@@ -40,12 +40,14 @@ class CurioProxy(abc.AsyncProxy):
|
|
|
40
40
|
self,
|
|
41
41
|
dest_host: str,
|
|
42
42
|
dest_port: int,
|
|
43
|
-
timeout: float = None,
|
|
44
|
-
|
|
43
|
+
timeout: Optional[float] = None,
|
|
44
|
+
**kwargs: Any,
|
|
45
45
|
) -> curio.io.Socket:
|
|
46
46
|
if timeout is None:
|
|
47
47
|
timeout = DEFAULT_TIMEOUT
|
|
48
48
|
|
|
49
|
+
_socket = kwargs.get('_socket')
|
|
50
|
+
|
|
49
51
|
try:
|
|
50
52
|
return await curio.timeout_after(
|
|
51
53
|
timeout,
|
|
@@ -110,7 +112,7 @@ class CurioProxy(abc.AsyncProxy):
|
|
|
110
112
|
return self._proxy_port
|
|
111
113
|
|
|
112
114
|
@classmethod
|
|
113
|
-
def create(cls, *args, **kwargs):
|
|
115
|
+
def create(cls, *args, **kwargs): # for backward compatibility
|
|
114
116
|
return cls(*args, **kwargs)
|
|
115
117
|
|
|
116
118
|
@classmethod
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from typing import Any, Optional
|
|
1
2
|
import trio
|
|
2
3
|
|
|
3
4
|
from ..._types import ProxyType
|
|
@@ -11,20 +12,19 @@ from ._connect import connect_tcp
|
|
|
11
12
|
from ..._protocols.errors import ReplyError
|
|
12
13
|
from ..._connectors.factory_async import create_connector
|
|
13
14
|
|
|
14
|
-
from ... import _abc as abc
|
|
15
15
|
|
|
16
16
|
DEFAULT_TIMEOUT = 60
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
class TrioProxy
|
|
19
|
+
class TrioProxy:
|
|
20
20
|
def __init__(
|
|
21
21
|
self,
|
|
22
22
|
proxy_type: ProxyType,
|
|
23
23
|
host: str,
|
|
24
24
|
port: int,
|
|
25
|
-
username: str = None,
|
|
26
|
-
password: str = None,
|
|
27
|
-
rdns: bool = None,
|
|
25
|
+
username: Optional[str] = None,
|
|
26
|
+
password: Optional[str] = None,
|
|
27
|
+
rdns: Optional[bool] = None,
|
|
28
28
|
):
|
|
29
29
|
self._proxy_type = proxy_type
|
|
30
30
|
self._proxy_host = host
|
|
@@ -39,12 +39,14 @@ class TrioProxy(abc.AsyncProxy):
|
|
|
39
39
|
self,
|
|
40
40
|
dest_host: str,
|
|
41
41
|
dest_port: int,
|
|
42
|
-
timeout: float = None,
|
|
43
|
-
|
|
42
|
+
timeout: Optional[float] = None,
|
|
43
|
+
**kwargs: Any,
|
|
44
44
|
) -> trio.socket.SocketType:
|
|
45
45
|
if timeout is None:
|
|
46
46
|
timeout = DEFAULT_TIMEOUT
|
|
47
47
|
|
|
48
|
+
_socket = kwargs.get('_socket')
|
|
49
|
+
|
|
48
50
|
try:
|
|
49
51
|
with trio.fail_after(timeout):
|
|
50
52
|
return await self._connect(
|
|
@@ -53,7 +55,9 @@ class TrioProxy(abc.AsyncProxy):
|
|
|
53
55
|
_socket=_socket,
|
|
54
56
|
)
|
|
55
57
|
except trio.TooSlowError as e:
|
|
56
|
-
raise ProxyTimeoutError(
|
|
58
|
+
raise ProxyTimeoutError(
|
|
59
|
+
'Proxy connection timed out: {}'.format(timeout)
|
|
60
|
+
) from e
|
|
57
61
|
|
|
58
62
|
async def _connect(
|
|
59
63
|
self,
|
|
@@ -109,7 +113,7 @@ class TrioProxy(abc.AsyncProxy):
|
|
|
109
113
|
return self._proxy_port
|
|
110
114
|
|
|
111
115
|
@classmethod
|
|
112
|
-
def create(cls, *args, **kwargs):
|
|
116
|
+
def create(cls, *args, **kwargs): # for backward compatibility
|
|
113
117
|
return cls(*args, **kwargs)
|
|
114
118
|
|
|
115
119
|
@classmethod
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import ssl
|
|
2
|
+
from typing import Optional
|
|
2
3
|
|
|
3
4
|
import trio
|
|
4
5
|
|
|
@@ -22,11 +23,11 @@ class TrioProxy:
|
|
|
22
23
|
proxy_type: ProxyType,
|
|
23
24
|
host: str,
|
|
24
25
|
port: int,
|
|
25
|
-
username: str = None,
|
|
26
|
-
password: str = None,
|
|
27
|
-
rdns: bool = None,
|
|
28
|
-
proxy_ssl: ssl.SSLContext = None,
|
|
29
|
-
forward: 'TrioProxy' = None,
|
|
26
|
+
username: Optional[str] = None,
|
|
27
|
+
password: Optional[str] = None,
|
|
28
|
+
rdns: Optional[bool] = None,
|
|
29
|
+
proxy_ssl: Optional[ssl.SSLContext] = None,
|
|
30
|
+
forward: Optional['TrioProxy'] = None,
|
|
30
31
|
):
|
|
31
32
|
self._proxy_type = proxy_type
|
|
32
33
|
self._proxy_host = host
|
|
@@ -44,8 +45,8 @@ class TrioProxy:
|
|
|
44
45
|
self,
|
|
45
46
|
dest_host: str,
|
|
46
47
|
dest_port: int,
|
|
47
|
-
dest_ssl: ssl.SSLContext = None,
|
|
48
|
-
timeout: float = None,
|
|
48
|
+
dest_ssl: Optional[ssl.SSLContext] = None,
|
|
49
|
+
timeout: Optional[float] = None,
|
|
49
50
|
) -> TrioSocketStream:
|
|
50
51
|
if timeout is None:
|
|
51
52
|
timeout = DEFAULT_TIMEOUT
|
|
@@ -64,7 +65,7 @@ class TrioProxy:
|
|
|
64
65
|
self,
|
|
65
66
|
dest_host: str,
|
|
66
67
|
dest_port: int,
|
|
67
|
-
dest_ssl: ssl.SSLContext = None,
|
|
68
|
+
dest_ssl: Optional[ssl.SSLContext] = None,
|
|
68
69
|
) -> TrioSocketStream:
|
|
69
70
|
if self._forward is None:
|
|
70
71
|
try:
|
|
@@ -120,7 +121,7 @@ class TrioProxy:
|
|
|
120
121
|
return stream
|
|
121
122
|
|
|
122
123
|
@classmethod
|
|
123
|
-
def create(cls, *args, **kwargs):
|
|
124
|
+
def create(cls, *args, **kwargs): # for backward compatibility
|
|
124
125
|
return cls(*args, **kwargs)
|
|
125
126
|
|
|
126
127
|
@classmethod
|
python_socks/py.typed
ADDED
|
File without changes
|
python_socks/sync/_proxy.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import socket
|
|
2
|
+
from typing import Optional, Any
|
|
2
3
|
|
|
3
4
|
from .._errors import ProxyConnectionError, ProxyTimeoutError, ProxyError
|
|
4
5
|
|
|
@@ -11,20 +12,19 @@ from ._stream import SyncSocketStream
|
|
|
11
12
|
from ._resolver import SyncResolver
|
|
12
13
|
from ._connect import connect_tcp
|
|
13
14
|
|
|
14
|
-
from .. import _abc as abc
|
|
15
15
|
|
|
16
16
|
DEFAULT_TIMEOUT = 60
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
class SyncProxy
|
|
19
|
+
class SyncProxy:
|
|
20
20
|
def __init__(
|
|
21
21
|
self,
|
|
22
22
|
proxy_type: ProxyType,
|
|
23
23
|
host: str,
|
|
24
24
|
port: int,
|
|
25
|
-
username: str = None,
|
|
26
|
-
password: str = None,
|
|
27
|
-
rdns: bool = None,
|
|
25
|
+
username: Optional[str] = None,
|
|
26
|
+
password: Optional[str] = None,
|
|
27
|
+
rdns: Optional[bool] = None,
|
|
28
28
|
):
|
|
29
29
|
self._proxy_type = proxy_type
|
|
30
30
|
self._proxy_host = host
|
|
@@ -39,12 +39,14 @@ class SyncProxy(abc.SyncProxy):
|
|
|
39
39
|
self,
|
|
40
40
|
dest_host: str,
|
|
41
41
|
dest_port: int,
|
|
42
|
-
timeout: float = None,
|
|
43
|
-
|
|
42
|
+
timeout: Optional[float] = None,
|
|
43
|
+
**kwargs: Any,
|
|
44
44
|
) -> socket.socket:
|
|
45
45
|
if timeout is None:
|
|
46
46
|
timeout = DEFAULT_TIMEOUT
|
|
47
47
|
|
|
48
|
+
_socket = kwargs.get('_socket')
|
|
49
|
+
|
|
48
50
|
if _socket is None:
|
|
49
51
|
try:
|
|
50
52
|
_socket = connect_tcp(
|
|
@@ -79,7 +81,9 @@ class SyncProxy(abc.SyncProxy):
|
|
|
79
81
|
return _socket
|
|
80
82
|
except socket.timeout as e:
|
|
81
83
|
stream.close()
|
|
82
|
-
raise ProxyTimeoutError(
|
|
84
|
+
raise ProxyTimeoutError(
|
|
85
|
+
'Proxy connection timed out: {}'.format(timeout)
|
|
86
|
+
) from e
|
|
83
87
|
except ReplyError as e:
|
|
84
88
|
stream.close()
|
|
85
89
|
raise ProxyError(e, error_code=e.error_code)
|
|
@@ -96,7 +100,7 @@ class SyncProxy(abc.SyncProxy):
|
|
|
96
100
|
return self._proxy_port
|
|
97
101
|
|
|
98
102
|
@classmethod
|
|
99
|
-
def create(cls, *args, **kwargs):
|
|
103
|
+
def create(cls, *args, **kwargs): # for backward compatibility
|
|
100
104
|
return cls(*args, **kwargs)
|
|
101
105
|
|
|
102
106
|
@classmethod
|
python_socks/sync/v2/_proxy.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import socket
|
|
2
2
|
import ssl
|
|
3
|
+
from typing import Optional
|
|
3
4
|
|
|
4
5
|
from ._connect import connect_tcp
|
|
5
6
|
from ._stream import SyncSocketStream
|
|
6
7
|
from .._resolver import SyncResolver
|
|
7
|
-
from ... import _abc as abc
|
|
8
8
|
from ..._types import ProxyType
|
|
9
9
|
from ..._errors import ProxyConnectionError, ProxyTimeoutError, ProxyError
|
|
10
10
|
from ..._helpers import parse_proxy_url
|
|
@@ -16,17 +16,17 @@ from ..._connectors.factory_sync import create_connector
|
|
|
16
16
|
DEFAULT_TIMEOUT = 60
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
class SyncProxy
|
|
19
|
+
class SyncProxy:
|
|
20
20
|
def __init__(
|
|
21
21
|
self,
|
|
22
22
|
proxy_type: ProxyType,
|
|
23
23
|
host: str,
|
|
24
24
|
port: int,
|
|
25
|
-
username: str = None,
|
|
26
|
-
password: str = None,
|
|
27
|
-
rdns: bool = None,
|
|
28
|
-
proxy_ssl: ssl.SSLContext = None,
|
|
29
|
-
forward: 'SyncProxy' = None,
|
|
25
|
+
username: Optional[str] = None,
|
|
26
|
+
password: Optional[str] = None,
|
|
27
|
+
rdns: Optional[bool] = None,
|
|
28
|
+
proxy_ssl: Optional[ssl.SSLContext] = None,
|
|
29
|
+
forward: Optional['SyncProxy'] = None,
|
|
30
30
|
):
|
|
31
31
|
self._proxy_type = proxy_type
|
|
32
32
|
self._proxy_host = host
|
|
@@ -43,8 +43,8 @@ class SyncProxy(abc.SyncProxy):
|
|
|
43
43
|
self,
|
|
44
44
|
dest_host: str,
|
|
45
45
|
dest_port: int,
|
|
46
|
-
dest_ssl: ssl.SSLContext = None,
|
|
47
|
-
timeout: float = None,
|
|
46
|
+
dest_ssl: Optional[ssl.SSLContext] = None,
|
|
47
|
+
timeout: Optional[float] = None,
|
|
48
48
|
) -> SyncSocketStream:
|
|
49
49
|
if timeout is None:
|
|
50
50
|
timeout = DEFAULT_TIMEOUT
|
|
@@ -109,7 +109,7 @@ class SyncProxy(abc.SyncProxy):
|
|
|
109
109
|
raise
|
|
110
110
|
|
|
111
111
|
@classmethod
|
|
112
|
-
def create(cls, *args, **kwargs):
|
|
112
|
+
def create(cls, *args, **kwargs): # for backward compatibility
|
|
113
113
|
return cls(*args, **kwargs)
|
|
114
114
|
|
|
115
115
|
@classmethod
|
|
@@ -1,22 +1,41 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-socks
|
|
3
|
-
Version: 2.
|
|
4
|
-
Summary:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Keywords: socks
|
|
3
|
+
Version: 2.6.0
|
|
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: Operating System :: MacOS
|
|
21
|
+
Classifier: Operating System :: Microsoft
|
|
22
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
23
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
24
|
+
Classifier: Intended Audience :: Developers
|
|
25
|
+
Classifier: Framework :: AsyncIO
|
|
26
|
+
Classifier: Framework :: Trio
|
|
27
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
28
|
+
Requires-Python: >=3.8.0
|
|
10
29
|
Description-Content-Type: text/markdown
|
|
11
30
|
License-File: LICENSE.txt
|
|
12
|
-
Provides-Extra: anyio
|
|
13
|
-
Requires-Dist: anyio<5.0.0,>=3.3.4; extra == "anyio"
|
|
14
31
|
Provides-Extra: asyncio
|
|
15
|
-
Requires-Dist: async-timeout>=
|
|
32
|
+
Requires-Dist: async-timeout>=4.0; python_version < "3.11" and extra == "asyncio"
|
|
33
|
+
Provides-Extra: trio
|
|
34
|
+
Requires-Dist: trio>=0.24; extra == "trio"
|
|
16
35
|
Provides-Extra: curio
|
|
17
36
|
Requires-Dist: curio>=1.4; extra == "curio"
|
|
18
|
-
Provides-Extra:
|
|
19
|
-
Requires-Dist:
|
|
37
|
+
Provides-Extra: anyio
|
|
38
|
+
Requires-Dist: anyio<5.0.0,>=3.3.4; extra == "anyio"
|
|
20
39
|
|
|
21
40
|
## python-socks
|
|
22
41
|
|
|
@@ -28,15 +47,15 @@ Requires-Dist: trio>=0.16.0; extra == "trio"
|
|
|
28
47
|
-->
|
|
29
48
|
|
|
30
49
|
The `python-socks` package provides a core proxy client functionality for Python.
|
|
31
|
-
Supports SOCKS4(a)
|
|
50
|
+
Supports `SOCKS4(a)`, `SOCKS5(h)`, `HTTP CONNECT` proxy and provides sync and async (asyncio, trio, curio, anyio) APIs.
|
|
32
51
|
You probably don't need to use `python-socks` directly.
|
|
33
52
|
It is used internally by
|
|
34
53
|
[aiohttp-socks](https://github.com/romis2012/aiohttp-socks) and [httpx-socks](https://github.com/romis2012/httpx-socks) packages.
|
|
35
54
|
|
|
36
55
|
## Requirements
|
|
37
|
-
- Python >= 3.
|
|
38
|
-
- async-timeout >=
|
|
39
|
-
- trio >= 0.
|
|
56
|
+
- Python >= 3.8
|
|
57
|
+
- async-timeout >= 4.0 (optional)
|
|
58
|
+
- trio >= 0.24 (optional)
|
|
40
59
|
- curio >= 1.4 (optional)
|
|
41
60
|
- anyio >= 3.3.4 (optional)
|
|
42
61
|
|
|
@@ -1,76 +1,77 @@
|
|
|
1
1
|
python_socks/__init__.py,sha256=gKywvwx_x4_0hWJEa2eif1dPzP9YeFXJdrNlHuvFmC8,367
|
|
2
|
-
python_socks/_abc.py,sha256=
|
|
2
|
+
python_socks/_abc.py,sha256=_juTZE0iqoTChE53IHjBKEYFO-fxYZfPhdUc6EgFlwE,909
|
|
3
3
|
python_socks/_errors.py,sha256=l2j03Zna_EJhNqF3yApTYuQ147BcY0k74pkT4HAlRp4,245
|
|
4
|
-
python_socks/_helpers.py,sha256=
|
|
4
|
+
python_socks/_helpers.py,sha256=UacO07M9i8G8CfqzBYWnehgCTFbZTlwJWAsFoXR3mVk,2708
|
|
5
5
|
python_socks/_types.py,sha256=dgQifNf2mIwdKoX7YmI91H_lUsW9-Y0ZkZGlIV6_NNw,90
|
|
6
|
-
python_socks/_version.py,sha256=
|
|
6
|
+
python_socks/_version.py,sha256=VDGUdSXYIOZqFTKm-y-mF5-8Rkwpzs--GH_DWxzC6pY,49
|
|
7
|
+
python_socks/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
8
|
python_socks/_connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
9
|
python_socks/_connectors/abc.py,sha256=1fgjPiv64UAMiJDsJXYr-GofPGhuHTwTzaodQfrzf7Q,397
|
|
9
|
-
python_socks/_connectors/factory_async.py,sha256=
|
|
10
|
-
python_socks/_connectors/factory_sync.py,sha256=
|
|
11
|
-
python_socks/_connectors/http_async.py,sha256=
|
|
12
|
-
python_socks/_connectors/http_sync.py,sha256=
|
|
13
|
-
python_socks/_connectors/socks4_async.py,sha256=
|
|
14
|
-
python_socks/_connectors/socks4_sync.py,sha256=
|
|
15
|
-
python_socks/_connectors/socks5_async.py,sha256=
|
|
16
|
-
python_socks/_connectors/socks5_sync.py,sha256=
|
|
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=N44bp-YwXHy8yIqf1y4x9MvIvGLslqtzl4f7M6Yt13A,2786
|
|
17
|
+
python_socks/_connectors/socks5_sync.py,sha256=uPExUVd-EAxG7Gsc431S-kyFRvLb_AvVpr1vYQHmTPo,2565
|
|
17
18
|
python_socks/_protocols/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
19
|
python_socks/_protocols/errors.py,sha256=4XqU4AqgrWaedmUVGMjd6TvQKXv3mV0H76s5lf8aazY,150
|
|
19
|
-
python_socks/_protocols/http.py,sha256=
|
|
20
|
-
python_socks/_protocols/socks4.py,sha256=
|
|
21
|
-
python_socks/_protocols/socks5.py,sha256=
|
|
20
|
+
python_socks/_protocols/http.py,sha256=QhLHqBgc6DfsvC8AIhylN1tjfk7QzxgwemrK1LuL3vk,4499
|
|
21
|
+
python_socks/_protocols/socks4.py,sha256=j1Psqi3PDiKAF19g_Mh3sf_RwXu7o-8X7BqWOaoTbKE,3061
|
|
22
|
+
python_socks/_protocols/socks5.py,sha256=1PEr1s4JxmpST9OYEeVgbidnV_d4Vb85JZHmWqK-r9c,9713
|
|
22
23
|
python_socks/async_/__init__.py,sha256=TeBn5oirLy6aPoWcTc3OW9OxXh5Uv5LADwF_Y7f7HjY,64
|
|
23
|
-
python_socks/async_/_proxy_chain.py,sha256=
|
|
24
|
+
python_socks/async_/_proxy_chain.py,sha256=YZR5aNqqG358ynVe1F14k32hjK3yb19v_hh2On0gZ_I,781
|
|
24
25
|
python_socks/async_/anyio/__init__.py,sha256=pZnrND4Qd-pIGg7KI1ML41kZNkWHmkd3vrvwZZIJyk4,106
|
|
25
26
|
python_socks/async_/anyio/_chain.py,sha256=EOXAd2w7OYEKsfugkvQpGKETej_80VeyjmZfH1_ZYZE,895
|
|
26
27
|
python_socks/async_/anyio/_connect.py,sha256=6Qr_gh3FkPlGm1GrQq0DC1QupvPdXnWKd-Fniu0Kn9c,268
|
|
27
|
-
python_socks/async_/anyio/_proxy.py,sha256=
|
|
28
|
+
python_socks/async_/anyio/_proxy.py,sha256=VSKRUIGmZE3hZC0PU6eyhidMA1Q9UrWSYLGQJsXr320,3960
|
|
28
29
|
python_socks/async_/anyio/_resolver.py,sha256=LPRLmEzgKPGCqAbEMmLSMVtFkNVKha_2u08MhrZZ-CY,590
|
|
29
30
|
python_socks/async_/anyio/_stream.py,sha256=OcCl4YkccA0-5hZh90CP4YmsBDLPwHpS3B0wCLytnAY,1614
|
|
30
31
|
python_socks/async_/anyio/v2/__init__.py,sha256=4xgyAJHDGpRANYVNfpUdn3Zo8Ib_gREWH8bH4APycK4,117
|
|
31
32
|
python_socks/async_/anyio/v2/_chain.py,sha256=baTCXD68hceOMWYITrUUSKv-B745RT4TdpQPDkSz68Y,593
|
|
32
33
|
python_socks/async_/anyio/v2/_connect.py,sha256=wOOuUxURCjIWOH1pd8H6gr3XZ3VnvRtmsAh97M_ULEA,330
|
|
33
|
-
python_socks/async_/anyio/v2/_proxy.py,sha256=
|
|
34
|
+
python_socks/async_/anyio/v2/_proxy.py,sha256=lTIPQHTfGm8hV4N6gpbvC7QxxDBxrfi0EHuXqu-nWoA,3897
|
|
34
35
|
python_socks/async_/anyio/v2/_stream.py,sha256=40D3Pmb0rryk9gaQlmjpAMdiJi5H5O0xbBseblGG1FY,1616
|
|
35
36
|
python_socks/async_/asyncio/__init__.py,sha256=0WAM07vy0YvI8IhKGmaUA0GaNLHaG3l-4mnJVbfoqHE,65
|
|
36
37
|
python_socks/async_/asyncio/_connect.py,sha256=niNKiz2o1kfeIPVR3kXW7YHZ2sTK_Uehgq9tmFwbp7w,1014
|
|
37
|
-
python_socks/async_/asyncio/_proxy.py,sha256=
|
|
38
|
+
python_socks/async_/asyncio/_proxy.py,sha256=dHBoSOZuxFux5pClhPy_4yGoi5VvkNI9gJsMUJy29Ac,4689
|
|
38
39
|
python_socks/async_/asyncio/_resolver.py,sha256=ROqOncuIub87J9_nMdvRTG_5zYOh8uafk265z0s2ORQ,681
|
|
39
40
|
python_socks/async_/asyncio/_stream.py,sha256=RP7BIP9iFFy5nLRf9kHH7s1h_zPfo0yoEVKNpExqFcI,1021
|
|
40
41
|
python_socks/async_/asyncio/v2/__init__.py,sha256=v9eJQeZ2yGJHeBQ0FYqNmIMCRrB547QqoAANHVBitxY,108
|
|
41
42
|
python_socks/async_/asyncio/v2/_chain.py,sha256=Yle3F3TKEpCo9Snd-T5hRnmfn9iWj2VNLb3UHz6yNiU,607
|
|
42
43
|
python_socks/async_/asyncio/v2/_connect.py,sha256=b3kQBR7L6wp-yvWVwtcdb4JUdQV04JW-DXF1g1P3gxI,587
|
|
43
|
-
python_socks/async_/asyncio/v2/_proxy.py,sha256=
|
|
44
|
+
python_socks/async_/asyncio/v2/_proxy.py,sha256=hgm276siuUn4nO5gK2iEaS12arvmVex1-Tz4NWNW_TM,4505
|
|
44
45
|
python_socks/async_/asyncio/v2/_stream.py,sha256=dOvZPMLd0lHeZwlJIL-bK-PQN9sjM6urA5AyFXxdaas,3834
|
|
45
46
|
python_socks/async_/curio/__init__.py,sha256=1OyhLhvLJ23iDROgyxGqQACice66SrIYCMqmwjw_dqY,63
|
|
46
47
|
python_socks/async_/curio/_connect.py,sha256=u1HRJ8n3OZbux-wETO9HuqZv9By2LGhhSsM78gnxr_0,328
|
|
47
|
-
python_socks/async_/curio/_proxy.py,sha256=
|
|
48
|
+
python_socks/async_/curio/_proxy.py,sha256=2JRxx8SQvGPAHKGgf9OImH_X2Gfhxxzb5brNkmq7KhM,3241
|
|
48
49
|
python_socks/async_/curio/_resolver.py,sha256=_jDZq_lzTl_QihxH2HNEY_7_ELo-qmzG6IO5PNNEOek,722
|
|
49
50
|
python_socks/async_/curio/_stream.py,sha256=sIAbwkPuiFF4c8cEs7exVdGb7cfFgoggKTV4LYqDcm0,855
|
|
50
51
|
python_socks/async_/trio/__init__.py,sha256=Y68xwGqkXGKXHcwM6nvev6n2ChbFpBUFW0RzBrsIrug,61
|
|
51
52
|
python_socks/async_/trio/_connect.py,sha256=uN_qwxLWdvy2zclPw5Z8R5TPqgT6jjzzTcSHd-xGFas,783
|
|
52
|
-
python_socks/async_/trio/_proxy.py,sha256=
|
|
53
|
+
python_socks/async_/trio/_proxy.py,sha256=F2jMJ_41__3YgNXrOWafgcZY0aW0g6c7rdJuIb7GbGk,3399
|
|
53
54
|
python_socks/async_/trio/_resolver.py,sha256=uqBoTkbYpwwESoph2SmXRUUHM_DsT7dALQDmKqp-sco,591
|
|
54
55
|
python_socks/async_/trio/_stream.py,sha256=xunx_XUiwH1pBLQjWbkqq3P92SeXaRypPMPRYwHOsPg,1003
|
|
55
56
|
python_socks/async_/trio/v2/__init__.py,sha256=cd8Sc6NLmrUZewkqeDvnxmQqGZBKNuwYEEb4NMW2qo0,116
|
|
56
57
|
python_socks/async_/trio/v2/_chain.py,sha256=sf32gS-flmzVe60b83LtwOhbzvlm1s7gPlgIpAbW1hM,591
|
|
57
58
|
python_socks/async_/trio/v2/_connect.py,sha256=9B7cpLC9HqrXdW-61jA8hGRspHuIgaLTniZyCqpSiPE,379
|
|
58
|
-
python_socks/async_/trio/v2/_proxy.py,sha256=
|
|
59
|
+
python_socks/async_/trio/v2/_proxy.py,sha256=8BmeQRJkxM1bMJFvWdQqeSs_MDRp3DIPsLBAtb6X_FU,3877
|
|
59
60
|
python_socks/async_/trio/v2/_stream.py,sha256=wGB7sDjRO1ywVNjF_DFgdF2orjD3zrh8dPSmW9aBEV0,1475
|
|
60
61
|
python_socks/sync/__init__.py,sha256=Dslh61MLGktjBK50UVGYjAQ-iGl8tjoLR93_-cvddWM,106
|
|
61
62
|
python_socks/sync/_chain.py,sha256=TJeIQmvCw5Z0slBQOD0V9mibC5jbM9pDD_xjlyYgHFs,804
|
|
62
63
|
python_socks/sync/_connect.py,sha256=5i834THkhSTOwgIvzWNihHYGwxNv7JIr3aCnaXU1SLY,334
|
|
63
|
-
python_socks/sync/_proxy.py,sha256=
|
|
64
|
+
python_socks/sync/_proxy.py,sha256=A4FKY9a28zrTsNEJfy3tUjfGQvQcFKpq77Xce8OKBfw,2964
|
|
64
65
|
python_socks/sync/_resolver.py,sha256=2rf9-NdjRktYrab1Oyv9ZJLKByP95ysFmRE3TgjRCSA,547
|
|
65
66
|
python_socks/sync/_stream.py,sha256=x01ovajA0DAjHkBCxpMeFaWYjns9BljgBQ-GGyBqrw4,818
|
|
66
67
|
python_socks/sync/v2/__init__.py,sha256=eVZc6zh0pLhNMf_uSPZiH_1vNGEvedwzX5gObUSkRT8,116
|
|
67
68
|
python_socks/sync/v2/_chain.py,sha256=IRVMioTVWwxylZ8maD5Gqxhhgw4VyrG5vo_hAOuEn8Q,579
|
|
68
69
|
python_socks/sync/v2/_connect.py,sha256=eqMKsH2wVnGZhV24_t9QfsNhjbnKtnipj7wzSNctM3Q,410
|
|
69
|
-
python_socks/sync/v2/_proxy.py,sha256
|
|
70
|
+
python_socks/sync/v2/_proxy.py,sha256=kklPAuHxhqJ9uwFgT-KLhPZxqOmonJcF6evpELvqCQU,3484
|
|
70
71
|
python_socks/sync/v2/_ssl_transport.py,sha256=MURwzvKu-S2-MI7o8KaZTvvBFOiiKIu5R0ERVIMvERE,6088
|
|
71
72
|
python_socks/sync/v2/_stream.py,sha256=Jq89x1xmIX3L_v-WyS1nRTItjTnYTcDcfDblsANxfJI,1544
|
|
72
|
-
python_socks-2.
|
|
73
|
-
python_socks-2.
|
|
74
|
-
python_socks-2.
|
|
75
|
-
python_socks-2.
|
|
76
|
-
python_socks-2.
|
|
73
|
+
python_socks-2.6.0.dist-info/LICENSE.txt,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
|
|
74
|
+
python_socks-2.6.0.dist-info/METADATA,sha256=pTdgOXsEuObKYZAQkOOxpM1-2vAtF-klRPZtrqhSugQ,7964
|
|
75
|
+
python_socks-2.6.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
76
|
+
python_socks-2.6.0.dist-info/top_level.txt,sha256=7qyDAVwjTZ0sIYG1iatFbE-SLpWhONjaoMQ0Ib2DX0Q,13
|
|
77
|
+
python_socks-2.6.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|