Skip to content

Commit

Permalink
disable multiplexing for some versions of curl
Browse files Browse the repository at this point in the history
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 rust-lang/cargo#12202 and its fix rust-lang/cargo#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
  • Loading branch information
Lctrs committed Nov 22, 2024
1 parent 38cb4bf commit 5dbea92
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
21 changes: 20 additions & 1 deletion src/Composer/Util/Http/CurlDownloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@
*/
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 */
private $multiHandle;
/** @var \CurlShareHandle */
Expand Down Expand Up @@ -99,7 +107,18 @@ public function __construct(IOInterface $io, Config $config, array $options = []

$this->multiHandle = $mh = curl_multi_init();
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')) {
curl_multi_setopt($mh, CURLMOPT_MAX_HOST_CONNECTIONS, 8);
}
Expand Down
5 changes: 5 additions & 0 deletions src/Composer/Util/Http/ProxyManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ public static function reset(): void
self::$instance = null;
}

public function hasProxy(): bool
{
return $this->httpProxy !== null && $this->httpsProxy !== null;
}

/**
* Returns a RequestProxy instance for the request url
*
Expand Down

0 comments on commit 5dbea92

Please sign in to comment.