python-socks 2.8.1__tar.gz → 3.0.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.
- python_socks-3.0.0/PKG-INFO +346 -0
- python_socks-3.0.0/README.md +309 -0
- python_socks-3.0.0/pyproject.toml +128 -0
- python_socks-3.0.0/python_socks/__init__.py +18 -0
- python_socks-3.0.0/python_socks/_abc.py +53 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/_connectors/abc.py +5 -3
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/_connectors/factory_async.py +8 -8
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/_connectors/factory_sync.py +8 -8
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/_connectors/http_async.py +7 -7
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/_connectors/http_sync.py +7 -7
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/_connectors/socks4_async.py +10 -10
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/_connectors/socks4_sync.py +10 -10
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/_connectors/socks5_async.py +29 -26
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/_connectors/socks5_sync.py +36 -28
- python_socks-3.0.0/python_socks/_errors.py +29 -0
- python_socks-3.0.0/python_socks/_helpers.py +84 -0
- python_socks-3.0.0/python_socks/_protocols/errors.py +13 -0
- python_socks-3.0.0/python_socks/_protocols/http.py +153 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/_protocols/socks4.py +22 -26
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/_protocols/socks5.py +95 -81
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/_types.py +4 -0
- python_socks-3.0.0/python_socks/_version.py +2 -0
- python_socks-3.0.0/python_socks/async_/anyio/__init__.py +3 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/anyio/_connect.py +6 -4
- python_socks-3.0.0/python_socks/async_/anyio/_proxy.py +130 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/anyio/_resolver.py +10 -3
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/anyio/_stream.py +11 -26
- python_socks-3.0.0/python_socks/async_/anyio/v2/__init__.py +3 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/anyio/v2/_connect.py +7 -4
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/anyio/v2/_proxy.py +36 -26
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/anyio/v2/_stream.py +11 -11
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/asyncio/__init__.py +1 -2
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/asyncio/_connect.py +12 -7
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/asyncio/_proxy.py +48 -49
- python_socks-3.0.0/python_socks/async_/asyncio/_resolver.py +32 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/asyncio/_stream.py +9 -13
- python_socks-3.0.0/python_socks/async_/asyncio/v2/__init__.py +3 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/asyncio/v2/_connect.py +8 -5
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/asyncio/v2/_proxy.py +38 -28
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/asyncio/v2/_stream.py +16 -18
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/trio/__init__.py +1 -1
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/trio/_connect.py +5 -4
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/trio/_proxy.py +46 -48
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/trio/_resolver.py +11 -3
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/trio/_stream.py +9 -9
- python_socks-3.0.0/python_socks/async_/trio/v2/__init__.py +3 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/trio/v2/_connect.py +3 -2
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/trio/v2/_proxy.py +34 -24
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/async_/trio/v2/_stream.py +13 -13
- python_socks-3.0.0/python_socks/py.typed +0 -0
- python_socks-3.0.0/python_socks/sync/__init__.py +3 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/sync/_connect.py +4 -3
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/sync/_proxy.py +42 -43
- python_socks-3.0.0/python_socks/sync/_resolver.py +28 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/sync/_stream.py +9 -9
- python_socks-3.0.0/python_socks/sync/v2/__init__.py +3 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/sync/v2/_connect.py +5 -3
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/sync/v2/_proxy.py +35 -26
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/sync/v2/_ssl_transport.py +3 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/sync/v2/_stream.py +19 -14
- python_socks-3.0.0/python_socks.egg-info/PKG-INFO +346 -0
- python_socks-3.0.0/python_socks.egg-info/SOURCES.txt +208 -0
- python_socks-3.0.0/python_socks.egg-info/requires.txt +11 -0
- python_socks-3.0.0/tests/__init__.py +0 -0
- python_socks-3.0.0/tests/__pycache__/__init__.cpython-310.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/__init__.cpython-311.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/__init__.cpython-312.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/__init__.cpython-313.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/__init__.cpython-314.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/__init__.cpython-39.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/config.cpython-310.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/config.cpython-311.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/config.cpython-312.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/config.cpython-313.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/config.cpython-314.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/config.cpython-39.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/conftest.cpython-310-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/conftest.cpython-311-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/conftest.cpython-312-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/conftest.cpython-313-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/conftest.cpython-314-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/conftest.cpython-39-pytest-8.4.2.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_app.cpython-310.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_app.cpython-311.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_app.cpython-312.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_app.cpython-313.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_app.cpython-314.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_app.cpython-39.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_app2.cpython-314.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_app2.cpython-39.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_server.cpython-310.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_server.cpython-311.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_server.cpython-312.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_server.cpython-313.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_server.cpython-314.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_server.cpython-39.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_server2.cpython-314.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/http_server2.cpython-39.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/mocks.cpython-310.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/mocks.cpython-311.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/mocks.cpython-312.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/mocks.cpython-313.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/mocks.cpython-314.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/mocks.cpython-39.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/patches.cpython-310.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/patches.cpython-311.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/patches.cpython-312.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/patches.cpython-313.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/patches.cpython-314.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/patches.cpython-39.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/proxy_server.cpython-310.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/proxy_server.cpython-311.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/proxy_server.cpython-312.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/proxy_server.cpython-313.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/proxy_server.cpython-314.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/proxy_server.cpython-39.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/proxy_server2.cpython-314.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/proxy_server2.cpython-39.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_misc.cpython-310-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_misc.cpython-311-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_misc.cpython-312-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_misc.cpython-313-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_misc.cpython-314-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_misc.cpython-39-pytest-8.4.2.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_aio.cpython-310-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_aio.cpython-311-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_aio.cpython-312-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_aio.cpython-313-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_aio.cpython-314-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_aio.cpython-39-pytest-8.4.2.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_aio_v2.cpython-310-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_aio_v2.cpython-311-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_aio_v2.cpython-312-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_aio_v2.cpython-313-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_aio_v2.cpython-314-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_aio_v2.cpython-39-pytest-8.4.2.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_anyio.cpython-310-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_anyio.cpython-311-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_anyio.cpython-312-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_anyio.cpython-313-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_anyio.cpython-314-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_anyio.cpython-39-pytest-8.4.2.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_anyio_v2.cpython-310-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_anyio_v2.cpython-311-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_anyio_v2.cpython-312-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_anyio_v2.cpython-313-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_anyio_v2.cpython-314-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_anyio_v2.cpython-39-pytest-8.4.2.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_trio.cpython-310-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_trio.cpython-311-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_trio.cpython-312-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_trio.cpython-313-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_trio.cpython-314-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_trio.cpython-39-pytest-8.4.2.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_trio_v2.cpython-310-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_trio_v2.cpython-311-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_trio_v2.cpython-312-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_trio_v2.cpython-313-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_trio_v2.cpython-314-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_async_trio_v2.cpython-39-pytest-8.4.2.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_sync.cpython-310-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_sync.cpython-311-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_sync.cpython-312-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_sync.cpython-313-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_sync.cpython-314-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_sync.cpython-39-pytest-8.4.2.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_sync_v2.cpython-310-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_sync_v2.cpython-311-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_sync_v2.cpython-312-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_sync_v2.cpython-313-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_sync_v2.cpython-314-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_proxy_sync_v2.cpython-39-pytest-8.4.2.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_resolvers.cpython-310-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_resolvers.cpython-311-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_resolvers.cpython-312-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_resolvers.cpython-313-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_resolvers.cpython-314-pytest-9.1.1.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/test_resolvers.cpython-39-pytest-8.4.2.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/utils.cpython-310.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/utils.cpython-311.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/utils.cpython-312.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/utils.cpython-313.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/utils.cpython-314.pyc +0 -0
- python_socks-3.0.0/tests/__pycache__/utils.cpython-39.pyc +0 -0
- python_socks-3.0.0/tests/config.py +54 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/tests/conftest.py +68 -73
- python_socks-3.0.0/tests/http_app.py +25 -0
- python_socks-3.0.0/tests/http_server.py +47 -0
- python_socks-3.0.0/tests/mocks.py +131 -0
- python_socks-3.0.0/tests/patches.py +58 -0
- python_socks-3.0.0/tests/proxy_server.py +131 -0
- python_socks-3.0.0/tests/test_misc.py +58 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/tests/test_proxy_async_aio.py +75 -53
- {python_socks-2.8.1 → python_socks-3.0.0}/tests/test_proxy_async_aio_v2.py +87 -69
- {python_socks-2.8.1 → python_socks-3.0.0}/tests/test_proxy_async_anyio.py +95 -80
- {python_socks-2.8.1 → python_socks-3.0.0}/tests/test_proxy_async_anyio_v2.py +90 -68
- {python_socks-2.8.1 → python_socks-3.0.0}/tests/test_proxy_async_trio.py +82 -60
- {python_socks-2.8.1 → python_socks-3.0.0}/tests/test_proxy_async_trio_v2.py +90 -70
- {python_socks-2.8.1 → python_socks-3.0.0}/tests/test_proxy_sync.py +77 -66
- {python_socks-2.8.1 → python_socks-3.0.0}/tests/test_proxy_sync_v2.py +81 -76
- python_socks-3.0.0/tests/test_resolvers.py +84 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/tests/utils.py +6 -5
- python_socks-2.8.1/PKG-INFO +0 -295
- python_socks-2.8.1/README.md +0 -254
- python_socks-2.8.1/pyproject.toml +0 -70
- python_socks-2.8.1/python_socks/__init__.py +0 -20
- python_socks-2.8.1/python_socks/_abc.py +0 -40
- python_socks-2.8.1/python_socks/_errors.py +0 -16
- python_socks-2.8.1/python_socks/_helpers.py +0 -81
- python_socks-2.8.1/python_socks/_protocols/errors.py +0 -4
- python_socks-2.8.1/python_socks/_protocols/http.py +0 -148
- python_socks-2.8.1/python_socks/_version.py +0 -2
- python_socks-2.8.1/python_socks/async_/__init__.py +0 -3
- python_socks-2.8.1/python_socks/async_/_proxy_chain.py +0 -34
- python_socks-2.8.1/python_socks/async_/anyio/__init__.py +0 -4
- python_socks-2.8.1/python_socks/async_/anyio/_chain.py +0 -42
- python_socks-2.8.1/python_socks/async_/anyio/_proxy.py +0 -137
- python_socks-2.8.1/python_socks/async_/anyio/v2/__init__.py +0 -7
- python_socks-2.8.1/python_socks/async_/anyio/v2/_chain.py +0 -32
- python_socks-2.8.1/python_socks/async_/asyncio/_resolver.py +0 -25
- python_socks-2.8.1/python_socks/async_/asyncio/v2/__init__.py +0 -4
- python_socks-2.8.1/python_socks/async_/asyncio/v2/_chain.py +0 -32
- python_socks-2.8.1/python_socks/async_/curio/__init__.py +0 -4
- python_socks-2.8.1/python_socks/async_/curio/_connect.py +0 -17
- python_socks-2.8.1/python_socks/async_/curio/_proxy.py +0 -132
- python_socks-2.8.1/python_socks/async_/curio/_resolver.py +0 -25
- python_socks-2.8.1/python_socks/async_/curio/_stream.py +0 -32
- python_socks-2.8.1/python_socks/async_/trio/v2/__init__.py +0 -7
- python_socks-2.8.1/python_socks/async_/trio/v2/_chain.py +0 -32
- python_socks-2.8.1/python_socks/sync/__init__.py +0 -5
- python_socks-2.8.1/python_socks/sync/_chain.py +0 -32
- python_socks-2.8.1/python_socks/sync/_resolver.py +0 -16
- python_socks-2.8.1/python_socks/sync/v2/__init__.py +0 -7
- python_socks-2.8.1/python_socks/sync/v2/_chain.py +0 -26
- python_socks-2.8.1/python_socks.egg-info/PKG-INFO +0 -295
- python_socks-2.8.1/python_socks.egg-info/SOURCES.txt +0 -100
- python_socks-2.8.1/python_socks.egg-info/requires.txt +0 -14
- python_socks-2.8.1/tests/__init__.py +0 -1
- python_socks-2.8.1/tests/config.py +0 -90
- python_socks-2.8.1/tests/http_app.py +0 -22
- python_socks-2.8.1/tests/http_server.py +0 -51
- python_socks-2.8.1/tests/mocks.py +0 -81
- python_socks-2.8.1/tests/proxy_server.py +0 -135
- python_socks-2.8.1/tests/test_misc.py +0 -21
- python_socks-2.8.1/tests/test_proxy_async_curio.py +0 -249
- python_socks-2.8.1/tests/test_resolvers.py +0 -99
- {python_socks-2.8.1 → python_socks-3.0.0}/LICENSE.txt +0 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/MANIFEST.in +0 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/_connectors/__init__.py +0 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks/_protocols/__init__.py +0 -0
- /python_socks-2.8.1/python_socks/py.typed → /python_socks-3.0.0/python_socks/async_/__init__.py +0 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks.egg-info/dependency_links.txt +0 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/python_socks.egg-info/top_level.txt +0 -0
- {python_socks-2.8.1 → python_socks-3.0.0}/setup.cfg +0 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-socks
|
|
3
|
+
Version: 3.0.0
|
|
4
|
+
Summary: Proxy (SOCKS4, SOCKS5, HTTP CONNECT) client for Python
|
|
5
|
+
Author-email: Roman Snegirev <snegiryev@gmail.com>
|
|
6
|
+
License-Expression: 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,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.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
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
|
+
Requires-Python: >=3.9.0
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE.txt
|
|
30
|
+
Provides-Extra: asyncio
|
|
31
|
+
Requires-Dist: async-timeout>=5.0.1; python_version < "3.11" and extra == "asyncio"
|
|
32
|
+
Provides-Extra: trio
|
|
33
|
+
Requires-Dist: trio>=0.30.0; extra == "trio"
|
|
34
|
+
Provides-Extra: anyio
|
|
35
|
+
Requires-Dist: anyio<5.0.0,>=4.12.1; extra == "anyio"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
## python-socks
|
|
39
|
+
|
|
40
|
+
[](https://github.com/romis2012/python-socks/actions/workflows/ci.yml)
|
|
41
|
+
[](https://codecov.io/gh/romis2012/python-socks)
|
|
42
|
+
[](https://pypi.python.org/pypi/python-socks)
|
|
43
|
+
[](https://github.com/romis2012/python-socks)
|
|
44
|
+
<!--
|
|
45
|
+
[](https://pepy.tech/project/python-socks)
|
|
46
|
+
-->
|
|
47
|
+
|
|
48
|
+
The `python-socks` package provides a core proxy client functionality for Python.
|
|
49
|
+
Supports `SOCKS4(a)`, `SOCKS5(h)`, `HTTP CONNECT` proxy and provides sync and async (asyncio, trio, anyio) APIs.
|
|
50
|
+
You probably don't need to use `python-socks` directly.
|
|
51
|
+
It is used internally by
|
|
52
|
+
[aiohttp-socks](https://github.com/romis2012/aiohttp-socks) and [httpx-socks](https://github.com/romis2012/httpx-socks) packages.
|
|
53
|
+
|
|
54
|
+
## Requirements
|
|
55
|
+
- Python >= 3.9
|
|
56
|
+
- async-timeout >= 5.0 (optional)
|
|
57
|
+
- trio >= 0.30 (optional)
|
|
58
|
+
- anyio >= 4.12 (optional)
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
only sync proxy support:
|
|
63
|
+
```
|
|
64
|
+
pip install python-socks
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
to include optional asyncio support:
|
|
68
|
+
```
|
|
69
|
+
pip install python-socks[asyncio]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
to include optional trio support:
|
|
73
|
+
```
|
|
74
|
+
pip install python-socks[trio]
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
to include optional anyio support:
|
|
78
|
+
```
|
|
79
|
+
pip install python-socks[anyio]
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Simple usage
|
|
83
|
+
We are making secure HTTP GET request via SOCKS5 proxy
|
|
84
|
+
|
|
85
|
+
#### Sync
|
|
86
|
+
```python
|
|
87
|
+
import ssl
|
|
88
|
+
from python_socks.sync import Proxy
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def fetch():
|
|
92
|
+
proxy = Proxy.from_url("socks5://user:password@127.0.0.1:1080")
|
|
93
|
+
|
|
94
|
+
# `connect` returns standard Python socket in blocking mode
|
|
95
|
+
sock = proxy.connect(
|
|
96
|
+
dest_host="check-host.net",
|
|
97
|
+
dest_port=443,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
sock = ssl.create_default_context().wrap_socket(
|
|
101
|
+
sock=sock,
|
|
102
|
+
server_hostname="check-host.net",
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
# fmt: off
|
|
106
|
+
request = (
|
|
107
|
+
b"GET /ip HTTP/1.1\r\n"
|
|
108
|
+
b"Host: check-host.net\r\n"
|
|
109
|
+
b"Connection: close\r\n\r\n"
|
|
110
|
+
)
|
|
111
|
+
# fmt: on
|
|
112
|
+
|
|
113
|
+
sock.sendall(request)
|
|
114
|
+
response = sock.recv(4096)
|
|
115
|
+
print(response)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
fetch()
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### Async (asyncio)
|
|
122
|
+
```python
|
|
123
|
+
import asyncio
|
|
124
|
+
import ssl
|
|
125
|
+
from python_socks.async_.asyncio import Proxy
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
async def fetch():
|
|
129
|
+
proxy = Proxy.from_url("socks5://user:password@127.0.0.1:1080")
|
|
130
|
+
|
|
131
|
+
# `connect` returns standard Python socket in non-blocking mode
|
|
132
|
+
# so we can pass it to asyncio.open_connection(...)
|
|
133
|
+
sock = await proxy.connect(
|
|
134
|
+
dest_host="check-host.net",
|
|
135
|
+
dest_port=443,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
reader, writer = await asyncio.open_connection(
|
|
139
|
+
sock=sock,
|
|
140
|
+
ssl=ssl.create_default_context(),
|
|
141
|
+
server_hostname="check-host.net",
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
# fmt: off
|
|
145
|
+
request = (
|
|
146
|
+
b"GET /ip HTTP/1.1\r\n"
|
|
147
|
+
b"Host: check-host.net\r\n"
|
|
148
|
+
b"Connection: close\r\n\r\n"
|
|
149
|
+
)
|
|
150
|
+
# fmt: on
|
|
151
|
+
|
|
152
|
+
writer.write(request)
|
|
153
|
+
response = await reader.read(-1)
|
|
154
|
+
print(response)
|
|
155
|
+
|
|
156
|
+
writer.close()
|
|
157
|
+
await writer.wait_closed()
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
asyncio.run(fetch())
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### Async (trio)
|
|
164
|
+
```python
|
|
165
|
+
import ssl
|
|
166
|
+
import trio
|
|
167
|
+
from python_socks.async_.trio import Proxy
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
async def fetch():
|
|
171
|
+
proxy = Proxy.from_url("socks5://user:password@127.0.0.1:1080")
|
|
172
|
+
|
|
173
|
+
# `connect` returns trio.socket.SocketType
|
|
174
|
+
# so we can pass it to trio.SocketStream
|
|
175
|
+
sock = await proxy.connect(
|
|
176
|
+
dest_host="check-host.net",
|
|
177
|
+
dest_port=443,
|
|
178
|
+
)
|
|
179
|
+
stream = trio.SocketStream(sock)
|
|
180
|
+
stream = trio.SSLStream(
|
|
181
|
+
stream,
|
|
182
|
+
ssl_context=ssl.create_default_context(),
|
|
183
|
+
server_hostname="check-host.net",
|
|
184
|
+
)
|
|
185
|
+
await stream.do_handshake()
|
|
186
|
+
|
|
187
|
+
# fmt: off
|
|
188
|
+
request = (
|
|
189
|
+
b"GET /ip HTTP/1.1\r\n"
|
|
190
|
+
b"Host: check-host.net\r\n"
|
|
191
|
+
b"Connection: close\r\n\r\n"
|
|
192
|
+
)
|
|
193
|
+
# fmt: on
|
|
194
|
+
|
|
195
|
+
await stream.send_all(request)
|
|
196
|
+
response = await stream.receive_some(4096)
|
|
197
|
+
print(response)
|
|
198
|
+
|
|
199
|
+
await stream.aclose()
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
trio.run(fetch)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
#### Async (anyio)
|
|
206
|
+
```python
|
|
207
|
+
import ssl
|
|
208
|
+
import anyio
|
|
209
|
+
from anyio.streams.tls import TLSStream
|
|
210
|
+
from python_socks.async_.anyio import Proxy
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
async def fetch():
|
|
214
|
+
proxy = Proxy.from_url("socks5://user:password@127.0.0.1:1080")
|
|
215
|
+
|
|
216
|
+
# `connect` returns anyio.abc.SocketStream
|
|
217
|
+
# we can use it directly
|
|
218
|
+
stream = await proxy.connect(
|
|
219
|
+
dest_host="check-host.net",
|
|
220
|
+
dest_port=443,
|
|
221
|
+
)
|
|
222
|
+
stream = await TLSStream.wrap(
|
|
223
|
+
stream,
|
|
224
|
+
ssl_context=ssl.create_default_context(),
|
|
225
|
+
hostname="check-host.net",
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
# fmt: off
|
|
229
|
+
request = (
|
|
230
|
+
b"GET /ip HTTP/1.1\r\n"
|
|
231
|
+
b"Host: check-host.net\r\n"
|
|
232
|
+
b"Connection: close\r\n\r\n"
|
|
233
|
+
)
|
|
234
|
+
# fmt: on
|
|
235
|
+
|
|
236
|
+
await stream.send(request)
|
|
237
|
+
response = await stream.receive(4096)
|
|
238
|
+
print(response)
|
|
239
|
+
|
|
240
|
+
await stream.aclose()
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
anyio.run(fetch)
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## More complex example
|
|
247
|
+
|
|
248
|
+
#### A urllib3 PoolManager that routes connections via the proxy
|
|
249
|
+
|
|
250
|
+
```python
|
|
251
|
+
from urllib3 import PoolManager, HTTPConnectionPool, HTTPSConnectionPool
|
|
252
|
+
from urllib3.connection import HTTPConnection, HTTPSConnection
|
|
253
|
+
from python_socks.sync import Proxy
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class ProxyHTTPConnection(HTTPConnection):
|
|
257
|
+
def __init__(self, *args, **kwargs):
|
|
258
|
+
socks_options = kwargs.pop("_socks_options")
|
|
259
|
+
self._proxy_url = socks_options["proxy_url"]
|
|
260
|
+
super().__init__(*args, **kwargs)
|
|
261
|
+
|
|
262
|
+
def _new_conn(self):
|
|
263
|
+
proxy = Proxy.from_url(self._proxy_url)
|
|
264
|
+
return proxy.connect(
|
|
265
|
+
dest_host=self.host,
|
|
266
|
+
dest_port=self.port,
|
|
267
|
+
timeout=self.timeout,
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
class ProxyHTTPSConnection(ProxyHTTPConnection, HTTPSConnection):
|
|
272
|
+
pass
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
class ProxyHTTPConnectionPool(HTTPConnectionPool):
|
|
276
|
+
ConnectionCls = ProxyHTTPConnection
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
class ProxyHTTPSConnectionPool(HTTPSConnectionPool):
|
|
280
|
+
ConnectionCls = ProxyHTTPSConnection
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
class ProxyPoolManager(PoolManager):
|
|
284
|
+
def __init__(
|
|
285
|
+
self,
|
|
286
|
+
proxy_url,
|
|
287
|
+
timeout=5,
|
|
288
|
+
num_pools=10,
|
|
289
|
+
headers=None,
|
|
290
|
+
**connection_pool_kw,
|
|
291
|
+
):
|
|
292
|
+
|
|
293
|
+
connection_pool_kw["_socks_options"] = {"proxy_url": proxy_url}
|
|
294
|
+
connection_pool_kw["timeout"] = timeout
|
|
295
|
+
|
|
296
|
+
super().__init__(num_pools, headers, **connection_pool_kw)
|
|
297
|
+
|
|
298
|
+
self.pool_classes_by_scheme = {
|
|
299
|
+
"http": ProxyHTTPConnectionPool,
|
|
300
|
+
"https": ProxyHTTPSConnectionPool,
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
### and how to use it
|
|
305
|
+
manager = ProxyPoolManager("socks5://user:password@127.0.0.1:1080")
|
|
306
|
+
response = manager.request("GET", "https://check-host.net/ip")
|
|
307
|
+
print(response.data)
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Proxy Chaining (sync example — same for asyncio, trio, anyio)
|
|
311
|
+
|
|
312
|
+
```python
|
|
313
|
+
import ssl
|
|
314
|
+
from python_socks.sync import Proxy
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def fetch():
|
|
318
|
+
proxy1 = Proxy.from_url("socks5://user:password@127.0.0.1:1080")
|
|
319
|
+
proxy2 = Proxy.from_url("socks4://127.0.0.1:1081", forward=proxy1)
|
|
320
|
+
proxy3 = Proxy.from_url("http://user:password@127.0.0.1:1082", forward=proxy2)
|
|
321
|
+
|
|
322
|
+
sock = proxy3.connect(
|
|
323
|
+
dest_host="check-host.net",
|
|
324
|
+
dest_port=443,
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
sock = ssl.create_default_context().wrap_socket(
|
|
328
|
+
sock=sock,
|
|
329
|
+
server_hostname="check-host.net",
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
# fmt: off
|
|
333
|
+
request = (
|
|
334
|
+
b"GET /ip HTTP/1.1\r\n"
|
|
335
|
+
b"Host: check-host.net\r\n"
|
|
336
|
+
b"Connection: close\r\n\r\n"
|
|
337
|
+
)
|
|
338
|
+
# fmt: on
|
|
339
|
+
|
|
340
|
+
sock.sendall(request)
|
|
341
|
+
response = sock.recv(4096)
|
|
342
|
+
print(response)
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
fetch()
|
|
346
|
+
```
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
## python-socks
|
|
2
|
+
|
|
3
|
+
[](https://github.com/romis2012/python-socks/actions/workflows/ci.yml)
|
|
4
|
+
[](https://codecov.io/gh/romis2012/python-socks)
|
|
5
|
+
[](https://pypi.python.org/pypi/python-socks)
|
|
6
|
+
[](https://github.com/romis2012/python-socks)
|
|
7
|
+
<!--
|
|
8
|
+
[](https://pepy.tech/project/python-socks)
|
|
9
|
+
-->
|
|
10
|
+
|
|
11
|
+
The `python-socks` package provides a core proxy client functionality for Python.
|
|
12
|
+
Supports `SOCKS4(a)`, `SOCKS5(h)`, `HTTP CONNECT` proxy and provides sync and async (asyncio, trio, anyio) APIs.
|
|
13
|
+
You probably don't need to use `python-socks` directly.
|
|
14
|
+
It is used internally by
|
|
15
|
+
[aiohttp-socks](https://github.com/romis2012/aiohttp-socks) and [httpx-socks](https://github.com/romis2012/httpx-socks) packages.
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
- Python >= 3.9
|
|
19
|
+
- async-timeout >= 5.0 (optional)
|
|
20
|
+
- trio >= 0.30 (optional)
|
|
21
|
+
- anyio >= 4.12 (optional)
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
only sync proxy support:
|
|
26
|
+
```
|
|
27
|
+
pip install python-socks
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
to include optional asyncio support:
|
|
31
|
+
```
|
|
32
|
+
pip install python-socks[asyncio]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
to include optional trio support:
|
|
36
|
+
```
|
|
37
|
+
pip install python-socks[trio]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
to include optional anyio support:
|
|
41
|
+
```
|
|
42
|
+
pip install python-socks[anyio]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Simple usage
|
|
46
|
+
We are making secure HTTP GET request via SOCKS5 proxy
|
|
47
|
+
|
|
48
|
+
#### Sync
|
|
49
|
+
```python
|
|
50
|
+
import ssl
|
|
51
|
+
from python_socks.sync import Proxy
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def fetch():
|
|
55
|
+
proxy = Proxy.from_url("socks5://user:password@127.0.0.1:1080")
|
|
56
|
+
|
|
57
|
+
# `connect` returns standard Python socket in blocking mode
|
|
58
|
+
sock = proxy.connect(
|
|
59
|
+
dest_host="check-host.net",
|
|
60
|
+
dest_port=443,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
sock = ssl.create_default_context().wrap_socket(
|
|
64
|
+
sock=sock,
|
|
65
|
+
server_hostname="check-host.net",
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
# fmt: off
|
|
69
|
+
request = (
|
|
70
|
+
b"GET /ip HTTP/1.1\r\n"
|
|
71
|
+
b"Host: check-host.net\r\n"
|
|
72
|
+
b"Connection: close\r\n\r\n"
|
|
73
|
+
)
|
|
74
|
+
# fmt: on
|
|
75
|
+
|
|
76
|
+
sock.sendall(request)
|
|
77
|
+
response = sock.recv(4096)
|
|
78
|
+
print(response)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
fetch()
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### Async (asyncio)
|
|
85
|
+
```python
|
|
86
|
+
import asyncio
|
|
87
|
+
import ssl
|
|
88
|
+
from python_socks.async_.asyncio import Proxy
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
async def fetch():
|
|
92
|
+
proxy = Proxy.from_url("socks5://user:password@127.0.0.1:1080")
|
|
93
|
+
|
|
94
|
+
# `connect` returns standard Python socket in non-blocking mode
|
|
95
|
+
# so we can pass it to asyncio.open_connection(...)
|
|
96
|
+
sock = await proxy.connect(
|
|
97
|
+
dest_host="check-host.net",
|
|
98
|
+
dest_port=443,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
reader, writer = await asyncio.open_connection(
|
|
102
|
+
sock=sock,
|
|
103
|
+
ssl=ssl.create_default_context(),
|
|
104
|
+
server_hostname="check-host.net",
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# fmt: off
|
|
108
|
+
request = (
|
|
109
|
+
b"GET /ip HTTP/1.1\r\n"
|
|
110
|
+
b"Host: check-host.net\r\n"
|
|
111
|
+
b"Connection: close\r\n\r\n"
|
|
112
|
+
)
|
|
113
|
+
# fmt: on
|
|
114
|
+
|
|
115
|
+
writer.write(request)
|
|
116
|
+
response = await reader.read(-1)
|
|
117
|
+
print(response)
|
|
118
|
+
|
|
119
|
+
writer.close()
|
|
120
|
+
await writer.wait_closed()
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
asyncio.run(fetch())
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
#### Async (trio)
|
|
127
|
+
```python
|
|
128
|
+
import ssl
|
|
129
|
+
import trio
|
|
130
|
+
from python_socks.async_.trio import Proxy
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
async def fetch():
|
|
134
|
+
proxy = Proxy.from_url("socks5://user:password@127.0.0.1:1080")
|
|
135
|
+
|
|
136
|
+
# `connect` returns trio.socket.SocketType
|
|
137
|
+
# so we can pass it to trio.SocketStream
|
|
138
|
+
sock = await proxy.connect(
|
|
139
|
+
dest_host="check-host.net",
|
|
140
|
+
dest_port=443,
|
|
141
|
+
)
|
|
142
|
+
stream = trio.SocketStream(sock)
|
|
143
|
+
stream = trio.SSLStream(
|
|
144
|
+
stream,
|
|
145
|
+
ssl_context=ssl.create_default_context(),
|
|
146
|
+
server_hostname="check-host.net",
|
|
147
|
+
)
|
|
148
|
+
await stream.do_handshake()
|
|
149
|
+
|
|
150
|
+
# fmt: off
|
|
151
|
+
request = (
|
|
152
|
+
b"GET /ip HTTP/1.1\r\n"
|
|
153
|
+
b"Host: check-host.net\r\n"
|
|
154
|
+
b"Connection: close\r\n\r\n"
|
|
155
|
+
)
|
|
156
|
+
# fmt: on
|
|
157
|
+
|
|
158
|
+
await stream.send_all(request)
|
|
159
|
+
response = await stream.receive_some(4096)
|
|
160
|
+
print(response)
|
|
161
|
+
|
|
162
|
+
await stream.aclose()
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
trio.run(fetch)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
#### Async (anyio)
|
|
169
|
+
```python
|
|
170
|
+
import ssl
|
|
171
|
+
import anyio
|
|
172
|
+
from anyio.streams.tls import TLSStream
|
|
173
|
+
from python_socks.async_.anyio import Proxy
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
async def fetch():
|
|
177
|
+
proxy = Proxy.from_url("socks5://user:password@127.0.0.1:1080")
|
|
178
|
+
|
|
179
|
+
# `connect` returns anyio.abc.SocketStream
|
|
180
|
+
# we can use it directly
|
|
181
|
+
stream = await proxy.connect(
|
|
182
|
+
dest_host="check-host.net",
|
|
183
|
+
dest_port=443,
|
|
184
|
+
)
|
|
185
|
+
stream = await TLSStream.wrap(
|
|
186
|
+
stream,
|
|
187
|
+
ssl_context=ssl.create_default_context(),
|
|
188
|
+
hostname="check-host.net",
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
# fmt: off
|
|
192
|
+
request = (
|
|
193
|
+
b"GET /ip HTTP/1.1\r\n"
|
|
194
|
+
b"Host: check-host.net\r\n"
|
|
195
|
+
b"Connection: close\r\n\r\n"
|
|
196
|
+
)
|
|
197
|
+
# fmt: on
|
|
198
|
+
|
|
199
|
+
await stream.send(request)
|
|
200
|
+
response = await stream.receive(4096)
|
|
201
|
+
print(response)
|
|
202
|
+
|
|
203
|
+
await stream.aclose()
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
anyio.run(fetch)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## More complex example
|
|
210
|
+
|
|
211
|
+
#### A urllib3 PoolManager that routes connections via the proxy
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
from urllib3 import PoolManager, HTTPConnectionPool, HTTPSConnectionPool
|
|
215
|
+
from urllib3.connection import HTTPConnection, HTTPSConnection
|
|
216
|
+
from python_socks.sync import Proxy
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
class ProxyHTTPConnection(HTTPConnection):
|
|
220
|
+
def __init__(self, *args, **kwargs):
|
|
221
|
+
socks_options = kwargs.pop("_socks_options")
|
|
222
|
+
self._proxy_url = socks_options["proxy_url"]
|
|
223
|
+
super().__init__(*args, **kwargs)
|
|
224
|
+
|
|
225
|
+
def _new_conn(self):
|
|
226
|
+
proxy = Proxy.from_url(self._proxy_url)
|
|
227
|
+
return proxy.connect(
|
|
228
|
+
dest_host=self.host,
|
|
229
|
+
dest_port=self.port,
|
|
230
|
+
timeout=self.timeout,
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class ProxyHTTPSConnection(ProxyHTTPConnection, HTTPSConnection):
|
|
235
|
+
pass
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class ProxyHTTPConnectionPool(HTTPConnectionPool):
|
|
239
|
+
ConnectionCls = ProxyHTTPConnection
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
class ProxyHTTPSConnectionPool(HTTPSConnectionPool):
|
|
243
|
+
ConnectionCls = ProxyHTTPSConnection
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
class ProxyPoolManager(PoolManager):
|
|
247
|
+
def __init__(
|
|
248
|
+
self,
|
|
249
|
+
proxy_url,
|
|
250
|
+
timeout=5,
|
|
251
|
+
num_pools=10,
|
|
252
|
+
headers=None,
|
|
253
|
+
**connection_pool_kw,
|
|
254
|
+
):
|
|
255
|
+
|
|
256
|
+
connection_pool_kw["_socks_options"] = {"proxy_url": proxy_url}
|
|
257
|
+
connection_pool_kw["timeout"] = timeout
|
|
258
|
+
|
|
259
|
+
super().__init__(num_pools, headers, **connection_pool_kw)
|
|
260
|
+
|
|
261
|
+
self.pool_classes_by_scheme = {
|
|
262
|
+
"http": ProxyHTTPConnectionPool,
|
|
263
|
+
"https": ProxyHTTPSConnectionPool,
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
### and how to use it
|
|
268
|
+
manager = ProxyPoolManager("socks5://user:password@127.0.0.1:1080")
|
|
269
|
+
response = manager.request("GET", "https://check-host.net/ip")
|
|
270
|
+
print(response.data)
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Proxy Chaining (sync example — same for asyncio, trio, anyio)
|
|
274
|
+
|
|
275
|
+
```python
|
|
276
|
+
import ssl
|
|
277
|
+
from python_socks.sync import Proxy
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def fetch():
|
|
281
|
+
proxy1 = Proxy.from_url("socks5://user:password@127.0.0.1:1080")
|
|
282
|
+
proxy2 = Proxy.from_url("socks4://127.0.0.1:1081", forward=proxy1)
|
|
283
|
+
proxy3 = Proxy.from_url("http://user:password@127.0.0.1:1082", forward=proxy2)
|
|
284
|
+
|
|
285
|
+
sock = proxy3.connect(
|
|
286
|
+
dest_host="check-host.net",
|
|
287
|
+
dest_port=443,
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
sock = ssl.create_default_context().wrap_socket(
|
|
291
|
+
sock=sock,
|
|
292
|
+
server_hostname="check-host.net",
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
# fmt: off
|
|
296
|
+
request = (
|
|
297
|
+
b"GET /ip HTTP/1.1\r\n"
|
|
298
|
+
b"Host: check-host.net\r\n"
|
|
299
|
+
b"Connection: close\r\n\r\n"
|
|
300
|
+
)
|
|
301
|
+
# fmt: on
|
|
302
|
+
|
|
303
|
+
sock.sendall(request)
|
|
304
|
+
response = sock.recv(4096)
|
|
305
|
+
print(response)
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
fetch()
|
|
309
|
+
```
|