1
0
Fork 0

disable multiplexing for some versions of curl (#12207)

* disable multiplexing for some versions of curl

I'm behind a corporate proxy and was hitting a `Curl 2 (...) [CONN-1-0] send: no filter connected` error when trying to download some packages.

Some google research led me to https://github.com/rust-lang/cargo/issues/12202 and its fix https://github.com/rust-lang/cargo/pull/12234.

This PR backports this fix to composer.

> In certain versions of libcurl when proxy is in use with HTTP/2
multiplexing, connections will continue stacking up. This was
fixed in libcurl 8.0.0 in curl/curl@821f6e2

* fix has proxy condition
pull/12211/head
Lctrs 2024-11-25 15:03:36 +01:00 committed by GitHub
parent e468b73cb2
commit dc2844cc72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 25 additions and 1 deletions

View File

@ -34,6 +34,14 @@ use Symfony\Component\HttpFoundation\IpUtils;
*/ */
class CurlDownloader class CurlDownloader
{ {
/**
* Known libcurl's broken versions when proxy is in use with HTTP/2
* multiplexing.
*
* @var list<non-empty-string>
*/
private const BAD_MULTIPLEXING_CURL_VERSIONS = ['7.87.0', '7.88.0', '7.88.1'];
/** @var \CurlMultiHandle */ /** @var \CurlMultiHandle */
private $multiHandle; private $multiHandle;
/** @var \CurlShareHandle */ /** @var \CurlShareHandle */
@ -99,7 +107,18 @@ class CurlDownloader
$this->multiHandle = $mh = curl_multi_init(); $this->multiHandle = $mh = curl_multi_init();
if (function_exists('curl_multi_setopt')) { if (function_exists('curl_multi_setopt')) {
curl_multi_setopt($mh, CURLMOPT_PIPELINING, \PHP_VERSION_ID >= 70400 ? /* CURLPIPE_MULTIPLEX */ 2 : /*CURLPIPE_HTTP1 | CURLPIPE_MULTIPLEX*/ 3); if (ProxyManager::getInstance()->hasProxy() && ($version = curl_version()) !== false && in_array($version['version'], self::BAD_MULTIPLEXING_CURL_VERSIONS, true)) {
/**
* Disable HTTP/2 multiplexing for some broken versions of libcurl.
*
* In certain versions of libcurl when proxy is in use with HTTP/2
* multiplexing, connections will continue stacking up. This was
* fixed in libcurl 8.0.0 in curl/curl@821f6e2a89de8aec1c7da3c0f381b92b2b801efc
*/
curl_multi_setopt($mh, CURLMOPT_PIPELINING, /* CURLPIPE_NOTHING */ 0);
} else {
curl_multi_setopt($mh, CURLMOPT_PIPELINING, \PHP_VERSION_ID >= 70400 ? /* CURLPIPE_MULTIPLEX */ 2 : /*CURLPIPE_HTTP1 | CURLPIPE_MULTIPLEX*/ 3);
}
if (defined('CURLMOPT_MAX_HOST_CONNECTIONS') && !defined('HHVM_VERSION')) { if (defined('CURLMOPT_MAX_HOST_CONNECTIONS') && !defined('HHVM_VERSION')) {
curl_multi_setopt($mh, CURLMOPT_MAX_HOST_CONNECTIONS, 8); curl_multi_setopt($mh, CURLMOPT_MAX_HOST_CONNECTIONS, 8);
} }

View File

@ -59,6 +59,11 @@ class ProxyManager
self::$instance = null; self::$instance = null;
} }
public function hasProxy(): bool
{
return $this->httpProxy !== null || $this->httpsProxy !== null;
}
/** /**
* Returns a RequestProxy instance for the request url * Returns a RequestProxy instance for the request url
* *