mirror of
				https://github.com/LonamiWebs/Telethon.git
				synced 2025-10-30 23:47:33 +03:00 
			
		
		
		
	Replace pysocks with python-proxy
This commit is contained in:
		
							parent
							
								
									9752f66eab
								
							
						
					
					
						commit
						ad7e62baf3
					
				|  | @ -1,4 +1,4 @@ | |||
| cryptg | ||||
| pysocks | ||||
| pproxy | ||||
| hachoir3 | ||||
| pillow | ||||
|  |  | |||
|  | @ -107,7 +107,7 @@ Signing In behind a Proxy | |||
| ========================= | ||||
| 
 | ||||
| If you need to use a proxy to access Telegram, | ||||
| you will need to  `install PySocks`__ and then change: | ||||
| you will need to  `install python-proxy`__ and then change: | ||||
| 
 | ||||
| .. code-block:: python | ||||
| 
 | ||||
|  | @ -117,12 +117,20 @@ with | |||
| 
 | ||||
| .. code-block:: python | ||||
| 
 | ||||
|     TelegramClient('anon', api_id, api_hash, proxy=(socks.SOCKS5, '127.0.0.1', 4444)) | ||||
|     TelegramClient('anon', api_id, api_hash, proxy='socks5://127.0.0.1:4444') | ||||
| 
 | ||||
|     # You can also use a ``dict`` (it will be translated to the same URI as above) | ||||
|     TelegramClient('anon', api_id, api_hash, proxy={ | ||||
|         'scheme': 'socks5', | ||||
|         'hostname': '127.0.0.1', | ||||
|         'port': 4444 | ||||
|     }) | ||||
| 
 | ||||
| 
 | ||||
| (of course, replacing the IP and port with the IP and port of the proxy). | ||||
| 
 | ||||
| The ``proxy=`` argument should be a tuple, a list or a dict, | ||||
| consisting of parameters described `in PySocks usage`__. | ||||
| consisting of parameters described `in python-proxy usage`__. | ||||
| 
 | ||||
| .. __: https://github.com/Anorov/PySocks#installation | ||||
| .. __: https://github.com/Anorov/PySocks#usage-1 | ||||
| .. __: https://github.com/qwj/python-proxy#quickstart | ||||
| .. __: https://github.com/qwj/python-proxy#uri-syntax | ||||
|  |  | |||
|  | @ -67,12 +67,11 @@ class TelegramBaseClient(abc.ABC): | |||
|             By default this is ``False`` as IPv6 support is not | ||||
|             too widespread yet. | ||||
| 
 | ||||
|         proxy (`tuple` | `list` | `dict`, optional): | ||||
|             An iterable consisting of the proxy info. If `connection` is | ||||
|             one of `MTProxy`, then it should contain MTProxy credentials: | ||||
|             ``('hostname', port, 'secret')``. Otherwise, it's meant to store | ||||
|             function parameters for PySocks, like ``(type, 'hostname', port)``. | ||||
|             See https://github.com/Anorov/PySocks#usage-1 for more. | ||||
|         proxy (`str` | `dict`, optional): | ||||
|             The URI with all the required proxy information, or a dictionary | ||||
|             with the fields to use (like ``schemepython``, ``hostname``, etc.). | ||||
| 
 | ||||
|             See https://github.com/qwj/python-proxy#uri-syntax for details. | ||||
| 
 | ||||
|         timeout (`int` | `float`, optional): | ||||
|             The timeout in seconds to be used when connecting. | ||||
|  | @ -171,7 +170,7 @@ class TelegramBaseClient(abc.ABC): | |||
|             *, | ||||
|             connection: 'typing.Type[Connection]' = ConnectionTcpFull, | ||||
|             use_ipv6: bool = False, | ||||
|             proxy: typing.Union[tuple, dict] = None, | ||||
|             proxy: typing.Union[str, dict] = None, | ||||
|             timeout: int = 10, | ||||
|             request_retries: int = 5, | ||||
|             connection_retries: int =5, | ||||
|  | @ -254,14 +253,14 @@ class TelegramBaseClient(abc.ABC): | |||
|         self._request_retries = request_retries | ||||
|         self._connection_retries = connection_retries | ||||
|         self._retry_delay = retry_delay or 0 | ||||
|         self._proxy = proxy | ||||
|         self._proxy = helpers._get_proxy_uri(proxy) | ||||
|         self._timeout = timeout | ||||
|         self._auto_reconnect = auto_reconnect | ||||
| 
 | ||||
