Repository: symfony/symfony
File: src/Symfony/Component/HttpClient/AmpHttpClient.php (PHP)

Code before:
        if ($options['resolve']) {
            $this->multi->dnsCache = $options['resolve'] + $this->multi->dnsCache;
        }

        if ($options['peer_fingerprint'] && !isset($options['peer_fingerprint']['pin-sha256'])) {
            throw new TransportException(__CLASS__.' supports only "pin-sha256" fingerprints.');
        }

        $request = new Request(implode('', $url), $method);
        $request->setBodySizeLimit(0);

        if ($options['http_version']) {
            $request->setProtocolVersions(match ((float) $options['http_version']) {
                1.0 => ['1.0'],
                1.1 => ['1.1', '1.0'],
                default => ['2', '1.1', '1.0'],
            });
        }

        foreach ($options['headers'] as $v) {
            $h = explode(': ', $v, 2);
            $request->addHeader($h[0], $h[1]);
        }

        if (0 < $options['max_connect_duration']) {
            $request->setTcpConnectTimeout($options['max_connect_duration']);
        } else {
            $request->setTcpConnectTimeout($options['timeout']);
        }

        $request->setTlsHandshakeTimeout($options['timeout']);
        $request->setTransferTimeout($options['max_duration']);
        $request->setInactivityTimeout(0);

        if ('' !== $request->getUri()->getUserInfo() && !$request->hasHeader('authorization')) {
            $auth = explode(':', $request->getUri()->getUserInfo(), 2);
            $auth = array_map('rawurldecode', $auth) + [1 => ''];
            $request->setHeader('Authorization', 'Basic '.base64_encode(implode(':', $auth)));
        }

        return new AmpResponse($this->multi, $request, $options, $this->logger);
    }

    public function stream(ResponseInterface|iterable $responses, ?float $timeout = null): ResponseStreamInterface
    {
        if ($responses instanceof AmpResponse) {
            $responses = [$responses];
        }

        return new ResponseStream(AmpResponse::stream($responses, $timeout));
    }

Review comment (suggestion):
This sets only the TCP timeout, while the option is about DNS+TCP+SSL.
We should likely add our own cancellation timer. See how SSL timeout works in AMP for inspiration.

Code after:
        if ($options['resolve']) {
            $this->multi->dnsCache = $options['resolve'] + $this->multi->dnsCache;
        }

        if ($options['peer_fingerprint'] && !isset($options['peer_fingerprint']['pin-sha256'])) {
            throw new TransportException(__CLASS__.' supports only "pin-sha256" fingerprints.');
        }

        $request = new Request(implode('', $url), $method);
        $request->setBodySizeLimit(0);

        if ($options['http_version']) {
            $request->setProtocolVersions(match ((float) $options['http_version']) {
                1.0 => ['1.0'],
                1.1 => ['1.1', '1.0'],
                default => ['2', '1.1', '1.0'],
            });
        }

        foreach ($options['headers'] as $v) {
            $h = explode(': ', $v, 2);
            $request->addHeader($h[0], $h[1]);
        }

        $request->setTcpConnectTimeout($options['timeout']);
        $request->setTlsHandshakeTimeout($options['timeout']);
        $request->setTransferTimeout($options['max_duration']);
        $request->setInactivityTimeout(0);

        if ('' !== $request->getUri()->getUserInfo() && !$request->hasHeader('authorization')) {
            $auth = explode(':', $request->getUri()->getUserInfo(), 2);
            $auth = array_map('rawurldecode', $auth) + [1 => ''];
            $request->setHeader('Authorization', 'Basic '.base64_encode(implode(':', $auth)));
        }

        return new AmpResponse($this->multi, $request, $options, $this->logger);
    }

    public function stream(ResponseInterface|iterable $responses, ?float $timeout = null): ResponseStreamInterface
    {
        if ($responses instanceof AmpResponse) {
            $responses = [$responses];
        }

        return new ResponseStream(AmpResponse::stream($responses, $timeout));
    }

    public function reset(): void
    {
        $this->multi->dnsCache = [];