From c848ae0ace8a6d496fdb52a7f8a0519d0259d839 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Wed, 20 Dec 2017 17:45:40 +0100 Subject: [PATCH] Move tgread_object() outside specific msg processing calls --- telethon/network/mtproto_sender.py | 94 +++++++++++++----------------- 1 file changed, 40 insertions(+), 54 deletions(-) diff --git a/telethon/network/mtproto_sender.py b/telethon/network/mtproto_sender.py index d76d44ae..7e4d2f18 100644 --- a/telethon/network/mtproto_sender.py +++ b/telethon/network/mtproto_sender.py @@ -220,41 +220,52 @@ class MtProtoSender: code = reader.read_int(signed=False) reader.seek(-4) - __log__.debug('Processing server message with ID %s', hex(code)) + # These are a bit of special case, not yet generated by the code gen if code == 0xf35c6d01: # rpc_result, (response of an RPC call) + __log__.debug('Processing Remote Procedure Call result') return self._handle_rpc_result(msg_id, sequence, reader) - if code == Pong.CONSTRUCTOR_ID: - return self._handle_pong(msg_id, sequence, reader) - if code == MessageContainer.CONSTRUCTOR_ID: + __log__.debug('Processing container result') return self._handle_container(msg_id, sequence, reader, state) if code == GzipPacked.CONSTRUCTOR_ID: + __log__.debug('Processing gzipped result') return self._handle_gzip_packed(msg_id, sequence, reader, state) - if code == BadServerSalt.CONSTRUCTOR_ID: - return self._handle_bad_server_salt(msg_id, sequence, reader) + if code not in tlobjects: + __log__.warning( + 'Unknown message with ID %d, data left in the buffer %s', + hex(code), repr(reader.get_bytes()[reader.tell_position():]) + ) + return False - if code == BadMsgNotification.CONSTRUCTOR_ID: - return self._handle_bad_msg_notification(msg_id, sequence, reader) + obj = reader.tgread_object() + __log__.debug('Processing %s result', type(obj).__name__) - if code == MsgDetailedInfo.CONSTRUCTOR_ID: - return self._handle_msg_detailed_info(msg_id, sequence, reader) + if isinstance(obj, Pong): + return self._handle_pong(msg_id, sequence, obj) - if code == MsgNewDetailedInfo.CONSTRUCTOR_ID: - return self._handle_msg_new_detailed_info(msg_id, sequence, reader) + if isinstance(obj, BadServerSalt): + return self._handle_bad_server_salt(msg_id, sequence, obj) - if code == NewSessionCreated.CONSTRUCTOR_ID: - return self._handle_new_session_created(msg_id, sequence, reader) + if isinstance(obj, BadMsgNotification): + return self._handle_bad_msg_notification(msg_id, sequence, obj) - if code == MsgsAck.CONSTRUCTOR_ID: # may handle the request we wanted - ack = reader.tgread_object() - assert isinstance(ack, MsgsAck) + if isinstance(obj, MsgDetailedInfo): + return self._handle_msg_detailed_info(msg_id, sequence, obj) + + if isinstance(obj, MsgNewDetailedInfo): + return self._handle_msg_new_detailed_info(msg_id, sequence, obj) + + if isinstance(obj, NewSessionCreated): + return self._handle_new_session_created(msg_id, sequence, obj) + + if isinstance(obj, MsgsAck): # may handle the request we wanted # Ignore every ack request *unless* when logging out, when it's # when it seems to only make sense. We also need to set a non-None # result since Telegram doesn't send the response for these. - for msg_id in ack.msg_ids: + for msg_id in obj.msg_ids: r = self._pop_request_of_type(msg_id, LogOutRequest) if r: r.result = True # Telegram won't send this value @@ -262,20 +273,12 @@ class MtProtoSender: return True - # If the code is not parsed manually then it should be a TLObject. - if code in tlobjects: - result = reader.tgread_object() - self.session.process_entities(result) - if state: - state.process(result) + # If the object isn't any of the above, then it should be an Update. + self.session.process_entities(obj) + if state: + state.process(obj) - return True - - __log__.warning( - 'Unknown message with ID %d, data left in the buffer %s', - hex(code), repr(reader.get_bytes()[reader.tell_position():]) - ) - return False + return True # endregion @@ -341,7 +344,7 @@ class MtProtoSender: if requests: return self.send(*requests) - def _handle_pong(self, msg_id, sequence, reader): + def _handle_pong(self, msg_id, sequence, pong): """ Handles a Pong response. @@ -350,9 +353,6 @@ class MtProtoSender: :param reader: the reader containing the Pong. :return: true, as it always succeeds. """ - pong = reader.tgread_object() - assert isinstance(pong, Pong) - request = self._pop_request(pong.msg_id) if request: request.result = pong @@ -384,7 +384,7 @@ class MtProtoSender: return True - def _handle_bad_server_salt(self, msg_id, sequence, reader): + def _handle_bad_server_salt(self, msg_id, sequence, bad_salt): """ Handles a BadServerSalt response. @@ -393,9 +393,6 @@ class MtProtoSender: :param reader: the reader containing the BadServerSalt. :return: true, as it always succeeds. """ - bad_salt = reader.tgread_object() - assert isinstance(bad_salt, BadServerSalt) - self.session.salt = bad_salt.new_server_salt self.session.save() @@ -404,7 +401,7 @@ class MtProtoSender: self._resend_request(bad_salt.bad_msg_id) return True - def _handle_bad_msg_notification(self, msg_id, sequence, reader): + def _handle_bad_msg_notification(self, msg_id, sequence, bad_msg): """ Handles a BadMessageError response. @@ -413,9 +410,6 @@ class MtProtoSender: :param reader: the reader containing the BadMessageError. :return: true, as it always succeeds. """ - bad_msg = reader.tgread_object() - assert isinstance(bad_msg, BadMsgNotification) - error = BadMessageError(bad_msg.error_code) __log__.warning('Read bad msg notification %s: %s', bad_msg, error) if bad_msg.error_code in (16, 17): @@ -441,7 +435,7 @@ class MtProtoSender: else: raise error - def _handle_msg_detailed_info(self, msg_id, sequence, reader): + def _handle_msg_detailed_info(self, msg_id, sequence, msg_new): """ Handles a MsgDetailedInfo response. @@ -450,15 +444,12 @@ class MtProtoSender: :param reader: the reader containing the MsgDetailedInfo. :return: true, as it always succeeds. """ - msg_new = reader.tgread_object() - assert isinstance(msg_new, MsgDetailedInfo) - # TODO For now, simply ack msg_new.answer_msg_id # Relevant tdesktop source code: https://goo.gl/VvpCC6 self._send_acknowledge(msg_new.answer_msg_id) return True - def _handle_msg_new_detailed_info(self, msg_id, sequence, reader): + def _handle_msg_new_detailed_info(self, msg_id, sequence, msg_new): """ Handles a MsgNewDetailedInfo response. @@ -467,15 +458,12 @@ class MtProtoSender: :param reader: the reader containing the MsgNewDetailedInfo. :return: true, as it always succeeds. """ - msg_new = reader.tgread_object() - assert isinstance(msg_new, MsgNewDetailedInfo) - # TODO For now, simply ack msg_new.answer_msg_id # Relevant tdesktop source code: https://goo.gl/G7DPsR self._send_acknowledge(msg_new.answer_msg_id) return True - def _handle_new_session_created(self, msg_id, sequence, reader): + def _handle_new_session_created(self, msg_id, sequence, new_session): """ Handles a NewSessionCreated response. @@ -484,8 +472,6 @@ class MtProtoSender: :param reader: the reader containing the NewSessionCreated. :return: true, as it always succeeds. """ - new_session = reader.tgread_object() - assert isinstance(new_session, NewSessionCreated) self.session.salt = new_session.server_salt # TODO https://goo.gl/LMyN7A return True