python-socks 2.8.2__py3-none-any.whl → 3.0.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 +16 -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.0.0.dist-info/METADATA +346 -0
- python_socks-3.0.0.dist-info/RECORD +65 -0
- {python_socks-2.8.2.dist-info → python_socks-3.0.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.0.0.dist-info}/licenses/LICENSE.txt +0 -0
- {python_socks-2.8.2.dist-info → python_socks-3.0.0.dist-info}/top_level.txt +0 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import ssl
|
|
2
4
|
from typing import Union
|
|
3
5
|
|
|
4
6
|
import trio
|
|
5
7
|
|
|
6
|
-
from ...._errors import ProxyError
|
|
7
8
|
from .... import _abc as abc
|
|
9
|
+
from ...._errors import IncompleteReadError
|
|
8
10
|
|
|
9
11
|
DEFAULT_RECEIVE_SIZE = 65536
|
|
10
12
|
|
|
@@ -12,31 +14,29 @@ TrioStreamType = Union[trio.SocketStream, trio.SSLStream]
|
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
class TrioSocketStream(abc.AsyncSocketStream):
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def __init__(self, stream: TrioStreamType):
|
|
17
|
+
def __init__(self, stream: TrioStreamType) -> None:
|
|
18
18
|
self._stream = stream
|
|
19
19
|
|
|
20
|
-
async def
|
|
20
|
+
async def write(self, data: bytes) -> None:
|
|
21
21
|
await self._stream.send_all(data)
|
|
22
22
|
|
|
23
|
-
async def read(self, max_bytes=DEFAULT_RECEIVE_SIZE):
|
|
24
|
-
return await self._stream.receive_some(max_bytes)
|
|
23
|
+
async def read(self, max_bytes: int = DEFAULT_RECEIVE_SIZE) -> bytes:
|
|
24
|
+
return await self._stream.receive_some(max_bytes) # type:ignore[return-value]
|
|
25
25
|
|
|
26
|
-
async def
|
|
26
|
+
async def read_exactly(self, n: int) -> bytes:
|
|
27
27
|
data = bytearray()
|
|
28
28
|
while len(data) < n:
|
|
29
29
|
packet = await self._stream.receive_some(n - len(data))
|
|
30
30
|
if not packet: # pragma: no cover
|
|
31
|
-
raise
|
|
32
|
-
data
|
|
33
|
-
return data
|
|
31
|
+
raise IncompleteReadError("Connection closed unexpectedly")
|
|
32
|
+
data.extend(packet)
|
|
33
|
+
return data # type:ignore[return-value]
|
|
34
34
|
|
|
35
35
|
async def start_tls(
|
|
36
36
|
self,
|
|
37
37
|
hostname: str,
|
|
38
38
|
ssl_context: ssl.SSLContext,
|
|
39
|
-
) ->
|
|
39
|
+
) -> TrioSocketStream:
|
|
40
40
|
ssl_stream = trio.SSLStream(
|
|
41
41
|
self._stream,
|
|
42
42
|
ssl_context=ssl_context,
|
|
@@ -47,7 +47,7 @@ class TrioSocketStream(abc.AsyncSocketStream):
|
|
|
47
47
|
await ssl_stream.do_handshake()
|
|
48
48
|
return TrioSocketStream(ssl_stream)
|
|
49
49
|
|
|
50
|
-
async def close(self):
|
|
50
|
+
async def close(self) -> None:
|
|
51
51
|
await self._stream.aclose()
|
|
52
52
|
|
|
53
53
|
@property
|
python_socks/sync/__init__.py
CHANGED
python_socks/sync/_connect.py
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import socket
|
|
2
|
-
from typing import Optional, Tuple
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
def connect_tcp(
|
|
6
7
|
host: str,
|
|
7
8
|
port: int,
|
|
8
|
-
timeout:
|
|
9
|
-
local_addr:
|
|
9
|
+
timeout: float | None = None,
|
|
10
|
+
local_addr: tuple[str, int] | None = None,
|
|
10
11
|
) -> socket.socket:
|
|
11
12
|
address = (host, port)
|
|
12
13
|
return socket.create_connection(
|
python_socks/sync/_proxy.py
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
import
|
|
2
|
-
from typing import Optional, Any
|
|
3
|
-
import warnings
|
|
1
|
+
from __future__ import annotations
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
import socket
|
|
4
|
+
from typing import Any
|
|
6
5
|
|
|
7
|
-
from ..
|
|
6
|
+
from .._connectors.factory_sync import create_connector
|
|
7
|
+
from .._errors import (
|
|
8
|
+
IncompleteReadError,
|
|
9
|
+
ProxyConnectionError,
|
|
10
|
+
ProxyError,
|
|
11
|
+
ProxyTimeoutError,
|
|
12
|
+
)
|
|
8
13
|
from .._helpers import parse_proxy_url
|
|
9
14
|
from .._protocols.errors import ReplyError
|
|
10
|
-
from ..
|
|
11
|
-
|
|
12
|
-
from ._stream import SyncSocketStream
|
|
13
|
-
from ._resolver import SyncResolver
|
|
15
|
+
from .._types import ProxyType
|
|
14
16
|
from ._connect import connect_tcp
|
|
15
|
-
|
|
17
|
+
from ._resolver import SyncResolver
|
|
18
|
+
from ._stream import SyncSocketStream
|
|
16
19
|
|
|
17
20
|
DEFAULT_TIMEOUT = 60
|
|
18
21
|
|
|
@@ -23,16 +26,18 @@ class SyncProxy:
|
|
|
23
26
|
proxy_type: ProxyType,
|
|
24
27
|
host: str,
|
|
25
28
|
port: int,
|
|
26
|
-
username:
|
|
27
|
-
password:
|
|
28
|
-
rdns:
|
|
29
|
-
|
|
29
|
+
username: str | None = None,
|
|
30
|
+
password: str | None = None,
|
|
31
|
+
rdns: bool | None = None, # noqa: FBT001
|
|
32
|
+
forward: SyncProxy | None = None,
|
|
33
|
+
) -> None:
|
|
30
34
|
self._proxy_type = proxy_type
|
|
31
35
|
self._proxy_host = host
|
|
32
36
|
self._proxy_port = port
|
|
33
37
|
self._password = password
|
|
34
38
|
self._username = username
|
|
35
39
|
self._rdns = rdns
|
|
40
|
+
self._forward = forward
|
|
36
41
|
|
|
37
42
|
self._resolver = SyncResolver()
|
|
38
43
|
|
|
@@ -40,38 +45,35 @@ class SyncProxy:
|
|
|
40
45
|
self,
|
|
41
46
|
dest_host: str,
|
|
42
47
|
dest_port: int,
|
|
43
|
-
timeout:
|
|
48
|
+
timeout: float | None = None,
|
|
44
49
|
**kwargs: Any,
|
|
45
50
|
) -> socket.socket:
|
|
46
51
|
if timeout is None:
|
|
47
52
|
timeout = DEFAULT_TIMEOUT
|
|
48
53
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
stacklevel=2,
|
|
54
|
+
if self._forward is not None:
|
|
55
|
+
sock = self._forward.connect(
|
|
56
|
+
dest_host=self._proxy_host,
|
|
57
|
+
dest_port=self._proxy_port,
|
|
58
|
+
timeout=timeout,
|
|
55
59
|
)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
local_addr = kwargs.get('local_addr')
|
|
60
|
+
else:
|
|
61
|
+
local_addr = kwargs.get("local_addr")
|
|
59
62
|
try:
|
|
60
|
-
|
|
63
|
+
sock = connect_tcp(
|
|
61
64
|
host=self._proxy_host,
|
|
62
65
|
port=self._proxy_port,
|
|
63
66
|
timeout=timeout,
|
|
64
67
|
local_addr=local_addr,
|
|
65
68
|
)
|
|
66
69
|
except OSError as e:
|
|
67
|
-
msg =
|
|
68
|
-
|
|
69
|
-
self._proxy_port
|
|
70
|
-
e.strerror,
|
|
70
|
+
msg = (
|
|
71
|
+
f"Could not connect to proxy "
|
|
72
|
+
f"{self._proxy_host}:{self._proxy_port} [{e.strerror}]"
|
|
71
73
|
)
|
|
72
74
|
raise ProxyConnectionError(e.errno, msg) from e
|
|
73
75
|
|
|
74
|
-
stream = SyncSocketStream(
|
|
76
|
+
stream = SyncSocketStream(sock)
|
|
75
77
|
|
|
76
78
|
try:
|
|
77
79
|
connector = create_connector(
|
|
@@ -87,30 +89,27 @@ class SyncProxy:
|
|
|
87
89
|
port=dest_port,
|
|
88
90
|
)
|
|
89
91
|
|
|
90
|
-
return
|
|
92
|
+
return sock
|
|
91
93
|
except socket.timeout as e:
|
|
92
94
|
stream.close()
|
|
93
|
-
raise ProxyTimeoutError(
|
|
95
|
+
raise ProxyTimeoutError(f"Proxy connection timed out: {timeout}") from e
|
|
94
96
|
except ReplyError as e:
|
|
95
97
|
stream.close()
|
|
96
|
-
raise ProxyError(e, error_code=e.error_code)
|
|
98
|
+
raise ProxyError(e, error_code=e.error_code) from e
|
|
99
|
+
except IncompleteReadError as e:
|
|
100
|
+
stream.close()
|
|
101
|
+
raise ProxyError(e) from e
|
|
97
102
|
except Exception:
|
|
98
103
|
stream.close()
|
|
99
104
|
raise
|
|
100
105
|
|
|
101
|
-
@property
|
|
102
|
-
def proxy_host(self):
|
|
103
|
-
return self._proxy_host
|
|
104
|
-
|
|
105
|
-
@property
|
|
106
|
-
def proxy_port(self):
|
|
107
|
-
return self._proxy_port
|
|
108
|
-
|
|
109
106
|
@classmethod
|
|
110
|
-
def create(
|
|
107
|
+
def create(
|
|
108
|
+
cls, *args: Any, **kwargs: Any
|
|
109
|
+
) -> SyncProxy: # for backward compatibility
|
|
111
110
|
return cls(*args, **kwargs)
|
|
112
111
|
|
|
113
112
|
@classmethod
|
|
114
|
-
def from_url(cls, url: str, **kwargs) ->
|
|
113
|
+
def from_url(cls, url: str, **kwargs: Any) -> SyncProxy:
|
|
115
114
|
url_args = parse_proxy_url(url)
|
|
116
115
|
return cls(*url_args, **kwargs)
|
python_socks/sync/_resolver.py
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
import socket
|
|
2
|
+
|
|
2
3
|
from .. import _abc as abc
|
|
4
|
+
from .._types import ResolvedAddress
|
|
3
5
|
|
|
4
6
|
|
|
5
7
|
class SyncResolver(abc.SyncResolver):
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
def resolve(
|
|
9
|
+
self,
|
|
10
|
+
host: str,
|
|
11
|
+
port: int = 0,
|
|
12
|
+
family: socket.AddressFamily = socket.AF_UNSPEC,
|
|
13
|
+
) -> ResolvedAddress:
|
|
14
|
+
infos = socket.getaddrinfo(
|
|
15
|
+
host=host,
|
|
16
|
+
port=port,
|
|
17
|
+
family=family,
|
|
18
|
+
type=socket.SOCK_STREAM,
|
|
19
|
+
)
|
|
9
20
|
|
|
10
21
|
if not infos: # pragma: no cover
|
|
11
|
-
raise OSError(
|
|
22
|
+
raise OSError(f"Can`t resolve address {host}:{port} [{family}]")
|
|
12
23
|
|
|
24
|
+
# use IPv4 address first
|
|
13
25
|
infos = sorted(infos, key=lambda info: info[0])
|
|
14
26
|
|
|
15
27
|
family, _, _, _, address = infos[0]
|
|
16
|
-
return family, address[0]
|
|
28
|
+
return family, address[0] # type: ignore[return-value]
|
python_socks/sync/_stream.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import socket
|
|
2
2
|
|
|
3
|
-
from .._errors import ProxyError
|
|
4
3
|
from .. import _abc as abc
|
|
4
|
+
from .._errors import IncompleteReadError
|
|
5
5
|
|
|
6
6
|
DEFAULT_RECEIVE_SIZE = 65536
|
|
7
7
|
|
|
@@ -9,24 +9,24 @@ DEFAULT_RECEIVE_SIZE = 65536
|
|
|
9
9
|
class SyncSocketStream(abc.SyncSocketStream):
|
|
10
10
|
_socket: socket.socket
|
|
11
11
|
|
|
12
|
-
def __init__(self, sock: socket.socket):
|
|
12
|
+
def __init__(self, sock: socket.socket) -> None:
|
|
13
13
|
self._socket = sock
|
|
14
14
|
|
|
15
|
-
def
|
|
15
|
+
def write(self, data: bytes) -> None:
|
|
16
16
|
self._socket.sendall(data)
|
|
17
17
|
|
|
18
|
-
def read(self, max_bytes=DEFAULT_RECEIVE_SIZE):
|
|
18
|
+
def read(self, max_bytes: int = DEFAULT_RECEIVE_SIZE) -> bytes:
|
|
19
19
|
return self._socket.recv(max_bytes)
|
|
20
20
|
|
|
21
|
-
def
|
|
21
|
+
def read_exactly(self, n: int) -> bytes:
|
|
22
22
|
data = bytearray()
|
|
23
23
|
while len(data) < n:
|
|
24
24
|
packet = self._socket.recv(n - len(data))
|
|
25
25
|
if not packet: # pragma: no cover
|
|
26
|
-
raise
|
|
27
|
-
data
|
|
28
|
-
return data
|
|
26
|
+
raise IncompleteReadError("Connection closed unexpectedly")
|
|
27
|
+
data.extend(packet)
|
|
28
|
+
return data # type:ignore[return-value]
|
|
29
29
|
|
|
30
|
-
def close(self):
|
|
30
|
+
def close(self) -> None:
|
|
31
31
|
if self._socket is not None:
|
|
32
32
|
self._socket.close()
|
python_socks/sync/v2/__init__.py
CHANGED
python_socks/sync/v2/_connect.py
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import socket
|
|
2
|
-
|
|
4
|
+
|
|
3
5
|
from ._stream import SyncSocketStream
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
def connect_tcp(
|
|
7
9
|
host: str,
|
|
8
10
|
port: int,
|
|
9
|
-
timeout:
|
|
10
|
-
local_addr:
|
|
11
|
+
timeout: float | None = None,
|
|
12
|
+
local_addr: tuple[str, int] | None = None,
|
|
11
13
|
) -> SyncSocketStream:
|
|
12
14
|
address = (host, port)
|
|
13
15
|
sock = socket.create_connection(
|
python_socks/sync/v2/_proxy.py
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import socket
|
|
2
4
|
import ssl
|
|
3
|
-
from typing import Any
|
|
5
|
+
from typing import Any
|
|
4
6
|
|
|
5
|
-
from .
|
|
6
|
-
from
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
from ..._connectors.factory_sync import create_connector
|
|
8
|
+
from ..._errors import (
|
|
9
|
+
IncompleteReadError,
|
|
10
|
+
ProxyConnectionError,
|
|
11
|
+
ProxyError,
|
|
12
|
+
ProxyTimeoutError,
|
|
13
|
+
)
|
|
10
14
|
from ..._helpers import parse_proxy_url
|
|
11
|
-
|
|
12
15
|
from ..._protocols.errors import ReplyError
|
|
13
|
-
from ...
|
|
14
|
-
|
|
16
|
+
from ..._types import ProxyType
|
|
17
|
+
from .._resolver import SyncResolver
|
|
18
|
+
from ._connect import connect_tcp
|
|
19
|
+
from ._stream import SyncSocketStream
|
|
15
20
|
|
|
16
21
|
DEFAULT_TIMEOUT = 60
|
|
17
22
|
|
|
@@ -22,12 +27,12 @@ class SyncProxy:
|
|
|
22
27
|
proxy_type: ProxyType,
|
|
23
28
|
host: str,
|
|
24
29
|
port: int,
|
|
25
|
-
username:
|
|
26
|
-
password:
|
|
27
|
-
rdns:
|
|
28
|
-
proxy_ssl:
|
|
29
|
-
forward:
|
|
30
|
-
):
|
|
30
|
+
username: str | None = None,
|
|
31
|
+
password: str | None = None,
|
|
32
|
+
rdns: bool | None = None, # noqa: FBT001
|
|
33
|
+
proxy_ssl: ssl.SSLContext | None = None,
|
|
34
|
+
forward: SyncProxy | None = None,
|
|
35
|
+
) -> None:
|
|
31
36
|
self._proxy_type = proxy_type
|
|
32
37
|
self._proxy_host = host
|
|
33
38
|
self._proxy_port = port
|
|
@@ -43,15 +48,15 @@ class SyncProxy:
|
|
|
43
48
|
self,
|
|
44
49
|
dest_host: str,
|
|
45
50
|
dest_port: int,
|
|
46
|
-
dest_ssl:
|
|
47
|
-
timeout:
|
|
51
|
+
dest_ssl: ssl.SSLContext | None = None,
|
|
52
|
+
timeout: float | None = None,
|
|
48
53
|
**kwargs: Any,
|
|
49
54
|
) -> SyncSocketStream:
|
|
50
55
|
if timeout is None:
|
|
51
56
|
timeout = DEFAULT_TIMEOUT
|
|
52
57
|
|
|
53
58
|
if self._forward is None:
|
|
54
|
-
local_addr = kwargs.get(
|
|
59
|
+
local_addr = kwargs.get("local_addr")
|
|
55
60
|
try:
|
|
56
61
|
stream = connect_tcp(
|
|
57
62
|
host=self._proxy_host,
|
|
@@ -60,10 +65,9 @@ class SyncProxy:
|
|
|
60
65
|
local_addr=local_addr,
|
|
61
66
|
)
|
|
62
67
|
except OSError as e:
|
|
63
|
-
msg =
|
|
64
|
-
|
|
65
|
-
self._proxy_port
|
|
66
|
-
e.strerror,
|
|
68
|
+
msg = (
|
|
69
|
+
f"Could not connect to proxy "
|
|
70
|
+
f"{self._proxy_host}:{self._proxy_port} [{e.strerror}]"
|
|
67
71
|
)
|
|
68
72
|
raise ProxyConnectionError(e.errno, msg) from e
|
|
69
73
|
else:
|
|
@@ -103,19 +107,24 @@ class SyncProxy:
|
|
|
103
107
|
|
|
104
108
|
except socket.timeout as e:
|
|
105
109
|
stream.close()
|
|
106
|
-
raise ProxyTimeoutError(f
|
|
110
|
+
raise ProxyTimeoutError(f"Proxy connection timed out: {timeout}") from e
|
|
107
111
|
except ReplyError as e:
|
|
108
112
|
stream.close()
|
|
109
|
-
raise ProxyError(e, error_code=e.error_code)
|
|
113
|
+
raise ProxyError(e, error_code=e.error_code) from e
|
|
114
|
+
except IncompleteReadError as e:
|
|
115
|
+
stream.close()
|
|
116
|
+
raise ProxyError(e) from e
|
|
110
117
|
except Exception:
|
|
111
118
|
stream.close()
|
|
112
119
|
raise
|
|
113
120
|
|
|
114
121
|
@classmethod
|
|
115
|
-
def create(
|
|
122
|
+
def create(
|
|
123
|
+
cls, *args: Any, **kwargs: Any
|
|
124
|
+
) -> SyncProxy: # for backward compatibility
|
|
116
125
|
return cls(*args, **kwargs)
|
|
117
126
|
|
|
118
127
|
@classmethod
|
|
119
|
-
def from_url(cls, url: str, **kwargs) ->
|
|
128
|
+
def from_url(cls, url: str, **kwargs: Any) -> SyncProxy:
|
|
120
129
|
url_args = parse_proxy_url(url)
|
|
121
130
|
return cls(*url_args, **kwargs)
|
python_socks/sync/v2/_stream.py
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import socket
|
|
2
4
|
import ssl
|
|
3
5
|
from typing import Union
|
|
4
6
|
|
|
5
|
-
from ._ssl_transport import SSLTransport
|
|
6
|
-
|
|
7
|
-
from ..._errors import ProxyError
|
|
8
7
|
from ... import _abc as abc
|
|
8
|
+
from ..._errors import IncompleteReadError
|
|
9
|
+
from ._ssl_transport import SSLTransport
|
|
9
10
|
|
|
10
11
|
DEFAULT_RECEIVE_SIZE = 65536
|
|
11
12
|
|
|
@@ -13,27 +14,31 @@ SocketType = Union[socket.socket, ssl.SSLSocket, SSLTransport]
|
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
class SyncSocketStream(abc.SyncSocketStream):
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def __init__(self, sock: SocketType):
|
|
17
|
+
def __init__(self, sock: SocketType) -> None:
|
|
19
18
|
self._socket = sock
|
|
20
19
|
|
|
21
|
-
def
|
|
20
|
+
def write(self, data: bytes) -> None:
|
|
22
21
|
self._socket.sendall(data)
|
|
23
22
|
|
|
24
|
-
def read(self, max_bytes=DEFAULT_RECEIVE_SIZE):
|
|
23
|
+
def read(self, max_bytes: int = DEFAULT_RECEIVE_SIZE) -> bytes:
|
|
25
24
|
return self._socket.recv(max_bytes)
|
|
26
25
|
|
|
27
|
-
def
|
|
26
|
+
def read_exactly(self, n: int) -> bytes:
|
|
28
27
|
data = bytearray()
|
|
29
28
|
while len(data) < n:
|
|
30
29
|
packet = self._socket.recv(n - len(data))
|
|
31
30
|
if not packet: # pragma: no cover
|
|
32
|
-
raise
|
|
33
|
-
data
|
|
34
|
-
return data
|
|
31
|
+
raise IncompleteReadError("Connection closed unexpectedly")
|
|
32
|
+
data.extend(packet)
|
|
33
|
+
return data # type:ignore[return-value]
|
|
34
|
+
|
|
35
|
+
def start_tls(
|
|
36
|
+
self,
|
|
37
|
+
hostname: str,
|
|
38
|
+
ssl_context: ssl.SSLContext,
|
|
39
|
+
) -> SyncSocketStream:
|
|
40
|
+
ssl_socket: ssl.SSLSocket | SSLTransport
|
|
35
41
|
|
|
36
|
-
def start_tls(self, hostname: str, ssl_context: ssl.SSLContext) -> 'SyncSocketStream':
|
|
37
42
|
if isinstance(self._socket, (ssl.SSLSocket, SSLTransport)):
|
|
38
43
|
ssl_socket = SSLTransport(
|
|
39
44
|
self._socket,
|
|
@@ -48,7 +53,7 @@ class SyncSocketStream(abc.SyncSocketStream):
|
|
|
48
53
|
|
|
49
54
|
return SyncSocketStream(ssl_socket)
|
|
50
55
|
|
|
51
|
-
def close(self):
|
|
56
|
+
def close(self) -> None:
|
|
52
57
|
self._socket.close()
|
|
53
58
|
|
|
54
59
|
@property
|