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@821f6e2pull/12207/head
parent
38cb4bfe71
commit
5dbea92a4e
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue