From 700f4ddbdc01b7cfa297ed0a6c81c03e0051e58d Mon Sep 17 00:00:00 2001 From: danogentili Date: Wed, 14 Sep 2016 23:10:34 +0200 Subject: [PATCH] Finished rewriting response management module --- composer.lock | 28 +++++++----- .../MTProtoTools/CallHandler.php | 8 ++-- .../MTProtoTools/MessageHandler.php | 2 +- .../MTProtoTools/MsgIdHandler.php | 18 ++++++-- .../MTProtoTools/ResponseHandler.php | 45 ++++++++----------- 5 files changed, 52 insertions(+), 49 deletions(-) diff --git a/composer.lock b/composer.lock index e16e9489..2f49dbbe 100644 --- a/composer.lock +++ b/composer.lock @@ -9,16 +9,16 @@ "packages": [ { "name": "danog/phpstruct", - "version": "1.1.2", + "version": "1.1.2.1", "source": { "type": "git", "url": "https://github.com/danog/PHPStruct.git", - "reference": "635b6a57a903b976c56c1283d00ee26b8a1b175d" + "reference": "da588a75fd4fdbd72745fd48f1241b775aee8fa9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/danog/PHPStruct/zipball/635b6a57a903b976c56c1283d00ee26b8a1b175d", - "reference": "635b6a57a903b976c56c1283d00ee26b8a1b175d", + "url": "https://api.github.com/repos/danog/PHPStruct/zipball/da588a75fd4fdbd72745fd48f1241b775aee8fa9", + "reference": "da588a75fd4fdbd72745fd48f1241b775aee8fa9", "shasum": "" }, "require": { @@ -46,14 +46,19 @@ "description": "PHP implementation of python's struct module.", "homepage": "https://daniil.it/phpstruct", "keywords": [ + "binary", "byte", "bytes", + "decimal", + "float", + "integer", "pack", "python", + "string", "struct", "unpack" ], - "time": "2016-08-14 17:51:55" + "time": "2016-08-25 11:07:20" }, { "name": "icicleio/icicle", @@ -123,23 +128,22 @@ }, { "name": "paragonie/constant_time_encoding", - "version": "v1.0.1", + "version": "v2.0.3", "source": { "type": "git", "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "d96e63b79a7135a65659ba5b1cb02826172bfedd" + "reference": "e085e08c939de49707dbf64315d178d90fbc708d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d96e63b79a7135a65659ba5b1cb02826172bfedd", - "reference": "d96e63b79a7135a65659ba5b1cb02826172bfedd", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/e085e08c939de49707dbf64315d178d90fbc708d", + "reference": "e085e08c939de49707dbf64315d178d90fbc708d", "shasum": "" }, "require": { - "php": "^5.3|^7" + "php": "^7" }, "require-dev": { - "paragonie/random_compat": "^1.4|^2.0", "phpunit/phpunit": "4.*|5.*" }, "type": "library", @@ -181,7 +185,7 @@ "hex2bin", "rfc4648" ], - "time": "2016-06-13 01:00:24" + "time": "2016-07-11 20:32:06" }, { "name": "paragonie/random_compat", diff --git a/src/danog/MadelineProto/MTProtoTools/CallHandler.php b/src/danog/MadelineProto/MTProtoTools/CallHandler.php index 85a559ad..8bf9fb18 100644 --- a/src/danog/MadelineProto/MTProtoTools/CallHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/CallHandler.php @@ -23,9 +23,8 @@ class CallHandler extends AuthKeyHandler $count = 0; while ($response == null && $count++ < $this->settings['max_tries']['response']) { $this->log->log('Getting response....'); - $deserialized = $this->recv_message(); - end($this->incoming_messages); - $tempres = $this->handle_message($deserialized, $last_sent, key($this->incoming_messages)); + $last_received = $this->recv_message(); + $this->handle_message($last_sent, $last_received); var_dump($this->incoming_messages); if (isset($this->outgoing_messages[$last_sent]['response']) && isset($this->incoming_messages[$this->outgoing_messages[$last_sent]['response']]['content'])) { $response = $this->incoming_messages[$this->outgoing_messages[$last_sent]['response']]['content']; @@ -52,7 +51,7 @@ class CallHandler extends AuthKeyHandler $this->outgoing_messages[$int_message_id]['content'] = ['method' => $method, 'args' => $args]; $server_answer = $this->wait_for_response($int_message_id); } catch (Exception $e) { - $this->log->log('An error occurred while calling method '.$method.': '.$e->getMessage().' in '.$e->getFile().':'.$e->getLine().'. Recreating connection and retrying to call method...'); + $this->log->log('An error occurred while calling method '.$method.': '.$e->getMessage().' in '.$e->getFile().':'.$e->getLine().$e->getTraceAsString().'. Recreating connection and retrying to call method...'); unset($this->sock); $this->sock = new \danog\MadelineProto\Connection($this->settings['connection']['ip_address'], $this->settings['connection']['port'], $this->settings['connection']['protocol']); continue; @@ -60,7 +59,6 @@ class CallHandler extends AuthKeyHandler if ($server_answer == null) { throw new Exception('An error occurred while calling method '.$method.'.'); } - return $server_answer; } throw new Exception('An error occurred while calling method '.$method.'.'); diff --git a/src/danog/MadelineProto/MTProtoTools/MessageHandler.php b/src/danog/MadelineProto/MTProtoTools/MessageHandler.php index 41935c03..70158911 100644 --- a/src/danog/MadelineProto/MTProtoTools/MessageHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/MessageHandler.php @@ -107,6 +107,6 @@ class MessageHandler extends Crypt $deserialized = $this->tl->deserialize(\danog\MadelineProto\Tools::fopen_and_write('php://memory', 'rw+b', $message_data)); $this->incoming_messages[$message_id]['content'] = $deserialized; - return $deserialized; + return $message_id; } } diff --git a/src/danog/MadelineProto/MTProtoTools/MsgIdHandler.php b/src/danog/MadelineProto/MTProtoTools/MsgIdHandler.php index 2e0db13c..2a5ad76b 100644 --- a/src/danog/MadelineProto/MTProtoTools/MsgIdHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/MsgIdHandler.php @@ -17,7 +17,7 @@ namespace danog\MadelineProto\MTProtoTools; */ class MsgIdHandler extends MessageHandler { - public function check_message_id($new_message_id, $outgoing) + public function check_message_id($new_message_id, $outgoing, $container = false) { if (((int) ((time() + $this->timedelta - 300) * pow(2, 30)) * 4) > $new_message_id) { throw new Exception('Given message id ('.$new_message_id.') is too old.'); @@ -37,15 +37,25 @@ class MsgIdHandler extends MessageHandler if ($new_message_id % 4 != 1 && $new_message_id % 4 != 3) { throw new Exception('message id mod 4 != 1 or 3'); } - foreach (array_keys($this->incoming_messages) as $message_id) { - if ($new_message_id <= $message_id) { - throw new Exception('Given message id ('.$new_message_id.') is lower than or equal than the current limit ('.$message_id.').'); + $keys = array_keys($this->incoming_messages); + if ($container) { + asort($keys); + if ($new_message_id >= end($keys)) { + throw new Exception('Given message id ('.$new_message_id.') is bigger than or equal than the current limit ('.end($keys).').'); + } + } else { + asort($keys); + foreach ($keys as $message_id) { + if ($new_message_id <= $message_id) { + throw new Exception('Given message id ('.$new_message_id.') is lower than or equal than the current limit ('.$message_id.').'); + } } } $this->incoming_messages[$new_message_id] = []; if (count($this->incoming_messages) > $this->settings['msg_array_limit']['incoming']) { array_shift($this->incoming_messages); } + ksort($this->incoming_messages); } } } diff --git a/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php b/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php index 944d23e0..face08fe 100644 --- a/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php @@ -17,11 +17,9 @@ namespace danog\MadelineProto\MTProtoTools; */ class ResponseHandler extends MsgIdHandler { - public function handle_message($response, $last_sent, $last_received) + public function handle_message($last_sent, $last_received) { - $this->incoming_messages[$last_received]['content'] = $response; - ksort($this->incoming_messages); - end($this->incoming_messages); + $response = $this->incoming_messages[$last_received]['content']; switch ($response['_']) { case 'msgs_ack': foreach ($response['msg_ids'] as $msg_id) { @@ -32,21 +30,21 @@ class ResponseHandler extends MsgIdHandler case 'rpc_result': $this->ack_incoming_message_id($last_received); // Acknowledge that I received the server's response $this->ack_outgoing_message_id($response['req_msg_id']); // Acknowledge that the server received my request - - return $this->handle_response($response['result'], $response['req_msg_id'], $last_received); + $this->outgoing_messages[$response['req_msg_id']]['response'] = $last_received; + $this->incoming_messages[$last_received]['content'] = $response['result']; break; case 'future_salts': $this->ack_outgoing_message_id($response['req_msg_id']); // Acknowledge that the server received my request - - return $this->handle_response($response, $response['req_msg_id'], $last_received); + $this->outgoing_messages[$response['req_msg_id']]['response'] = $last_received; + $this->incoming_messages[$last_received]['content'] = $response; break; case 'bad_msg_notification': case 'bad_server_salt': $this->ack_outgoing_message_id($response['bad_msg_id']); // Acknowledge that the server received my request - - return $this->handle_response($response, $response['bad_msg_id'], $last_received); + $this->outgoing_messages[$response['bad_msg_id']]['response'] = $last_received; + $this->incoming_messages[$last_received]['content'] = $response; break; case 'pong': @@ -68,8 +66,9 @@ class ResponseHandler extends MsgIdHandler $this->log->log('Received container.'); $this->log->log($response['messages']); foreach ($response['messages'] as $message) { - $this->incoming_messages[$message['msg_id']] = ['seq_no' => $message['seqno']]; - $responses[] = $this->handle_message($message['body'], $last_sent, $message['msg_id']); + $this->check_message_id($message['msg_id'], false, true); + $this->incoming_messages[$message['msg_id']] = ['seq_no' => $message['seqno'], 'content' => $message['body']]; + $responses[] = $this->handle_message($last_sent, $message['msg_id']); } foreach ($responses as $key => $response) { if ($response == null) { @@ -96,33 +95,25 @@ class ResponseHandler extends MsgIdHandler if (isset($this->incoming_messages[$response['orig_message']['msg_id']])) { $this->ack_incoming_message_id($response['orig_message']['msg_id']); // Acknowledge that I received the server's response } else { - $this->check_message_id($message['orig_message']['msg_id'], false); - - return $this->handle_message($response['orig_message']); + $this->check_message_id($message['orig_message']['msg_id'], false, true); + $this->incoming_messages[$message['orig_message']['msg_id']] = ['content' => $response['orig_message']]; + return $this->handle_message($last_sent, $message['orig_message']['msg_id']); } break; case 'http_wait': $this->log->log('Received http wait.'); $this->log->log($response); break; - default: - $this->ack_incoming_message_id($last_received); // Acknowledge that I received the server's response - return $this->handle_response($response, $last_sent, $last_received); - break; - } - } - - public function handle_response($response, $res_id, $last_received) - { - switch ($response['_']) { case 'gzip_packed': - return $this->handle_response(gzdecode($response), $res_id, $last_received); + $this->incoming_messages[$last_received]['content'] = gzdecode($response); + return $this->handle_message($last_sent, $last_received); break; case 'rpc_answer_dropped_running': case 'rpc_answer_dropped': $this->ack_outgoing_message_id($response['req_msg_id']); // Acknowledge that the server received the original query (the same one, the response to which we wish to forget) default: - $this->outgoing_messages[$res_id]['response'] = $last_received; + $this->ack_incoming_message_id($last_received); // Acknowledge that I received the server's response + $this->outgoing_messages[$last_sent]['response'] = $last_received; $this->incoming_messages[$last_received]['content'] = $response; break; }