|         assert isinstance(connection, type) | ||||
|         self._connection = connection | ||||
|         init_proxy = None if not issubclass(connection, TcpMTProxy) else \ | ||||
|             types.InputClientProxy(*connection.address_info(proxy)) | ||||
|             types.InputClientProxy(*connection.address_info(self._proxy)) | ||||
| 
 | ||||
|         # Used on connection. Capture the variables in a lambda since | ||||
|         # exporting clients need to create this InvokeWithLayerRequest. | ||||
|  |  | |||
|  | @ -131,6 +131,43 @@ def _sync_exit(self, *args): | |||
|     return loop.run_until_complete(self.__aexit__(*args)) | ||||
| 
 | ||||
| 
 | ||||
| def _get_proxy_uri(proxy): | ||||
|     if not proxy: | ||||
|         return None | ||||
|     elif isinstance(proxy, str): | ||||
|         return proxy | ||||
|     elif isinstance(proxy, dict): | ||||
|         fmt = { | ||||
|             'scheme': 'socks5', | ||||
|             'cipher': '', | ||||
|             'netloc': '', | ||||
|             'localbind': '', | ||||
|             'plugins': '', | ||||
|             'rules': '', | ||||
|             'auth': '' | ||||
|         } | ||||
|         fmt.update(proxy) | ||||
|         if 'hostname' in fmt: | ||||
|             fmt['netloc'] = '{}:{}'.format(fmt.pop('hostname'), fmt.pop('port')) | ||||
|         if 'username' in fmt: | ||||
|             fmt['auth'] = '{}:{}'.format(fmt.pop('username'), fmt.pop('password')) | ||||
| 
 | ||||
|         fix = { | ||||
|             'cipher': '{}@', | ||||
|             'localbind': '@{}', | ||||
|             'plugins': ',{}', | ||||
|             'rules': '?{}', | ||||
|             'auth': '#{}' | ||||
|         } | ||||
|         for k, v in fix.items(): | ||||
|             if fmt[k]: | ||||
|                 fmt[k] = v.format(fmt[k]) | ||||
| 
 | ||||
|         return '{scheme}://{cipher}{netloc}/{localbind}{plugins}{rules}{auth}'.format(**fmt) | ||||
|     else: | ||||
|         raise TypeError('{!r} is not a valid proxy (must be str URI or dict)'.format(proxy)) | ||||
| 
 | ||||
| 
 | ||||
| # endregion | ||||
| 
 | ||||
| # region Cryptographic related utils | ||||
|  |  | |||
|  | @ -43,43 +43,19 @@ class Connection(abc.ABC): | |||
| 
 | ||||
|     async def _connect(self, timeout=None, ssl=None): | ||||
|         if not self._proxy: | ||||
|             connect_coroutine = asyncio.open_connection( | ||||
|                 self._ip, self._port, loop=self._loop, ssl=ssl) | ||||
|         else: | ||||
|             import pproxy | ||||
| 
 | ||||
|             # FIXME https://github.com/qwj/python-proxy/issues/41 | ||||
|             connect_coroutine = pproxy.Connection( | ||||
|                 self._proxy).tcp_connect(self._ip, self._port) | ||||
| 
 | ||||
