python-socks 2.2.0__tar.gz → 2.3.0__tar.gz

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.
Files changed (97) hide show
  1. {python-socks-2.2.0/python_socks.egg-info → python-socks-2.3.0}/PKG-INFO +4 -1
  2. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_version.py +1 -1
  3. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/anyio/v2/_proxy.py +6 -0
  4. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/asyncio/v2/_proxy.py +6 -0
  5. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/trio/v2/_proxy.py +6 -0
  6. {python-socks-2.2.0/python_socks/async_/anyio → python-socks-2.3.0/python_socks/sync}/v2/__init__.py +1 -1
  7. python-socks-2.3.0/python_socks/sync/v2/_chain.py +26 -0
  8. python-socks-2.3.0/python_socks/sync/v2/_connect.py +19 -0
  9. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/sync/v2/_proxy.py +71 -64
  10. {python-socks-2.2.0 → python-socks-2.3.0/python_socks.egg-info}/PKG-INFO +4 -1
  11. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks.egg-info/SOURCES.txt +2 -12
  12. python-socks-2.2.0/python_socks/sync/v2/_chain.py +0 -36
  13. python-socks-2.2.0/tests/test_misc.py +0 -21
  14. python-socks-2.2.0/tests/test_proxy_async_aio.py +0 -212
  15. python-socks-2.2.0/tests/test_proxy_async_aio_v2.py +0 -226
  16. python-socks-2.2.0/tests/test_proxy_async_anyio.py +0 -232
  17. python-socks-2.2.0/tests/test_proxy_async_anyio_v2.py +0 -232
  18. python-socks-2.2.0/tests/test_proxy_async_curio.py +0 -249
  19. python-socks-2.2.0/tests/test_proxy_async_trio.py +0 -214
  20. python-socks-2.2.0/tests/test_proxy_async_trio_v2.py +0 -232
  21. python-socks-2.2.0/tests/test_proxy_sync.py +0 -205
  22. python-socks-2.2.0/tests/test_proxy_sync_v2.py +0 -235
  23. python-socks-2.2.0/tests/test_resolvers.py +0 -99
  24. {python-socks-2.2.0 → python-socks-2.3.0}/LICENSE.txt +0 -0
  25. {python-socks-2.2.0 → python-socks-2.3.0}/MANIFEST.in +0 -0
  26. {python-socks-2.2.0 → python-socks-2.3.0}/README.md +0 -0
  27. {python-socks-2.2.0 → python-socks-2.3.0}/pyproject.toml +0 -0
  28. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/__init__.py +0 -0
  29. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_abc.py +0 -0
  30. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_basic_auth.py +0 -0
  31. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_errors.py +0 -0
  32. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_helpers.py +0 -0
  33. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_proto/__init__.py +0 -0
  34. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_proto/http.py +0 -0
  35. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_proto/http_async.py +0 -0
  36. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_proto/http_sync.py +0 -0
  37. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_proto/socks4.py +0 -0
  38. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_proto/socks4_async.py +0 -0
  39. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_proto/socks4_sync.py +0 -0
  40. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_proto/socks5.py +0 -0
  41. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_proto/socks5_async.py +0 -0
  42. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_proto/socks5_sync.py +0 -0
  43. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_proxy_factory.py +0 -0
  44. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/_types.py +0 -0
  45. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/__init__.py +0 -0
  46. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/_proxy_chain.py +0 -0
  47. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/anyio/__init__.py +0 -0
  48. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/anyio/_chain.py +0 -0
  49. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/anyio/_connect.py +0 -0
  50. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/anyio/_factory.py +0 -0
  51. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/anyio/_proxy.py +0 -0
  52. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/anyio/_resolver.py +0 -0
  53. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/anyio/_stream.py +0 -0
  54. {python-socks-2.2.0/python_socks/async_/trio → python-socks-2.3.0/python_socks/async_/anyio}/v2/__init__.py +0 -0
  55. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/anyio/v2/_chain.py +0 -0
  56. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/anyio/v2/_connect.py +0 -0
  57. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/anyio/v2/_factory.py +0 -0
  58. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/anyio/v2/_stream.py +0 -0
  59. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/asyncio/__init__.py +0 -0
  60. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/asyncio/_connect.py +0 -0
  61. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/asyncio/_proxy.py +0 -0
  62. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/asyncio/_resolver.py +0 -0
  63. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/asyncio/_stream.py +0 -0
  64. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/asyncio/v2/__init__.py +0 -0
  65. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/asyncio/v2/_chain.py +0 -0
  66. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/asyncio/v2/_connect.py +0 -0
  67. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/asyncio/v2/_factory.py +0 -0
  68. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/asyncio/v2/_stream.py +0 -0
  69. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/curio/__init__.py +0 -0
  70. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/curio/_connect.py +0 -0
  71. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/curio/_proxy.py +0 -0
  72. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/curio/_resolver.py +0 -0
  73. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/curio/_stream.py +0 -0
  74. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/trio/__init__.py +0 -0
  75. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/trio/_connect.py +0 -0
  76. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/trio/_proxy.py +0 -0
  77. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/trio/_resolver.py +0 -0
  78. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/trio/_stream.py +0 -0
  79. {python-socks-2.2.0/python_socks/sync → python-socks-2.3.0/python_socks/async_/trio}/v2/__init__.py +0 -0
  80. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/trio/v2/_chain.py +0 -0
  81. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/trio/v2/_connect.py +0 -0
  82. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/trio/v2/_factory.py +0 -0
  83. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/async_/trio/v2/_stream.py +0 -0
  84. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/sync/__init__.py +0 -0
  85. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/sync/_chain.py +0 -0
  86. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/sync/_connect.py +0 -0
  87. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/sync/_proxy.py +0 -0
  88. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/sync/_resolver.py +0 -0
  89. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/sync/_stream.py +0 -0
  90. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/sync/v2/_factory.py +0 -0
  91. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/sync/v2/_ssl_transport.py +0 -0
  92. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks/sync/v2/_stream.py +0 -0
  93. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks.egg-info/dependency_links.txt +0 -0
  94. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks.egg-info/requires.txt +0 -0
  95. {python-socks-2.2.0 → python-socks-2.3.0}/python_socks.egg-info/top_level.txt +0 -0
  96. {python-socks-2.2.0 → python-socks-2.3.0}/setup.cfg +0 -0
  97. {python-socks-2.2.0 → python-socks-2.3.0}/setup.py +0 -0
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-socks
3
- Version: 2.2.0
3
+ Version: 2.3.0
4
4
  Summary: Core proxy (SOCKS4, SOCKS5, HTTP tunneling) functionality for Python
