diff --git a/bot.php b/bot.php
index b08e8d9f..33cbc70b 100755
--- a/bot.php
+++ b/bot.php
@@ -46,19 +46,6 @@ class EventHandler extends \danog\MadelineProto\EventHandler
yield $this->messages->sendMessage(['peer' => $update, 'message' => "$res
", 'reply_to_msg_id' => isset($update['message']['id']) ? $update['message']['id'] : null, 'parse_mode' => 'HTML']); //'entities' => [['_' => 'messageEntityPre', 'offset' => 0, 'length' => strlen($res), 'language' => 'json']]]);
if (isset($update['message']['media']) && $update['message']['media']['_'] !== 'messageMediaGame') {
yield $this->messages->sendMedia(['peer' => $update, 'message' => $update['message']['message'], 'media' => $update]);
- yield $this->messages->sendMedia([
- 'peer' => '@danogentili',
- 'media' => [
- '_' => 'inputMediaUploadedDocument',
- 'file' => 'https://google.com',
- 'attributes' => [
- ['_' => 'documentAttributeFilename', 'file_name' => 'document.txt']
- ]
- ],
- 'message' => '[This is the caption](https://t.me/MadelineProto)',
- 'parse_mode' => 'Markdown'
- ]);
-
//yield $this->download_to_dir($update, '/tmp');
}
} catch (\danog\MadelineProto\RPCErrorException $e) {
diff --git a/docs b/docs
index cbd913fb..dc05dc5c 160000
--- a/docs
+++ b/docs
@@ -1 +1 @@
-Subproject commit cbd913fba2249a0055bb732452a67f911119c40a
+Subproject commit dc05dc5cebfcec90ac7851928c522a4d635dbab6
diff --git a/src/danog/MadelineProto/MTProtoTools/Files.php b/src/danog/MadelineProto/MTProtoTools/Files.php
index 2c3d3478..4e9aa90d 100644
--- a/src/danog/MadelineProto/MTProtoTools/Files.php
+++ b/src/danog/MadelineProto/MTProtoTools/Files.php
@@ -34,7 +34,7 @@ use danog\MadelineProto\Exception;
use danog\MadelineProto\FileCallbackInterface;
use danog\MadelineProto\Logger;
use danog\MadelineProto\RPCErrorException;
-use danog\MadelineProto\Stream\Common\BufferedRawStream;
+use danog\MadelineProto\Stream\Common\SimpleBufferedRawStream;
use danog\MadelineProto\Stream\ConnectionContext;
use danog\MadelineProto\Stream\Transport\PremadeStream;
use function Amp\File\exists;
@@ -43,6 +43,7 @@ use function Amp\File\stat;
use function Amp\File\touch;
use function Amp\Promise\all;
use Amp\File\BlockingHandle;
+use Amp\Artax\Client;
/**
* Manages upload and download of files.
@@ -94,7 +95,7 @@ trait Files
$url = $url->getFile();
}
/** @var $response \Amp\Artax\Response */
- $response = yield $this->datacenter->getHTTPClient()->request($url);
+ $response = yield $this->datacenter->getHTTPClient()->request($url, [Client::OP_MAX_BODY_BYTES => 512 * 1024 * 3000, Client::OP_TRANSFER_TIMEOUT => 10*1000*3600]);
if (200 !== $status = $response->getStatus()) {
throw new Exception("Wrong status code: $status ".$response->getReason());
}
@@ -103,6 +104,8 @@ trait Files
$stream = $response->getBody();
if (!$size) {
+ $this->logger->logger("No content length for $url, caching first");
+
$body = $stream;
$stream = new BlockingHandle(fopen('php://temp', 'r+b'), 'php://temp', 'r+b');
@@ -141,7 +144,9 @@ trait Files
}
}
- if ($stream instanceof Handle || $stream instanceof BufferedRawStream) {
+ $created = false;
+
+ if ($stream instanceof Handle) {
$callable = static function (int $offset, int $size) use ($stream, $seekable) {
if ($seekable) {
while ($stream->tell() !== $offset) {
@@ -151,18 +156,30 @@ trait Files
return yield $stream->read($size);
};
} else {
- $ctx = (new ConnectionContext)
- ->addStream(PremadeStream::getName(), $stream)
- ->addStream(BufferedRawStream::getName());
-
- $stream = yield $ctx->getStream();
-
+ if (!$stream instanceof BufferedRawStream) {
+ $ctx = (new ConnectionContext)
+ ->addStream(PremadeStream::getName(), $stream)
+ ->addStream(SimpleBufferedRawStream::getName());
+ $stream = yield $ctx->getStream();
+ $created = true;
+ }
$callable = static function (int $offset, int $size) use ($stream) {
- return yield $stream->read($size);
+ $reader = yield $stream->getReadBuffer($l);
+ try {
+ return yield $reader->bufferRead($size);
+ } catch (\danog\MadelineProto\NothingInTheSocketException $e) {
+ $reader = yield $stream->getReadBuffer($size);
+ return yield $reader->bufferRead($size);
+ }
};
+ $seekable = false;
}
- return yield $this->upload_from_callable_async($callable, $size, $mime, $file_name, $cb, $seekable, $encrypted);
+ $res = yield $this->upload_from_callable_async($callable, $size, $mime, $file_name, $cb, $seekable, $encrypted);
+ if ($created) {
+ $stream->disconnect();
+ }
+ return $res;
}
public function upload_from_callable_async($callable, int $size, string $mime, string $file_name = '', $cb = null, bool $refetchable = true, bool $encrypted = false)
{
diff --git a/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php b/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php
index 0c0eeaf1..9f0b7728 100644
--- a/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php
+++ b/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php
@@ -368,6 +368,10 @@ trait ResponseHandler
return;
}
+ if (in_array($response['error_message'], ['MSGID_DECREASE_RETRY', 'RPC_CALL_FAIL', 'RPC_MCGET_FAIL', 'no workers running'])) {
+ Loop::delay(1 * 1000, [$this, 'method_recall'], ['message_id' => $request_id, 'datacenter' => $datacenter]);
+ return;
+ }
$this->got_response_for_outgoing_message_id($request_id, $datacenter);
$this->handle_reject($datacenter, $request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], isset($request['_']) ? $request['_'] : ''));
diff --git a/src/danog/MadelineProto/Stream/Common/SimpleBufferedRawStream.php b/src/danog/MadelineProto/Stream/Common/SimpleBufferedRawStream.php
new file mode 100644
index 00000000..f55d0b71
--- /dev/null
+++ b/src/danog/MadelineProto/Stream/Common/SimpleBufferedRawStream.php
@@ -0,0 +1,77 @@
+.
+ *
+ * @author Daniil Gentili
+ * @copyright 2016-2019 Daniil Gentili
+ * @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
+ *
+ * @link https://docs.madelineproto.xyz MadelineProto documentation
+ */
+
+namespace danog\MadelineProto\Stream\Common;
+
+use Amp\Promise;
+use Amp\Success;
+use danog\MadelineProto\Exception;
+use danog\MadelineProto\Stream\Async\RawStream;
+use danog\MadelineProto\Stream\ConnectionContext;
+use function Amp\Socket\connect;
+use danog\MadelineProto\Stream\BufferedStreamInterface;
+use danog\MadelineProto\Stream\BufferInterface;
+use danog\MadelineProto\Stream\RawStreamInterface;
+
+/**
+ * Buffered raw stream.
+ *
+ * @author Daniil Gentili
+ */
+class SimpleBufferedRawStream extends BufferedRawStream implements BufferedStreamInterface, BufferInterface, RawStreamInterface
+{
+ /**
+ * Read data asynchronously.
+ *
+ * @param int $length Amount of data to read
+ *
+ * @return \Generator
+ */
+ public function bufferReadAsync(int $length): \Generator
+ {
+ $size = fstat($this->memory_stream)['size'];
+ $offset = ftell($this->memory_stream);
+ $buffer_length = $size - $offset;
+ if ($buffer_length < $length && $buffer_length) {
+ fseek($this->memory_stream, $offset + $buffer_length);
+ }
+
+ while ($buffer_length < $length) {
+ $chunk = yield $this->read();
+ if ($chunk === null) {
+ fseek($this->memory_stream, $offset);
+ break;
+ }
+ fwrite($this->memory_stream, $chunk);
+ $buffer_length += strlen($chunk);
+ }
+ fseek($this->memory_stream, $offset);
+
+ return fread($this->memory_stream, $length);
+ }
+
+ /**
+ * Get class name.
+ *
+ * @return string
+ */
+ public static function getName(): string
+ {
+ return __CLASS__;
+ }
+}
diff --git a/src/danog/MadelineProto/Stream/Transport/PremadeStream.php b/src/danog/MadelineProto/Stream/Transport/PremadeStream.php
index 7fd2dc8d..ee2faf60 100644
--- a/src/danog/MadelineProto/Stream/Transport/PremadeStream.php
+++ b/src/danog/MadelineProto/Stream/Transport/PremadeStream.php
@@ -95,7 +95,9 @@ class PremadeStream extends Socket implements RawStreamInterface, ProxyStreamInt
{
try {
if ($this->stream) {
- $this->stream->close();
+ if (method_exists($this->stream, 'close')) {
+ $this->stream->close();
+ }
$this->stream = null;
}
} catch (\Throwable $e) {
diff --git a/src/danog/MadelineProto/VoIP/AuthKeyHandler.php b/src/danog/MadelineProto/VoIP/AuthKeyHandler.php
index 3d25a39d..27eb379e 100644
--- a/src/danog/MadelineProto/VoIP/AuthKeyHandler.php
+++ b/src/danog/MadelineProto/VoIP/AuthKeyHandler.php
@@ -191,7 +191,6 @@ trait AuthKeyHandler
$visualization[] = \danog\MadelineProto\Magic::$emojis[(int) (new \phpseclib\Math\BigInteger($number, 256))->divide($length)[1]->toString()];
}
$this->calls[$params['id']]->setVisualization($visualization);
- var_dump($params);
$this->calls[$params['id']]->configuration['endpoints'] = array_merge($params['connections'], $this->calls[$params['id']]->configuration['endpoints']);
$this->calls[$params['id']]->configuration = array_merge(['recv_timeout' => $this->config['call_receive_timeout_ms'] / 1000, 'init_timeout' => $this->config['call_connect_timeout_ms'] / 1000, 'data_saving' => \danog\MadelineProto\VoIP::DATA_SAVING_NEVER, 'enable_NS' => true, 'enable_AEC' => true, 'enable_AGC' => true, 'auth_key' => $key, 'auth_key_id' => substr(sha1($key, true), -8), 'call_id' => substr(hash('sha256', $key, true), -16), 'network_type' => \danog\MadelineProto\VoIP::NET_TYPE_ETHERNET], $this->calls[$params['id']]->configuration);
$this->calls[$params['id']]->parseConfig();