|         self._reader, self._writer = await asyncio.wait_for( | ||||
|                 asyncio.open_connection( | ||||
|                     self._ip, self._port, loop=self._loop, ssl=ssl), | ||||
|             connect_coroutine, | ||||
|             loop=self._loop, timeout=timeout | ||||
|         ) | ||||
|         else: | ||||
|             import socks | ||||
|             if ':' in self._ip: | ||||
|                 mode, address = socket.AF_INET6, (self._ip, self._port, 0, 0) | ||||
|             else: | ||||
|                 mode, address = socket.AF_INET, (self._ip, self._port) | ||||
| 
 | ||||
|             s = socks.socksocket(mode, socket.SOCK_STREAM) | ||||
|             if isinstance(self._proxy, dict): | ||||
|                 s.set_proxy(**self._proxy) | ||||
|             else: | ||||
|                 s.set_proxy(*self._proxy) | ||||
| 
 | ||||
|             s.setblocking(False) | ||||
|             await asyncio.wait_for( | ||||
|                 self._loop.sock_connect(s, address), | ||||
|                 timeout=timeout, | ||||
|                 loop=self._loop | ||||
|             ) | ||||
|             if ssl: | ||||
|                 s.settimeout(timeout) | ||||
|                 s = ssl_mod.wrap_socket( | ||||
|                     s, | ||||
|                     do_handshake_on_connect=True, | ||||
|                     ssl_version=ssl_mod.PROTOCOL_SSLv23, | ||||
|                     ciphers='ADH-AES256-SHA' | ||||
|                 ) | ||||
|                 s.setblocking(False) | ||||
| 
 | ||||
|             self._reader, self._writer = \ | ||||
|                 await asyncio.open_connection(sock=s, loop=self._loop) | ||||
| 
 | ||||
|         self._codec = self.packet_codec(self) | ||||
|         self._init_conn() | ||||
|         await self._writer.drain() | ||||
|  |  | |||
|  | @ -126,6 +126,7 @@ class TcpMTProxy(ObfuscatedConnection): | |||
| 
 | ||||
|     @staticmethod | ||||
|     def address_info(proxy_info): | ||||
|         raise NotImplementedError('New proxy format is not implemented') | ||||
|         if proxy_info is None: | ||||
|             raise ValueError("No proxy info specified for MTProxy connection") | ||||
|         return proxy_info[:2] | ||||
|  |  | |||
|  | @ -116,9 +116,8 @@ class InteractiveTelegramClient(TelegramClient): | |||
|         try: | ||||
|             loop.run_until_complete(self.connect()) | ||||
|         except IOError: | ||||
|             # We handle IOError and not ConnectionError because | ||||
|             # PySocks' errors do not subclass ConnectionError | ||||
|             # (so this will work with and without proxies). | ||||
|             # To avoid issues in the future, we except the most | ||||
|             # generic IOError as possible (instead of ConnectionError) | ||||
|             print('Initial connection failed. Retrying...') | ||||
|             loop.run_until_complete(self.connect()) | ||||
| 
 | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ def get_env(name, message, cast=str): | |||
| session = os.environ.get('TG_SESSION', 'printer') | ||||
| api_id = get_env('TG_API_ID', 'Enter your API ID: ', int) | ||||
| api_hash = get_env('TG_API_HASH', 'Enter your API hash: ') | ||||
| proxy = None  # https://github.com/Anorov/PySocks | ||||
| proxy = None  # https://github.com/qwj/python-proxy#uri-syntax | ||||
| 
 | ||||
| # Create and start the client so we can make requests (we don't here) | ||||
| client = TelegramClient(session, api_id, api_hash, proxy=proxy).start() | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ def get_env(name, message, cast=str): | |||
| session = os.environ.get('TG_SESSION', 'printer') | ||||
| api_id = get_env('TG_API_ID', 'Enter your API ID: ', int) | ||||
| api_hash = get_env('TG_API_HASH', 'Enter your API hash: ') | ||||
| proxy = None  # https://github.com/Anorov/PySocks | ||||
| proxy = None  # https://github.com/qwj/python-proxy#uri-syntax | ||||
| 
 | ||||
| 
 | ||||
| # This is our update handler. It is called when a new update arrives. | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user