mirror of
				https://github.com/LonamiWebs/Telethon.git
				synced 2025-10-31 07:57:38 +03:00 
			
		
		
		
	Replace pysocks with python-proxy
This commit is contained in:
		
							parent
							
								
									9752f66eab
								
							
						
					
					
						commit
						ad7e62baf3
					
				|  | @ -1,4 +1,4 @@ | ||||||
| cryptg | cryptg | ||||||
| pysocks | pproxy | ||||||
| hachoir3 | hachoir3 | ||||||
| pillow | pillow | ||||||
|  |  | ||||||
|  | @ -107,7 +107,7 @@ Signing In behind a Proxy | ||||||
| ========================= | ========================= | ||||||
| 
 | 
 | ||||||
| If you need to use a proxy to access Telegram, | 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 | .. code-block:: python | ||||||
| 
 | 
 | ||||||
|  | @ -117,12 +117,20 @@ with | ||||||
| 
 | 
 | ||||||
| .. code-block:: python | .. 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). | (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, | 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/qwj/python-proxy#quickstart | ||||||
| .. __: https://github.com/Anorov/PySocks#usage-1 | .. __: 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 |             By default this is ``False`` as IPv6 support is not | ||||||
|             too widespread yet. |             too widespread yet. | ||||||
| 
 | 
 | ||||||
|         proxy (`tuple` | `list` | `dict`, optional): |         proxy (`str` | `dict`, optional): | ||||||
|             An iterable consisting of the proxy info. If `connection` is |             The URI with all the required proxy information, or a dictionary | ||||||
|             one of `MTProxy`, then it should contain MTProxy credentials: |             with the fields to use (like ``schemepython``, ``hostname``, etc.). | ||||||
|             ``('hostname', port, 'secret')``. Otherwise, it's meant to store | 
 | ||||||
|             function parameters for PySocks, like ``(type, 'hostname', port)``. |             See https://github.com/qwj/python-proxy#uri-syntax for details. | ||||||
|             See https://github.com/Anorov/PySocks#usage-1 for more. |  | ||||||
| 
 | 
 | ||||||
|         timeout (`int` | `float`, optional): |         timeout (`int` | `float`, optional): | ||||||
|             The timeout in seconds to be used when connecting. |             The timeout in seconds to be used when connecting. | ||||||
|  | @ -171,7 +170,7 @@ class TelegramBaseClient(abc.ABC): | ||||||
|             *, |             *, | ||||||
|             connection: 'typing.Type[Connection]' = ConnectionTcpFull, |             connection: 'typing.Type[Connection]' = ConnectionTcpFull, | ||||||
|             use_ipv6: bool = False, |             use_ipv6: bool = False, | ||||||
|             proxy: typing.Union[tuple, dict] = None, |             proxy: typing.Union[str, dict] = None, | ||||||
|             timeout: int = 10, |             timeout: int = 10, | ||||||
|             request_retries: int = 5, |             request_retries: int = 5, | ||||||
|             connection_retries: int =5, |             connection_retries: int =5, | ||||||
|  | @ -254,14 +253,14 @@ class TelegramBaseClient(abc.ABC): | ||||||
|         self._request_retries = request_retries |         self._request_retries = request_retries | ||||||
|         self._connection_retries = connection_retries |         self._connection_retries = connection_retries | ||||||
|         self._retry_delay = retry_delay or 0 |         self._retry_delay = retry_delay or 0 | ||||||
|         self._proxy = proxy |         self._proxy = helpers._get_proxy_uri(proxy) | ||||||
|         self._timeout = timeout |         self._timeout = timeout | ||||||
|         self._auto_reconnect = auto_reconnect |         self._auto_reconnect = auto_reconnect | ||||||
| 
 | 
 | ||||||
|         assert isinstance(connection, type) |         assert isinstance(connection, type) | ||||||
|         self._connection = connection |         self._connection = connection | ||||||
|         init_proxy = None if not issubclass(connection, TcpMTProxy) else \ |         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 |         # Used on connection. Capture the variables in a lambda since | ||||||
|         # exporting clients need to create this InvokeWithLayerRequest. |         # exporting clients need to create this InvokeWithLayerRequest. | ||||||
|  |  | ||||||
|  | @ -131,6 +131,43 @@ def _sync_exit(self, *args): | ||||||
|     return loop.run_until_complete(self.__aexit__(*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 | # endregion | ||||||
| 
 | 
 | ||||||
| # region Cryptographic related utils | # region Cryptographic related utils | ||||||
|  |  | ||||||
|  | @ -43,43 +43,19 @@ class Connection(abc.ABC): | ||||||
| 
 | 
 | ||||||
|     async def _connect(self, timeout=None, ssl=None): |     async def _connect(self, timeout=None, ssl=None): | ||||||
|         if not self._proxy: |         if not self._proxy: | ||||||
|             self._reader, self._writer = await asyncio.wait_for( |             connect_coroutine = asyncio.open_connection( | ||||||
|                 asyncio.open_connection( |                 self._ip, self._port, loop=self._loop, ssl=ssl) | ||||||
|                     self._ip, self._port, loop=self._loop, ssl=ssl), |  | ||||||
|                 loop=self._loop, timeout=timeout |  | ||||||
|             ) |  | ||||||
|         else: |         else: | ||||||
|             import socks |             import pproxy | ||||||
|             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) |             # FIXME https://github.com/qwj/python-proxy/issues/41 | ||||||
|             if isinstance(self._proxy, dict): |             connect_coroutine = pproxy.Connection( | ||||||
|                 s.set_proxy(**self._proxy) |                 self._proxy).tcp_connect(self._ip, self._port) | ||||||
|             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._reader, self._writer = await asyncio.wait_for( | ||||||
|  |             connect_coroutine, | ||||||
|  |             loop=self._loop, timeout=timeout | ||||||
|  |         ) | ||||||
|         self._codec = self.packet_codec(self) |         self._codec = self.packet_codec(self) | ||||||
|         self._init_conn() |         self._init_conn() | ||||||
|         await self._writer.drain() |         await self._writer.drain() | ||||||
|  |  | ||||||
|  | @ -126,6 +126,7 @@ class TcpMTProxy(ObfuscatedConnection): | ||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def address_info(proxy_info): |     def address_info(proxy_info): | ||||||
|  |         raise NotImplementedError('New proxy format is not implemented') | ||||||
|         if proxy_info is None: |         if proxy_info is None: | ||||||
|             raise ValueError("No proxy info specified for MTProxy connection") |             raise ValueError("No proxy info specified for MTProxy connection") | ||||||
|         return proxy_info[:2] |         return proxy_info[:2] | ||||||
|  |  | ||||||
|  | @ -116,9 +116,8 @@ class InteractiveTelegramClient(TelegramClient): | ||||||
|         try: |         try: | ||||||
|             loop.run_until_complete(self.connect()) |             loop.run_until_complete(self.connect()) | ||||||
|         except IOError: |         except IOError: | ||||||
|             # We handle IOError and not ConnectionError because |             # To avoid issues in the future, we except the most | ||||||
|             # PySocks' errors do not subclass ConnectionError |             # generic IOError as possible (instead of ConnectionError) | ||||||
|             # (so this will work with and without proxies). |  | ||||||
|             print('Initial connection failed. Retrying...') |             print('Initial connection failed. Retrying...') | ||||||
|             loop.run_until_complete(self.connect()) |             loop.run_until_complete(self.connect()) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -22,7 +22,7 @@ def get_env(name, message, cast=str): | ||||||
| session = os.environ.get('TG_SESSION', 'printer') | session = os.environ.get('TG_SESSION', 'printer') | ||||||
| api_id = get_env('TG_API_ID', 'Enter your API ID: ', int) | api_id = get_env('TG_API_ID', 'Enter your API ID: ', int) | ||||||
| api_hash = get_env('TG_API_HASH', 'Enter your API hash: ') | 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) | # Create and start the client so we can make requests (we don't here) | ||||||
| client = TelegramClient(session, api_id, api_hash, proxy=proxy).start() | 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') | session = os.environ.get('TG_SESSION', 'printer') | ||||||
| api_id = get_env('TG_API_ID', 'Enter your API ID: ', int) | api_id = get_env('TG_API_ID', 'Enter your API ID: ', int) | ||||||
| api_hash = get_env('TG_API_HASH', 'Enter your API hash: ') | 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. | # This is our update handler. It is called when a new update arrives. | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user