Create and use a new GzipPacked class, also when sending

This commit is contained in:
Lonami Exo 2017-09-27 13:46:53 +02:00
parent 7b736aa6ef
commit 6df9fc558e
4 changed files with 49 additions and 9 deletions

View File

@ -9,7 +9,7 @@ from ..errors import (
rpc_message_to_error
)
from ..extensions import BinaryReader, BinaryWriter
from ..tl import MessageContainer
from ..tl import MessageContainer, GzipPacked
from ..tl.all_tlobjects import tlobjects
from ..tl.types import MsgsAck
@ -68,10 +68,12 @@ class MtProtoSender:
self._pending_receive.extend(requests)
if len(requests) == 1:
request = requests[0]
data = GzipPacked.gzip_if_smaller(request)
else:
request = MessageContainer(self.session, requests)
data = request.to_bytes()
self._send_packet(request.to_bytes(), request)
self._send_packet(data, request)
def _send_acknowledges(self):
"""Sends a messages acknowledge for all those who _need_confirmation"""
@ -376,11 +378,7 @@ class MtProtoSender:
def _handle_gzip_packed(self, msg_id, sequence, reader, state):
self._logger.debug('Handling gzip packed data')
reader.read_int(signed=False) # code
packed_data = reader.tgread_bytes()
unpacked_data = gzip.decompress(packed_data)
with BinaryReader(unpacked_data) as compressed_reader:
with BinaryReader(GzipPacked.read(reader)) as compressed_reader:
return self._process_msg(msg_id, sequence, compressed_reader, state)
# endregion

View File

@ -1,3 +1,4 @@
from .tlobject import TLObject
from .session import Session
from .gzip_packed import GzipPacked
from .message_container import MessageContainer

View File

@ -0,0 +1,40 @@
import gzip
from . import TLObject
from ..extensions import BinaryWriter
class GzipPacked(TLObject):
constructor_id = 0x3072cfa1
def __init__(self, data):
super().__init__()
self.data = data
@staticmethod
def gzip_if_smaller(request):
"""Calls request.to_bytes(), and based on a certain threshold,
optionally gzips the resulting data. If the gzipped data is
smaller than the original byte array, this is returned instead.
Note that this only applies to content related requests.
"""
data = request.to_bytes()
# TODO This threshold could be configurable
if request.content_related and len(data) > 512:
gzipped = GzipPacked(data).to_bytes()
return gzipped if len(gzipped) < len(data) else data
else:
return data
def to_bytes(self):
# TODO Maybe compress level could be an option
with BinaryWriter() as writer:
writer.write_int(GzipPacked.constructor_id, signed=False)
writer.tgwrite_bytes(gzip.compress(self.data))
return writer.get_bytes()
@staticmethod
def read(reader):
reader.read_int(signed=False) # code
return gzip.decompress(reader.tgread_bytes())

View File

@ -1,4 +1,4 @@
from . import TLObject
from . import TLObject, GzipPacked
from ..extensions import BinaryWriter
@ -24,7 +24,8 @@ class MessageContainer(TLObject):
writer.write_int(
self.session.generate_sequence(x.content_related)
)
packet = x.to_bytes()
packet = GzipPacked.gzip_if_smaller(x)
writer.write_int(len(packet))
writer.write(packet)