MadelineProto/src/danog/MadelineProto/MTProtoTools/Files.php

1103 lines
51 KiB
PHP
Raw Normal View History

<?php
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
/**
* Files module.
*
* This file is part of MadelineProto.
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License for more details.
* You should have received a copy of the GNU General Public License along with MadelineProto.
* If not, see <http://www.gnu.org/licenses/>.
*
* @author Daniil Gentili <daniil@daniil.it>
2020-02-17 14:13:46 +01:00
* @copyright 2016-2020 Daniil Gentili <daniil@daniil.it>
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
*
2019-10-31 15:07:35 +01:00
* @link https://docs.madelineproto.xyz MadelineProto documentation
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
*/
2018-02-24 17:54:39 +01:00
namespace danog\MadelineProto\MTProtoTools;
2019-06-24 18:55:37 +02:00
use Amp\Deferred;
2019-12-13 12:57:47 +01:00
use Amp\File\BlockingFile;
2020-02-05 17:55:18 +01:00
use Amp\File\StatCache as StatCacheAsync;
2019-12-13 17:55:05 +01:00
use Amp\Http\Client\Request;
use Amp\Http\Status;
2019-12-29 18:28:47 +01:00
use Amp\Promise;
2019-06-24 14:42:14 +02:00
use Amp\Success;
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
use danog\MadelineProto\Exception;
2019-06-23 17:46:51 +02:00
use danog\MadelineProto\FileCallbackInterface;
use danog\MadelineProto\Settings;
2019-09-01 23:39:29 +02:00
use danog\MadelineProto\Tools;
2020-04-05 14:57:33 +02:00
use tgseclib\Crypt\AES;
use const danog\Decoder\TYPES;
2019-06-24 18:55:37 +02:00
use function Amp\File\exists;
2019-06-23 17:46:51 +02:00
use function Amp\File\open;
2020-02-05 17:55:18 +01:00
use function Amp\File\stat as statAsync;
2019-05-13 13:07:30 +02:00
use function Amp\Promise\all;
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
/**
2017-03-11 19:55:56 +01:00
* Manages upload and download of files.
*
* @property Settings $settings Settings
*/
trait Files
{
use FilesLogic;
2019-12-27 20:29:22 +01:00
/**
* Upload file from URL.
*
* @param string|FileCallbackInterface $url URL of file
* @param integer $size Size of file
2019-12-29 14:21:25 +01:00
* @param string $fileName File name
2019-12-27 20:29:22 +01:00
* @param callable $cb Callback (DEPRECATED, use FileCallbackInterface)
* @param boolean $encrypted Whether to encrypt file for secret chats
*
2020-10-02 16:13:19 +02:00
* @return \Generator
*
* @psalm-return \Generator<int|mixed, \Amp\Promise|\Amp\Promise<\Amp\Http\Client\Response>|\Amp\Promise<int>|\Amp\Promise<null|string>|\danog\MadelineProto\Stream\StreamInterface|array|int|mixed, mixed, mixed>
2019-12-27 20:29:22 +01:00
*/
2019-12-29 14:21:25 +01:00
public function uploadFromUrl($url, int $size = 0, string $fileName = '', $cb = null, bool $encrypted = false): \Generator
2019-06-24 18:55:37 +02:00
{
2019-09-01 23:39:29 +02:00
if (\is_object($url) && $url instanceof FileCallbackInterface) {
2019-06-24 18:55:37 +02:00
$cb = $url;
$url = $url->getFile();
}
2019-12-13 12:57:47 +01:00
/** @var $response \Amp\Http\Client\Response */
2019-12-13 17:55:05 +01:00
$request = new Request($url);
2020-01-31 19:29:43 +01:00
$request->setTransferTimeout(10 * 1000 * 3600);
$request->setBodySizeLimit(512 * 1024 * 4000);
2019-12-13 17:55:05 +01:00
$response = yield $this->datacenter->getHTTPClient()->request($request);
2020-01-31 19:29:43 +01:00
if (200 !== ($status = $response->getStatus())) {
2020-02-05 17:55:18 +01:00
throw new Exception("Wrong status code: {$status} ".$response->getReason());
}
2019-09-01 23:39:29 +02:00
$mime = \trim(\explode(';', $response->getHeader('content-type') ?? 'application/octet-stream')[0]);
2019-06-24 18:55:37 +02:00
$size = $response->getHeader('content-length') ?? $size;
$stream = $response->getBody();
2019-06-24 18:55:37 +02:00
if (!$size) {
2020-01-31 19:29:43 +01:00
$this->logger->logger("No content length for {$url}, caching first");
$body = $stream;
2019-12-13 12:57:47 +01:00
$stream = new BlockingFile(\fopen('php://temp', 'r+b'), 'php://temp', 'r+b');
2020-01-31 19:29:43 +01:00
while (null !== ($chunk = yield $body->read())) {
yield $stream->write($chunk);
}
$size = $stream->tell();
if (!$size) {
throw new Exception('Wrong size!');
}
yield $stream->seek(0);
}
2020-01-31 19:29:43 +01:00
return yield from $this->uploadFromStream($stream, $size, $mime, $fileName, $cb, $encrypted);
2019-06-24 18:55:37 +02:00
}
2019-12-27 20:29:22 +01:00
/**
* Upload file from callable.
*
2019-12-27 21:24:50 +01:00
* The callable must accept two parameters: int $offset, int $size
* The callable must return a string with the contest of the file at the specified offset and size.
*
* @param mixed $callable Callable
* @param integer $size File size
* @param string $mime Mime type
2019-12-29 14:21:25 +01:00
* @param string $fileName File name
2019-12-27 21:24:50 +01:00
* @param callable $cb Callback (DEPRECATED, use FileCallbackInterface)
* @param boolean $seekable Whether chunks can be fetched out of order
* @param boolean $encrypted Whether to encrypt file for secret chats
2019-12-27 20:29:22 +01:00
*
2020-10-02 16:13:19 +02:00
* @return \Generator
*
* @psalm-return \Generator<int, \Amp\Promise|\Amp\Promise<array>, mixed, array{_: string, id: string, parts: int, name: string, mime_type: string, key_fingerprint?: mixed, key?: mixed, iv?: mixed, md5_checksum: string}>
2019-12-27 20:29:22 +01:00
*/
2020-01-18 16:59:59 +01:00
public function uploadFromCallable(callable $callable, int $size, string $mime, string $fileName = '', $cb = null, bool $seekable = true, bool $encrypted = false): \Generator
2019-06-24 15:14:09 +02:00
{
2019-09-01 23:39:29 +02:00
if (\is_object($callable) && $callable instanceof FileCallbackInterface) {
2019-06-24 15:14:09 +02:00
$cb = $callable;
$callable = $callable->getFile();
}
2019-09-01 23:39:29 +02:00
if (!\is_callable($callable)) {
2019-06-24 15:14:09 +02:00
throw new Exception('Invalid callable provided');
}
2019-06-24 18:55:37 +02:00
if ($cb === null) {
$cb = function ($percent) {
2020-02-05 17:55:18 +01:00
$this->logger->logger('Upload status: '.$percent.'%', \danog\MadelineProto\Logger::NOTICE);
2019-06-24 18:55:37 +02:00
};
}
$datacenter = $this->settings->getDefaultDc();
2020-02-05 17:55:18 +01:00
if ($this->datacenter->has($datacenter.'_media')) {
2019-06-24 18:55:37 +02:00
$datacenter .= '_media';
}
$part_size = 512 * 1024;
$parallel_chunks = $this->settings->getFiles()->getUploadParallelChunks();
2019-09-01 23:39:29 +02:00
$part_total_num = (int) \ceil($size / $part_size);
2019-06-24 15:14:09 +02:00
$part_num = 0;
$method = $size > 10 * 1024 * 1024 ? 'upload.saveBigFilePart' : 'upload.saveFilePart';
2020-02-05 17:55:18 +01:00
$constructor = 'input'.($encrypted === true ? 'Encrypted' : '').($size > 10 * 1024 * 1024 ? 'FileBig' : 'File').($encrypted === true ? 'Uploaded' : '');
2020-08-29 17:58:02 +02:00
$file_id = Tools::random(8);
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
$ige = null;
2020-10-02 16:13:19 +02:00
$fingerprint = null;
$iv = null;
$key = null;
if ($encrypted === true) {
2020-08-29 17:58:02 +02:00
$key = Tools::random(32);
$iv = Tools::random(32);
2020-02-05 17:55:18 +01:00
$digest = \hash('md5', $key.$iv, true);
2020-08-29 17:58:02 +02:00
$fingerprint = Tools::unpackSignedInt(\substr($digest, 0, 4) ^ \substr($digest, 4, 4));
$ige = new \tgseclib\Crypt\AES('ige');
$ige->setIV($iv);
$ige->setKey($key);
$ige->enableContinuousBuffer();
2019-12-27 21:24:50 +01:00
$seekable = false;
}
2019-12-29 21:45:52 +01:00
//$ctx = \hash_init('md5');
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
$promises = [];
$speed = 0;
$time = 0;
$cb = function () use ($cb, $part_total_num, &$speed, &$time) {
2019-06-24 18:55:37 +02:00
static $cur = 0;
$cur++;
2020-08-29 17:58:02 +02:00
Tools::callFork($cb($cur * 100 / $part_total_num, $speed, $time));
2019-06-24 18:55:37 +02:00
};
2020-01-31 19:29:43 +01:00
$callable = static function (int $part_num) use ($file_id, $part_total_num, $part_size, $callable, $ige): \Generator {
2019-12-29 18:28:47 +01:00
$bytes = yield $callable($part_num * $part_size, $part_size);
if ($ige) {
$bytes = $ige->encrypt(\str_pad($bytes, $part_size, \chr(0)));
}
2019-12-29 21:45:52 +01:00
//\hash_update($ctx, $bytes);
2019-12-29 18:28:47 +01:00
return ['file_id' => $file_id, 'file_part' => $part_num, 'file_total_parts' => $part_total_num, 'bytes' => $bytes];
};
$resPromises = [];
2019-12-31 12:45:49 +01:00
$exception = null;
2019-12-29 18:28:47 +01:00
$start = \microtime(true);
while ($part_num < $part_total_num) {
$resa = $callable($part_num);
$writePromise = Tools::call($this->methodCallAsyncWrite($method, $resa, ['heavy' => true, 'file' => true, 'datacenter' => &$datacenter]));
2019-12-29 18:28:47 +01:00
if (!$seekable) {
yield $writePromise;
}
2020-01-31 19:29:43 +01:00
$writePromise->onResolve(function ($e, $readDeferred) use ($cb, $part_num, &$resPromises, &$exception): \Generator {
if ($e) {
$this->logger("Got exception while uploading: {$e}");
$exception = $e;
return;
}
$resPromises[] = $readDeferred->promise();
try {
// Wrote chunk!
if (!yield Tools::call($readDeferred->promise())) {
2020-02-05 17:55:18 +01:00
throw new \danog\MadelineProto\Exception('Upload of part '.$part_num.' failed');
2019-12-29 18:28:47 +01:00
}
2020-01-31 19:29:43 +01:00
// Got OK from server for chunk!
$cb();
} catch (\Throwable $e) {
$this->logger("Got exception while uploading: {$e}");
$exception = $e;
2019-06-24 18:55:37 +02:00
}
2020-01-31 19:29:43 +01:00
});
$promises[] = $writePromise;
2019-12-29 18:28:47 +01:00
++$part_num;
2020-01-31 19:29:43 +01:00
if (!($part_num % $parallel_chunks)) {
// By default, 10 mb at a time, for a typical bandwidth of 1gbps (run the code in this every second)
2019-12-29 18:28:47 +01:00
yield Tools::all($promises);
2019-06-24 18:55:37 +02:00
$promises = [];
2019-12-31 12:45:49 +01:00
if ($exception) {
throw $exception;
}
2019-09-01 23:39:29 +02:00
$time = \microtime(true) - $start;
2020-01-31 19:29:43 +01:00
$speed = (int) ($size * 8 / $time) / 1000000;
$this->logger->logger("Partial upload time: {$time}");
$this->logger->logger("Partial upload speed: {$speed} mbps");
2019-06-24 18:55:37 +02:00
}
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
}
2019-12-29 18:28:47 +01:00
yield all($promises);
yield all($resPromises);
2019-09-01 23:39:29 +02:00
$time = \microtime(true) - $start;
2020-01-31 19:29:43 +01:00
$speed = (int) ($size * 8 / $time) / 1000000;
$this->logger->logger("Total upload time: {$time}");
$this->logger->logger("Total upload speed: {$speed} mbps");
2019-12-29 14:21:25 +01:00
$constructor = ['_' => $constructor, 'id' => $file_id, 'parts' => $part_total_num, 'name' => $fileName, 'mime_type' => $mime];
if ($encrypted === true) {
$constructor['key_fingerprint'] = $fingerprint;
$constructor['key'] = $key;
$constructor['iv'] = $iv;
}
2020-01-31 19:29:43 +01:00
$constructor['md5_checksum'] = '';
//\hash_final($ctx);
return $constructor;
}
2019-12-27 20:29:22 +01:00
/**
* Reupload telegram file.
*
* @param mixed $media Telegram file
* @param callable $cb Callback (DEPRECATED, use FileCallbackInterface)
* @param boolean $encrypted Whether to encrypt file for secret chats
*
2020-10-02 16:13:19 +02:00
* @return \Generator
*
* @psalm-return \Generator<int|mixed, \Amp\Promise|array, mixed, mixed>
2019-12-27 20:29:22 +01:00
*/
public function uploadFromTgfile($media, $cb = null, bool $encrypted = false): \Generator
2019-06-24 18:55:37 +02:00
{
2019-09-01 23:39:29 +02:00
if (\is_object($media) && $media instanceof FileCallbackInterface) {
2019-06-24 18:55:37 +02:00
$cb = $media;
$media = $media->getFile();
}
2020-01-31 19:29:43 +01:00
$media = (yield from $this->getDownloadInfo($media));
2019-06-24 18:55:37 +02:00
if (!isset($media['size'], $media['mime'])) {
throw new Exception('Wrong file provided!');
}
$size = $media['size'];
$mime = $media['mime'];
$chunk_size = 512 * 1024;
2019-12-30 00:22:01 +01:00
$bridge = new class($size, $chunk_size, $cb) {
2019-12-29 18:28:47 +01:00
/**
* Read promises.
*
* @var Deferred[]
*/
private $read = [];
2020-01-16 21:14:38 +01:00
/**
* Read promises (write lenth).
*
* @var int[]
*/
private $wrote = [];
2019-12-29 18:28:47 +01:00
/**
* Write promises.
*
* @var Deferred[]
*/
private $write = [];
/**
* Part size.
*
* @var int
*/
private $partSize;
/**
* Offset for callback.
2019-12-29 18:28:47 +01:00
*
* @var int
*/
private $offset = 0;
2019-12-30 00:22:01 +01:00
/**
2019-12-30 01:04:06 +01:00
* Callback.
2019-12-30 00:22:01 +01:00
*
* @var ?callable
*/
private $cb;
2019-12-29 18:28:47 +01:00
/**
* Constructor.
*
2020-01-17 14:30:12 +01:00
* @param integer $size Total file size
* @param integer $partSize Part size
2020-01-18 16:59:59 +01:00
* @param ?callable $cb Callback
2019-12-29 18:28:47 +01:00
*/
2020-01-18 16:59:59 +01:00
public function __construct(int $size, int $partSize, ?callable $cb)
2019-06-24 18:55:37 +02:00
{
2019-12-29 18:28:47 +01:00
for ($x = 0; $x < $size; $x += $partSize) {
2020-01-31 19:29:43 +01:00
$this->read[] = new Deferred();
$this->write[] = new Deferred();
$this->wrote[] = $size - $x < $partSize ? $size - $x : $partSize;
2019-06-24 18:55:37 +02:00
}
2019-12-29 18:28:47 +01:00
$this->partSize = $partSize;
2019-12-30 00:22:01 +01:00
$this->cb = $cb;
2019-06-25 12:39:31 +02:00
}
2019-12-29 18:28:47 +01:00
/**
* Read chunk.
*
* @param integer $offset Offset
* @param integer $size Chunk size
*
* @return Promise
*/
public function read(int $offset, int $size): Promise
2019-06-25 12:39:31 +02:00
{
2019-12-29 18:28:47 +01:00
$offset /= $this->partSize;
return $this->write[$offset]->promise();
}
/**
* Write chunk.
*
* @param string $data Data
* @param integer $offset Offset
*
* @return Promise
*/
public function write(string $data, int $offset): Promise
{
$offset /= $this->partSize;
$this->write[$offset]->resolve($data);
return $this->read[$offset]->promise();
}
/**
* Read callback, called when the chunk is read and fully resent.
2019-12-29 18:28:47 +01:00
*
2019-12-30 00:30:02 +01:00
* @param mixed ...$params Params to be passed to cb
*
2019-12-29 18:28:47 +01:00
* @return void
*/
2019-12-30 00:30:02 +01:00
public function callback(...$params): void
2019-12-29 18:28:47 +01:00
{
2020-01-16 21:14:38 +01:00
$offset = $this->offset++;
$this->read[$offset]->resolve($this->wrote[$offset]);
2019-12-30 00:22:01 +01:00
if ($this->cb) {
2019-12-30 00:30:02 +01:00
Tools::callFork(($this->cb)(...$params));
2019-12-30 00:22:01 +01:00
}
2019-06-24 18:55:37 +02:00
}
};
$reader = [$bridge, 'read'];
$writer = [$bridge, 'write'];
2019-12-30 00:22:01 +01:00
$cb = [$bridge, 'callback'];
2019-12-29 18:28:47 +01:00
$read = $this->uploadFromCallable($reader, $size, $mime, '', $cb, true, $encrypted);
2019-10-29 21:33:23 +01:00
$write = $this->downloadToCallable($media, $writer, null, true, 0, -1, $chunk_size);
2020-08-29 17:58:02 +02:00
[$res] = yield Tools::all([$read, $write]);
2019-06-25 12:39:31 +02:00
return $res;
2019-06-24 18:55:37 +02:00
}
2020-01-31 19:29:43 +01:00
private function genAllFile($media): \Generator
2018-03-23 16:39:58 +01:00
{
2019-11-01 12:45:15 +01:00
$res = [$this->TL->getConstructors()->findByPredicate($media['_'])['type'] => $media];
switch ($media['_']) {
2019-05-06 13:25:38 +02:00
case 'messageMediaPoll':
$res['Poll'] = $media['poll'];
$res['InputMedia'] = ['_' => 'inputMediaPoll', 'poll' => $res['Poll']];
if (isset($res['Poll']['quiz']) && $res['Poll']['quiz']) {
if (empty($media['results']['results'])) {
//quizzes need a correct answer
throw new \danog\MadelineProto\Exception('No poll results');
}
foreach ($media['results']['results'] as $answer) {
if ($answer['correct']) {
$res['InputMedia']['correct_answers'][] = $answer['option'];
}
}
}
if (isset($media['results']['solution'])) {
$res['InputMedia']['solution'] = $media['results']['solution'];
}
if (isset($media['results']['solution_entities'])) {
$res['InputMedia']['solution_entities'] = $media['results']['solution_entities'];
}
2019-05-06 13:25:38 +02:00
break;
case 'updateMessagePoll':
$res['Poll'] = $media['poll'];
$res['InputMedia'] = ['_' => 'inputMediaPoll', 'poll' => $res['Poll']];
$res['MessageMedia'] = ['_' => 'messageMediaPoll', 'poll' => $res['Poll'], 'results' => $media['results']];
if (isset($res['Poll']['quiz']) && $res['Poll']['quiz']) {
if (empty($media['results']['results'])) {
//quizzes need a correct answer
throw new \danog\MadelineProto\Exception('No poll results');
}
foreach ($media['results']['results'] as $answer) {
if ($answer['correct']) {
$res['InputMedia']['correct_answers'][] = $answer['option'];
}
}
}
if (isset($media['results']['solution'])) {
$res['InputMedia']['solution'] = $media['results']['solution'];
}
if (isset($media['results']['solution_entities'])) {
$res['InputMedia']['solution_entities'] = $media['results']['solution_entities'];
}
2019-05-06 13:25:38 +02:00
break;
case 'messageMediaPhoto':
if (!isset($media['photo']['access_hash'])) {
throw new \danog\MadelineProto\Exception('No access hash');
}
$res['Photo'] = $media['photo'];
2020-09-12 20:01:34 +02:00
$res['InputPhoto'] = ['_' => 'inputPhoto', 'id' => $media['photo']['id'], 'access_hash' => $media['photo']['access_hash'], 'file_reference' => yield from $this->referenceDatabase->getReference(ReferenceDatabase::PHOTO_LOCATION, $media['photo'])];
$res['InputMedia'] = ['_' => 'inputMediaPhoto', 'id' => $res['InputPhoto']];
if (isset($media['ttl_seconds'])) {
$res['InputMedia']['ttl_seconds'] = $media['ttl_seconds'];
}
break;
case 'messageMediaDocument':
if (!isset($media['document']['access_hash'])) {
throw new \danog\MadelineProto\Exception('No access hash');
}
$res['Document'] = $media['document'];
2020-09-12 20:01:34 +02:00
$res['InputDocument'] = ['_' => 'inputDocument', 'id' => $media['document']['id'], 'access_hash' => $media['document']['access_hash'], 'file_reference' => yield from $this->referenceDatabase->getReference(ReferenceDatabase::DOCUMENT_LOCATION, $media['document'])];
$res['InputMedia'] = ['_' => 'inputMediaDocument', 'id' => $res['InputDocument']];
if (isset($media['ttl_seconds'])) {
$res['InputMedia']['ttl_seconds'] = $media['ttl_seconds'];
}
break;
2020-03-31 17:30:25 +02:00
case 'messageMediaDice':
$res['InputMedia'] = ['_' => 'inputMediaDice', 'emoticon' => $media['emoticon']];
2020-03-31 17:30:25 +02:00
break;
2019-05-06 13:25:38 +02:00
case 'poll':
$res['InputMedia'] = ['_' => 'inputMediaPoll', 'poll' => $res['Poll']];
break;
case 'document':
if (!isset($media['access_hash'])) {
throw new \danog\MadelineProto\Exception('No access hash');
}
2020-09-12 20:01:34 +02:00
$res['InputDocument'] = ['_' => 'inputDocument', 'id' => $media['id'], 'access_hash' => $media['access_hash'], 'file_reference' => yield from $this->referenceDatabase->getReference(ReferenceDatabase::DOCUMENT_LOCATION, $media)];
$res['InputMedia'] = ['_' => 'inputMediaDocument', 'id' => $res['InputDocument']];
$res['MessageMedia'] = ['_' => 'messageMediaDocument', 'document' => $media];
break;
case 'photo':
if (!isset($media['access_hash'])) {
throw new \danog\MadelineProto\Exception('No access hash');
}
2020-09-12 20:01:34 +02:00
$res['InputPhoto'] = ['_' => 'inputPhoto', 'id' => $media['id'], 'access_hash' => $media['access_hash'], 'file_reference' => yield from $this->referenceDatabase->getReference(ReferenceDatabase::PHOTO_LOCATION, $media)];
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
$res['InputMedia'] = ['_' => 'inputMediaPhoto', 'id' => $res['InputPhoto']];
$res['MessageMedia'] = ['_' => 'messageMediaPhoto', 'photo' => $media];
break;
default:
2018-12-28 03:37:00 +01:00
throw new \danog\MadelineProto\Exception("Could not convert media object of type {$media['_']}");
}
2018-03-23 16:39:58 +01:00
return $res;
}
/**
* Get info about file.
*
* @param mixed $constructor File ID
*
* @return \Generator<array>
*/
public function getFileInfo($constructor): \Generator
2018-03-23 16:39:58 +01:00
{
2019-09-01 23:39:29 +02:00
if (\is_string($constructor)) {
2020-01-16 20:19:03 +01:00
$constructor = $this->unpackFileId($constructor);
if (isset($constructor['MessageMedia'])) {
$constructor = $constructor['MessageMedia'];
} elseif (isset($constructor['InputMedia'])) {
return $constructor;
} elseif (isset($constructor['Chat']) || isset($constructor['User'])) {
2020-02-09 16:24:57 +01:00
throw new Exception("Chat photo file IDs can't be reused to resend chat photos, please use getPwrChat()['photo'], instead");
2020-01-16 20:19:03 +01:00
}
}
switch ($constructor['_']) {
case 'updateNewMessage':
case 'updateNewChannelMessage':
case 'updateEditMessage':
case 'updateEditChannelMessage':
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
$constructor = $constructor['message'];
2020-01-31 19:29:43 +01:00
// no break
case 'message':
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
$constructor = $constructor['media'];
}
2020-01-31 19:29:43 +01:00
return yield from $this->genAllFile($constructor);
}
2019-12-27 20:29:22 +01:00
/**
* Get download info of the propic of a user
* Returns an array with the following structure:.
*
* `$info['ext']` - The file extension
* `$info['name']` - The file name, without the extension
* `$info['mime']` - The file mime type
* `$info['size']` - The file size
*
* @param mixed $messageMedia File ID
2019-12-27 20:29:22 +01:00
*
* @return \Generator<array>
*/
public function getPropicInfo($data): \Generator
{
return yield from $this->getDownloadInfo(yield $this->chats[(yield from $this->getInfo($data))['bot_api_id']]);
}
/**
* Extract file info from bot API message.
*
* @param array $info Bot API message object
*
* @return ?array
*/
public static function extractBotAPIFile(array $info): ?array
{
foreach (TYPES as $type) {
if (isset($info[$type]) && \is_array($info[$type])) {
$method = $type;
break;
}
}
if (!isset($method)) {
return null;
}
$info = $info[$method];
if ($method === 'photo') {
$info = $info[0];
}
$info['file_type'] = $method;
return $info;
}
2019-12-27 20:29:22 +01:00
/**
* Get download info of file
* Returns an array with the following structure:.
*
* `$info['ext']` - The file extension
* `$info['name']` - The file name, without the extension
* `$info['mime']` - The file mime type
* `$info['size']` - The file size
*
* @param mixed $messageMedia File ID
2019-12-27 20:29:22 +01:00
*
* @return \Generator<array>
*/
public function getDownloadInfo($messageMedia): \Generator
{
if (\is_string($messageMedia)) {
$messageMedia = $this->unpackFileId($messageMedia);
if (isset($messageMedia['InputFileLocation'])) {
return $messageMedia;
2020-01-16 20:19:03 +01:00
}
$messageMedia = $messageMedia['MessageMedia'] ?? $messageMedia['User'] ?? $messageMedia['Chat'];
}
if (!isset($messageMedia['_'])) {
if (!isset($messageMedia['InputFileLocation']) && !isset($messageMedia['file_id'])) {
$messageMedia = self::extractBotAPIFile($messageMedia) ?? $messageMedia;
}
if (isset($messageMedia['file_id'])) {
$res = yield from $this->getDownloadInfo($messageMedia['file_id']);
$res['size'] = $messageMedia['file_size'] ?? 0;
$res['mime'] = $messageMedia['mime_type'] ?? 'application/octet-stream';
$pathinfo = \pathinfo($messageMedia['file_name']);
if (isset($pathinfo['extension'])) {
$res['ext'] = '.'.$pathinfo['extension'];
}
$res['name'] = $pathinfo['filename'];
return $res;
}
return $messageMedia;
}
$res = [];
switch ($messageMedia['_']) {
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
// Updates
case 'updateNewMessage':
case 'updateNewChannelMessage':
$messageMedia = $messageMedia['message'];
2020-01-31 19:29:43 +01:00
// no break
case 'message':
return yield from $this->getDownloadInfo($messageMedia['media']);
case 'updateNewEncryptedMessage':
$messageMedia = $messageMedia['message'];
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
// Secret media
2019-09-01 23:39:29 +02:00
// no break
case 'encryptedMessage':
if ($messageMedia['decrypted_message']['media']['_'] === 'decryptedMessageMediaExternalDocument') {
return yield from $this->getDownloadInfo($messageMedia['decrypted_message']['media']);
2017-03-11 19:55:56 +01:00
}
$res['InputFileLocation'] = ['_' => 'inputEncryptedFileLocation', 'id' => $messageMedia['file']['id'], 'access_hash' => $messageMedia['file']['access_hash'], 'dc_id' => $messageMedia['file']['dc_id']];
$res['size'] = $messageMedia['decrypted_message']['media']['size'];
$res['key_fingerprint'] = $messageMedia['file']['key_fingerprint'];
$res['key'] = $messageMedia['decrypted_message']['media']['key'];
$res['iv'] = $messageMedia['decrypted_message']['media']['iv'];
if (isset($messageMedia['decrypted_message']['media']['file_name'])) {
$pathinfo = \pathinfo($messageMedia['decrypted_message']['media']['file_name']);
if (isset($pathinfo['extension'])) {
2020-02-05 17:55:18 +01:00
$res['ext'] = '.'.$pathinfo['extension'];
}
$res['name'] = $pathinfo['filename'];
}
if (isset($messageMedia['decrypted_message']['media']['mime_type'])) {
$res['mime'] = $messageMedia['decrypted_message']['media']['mime_type'];
} elseif ($messageMedia['decrypted_message']['media']['_'] === 'decryptedMessageMediaPhoto') {
$res['mime'] = 'image/jpeg';
2017-03-11 19:55:56 +01:00
}
if (isset($messageMedia['decrypted_message']['media']['attributes'])) {
foreach ($messageMedia['decrypted_message']['media']['attributes'] as $attribute) {
switch ($attribute['_']) {
case 'documentAttributeFilename':
2019-09-01 23:39:29 +02:00
$pathinfo = \pathinfo($attribute['file_name']);
if (isset($pathinfo['extension'])) {
2020-02-05 17:55:18 +01:00
$res['ext'] = '.'.$pathinfo['extension'];
}
$res['name'] = $pathinfo['filename'];
break;
case 'documentAttributeAudio':
$audio = $attribute;
break;
}
}
}
if (isset($audio) && isset($audio['title']) && !isset($res['name'])) {
$res['name'] = $audio['title'];
if (isset($audio['performer'])) {
2020-02-05 17:55:18 +01:00
$res['name'] .= ' - '.$audio['performer'];
}
}
2019-06-24 20:03:15 +02:00
if (!isset($res['ext']) || $res['ext'] === '') {
$res['ext'] = Tools::getExtensionFromLocation($res['InputFileLocation'], Tools::getExtensionFromMime($res['mime'] ?? 'image/jpeg'));
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
}
2019-06-24 20:03:15 +02:00
if (!isset($res['mime']) || $res['mime'] === '') {
$res['mime'] = Tools::getMimeFromExtension($res['ext'], 'image/jpeg');
}
2019-06-24 20:03:15 +02:00
if (!isset($res['name']) || $res['name'] === '') {
$res['name'] = Tools::unpackSignedLongString($messageMedia['file']['access_hash']);
}
return $res;
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
// Wallpapers
case 'wallPaper':
2020-04-05 14:57:33 +02:00
return $this->getDownloadInfo($messageMedia['document']);
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
// Photos
case 'photo':
case 'messageMediaPhoto':
if ($messageMedia['_'] == 'photo') {
$messageMedia = ['_' => 'messageMediaPhoto', 'photo' => $messageMedia, 'ttl_seconds' => 0];
}
$res['MessageMedia'] = $messageMedia;
$messageMedia = $messageMedia['photo'];
2020-10-01 18:02:54 +02:00
$size = Tools::maxSize($messageMedia['sizes']);
2020-01-31 19:29:43 +01:00
$res = \array_merge($res, yield from $this->getDownloadInfo($size));
2020-09-12 20:01:34 +02:00
$res['InputFileLocation'] = ['_' => 'inputPhotoFileLocation', 'thumb_size' => $res['thumb_size'] ?? 'x', 'dc_id' => $messageMedia['dc_id'], 'access_hash' => $messageMedia['access_hash'], 'id' => $messageMedia['id'], 'file_reference' => yield from $this->referenceDatabase->getReference(ReferenceDatabase::PHOTO_LOCATION, $messageMedia)];
2019-06-22 18:22:38 +02:00
return $res;
case 'user':
case 'folder':
case 'channel':
case 'chat':
case 'updateUserPhoto':
$res = (yield from $this->getDownloadInfo($messageMedia['photo']));
if (\is_array($messageMedia) && ($messageMedia['min'] ?? false) && isset($messageMedia['access_hash'])) {
2020-01-31 19:29:43 +01:00
// bot API file ID
$messageMedia['min'] = false;
$peer = $this->genAll($messageMedia)['InputPeer'];
2020-01-16 20:19:03 +01:00
} else {
$peer = (yield from $this->getInfo($messageMedia))['InputPeer'];
2020-01-16 20:19:03 +01:00
}
2020-01-31 19:29:43 +01:00
$res['InputFileLocation'] = ['_' => 'inputPeerPhotoFileLocation', 'big' => $res['big'], 'dc_id' => $res['InputFileLocation']['dc_id'], 'peer' => $peer, 'volume_id' => $res['InputFileLocation']['volume_id'], 'local_id' => $res['InputFileLocation']['local_id']];
2019-06-22 18:22:38 +02:00
return $res;
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
case 'userProfilePhoto':
case 'chatPhoto':
$size = $messageMedia['photo_big'] ?? $messageMedia['photo_small'];
2020-01-31 19:29:43 +01:00
$res = (yield from $this->getDownloadInfo($size));
$res['big'] = isset($messageMedia['photo_big']);
$res['InputFileLocation']['dc_id'] = $messageMedia['dc_id'];
2019-06-22 18:22:38 +02:00
return $res;
case 'photoStrippedSize':
$res['size'] = \strlen($messageMedia['bytes']['bytes'] ?? $messageMedia['bytes']);
$res['data'] = $messageMedia['bytes'];
2019-06-22 18:22:38 +02:00
$res['thumb_size'] = 'JPG';
return $res;
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
case 'photoCachedSize':
$res['size'] = \strlen($messageMedia['bytes']);
$res['data'] = $messageMedia['bytes'];
2019-06-22 18:22:38 +02:00
//$res['thumb_size'] = $res['data'];
$res['thumb_size'] = $messageMedia['type'];
if ($messageMedia['location']['_'] === 'fileLocationUnavailable') {
$res['name'] = Tools::unpackSignedLongString($messageMedia['volume_id']).'_'.$messageMedia['local_id'];
$res['mime'] = Tools::getMimeFromBuffer($res['data']);
$res['ext'] = TOols::getExtensionFromMime($res['mime']);
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
} else {
$res = \array_merge($res, yield from $this->getDownloadInfo($messageMedia['location']));
}
return $res;
case 'photoSize':
$res = (yield from $this->getDownloadInfo($messageMedia['location']));
$res['thumb_size'] = $messageMedia['type'];
2019-06-22 18:22:38 +02:00
//$res['thumb_size'] = $size;
if (isset($messageMedia['size'])) {
$res['size'] = $messageMedia['size'];
}
return $res;
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
case 'fileLocationUnavailable':
throw new \danog\MadelineProto\Exception('File location unavailable');
case 'fileLocation':
$res['name'] = Tools::unpackSignedLongString($messageMedia['volume_id']).'_'.$messageMedia['local_id'];
2020-09-12 20:01:34 +02:00
$res['InputFileLocation'] = ['_' => 'inputFileLocation', 'volume_id' => $messageMedia['volume_id'], 'local_id' => $messageMedia['local_id'], 'secret' => $messageMedia['secret'], 'dc_id' => $messageMedia['dc_id'], 'file_reference' => yield from $this->referenceDatabase->getReference(ReferenceDatabase::PHOTO_LOCATION_LOCATION, $messageMedia)];
$res['ext'] = Tools::getExtensionFromLocation($res['InputFileLocation'], '.jpg');
$res['mime'] = Tools::getMimeFromExtension($res['ext'], 'image/jpeg');
2019-06-22 18:22:38 +02:00
return $res;
case 'fileLocationToBeDeprecated':
$res['name'] = Tools::unpackSignedLongString($messageMedia['volume_id']).'_'.$messageMedia['local_id'];
2019-06-22 18:22:38 +02:00
$res['ext'] = '.jpg';
$res['mime'] = Tools::getMimeFromExtension($res['ext'], 'image/jpeg');
2019-06-22 18:22:38 +02:00
$res['InputFileLocation'] = [
2020-01-31 19:29:43 +01:00
'_' => 'inputFileLocationTemp',
// Will be overwritten
'volume_id' => $messageMedia['volume_id'],
'local_id' => $messageMedia['local_id'],
2019-06-22 18:22:38 +02:00
];
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
return $res;
// Documents
case 'decryptedMessageMediaExternalDocument':
case 'document':
$messageMedia = ['_' => 'messageMediaDocument', 'ttl_seconds' => 0, 'document' => $messageMedia];
2020-01-31 19:29:43 +01:00
// no break
case 'messageMediaDocument':
$res['MessageMedia'] = $messageMedia;
foreach ($messageMedia['document']['attributes'] as $attribute) {
switch ($attribute['_']) {
case 'documentAttributeFilename':
2019-09-01 23:39:29 +02:00
$pathinfo = \pathinfo($attribute['file_name']);
if (isset($pathinfo['extension'])) {
2020-02-05 17:55:18 +01:00
$res['ext'] = '.'.$pathinfo['extension'];
}
$res['name'] = $pathinfo['filename'];
break;
case 'documentAttributeAudio':
$audio = $attribute;
break;
2017-02-16 04:55:47 +01:00
}
}
if (isset($audio) && isset($audio['title']) && !isset($res['name'])) {
$res['name'] = $audio['title'];
if (isset($audio['performer'])) {
2020-02-05 17:55:18 +01:00
$res['name'] .= ' - '.$audio['performer'];
}
}
2020-09-12 20:01:34 +02:00
$res['InputFileLocation'] = ['_' => 'inputDocumentFileLocation', 'id' => $messageMedia['document']['id'], 'access_hash' => $messageMedia['document']['access_hash'], 'version' => isset($messageMedia['document']['version']) ? $messageMedia['document']['version'] : 0, 'dc_id' => $messageMedia['document']['dc_id'], 'file_reference' => yield from $this->referenceDatabase->getReference(ReferenceDatabase::DOCUMENT_LOCATION, $messageMedia['document'])];
2019-06-24 20:03:15 +02:00
if (!isset($res['ext']) || $res['ext'] === '') {
$res['ext'] = Tools::getExtensionFromLocation($res['InputFileLocation'], Tools::getExtensionFromMime($messageMedia['document']['mime_type']));
}
2019-06-24 20:03:15 +02:00
if (!isset($res['name']) || $res['name'] === '') {
$res['name'] = Tools::unpackSignedLongString($messageMedia['document']['access_hash']);
}
if (isset($messageMedia['document']['size'])) {
$res['size'] = $messageMedia['document']['size'];
}
2020-03-28 11:42:02 +01:00
$res['name'] .= '_'.Tools::unpackSignedLongString($messageMedia['document']['id']);
$res['mime'] = $messageMedia['document']['mime_type'];
return $res;
default:
throw new \danog\MadelineProto\Exception('Invalid constructor provided: '.$messageMedia['_']);
}
}
2019-12-27 20:29:22 +01:00
/**
* Download file to directory.
*
* @param mixed $messageMedia File to download
2019-12-27 20:29:22 +01:00
* @param string|FileCallbackInterface $dir Directory where to download the file
* @param callable $cb Callback (DEPRECATED, use FileCallbackInterface)
*
2020-10-02 16:13:19 +02:00
* @return \Generator
*
* @psalm-return \Generator<int|mixed, \Amp\Promise|\Amp\Promise<\Amp\File\File>|\Amp\Promise<\Amp\Ipc\Sync\ChannelledSocket>|\Amp\Promise<callable|null>|\Amp\Promise<mixed>|array|bool|mixed, mixed, false|string>
2019-12-27 20:29:22 +01:00
*/
public function downloadToDir($messageMedia, $dir, $cb = null): \Generator
{
2019-09-01 23:39:29 +02:00
if (\is_object($dir) && $dir instanceof FileCallbackInterface) {
$cb = $dir;
$dir = $dir->getFile();
}
$messageMedia = (yield from $this->getDownloadInfo($messageMedia));
return yield from $this->downloadToFile($messageMedia, $dir.'/'.$messageMedia['name'].$messageMedia['ext'], $cb);
}
2019-12-27 20:29:22 +01:00
/**
* Download file.
*
* @param mixed $messageMedia File to download
2019-12-27 20:29:22 +01:00
* @param string|FileCallbackInterface $file Downloaded file path
* @param callable $cb Callback (DEPRECATED, use FileCallbackInterface)
*
2020-10-02 16:13:19 +02:00
* @return \Generator Downloaded file path
*
* @psalm-return \Generator<int|mixed, \Amp\Promise|\Amp\Promise<\Amp\File\File>|\Amp\Promise<\Amp\Ipc\Sync\ChannelledSocket>|\Amp\Promise<callable|null>|\Amp\Promise<mixed>|array|bool|mixed, mixed, false|string>
2019-12-27 20:29:22 +01:00
*/
public function downloadToFile($messageMedia, $file, $cb = null): \Generator
{
2019-09-01 23:39:29 +02:00
if (\is_object($file) && $file instanceof FileCallbackInterface) {
$cb = $file;
$file = $file->getFile();
}
2020-04-05 22:22:47 +02:00
$file = Tools::absolute(\preg_replace('|/+|', '/', $file));
2019-06-24 18:55:37 +02:00
if (!yield exists($file)) {
2019-09-01 23:39:29 +02:00
yield \touch($file);
2017-02-16 04:55:47 +01:00
}
2019-09-01 23:39:29 +02:00
$file = \realpath($file);
$messageMedia = (yield from $this->getDownloadInfo($messageMedia));
2020-02-05 17:55:18 +01:00
StatCacheAsync::clear($file);
$size = (yield statAsync($file))['size'];
2019-06-23 17:46:51 +02:00
$stream = yield open($file, 'cb');
2018-04-08 19:53:30 +02:00
$this->logger->logger('Waiting for lock of file to download...');
2020-08-29 17:58:02 +02:00
$unlock = yield Tools::flock($file, LOCK_EX);
2020-01-16 21:14:38 +01:00
$this->logger->logger('Got lock of file to download');
2018-02-18 15:59:39 +01:00
try {
yield from $this->downloadToStream($messageMedia, $stream, $cb, $size, -1);
2018-02-18 15:59:39 +01:00
} finally {
2019-06-23 17:46:51 +02:00
$unlock();
yield $stream->close();
2020-02-05 17:55:18 +01:00
StatCacheAsync::clear($file);
2018-02-18 15:59:39 +01:00
}
return $file;
}
2019-12-27 20:29:22 +01:00
/**
* Download file to callable.
* The callable must accept two parameters: string $payload, int $offset
* The callable will be called (possibly out of order, depending on the value of $seekable).
* The callable should return the number of written bytes.
*
* @param mixed $messageMedia File to download
2019-12-27 20:29:22 +01:00
* @param callable|FileCallbackInterface $callable Chunk callback
* @param callable $cb Status callback (DEPRECATED, use FileCallbackInterface)
* @param bool $seekable Whether the callable can be called out of order
* @param int $offset Offset where to start downloading
* @param int $end Offset where to stop downloading (inclusive)
* @param int $part_size Size of each chunk
*
2020-10-02 16:13:19 +02:00
* @return \Generator
*
* @psalm-return \Generator<int|mixed, \Amp\Promise|array, mixed, true>
2019-12-27 20:29:22 +01:00
*/
public function downloadToCallable($messageMedia, callable $callable, $cb = null, bool $seekable = true, int $offset = 0, int $end = -1, int $part_size = null): \Generator
2019-06-24 14:42:14 +02:00
{
$messageMedia = (yield from $this->getDownloadInfo($messageMedia));
2019-09-01 23:39:29 +02:00
if (\is_object($callable) && $callable instanceof FileCallbackInterface) {
2019-06-24 14:42:14 +02:00
$cb = $callable;
$callable = $callable->getFile();
}
2019-09-01 23:39:29 +02:00
if (!\is_callable($callable)) {
2019-06-24 15:14:09 +02:00
throw new Exception('Wrong callable provided');
}
2019-06-24 18:55:37 +02:00
if ($cb === null) {
$cb = function ($percent) {
2020-02-05 17:55:18 +01:00
$this->logger->logger('Download status: '.$percent.'%', \danog\MadelineProto\Logger::NOTICE);
2019-06-24 18:55:37 +02:00
};
}
if ($end === -1 && isset($messageMedia['size'])) {
$end = $messageMedia['size'];
2017-05-17 00:38:38 +02:00
}
$part_size = $part_size ?? 1024 * 1024;
$parallel_chunks = $this->settings->getFiles()->getDownloadParallelChunks();
$datacenter = $messageMedia['InputFileLocation']['dc_id'] ?? $this->settings->getDefaultDc();
2020-02-05 17:55:18 +01:00
if ($this->datacenter->has($datacenter.'_media')) {
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
$datacenter .= '_media';
}
if (isset($messageMedia['key'])) {
$digest = \hash('md5', $messageMedia['key'].$messageMedia['iv'], true);
2020-08-29 17:58:02 +02:00
$fingerprint = Tools::unpackSignedInt(\substr($digest, 0, 4) ^ \substr($digest, 4, 4));
if ($fingerprint !== $messageMedia['key_fingerprint']) {
2017-03-11 19:55:56 +01:00
throw new \danog\MadelineProto\Exception('Fingerprint mismatch!');
}
2020-04-05 14:57:33 +02:00
$ige = new AES('ige');
$ige->setIV($messageMedia['iv']);
$ige->setKey($messageMedia['key']);
$ige->enableContinuousBuffer();
2019-12-27 20:29:22 +01:00
$seekable = false;
}
2019-06-23 17:46:51 +02:00
if ($offset === $end) {
2020-01-18 16:11:40 +01:00
$cb(100, 0, 0);
2019-06-23 17:46:51 +02:00
return true;
}
$params = [];
$start_at = $offset % $part_size;
$probable_end = $end !== -1 ? $end : 512 * 1024 * 4000;
2019-06-23 17:46:51 +02:00
$breakOut = false;
for ($x = $offset - $start_at; $x < $probable_end; $x += $part_size) {
$end_at = $part_size;
2019-06-24 14:42:14 +02:00
if ($end !== -1 && $x + $part_size > $end) {
2019-06-25 12:39:31 +02:00
$end_at = $end % $part_size;
2019-06-23 17:46:51 +02:00
$breakOut = true;
}
2020-01-31 19:29:43 +01:00
$params[] = ['offset' => $x, 'limit' => $part_size, 'part_start_at' => $start_at, 'part_end_at' => $end_at];
2019-06-23 17:46:51 +02:00
$start_at = 0;
if ($breakOut) {
break;
}
}
if (!$params) {
2020-01-18 16:11:40 +01:00
$cb(100, 0, 0);
2019-06-23 17:46:51 +02:00
return true;
}
2019-09-01 23:39:29 +02:00
$count = \count($params);
$time = 0;
$speed = 0;
2020-01-16 20:19:03 +01:00
$origCb = $cb;
$cb = static function () use ($cb, $count, &$time, &$speed) {
2019-06-23 17:46:51 +02:00
static $cur = 0;
$cur++;
2020-08-29 17:58:02 +02:00
Tools::callFork($cb($cur * 100 / $count, $time, $speed));
2019-06-23 17:46:51 +02:00
};
$cdn = false;
2019-06-23 17:46:51 +02:00
$params[0]['previous_promise'] = new Success(true);
2019-09-01 23:39:29 +02:00
$start = \microtime(true);
2020-04-05 15:33:01 +02:00
$old_dc = null;
2020-02-12 18:16:08 +01:00
$size = yield from $this->downloadPart($messageMedia, $cdn, $datacenter, $old_dc, $ige, $cb, $initParam = \array_shift($params), $callable, $seekable);
2020-01-31 19:29:43 +01:00
if ($initParam['part_end_at'] - $initParam['part_start_at'] !== $size) {
// Premature end for undefined length files
2020-01-18 16:11:40 +01:00
$origCb(100, 0, 0);
2020-01-16 20:19:03 +01:00
return true;
}
2020-08-29 17:58:02 +02:00
$parallel_chunks = $seekable ? $parallel_chunks : 1;
2019-06-23 17:46:51 +02:00
if ($params) {
$previous_promise = new Success(true);
$promises = [];
foreach ($params as $key => $param) {
$param['previous_promise'] = $previous_promise;
2020-08-29 17:58:02 +02:00
$previous_promise = Tools::call($this->downloadPart($messageMedia, $cdn, $datacenter, $old_dc, $ige, $cb, $param, $callable, $seekable));
2019-06-23 17:46:51 +02:00
$previous_promise->onResolve(static function ($e, $res) use (&$size) {
if ($res) {
$size += $res;
}
});
2019-06-24 14:42:14 +02:00
$promises[] = $previous_promise;
2020-01-31 19:29:43 +01:00
if (!($key % $parallel_chunks)) {
// 20 mb at a time, for a typical bandwidth of 1gbps
2020-08-29 17:58:02 +02:00
$res = yield Tools::all($promises);
2020-01-16 21:14:38 +01:00
$promises = [];
foreach ($res as $r) {
if (!$r) {
break 2;
}
2020-01-16 20:19:03 +01:00
}
2019-09-01 23:39:29 +02:00
$time = \microtime(true) - $start;
2020-01-31 19:29:43 +01:00
$speed = (int) ($size * 8 / $time) / 1000000;
$this->logger->logger("Partial download time: {$time}");
$this->logger->logger("Partial download speed: {$speed} mbps");
2019-06-23 17:46:51 +02:00
}
}
if ($promises) {
2020-08-29 17:58:02 +02:00
yield Tools::all($promises);
2017-04-23 16:30:11 +02:00
}
2019-06-23 17:46:51 +02:00
}
2019-09-01 23:39:29 +02:00
$time = \microtime(true) - $start;
2020-01-31 19:29:43 +01:00
$speed = (int) ($size * 8 / $time) / 1000000;
$this->logger->logger("Total download time: {$time}");
$this->logger->logger("Total download speed: {$speed} mbps");
2019-06-23 17:46:51 +02:00
if ($cdn) {
$this->clearCdnHashes($messageMedia['file_token']);
2019-06-23 17:46:51 +02:00
}
if (!isset($messageMedia['size'])) {
2020-01-18 16:59:59 +01:00
$origCb(100, $time, $speed);
2020-01-16 20:19:03 +01:00
}
2019-06-23 17:46:51 +02:00
return true;
}
2019-12-27 20:29:22 +01:00
/**
* Download file part.
*
* @param array $messageMedia File object
2019-12-27 20:29:22 +01:00
* @param bool $cdn Whether this is a CDN file
* @param string $datacenter DC ID
* @param ?string $old_dc Previous DC ID
2019-12-27 20:29:22 +01:00
* @param AES $ige IGE decryptor instance
* @param callable $cb Status callback
2019-12-28 03:43:21 +01:00
* @param array $offset Offset
2019-12-27 20:29:22 +01:00
* @param callable $callable Chunk callback
* @param boolean $seekable Whether the download file is seekable
* @param boolean $postpone Whether to postpone method call
*
* @return \Generator
*/
private function downloadPart(&$messageMedia, bool &$cdn, &$datacenter, &$old_dc, &$ige, $cb, array $offset, $callable, bool $seekable, bool $postpone = false): \Generator
2019-06-23 17:46:51 +02:00
{
static $method = [
2020-01-31 19:29:43 +01:00
false => 'upload.getFile',
// non-cdn
true => 'upload.getCdnFile',
2019-06-23 17:46:51 +02:00
];
do {
if (!$cdn) {
$basic_param = ['location' => $messageMedia['InputFileLocation']];
2019-06-23 17:46:51 +02:00
} else {
$basic_param = ['file_token' => $messageMedia['file_token']];
2019-06-23 17:46:51 +02:00
}
//$x = 0;
while (true) {
try {
2020-02-05 17:37:01 +01:00
$res = yield from $this->methodCallAsyncRead($method[$cdn], $basic_param + $offset, ['heavy' => true, 'file' => true, 'FloodWaitLimit' => 0, 'datacenter' => &$datacenter, 'postpone' => $postpone]);
break;
} catch (\danog\MadelineProto\RPCErrorException $e) {
if (\strpos($e->rpc, 'FLOOD_WAIT_') === 0) {
yield Tools::sleep(1);
continue;
}
switch ($e->rpc) {
case 'FILE_TOKEN_INVALID':
$cdn = false;
continue 3;
default:
throw $e;
}
2017-02-16 04:55:47 +01:00
}
}
2020-02-12 18:16:08 +01:00
if ($res['_'] === 'upload.fileCdnRedirect') {
$cdn = true;
$messageMedia['file_token'] = $res['file_token'];
$messageMedia['cdn_key'] = $res['encryption_key'];
$messageMedia['cdn_iv'] = $res['encryption_iv'];
$old_dc = $datacenter;
2020-02-05 17:55:18 +01:00
$datacenter = $res['dc_id'].'_cdn';
2019-09-01 23:39:29 +02:00
if (!$this->datacenter->has($datacenter)) {
2017-08-01 12:17:53 +02:00
$this->config['expires'] = -1;
yield from $this->getConfig([]);
2017-08-01 12:17:53 +02:00
}
2018-04-08 19:53:30 +02:00
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['stored_on_cdn'], \danog\MadelineProto\Logger::NOTICE);
2019-09-01 23:39:29 +02:00
} elseif ($res['_'] === 'upload.cdnFileReuploadNeeded') {
2018-04-08 19:53:30 +02:00
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['cdn_reupload'], \danog\MadelineProto\Logger::NOTICE);
yield from $this->getConfig([]);
try {
$this->addCdnHashes($messageMedia['file_token'], yield from $this->methodCallAsyncRead('upload.reuploadCdnFile', ['file_token' => $messageMedia['file_token'], 'request_token' => $res['request_token']], ['heavy' => true, 'datacenter' => $old_dc]));
} catch (\danog\MadelineProto\RPCErrorException $e) {
switch ($e->rpc) {
case 'FILE_TOKEN_INVALID':
case 'REQUEST_TOKEN_INVALID':
$cdn = false;
continue 2;
default:
throw $e;
}
}
continue;
}
2020-01-16 21:14:38 +01:00
$res['bytes'] = (string) $res['bytes'];
if ($cdn === false && $res['type']['_'] === 'storage.fileUnknown' && $res['bytes'] === '') {
2019-06-23 17:46:51 +02:00
$datacenter = 0;
}
2020-01-31 19:29:43 +01:00
while ($cdn === false && $res['type']['_'] === 'storage.fileUnknown' && $res['bytes'] === '' && $this->datacenter->has(++$datacenter)) {
2020-02-05 17:37:01 +01:00
$res = yield from $this->methodCallAsyncRead('upload.getFile', $basic_param + $offset, ['heavy' => true, 'file' => true, 'FloodWaitLimit' => 0, 'datacenter' => $datacenter]);
}
2020-01-16 20:19:03 +01:00
if ($res['bytes'] === '') {
return 0;
}
if (isset($messageMedia['cdn_key'])) {
$ivec = \substr($messageMedia['cdn_iv'], 0, 12).\pack('N', $offset['offset'] >> 4);
2020-04-05 22:22:47 +02:00
$res['bytes'] = Crypt::ctrEncrypt($res['bytes'], $messageMedia['cdn_key'], $ivec);
$this->checkCdnHash($messageMedia['file_token'], $offset['offset'], $res['bytes'], $old_dc);
}
if (isset($messageMedia['key'])) {
$res['bytes'] = $ige->decrypt($res['bytes']);
}
2019-06-23 17:46:51 +02:00
if ($offset['part_start_at'] || $offset['part_end_at'] !== $offset['limit']) {
2019-09-01 23:39:29 +02:00
$res['bytes'] = \substr($res['bytes'], $offset['part_start_at'], $offset['part_end_at'] - $offset['part_start_at']);
2017-04-23 16:30:11 +02:00
}
2019-06-23 17:46:51 +02:00
if (!$seekable) {
2020-02-05 17:18:22 +01:00
yield $offset['previous_promise'];
2017-02-16 04:55:47 +01:00
}
2020-01-16 21:14:38 +01:00
$res = yield $callable($res['bytes'], $offset['offset'] + $offset['part_start_at']);
2019-06-23 17:46:51 +02:00
$cb();
2019-06-24 14:42:14 +02:00
return $res;
2019-06-23 17:46:51 +02:00
} while (true);
}
2017-07-23 17:44:01 +02:00
private $cdn_hashes = [];
2020-10-01 21:36:07 +02:00
private function addCdnHashes($file, $hashes): void
2017-07-23 17:44:47 +02:00
{
2017-07-23 17:44:01 +02:00
if (!isset($this->cdn_hashes[$file])) {
$this->cdn_hashes = [];
}
foreach ($hashes as $hash) {
2018-02-19 13:23:34 +01:00
$this->cdn_hashes[$file][$hash['offset']] = ['limit' => $hash['limit'], 'hash' => (string) $hash['hash']];
2017-07-23 17:44:01 +02:00
}
}
2020-01-31 19:29:43 +01:00
private function checkCdnHash($file, $offset, $data, &$datacenter): \Generator
2017-07-23 17:44:47 +02:00
{
2019-09-01 23:39:29 +02:00
while (\strlen($data)) {
2018-02-19 12:48:43 +01:00
if (!isset($this->cdn_hashes[$file][$offset])) {
2020-02-05 17:37:01 +01:00
$this->addCdnHashes($file, yield from $this->methodCallAsyncRead('upload.getCdnFileHashes', ['file_token' => $file, 'offset' => $offset], ['datacenter' => $datacenter]));
2018-02-19 12:48:43 +01:00
}
if (!isset($this->cdn_hashes[$file][$offset])) {
2020-02-05 17:55:18 +01:00
throw new \danog\MadelineProto\Exception('Could not fetch CDN hashes for offset '.$offset);
2018-02-19 12:48:43 +01:00
}
2019-09-01 23:39:29 +02:00
if (\hash('sha256', \substr($data, 0, $this->cdn_hashes[$file][$offset]['limit']), true) !== $this->cdn_hashes[$file][$offset]['hash']) {
2020-02-05 17:55:18 +01:00
throw new \danog\MadelineProto\SecurityException('CDN hash mismatch for offset '.$offset);
2018-02-19 12:48:43 +01:00
}
2019-09-01 23:39:29 +02:00
$data = \substr($data, $this->cdn_hashes[$file][$offset]['limit']);
2018-02-19 12:48:43 +01:00
$offset += $this->cdn_hashes[$file][$offset]['limit'];
2017-07-23 17:44:01 +02:00
}
2017-07-24 09:18:10 +02:00
return true;
2017-07-23 17:44:01 +02:00
}
2020-10-01 21:36:07 +02:00
/**
* @return true
*/
private function clearCdnHashes($file): bool
2017-07-23 17:44:47 +02:00
{
2017-07-24 09:18:10 +02:00
unset($this->cdn_hashes[$file]);
return true;
2017-07-23 17:44:01 +02:00
}
2018-02-24 17:54:39 +01:00
}