Support custom event loops

This commit is contained in:
Lonami Exo
2018-06-14 19:35:12 +02:00
parent 908dfa148b
commit 0f14f3b16a
11 changed files with 48 additions and 40 deletions

View File

@@ -21,13 +21,15 @@ class Connection(abc.ABC):
Subclasses should implement the actual protocol
being used when encoding/decoding messages.
"""
def __init__(self, proxy=None, timeout=timedelta(seconds=5)):
def __init__(self, *, loop, proxy=None, timeout=timedelta(seconds=5)):
"""
Initializes a new connection.
:param loop: the event loop to be used.
:param proxy: whether to use a proxy or not.
:param timeout: timeout to be used for all operations.
"""
self._loop = loop
self._proxy = proxy
self._timeout = timeout
@@ -54,10 +56,13 @@ class Connection(abc.ABC):
"""Closes the connection."""
raise NotImplementedError
@abc.abstractmethod
def clone(self):
"""Creates a copy of this Connection."""
raise NotImplementedError
return self.__class__(
loop=self._loop,
proxy=self._proxy,
timeout=self._timeout
)
@abc.abstractmethod
async def recv(self):

View File

@@ -14,9 +14,6 @@ class ConnectionTcpAbridged(ConnectionTcpFull):
await self.conn.write(b'\xef')
return result
def clone(self):
return ConnectionTcpAbridged(self._proxy, self._timeout)
async def recv(self):
length = struct.unpack('<B', await self.read(1))[0]
if length >= 127:

View File

@@ -13,10 +13,12 @@ class ConnectionTcpFull(Connection):
Default Telegram mode. Sends 12 additional bytes and
needs to calculate the CRC value of the packet itself.
"""
def __init__(self, proxy=None, timeout=timedelta(seconds=5)):
super().__init__(proxy, timeout)
def __init__(self, *, loop, proxy=None, timeout=timedelta(seconds=5)):
super().__init__(loop=loop, proxy=proxy, timeout=timeout)
self._send_counter = 0
self.conn = TcpClient(proxy=self._proxy, timeout=self._timeout)
self.conn = TcpClient(
proxy=self._proxy, timeout=self._timeout, loop=self._loop
)
self.read = self.conn.read
self.write = self.conn.write
@@ -40,9 +42,6 @@ class ConnectionTcpFull(Connection):
async def close(self):
self.conn.close()
def clone(self):
return ConnectionTcpFull(self._proxy, self._timeout)
async def recv(self):
packet_len_seq = await self.read(8) # 4 and 4
packet_len, seq = struct.unpack('<ii', packet_len_seq)

View File

@@ -13,9 +13,6 @@ class ConnectionTcpIntermediate(ConnectionTcpFull):
await self.conn.write(b'\xee\xee\xee\xee')
return result
def clone(self):
return ConnectionTcpIntermediate(self._proxy, self._timeout)
async def recv(self):
return await self.read(struct.unpack('<i', await self.read(4))[0])

View File

@@ -12,8 +12,8 @@ class ConnectionTcpObfuscated(ConnectionTcpAbridged):
every message with a randomly generated key using the
AES-CTR mode so the packets are harder to discern.
"""
def __init__(self, proxy=None, timeout=timedelta(seconds=5)):
super().__init__(proxy, timeout)
def __init__(self, *, loop, proxy=None, timeout=timedelta(seconds=5)):
super().__init__(loop=loop, proxy=proxy, timeout=timeout)
self._aes_encrypt, self._aes_decrypt = None, None
self.read = lambda s: self._aes_decrypt.encrypt(self.conn.read(s))
self.write = lambda d: self.conn.write(self._aes_encrypt.encrypt(d))
@@ -45,6 +45,3 @@ class ConnectionTcpObfuscated(ConnectionTcpAbridged):
random[56:64] = self._aes_encrypt.encrypt(bytes(random))[56:64]
await self.conn.write(bytes(random))
return result
def clone(self):
return ConnectionTcpObfuscated(self._proxy, self._timeout)