. * * @author Daniil Gentili * @copyright 2016-2023 Daniil Gentili * @license https://opensource.org/licenses/AGPL-3.0 AGPLv3 * @link https://docs.madelineproto.xyz MadelineProto documentation */ namespace danog\MadelineProto; use Amp\Cancellation; use Amp\Socket\ConnectContext; use Amp\Socket\Socket; use Amp\Socket\SocketAddress; use Amp\Socket\SocketConnector; use Throwable; /** @internal */ final class ContextConnector implements SocketConnector { public function __construct(private DoHWrapper $doHWrapper, private LoggerGetter $loggerGetter, private bool $fromDns = false) { } public function connect(SocketAddress|string $uri, ?ConnectContext $context = null, ?Cancellation $cancellation = null): Socket { $ctx = $context ?? new ConnectContext(); $ctxs = $this->doHWrapper->generateContexts($uri, $ctx); if (empty($ctxs)) { throw new Exception("No contexts for raw connection to URI {$uri}"); } $logger = $this->loggerGetter->getLogger(); foreach ($ctxs as $ctx) { try { $ctx->setIsDns($this->fromDns); if ($cancellation) { $ctx->setCancellation($cancellation); } $result = ($ctx->getStream()); $logger->logger('OK!', Logger::WARNING); return $result->getSocket(); } catch (Throwable $e) { if (\defined('MADELINEPROTO_TEST') && \constant('MADELINEPROTO_TEST') === 'pony') { throw $e; } $logger->logger('Connection failed: '.$e, Logger::ERROR); } } throw new Exception("Could not connect to URI {$uri}"); } }