Finished rewriting response management module

This commit is contained in:
danogentili 2016-09-14 23:10:34 +02:00
parent 10d7b3b40b
commit 700f4ddbdc
5 changed files with 52 additions and 49 deletions

28
composer.lock generated
View File

@ -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",

View File

@ -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.'.');

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}