5
5
  Home-page: https://github.com/romis2012/python-socks
6
6
  Author: Roman Snegirev
7
7
  Author-email: snegiryev@gmail.com
8
8
  License: Apache 2
9
9
  Keywords: socks socks5 socks4 http proxy asyncio trio curio anyio
10
+ Platform: UNKNOWN
10
11
  Description-Content-Type: text/markdown
11
12
  Provides-Extra: asyncio
12
13
  Provides-Extra: trio
@@ -267,3 +268,5 @@ manager = ProxyPoolManager('socks5://user:password@127.0.0.1:1080')
267
268
  response = manager.request('GET', 'https://check-host.net/ip')
268
269
  print(response.data)
269
270
  ```
271
+
272
+
@@ -1,2 +1,2 @@
1
1
  __title__ = 'python-socks'
2
- __version__ = '2.2.0'
2
+ __version__ = '2.3.0'
@@ -114,11 +114,13 @@ class Socks5Proxy(AnyioProxy):
114
114
  password=None,
115
115
  rdns=None,
116
116
  proxy_ssl=None,
117
+ forward: 'AnyioProxy' = None,
117
118
  ):
118
119
  super().__init__(
119
120
  proxy_host=proxy_host,
120
121
  proxy_port=proxy_port,
121
122
  proxy_ssl=proxy_ssl,
123
+ forward=forward,
122
124
  )
123
125
  self._username = username
124
126
  self._password = password
@@ -150,11 +152,13 @@ class Socks4Proxy(AnyioProxy):
150
152
  user_id=None,
151
153
  rdns=None,
152
154
  proxy_ssl=None,
155
+ forward: 'AnyioProxy' = None,
153
156
  ):
154
157
  super().__init__(
155
158
  proxy_host=proxy_host,
156
159
  proxy_port=proxy_port,
157
160
  proxy_ssl=proxy_ssl,
161
+ forward=forward,
158
162
  )
159
163
  self._user_id = user_id
160
164
  self._rdns = rdns
@@ -184,11 +188,13 @@ class HttpProxy(AnyioProxy):
184
188
  username=None,
185
189
  password=None,
186
190
  proxy_ssl=None,
191
+ forward: 'AnyioProxy' = None,
187
192
  ):
188
193
  super().__init__(
189
194
  proxy_host=proxy_host,
190
195
  proxy_port=proxy_port,
191
196
  proxy_ssl=proxy_ssl,
197
+ forward=forward,
192
198
  )
193
199
  self._username = username
194
200
  self._password = password
@@ -132,12 +132,14 @@ class Socks5Proxy(AsyncioProxy):
132
132
  password=None,
133
133
  rdns=None,
134
134
  proxy_ssl=None,
135
+ forward: 'AsyncioProxy' = None,
135
136
  loop: asyncio.AbstractEventLoop = None,
136
137
  ):
137
138
  super().__init__(
138
139
  proxy_host=proxy_host,
139
140
  proxy_port=proxy_port,
140
141
  proxy_ssl=proxy_ssl,
142
+ forward=forward,
141
143
  loop=loop,
142
144
  )
143
145
  self._username = username
@@ -170,12 +172,14 @@ class Socks4Proxy(AsyncioProxy):
170
172
  user_id=None,
171
173
  rdns=None,
172
174
  proxy_ssl=None,
175
+ forward: 'AsyncioProxy' = None,
173
176
  loop: asyncio.AbstractEventLoop = None,
174
177
  ):
175
178
  super().__init__(
176
179
  proxy_host=proxy_host,
177
180
  proxy_port=proxy_port,
178
181
  proxy_ssl=proxy_ssl,
182
+ forward=forward,
179
183
  loop=loop,
180
184
  )
181
185
  self._user_id = user_id
@@ -206,12 +210,14 @@ class HttpProxy(AsyncioProxy):
206
210
  username=None,
207
211
  password=None,
208
212
  proxy_ssl=None,
213
+ forward: 'AsyncioProxy' = None,
209
214
  loop: asyncio.AbstractEventLoop = None,
210
215
  ):
211
216
  super().__init__(
212
217
  proxy_host=proxy_host,
213
218
  proxy_port=proxy_port,
214
219
  proxy_ssl=proxy_ssl,
220
+ forward=forward,
215
221
  loop=loop,
216
222
  )
217
223
  self._username = username
@@ -114,11 +114,13 @@ class Socks5Proxy(TrioProxy):
114
114
  password=None,
115
115
  rdns=None,
116
116
  proxy_ssl=None,
117
+ forward: 'TrioProxy' = None,
117
118
  ):
118
119
  super().__init__(
119
120
  proxy_host=proxy_host,
120
121
  proxy_port=proxy_port,
121
122
  proxy_ssl=proxy_ssl,
123
+ forward=forward,
122
124
  )
123
125
  self._username = username
124
126
  self._password = password
@@ -150,11 +152,13 @@ class Socks4Proxy(TrioProxy):
150
152
  user_id=None,
151
153
  rdns=None,
152
154
  proxy_ssl=None,
155
+ forward: 'TrioProxy' = None,
153
156
  ):
154
157
  super().__init__(
155
158
  proxy_host=proxy_host,
156
159
  proxy_port=proxy_port,
157
160
  proxy_ssl=proxy_ssl,
161
+ forward=forward,
158
162
  )
159
163
  self._user_id = user_id
160
164
  self._rdns = rdns
@@ -184,11 +188,13 @@ class HttpProxy(TrioProxy):
184
188
  username=None,
185
189
  password=None,
186
190
  proxy_ssl=None,
191
+ forward: 'TrioProxy' = None,
187
192
  ):
188
193
  super().__init__(
189
194
  proxy_host=proxy_host,
190
195
  proxy_port=proxy_port,
191
196
  proxy_ssl=proxy_ssl,
197
+ forward=forward,
192
198
  )
193
199
  self._username = username
194
200
  self._password = password
@@ -5,4 +5,4 @@ from ._chain import ProxyChain
5
5
  __all__ = (
6
6
  'Proxy',
7
7
  'ProxyChain',
8
- )
8
+ )
@@ -0,0 +1,26 @@
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
+ )
@@ -0,0 +1,19 @@
1
+ import socket
2
+ from typing import Optional, Tuple
3
+ from ._stream import SyncSocketStream
4
+
5
+
6
+ def connect_tcp(
7
+ host: str,
8
+ port: int,
9
+ timeout: float = None,
10
+ local_addr: Optional[Tuple[str, int]] = None,
11
+ ) -> SyncSocketStream:
12
+ address = (host, port)
13
+ sock = socket.create_connection(
14
+ address,
15
+ timeout,
16
+ source_address=local_addr,
17
+ )
18
+
19
+ return SyncSocketStream(sock)
@@ -1,9 +1,8 @@
1
1
  import socket
2
2
  import ssl
3
- from typing import Optional
4
3
 
4
+ from ._connect import connect_tcp
5
5
  from ._stream import SyncSocketStream
6
- from .._connect import connect_tcp
7
6
  from .._resolver import SyncResolver
8
7
  from ... import _abc as abc
9
8
  from ..._errors import ProxyConnectionError, ProxyTimeoutError
@@ -15,24 +14,18 @@ DEFAULT_TIMEOUT = 60
15
14
 
16
15
 
17
16
  class SyncProxy(abc.SyncProxy):
18
- _stream: Optional[SyncSocketStream]
19
-
20
17
  def __init__(
21
18
  self,
22
19
  proxy_host: str,
23
20
  proxy_port: int,
24
21
  proxy_ssl: ssl.SSLContext = None,
22
+ forward: 'SyncProxy' = None,
25
23
  ):
26
24
  self._proxy_host = proxy_host
27
25
  self._proxy_port = proxy_port
28
26
  self._proxy_ssl = proxy_ssl
27
+ self._forward = forward
29
28
 
30
- self._dest_host = None
31
- self._dest_port = None
32
- self._dest_ssl = None
33
- self._timeout = None
34
-
35
- self._stream = None
36
29
  self._resolver = SyncResolver()
37
30
 
38
31
  def connect(
@@ -41,74 +34,67 @@ class SyncProxy(abc.SyncProxy):
41
34
  dest_port: int,
42
35
  dest_ssl: ssl.SSLContext = None,
43
36
  timeout: float = None,
44
- _stream: SyncSocketStream = None,
45
37
  ) -> SyncSocketStream:
46
-
47
38
  if timeout is None:
48
39
  timeout = DEFAULT_TIMEOUT
49
40
 
50
- self._dest_host = dest_host
51
- self._dest_port = dest_port
52
- self._dest_ssl = dest_ssl
53
- self._timeout = timeout
54
-
55
41
  try:
56
- if _stream is None:
57
- sock = connect_tcp(
42
+ if self._forward is None:
43
+ stream = connect_tcp(
58
44
  host=self._proxy_host,
59
45
  port=self._proxy_port,
60
46
  timeout=timeout,
61
47
  )
62
- self._stream = SyncSocketStream(sock)
63
48
  else:
64
- self._stream = _stream
49
+ stream = self._forward.connect(
50
+ dest_host=self._proxy_host,
51
+ dest_port=self._proxy_port,
52
+ timeout=timeout,
53
+ )
54
+ except OSError as e:
55
+ msg = 'Could not connect to proxy {}:{} [{}]'.format(
56
+ self._proxy_host,
57
+ self._proxy_port,
58
+ e.strerror,
59
+ )
60
+ raise ProxyConnectionError(e.errno, msg) from e
65
61
 
62
+ try:
66
63
  if self._proxy_ssl is not None:
67
- self._stream = self._stream.start_tls(
64
+ stream = stream.start_tls(
68
65
  hostname=self._proxy_host,
69
66
  ssl_context=self._proxy_ssl,
70
67
  )
71
68
 
72
- self._negotiate()
69
+ self._negotiate(
70
+ stream=stream,
71
+ dest_host=dest_host,
72
+ dest_port=dest_port,
73
+ )
73
74
 
74
- if self._dest_ssl is not None:
75
- self._stream = self._stream.start_tls(
76
- hostname=self._dest_host,
77
- ssl_context=self._dest_ssl,
75
+ if dest_ssl is not None:
76
+ stream = stream.start_tls(
77
+ hostname=dest_host,
78
+ ssl_context=dest_ssl,
78
79
  )
79
80
 
80
- return self._stream
81
+ return stream
81
82
 
82
83
  except socket.timeout as e:
83
- self._close()
84
- raise ProxyTimeoutError('Proxy connection timed out: {}'.format(self._timeout)) from e
85
- except OSError as e:
86
- self._close()
87
- msg = 'Could not connect to proxy {}:{} [{}]'.format(
88
- self._proxy_host,
89
- self._proxy_port,
90
- e.strerror,
91
- )
92
- raise ProxyConnectionError(e.errno, msg) from e
84
+ stream.close()
85
+ raise ProxyTimeoutError('Proxy connection timed out: {}'.format(timeout)) from e
93
86
  except Exception:
94
- self._close()
87
+ stream.close()
95
88
  raise
96
89
 
97
- def _negotiate(self):
90
+ def _negotiate(
91
+ self,
92
+ stream: SyncSocketStream,
93
+ dest_host: str,
94
+ dest_port: int,
95
+ ):
98
96
  raise NotImplementedError
99
97
 
100
- def _close(self):
101
- if self._stream is not None:
102
- self._stream.close()
103
-
104
- @property
105
- def proxy_host(self):
106
- return self._proxy_host
107
-
108
- @property
109
- def proxy_port(self):
110
- return self._proxy_port
111
-
112
98
 
113
99
  class Socks5Proxy(SyncProxy):
114
100
  def __init__(
@@ -119,22 +105,29 @@ class Socks5Proxy(SyncProxy):
119
105
  password=None,
120
106
  rdns=None,
121
107
  proxy_ssl=None,
108
+ forward: 'SyncProxy' = None,
122
109
  ):
123
110
  super().__init__(
124
111
  proxy_host=proxy_host,
125
112
  proxy_port=proxy_port,
126
113
  proxy_ssl=proxy_ssl,
114
+ forward=forward,
127
115
  )
128
116
  self._username = username
129
117
  self._password = password
130
118
  self._rdns = rdns
131
119
 
132
- def _negotiate(self):
120
+ def _negotiate(
121
+ self,
122
+ stream: SyncSocketStream,
123
+ dest_host: str,
124
+ dest_port: int,
125
+ ):
133
126
  proto = Socks5Proto(
134
- stream=self._stream,
127
+ stream=stream,
135
128
  resolver=self._resolver,
136
- dest_host=self._dest_host,
137
- dest_port=self._dest_port,
129
+ dest_host=dest_host,
130
+ dest_port=dest_port,
138
131
  username=self._username,
139
132
  password=self._password,
140
133
  rdns=self._rdns,
@@ -150,21 +143,28 @@ class Socks4Proxy(SyncProxy):
150
143
  user_id=None,
151
144
  rdns=None,
152
145
  proxy_ssl=None,
146
+ forward: 'SyncProxy' = None,
153
147
  ):
154
148
  super().__init__(
155
149
  proxy_host=proxy_host,
156
150
  proxy_port=proxy_port,
157
151
  proxy_ssl=proxy_ssl,
152
+ forward=forward,
158
153
  )
159
154
  self._user_id = user_id
160
155
  self._rdns = rdns
161
156
 
162
- def _negotiate(self):
157
+ def _negotiate(
158
+ self,
159
+ stream: SyncSocketStream,
160
+ dest_host: str,
161
+ dest_port: int,
162
+ ):
163
163
  proto = Socks4Proto(
164
- stream=self._stream,
164
+ stream=stream,
165
165
  resolver=self._resolver,
166
- dest_host=self._dest_host,
167
- dest_port=self._dest_port,
166
+ dest_host=dest_host,
167
+ dest_port=dest_port,
168
168
  user_id=self._user_id,
169
169
  rdns=self._rdns,
170
170
  )
@@ -179,20 +179,27 @@ class HttpProxy(SyncProxy):
179
179
  username=None,
180
180
  password=None,
181
181
  proxy_ssl=None,
182
+ forward: 'SyncProxy' = None,
182
183
  ):
183
184
  super().__init__(
184
185
  proxy_host=proxy_host,
185
186
  proxy_port=proxy_port,
186
187
  proxy_ssl=proxy_ssl,
188
+ forward=forward,
187
189
  )
188
190
  self._username = username
189
191
  self._password = password
190
192
 
191
- def _negotiate(self):
193
+ def _negotiate(
194
+ self,
195
+ stream: SyncSocketStream,
196
+ dest_host: str,
197
+ dest_port: int,
198
+ ):
192
199
  proto = HttpProto(
193
- stream=self._stream,
194
- dest_host=self._dest_host,
195
- dest_port=self._dest_port,
200
+ stream=stream,
201
+ dest_host=dest_host,
202
+ dest_port=dest_port,
196
203
  username=self._username,
197
204
  password=self._password,
198
205
  )
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-socks
3
- Version: 2.2.0
3
+ Version: 2.3.0
4
4
  Summary: Core proxy (SOCKS4, SOCKS5, HTTP tunneling) functionality for Python
5
5
  Home-page: https://github.com/romis2012/python-socks
6
6
  Author: Roman Snegirev
7
7
  Author-email: snegiryev@gmail.com
8
8
  License: Apache 2
9
9
  Keywords: socks socks5 socks4 http proxy asyncio trio curio anyio
10
+ Platform: UNKNOWN
10
11
  Description-Content-Type: text/markdown
11
12
  Provides-Extra: asyncio
12
13
  Provides-Extra: trio
@@ -267,3 +268,5 @@ manager = ProxyPoolManager('socks5://user:password@127.0.0.1:1080')
267
268
  response = manager.request('GET', 'https://check-host.net/ip')
268
269
  print(response.data)
269
270
  ```
