Files
wechatAiclaw/.venv/lib/python3.9/site-packages/python_socks/sync/_proxy.py
2026-03-15 17:16:05 +08:00

117 lines
3.2 KiB
Python

import socket
from typing import Optional, Any
import warnings
from .._errors import ProxyConnectionError, ProxyTimeoutError, ProxyError
from .._types import ProxyType
from .._helpers import parse_proxy_url
from .._protocols.errors import ReplyError
from .._connectors.factory_sync import create_connector
from ._stream import SyncSocketStream
from ._resolver import SyncResolver
from ._connect import connect_tcp
DEFAULT_TIMEOUT = 60
class SyncProxy:
def __init__(
self,
proxy_type: ProxyType,
host: str,
port: int,
username: Optional[str] = None,
password: Optional[str] = None,
rdns: Optional[bool] = None,
):
self._proxy_type = proxy_type
self._proxy_host = host
self._proxy_port = port
self._password = password
self._username = username
self._rdns = rdns
self._resolver = SyncResolver()
def connect(
self,
dest_host: str,
dest_port: int,
timeout: Optional[float] = None,
**kwargs: Any,
) -> socket.socket:
if timeout is None:
timeout = DEFAULT_TIMEOUT
_socket = kwargs.get('_socket')
if _socket is not None:
warnings.warn(
"The '_socket' argument is deprecated and will be removed in the future",
DeprecationWarning,
stacklevel=2,
)
if _socket is None:
local_addr = kwargs.get('local_addr')
try:
_socket = connect_tcp(
host=self._proxy_host,
port=self._proxy_port,
timeout=timeout,
local_addr=local_addr,
)
except OSError as e:
msg = 'Could not connect to proxy {}:{} [{}]'.format(
self._proxy_host,
self._proxy_port,
e.strerror,
)
raise ProxyConnectionError(e.errno, msg) from e
stream = SyncSocketStream(_socket)
try:
connector = create_connector(
proxy_type=self._proxy_type,
username=self._username,
password=self._password,
rdns=self._rdns,
resolver=self._resolver,
)
connector.connect(
stream=stream,
host=dest_host,
port=dest_port,
)
return _socket
except socket.timeout as e:
stream.close()
raise ProxyTimeoutError('Proxy connection timed out: {}'.format(timeout)) from e
except ReplyError as e:
stream.close()
raise ProxyError(e, error_code=e.error_code)
except Exception:
stream.close()
raise
@property
def proxy_host(self):
return self._proxy_host
@property
def proxy_port(self):
return self._proxy_port
@classmethod
def create(cls, *args, **kwargs): # for backward compatibility
return cls(*args, **kwargs)
@classmethod
def from_url(cls, url: str, **kwargs) -> 'SyncProxy':
url_args = parse_proxy_url(url)
return cls(*url_args, **kwargs)