271
+
272
+
@@ -76,18 +76,8 @@ python_socks/sync/_resolver.py
76
76
  python_socks/sync/_stream.py
77
77
  python_socks/sync/v2/__init__.py
78
78
  python_socks/sync/v2/_chain.py
79
+ python_socks/sync/v2/_connect.py
79
80
  python_socks/sync/v2/_factory.py
80
81
  python_socks/sync/v2/_proxy.py
81
82
  python_socks/sync/v2/_ssl_transport.py
82
- python_socks/sync/v2/_stream.py
83
- tests/test_misc.py
84
- tests/test_proxy_async_aio.py
85
- tests/test_proxy_async_aio_v2.py
86
- tests/test_proxy_async_anyio.py
87
- tests/test_proxy_async_anyio_v2.py
88
- tests/test_proxy_async_curio.py
89
- tests/test_proxy_async_trio.py
90
- tests/test_proxy_async_trio_v2.py
91
- tests/test_proxy_sync.py
92
- tests/test_proxy_sync_v2.py
93
- tests/test_resolvers.py
83
+ python_socks/sync/v2/_stream.py
@@ -1,36 +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
- stream = None
17
- proxies = list(self._proxies)
18
-
19
- length = len(proxies) - 1
20
- for i in range(length):
21
- stream = proxies[i].connect(
22
- dest_host=proxies[i + 1].proxy_host,
23
- dest_port=proxies[i + 1].proxy_port,
24
- timeout=timeout,
25
- _stream=stream,
26
- )
27
-
28
- stream = proxies[length].connect(
29
- dest_host=dest_host,
30
- dest_port=dest_port,
31
- dest_ssl=dest_ssl,
32
- timeout=timeout,
33
- _stream=stream,
34
- )
35
-
36
- return stream
@@ -1,21 +0,0 @@
1
- # noinspection PyPackageRequirements
2
- import pytest
3
-
4
- from python_socks._helpers import is_ip_address # noqa
5
- from python_socks._basic_auth import BasicAuth # noqa
6
-
7
-
8
- @pytest.mark.parametrize('address', ('::1', b'::1', '127.0.0.1', b'127.0.0.1'))
9
- def test_is_ip_address(address):
10
- assert is_ip_address(address)
11
-
12
-
13
- def test_basic_auth():
14
- login = 'login'
15
- password = 'password'
16
-
17
- auth1 = BasicAuth(login=login, password=password)
18
- auth2 = BasicAuth.decode(auth1.encode())
19
-
20
- assert auth2.login == login
21
- assert auth2.password == password