feature #35924 [HttpClient] make HttpClient::create()
return an AmpHttpClient
when amphp/http-client
is found but curl is not or too old (nicolas-grekas)
This PR was merged into the 5.1-dev branch.
Discussion
----------
[HttpClient] make `HttpClient::create()` return an `AmpHttpClient` when `amphp/http-client` is found but curl is not or too old
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
Follows #35115
Let's use `amphp/http-client` by default, after `curl` and before `fopen()`.
Commits
-------
7991685e04
[HttpClient] made `HttpClient::create()` return an `AmpHttpClient` when `amphp/http-client` is found but curl is not or too old
This commit is contained in:
commit
d5c4ba980b
@ -7,6 +7,7 @@ CHANGELOG
|
|||||||
* added `NoPrivateNetworkHttpClient` decorator
|
* added `NoPrivateNetworkHttpClient` decorator
|
||||||
* added `AmpHttpClient`, a portable HTTP/2 implementation based on Amp
|
* added `AmpHttpClient`, a portable HTTP/2 implementation based on Amp
|
||||||
* added `LoggerAwareInterface` to `ScopingHttpClient` and `TraceableHttpClient`
|
* added `LoggerAwareInterface` to `ScopingHttpClient` and `TraceableHttpClient`
|
||||||
|
* made `HttpClient::create()` return an `AmpHttpClient` when `amphp/http-client` is found but curl is not or too old
|
||||||
|
|
||||||
4.4.0
|
4.4.0
|
||||||
-----
|
-----
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\HttpClient;
|
namespace Symfony\Component\HttpClient;
|
||||||
|
|
||||||
|
use Amp\Http\Client\Connection\ConnectionLimitingPool;
|
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,6 +30,25 @@ final class HttpClient
|
|||||||
*/
|
*/
|
||||||
public static function create(array $defaultOptions = [], int $maxHostConnections = 6, int $maxPendingPushes = 50): HttpClientInterface
|
public static function create(array $defaultOptions = [], int $maxHostConnections = 6, int $maxPendingPushes = 50): HttpClientInterface
|
||||||
{
|
{
|
||||||
|
if ($amp = class_exists(ConnectionLimitingPool::class)) {
|
||||||
|
if (!\extension_loaded('curl')) {
|
||||||
|
return new AmpHttpClient($defaultOptions, null, $maxHostConnections, $maxPendingPushes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip curl when HTTP/2 push is unsupported or buggy, see https://bugs.php.net/77535
|
||||||
|
if (\PHP_VERSION_ID < 70217 || (\PHP_VERSION_ID >= 70300 && \PHP_VERSION_ID < 70304) || !\defined('CURLMOPT_PUSHFUNCTION')) {
|
||||||
|
return new AmpHttpClient($defaultOptions, null, $maxHostConnections, $maxPendingPushes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static $curlVersion = null;
|
||||||
|
$curlVersion = $curlVersion ?? curl_version();
|
||||||
|
|
||||||
|
// HTTP/2 push crashes before curl 7.61
|
||||||
|
if (0x073d00 > $curlVersion['version_number'] || !(CURL_VERSION_HTTP2 & $curlVersion['features'])) {
|
||||||
|
return new AmpHttpClient($defaultOptions, null, $maxHostConnections, $maxPendingPushes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (\extension_loaded('curl')) {
|
if (\extension_loaded('curl')) {
|
||||||
if ('\\' !== \DIRECTORY_SEPARATOR || ini_get('curl.cainfo') || ini_get('openssl.cafile') || ini_get('openssl.capath')) {
|
if ('\\' !== \DIRECTORY_SEPARATOR || ini_get('curl.cainfo') || ini_get('openssl.cafile') || ini_get('openssl.capath')) {
|
||||||
return new CurlHttpClient($defaultOptions, $maxHostConnections, $maxPendingPushes);
|
return new CurlHttpClient($defaultOptions, $maxHostConnections, $maxPendingPushes);
|
||||||
@ -37,6 +57,10 @@ final class HttpClient
|
|||||||
@trigger_error('Configure the "curl.cainfo", "openssl.cafile" or "openssl.capath" php.ini setting to enable the CurlHttpClient', E_USER_WARNING);
|
@trigger_error('Configure the "curl.cainfo", "openssl.cafile" or "openssl.capath" php.ini setting to enable the CurlHttpClient', E_USER_WARNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($amp) {
|
||||||
|
return new AmpHttpClient($defaultOptions, null, $maxHostConnections, $maxPendingPushes);
|
||||||
|
}
|
||||||
|
|
||||||
return new NativeHttpClient($defaultOptions, $maxHostConnections);
|
return new NativeHttpClient($defaultOptions, $maxHostConnections);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,9 @@ final class AmpClientState extends ClientState
|
|||||||
};
|
};
|
||||||
$connector->connector = new DnsConnector(new AmpResolver($this->dnsCache));
|
$connector->connector = new DnsConnector(new AmpResolver($this->dnsCache));
|
||||||
|
|
||||||
$context = (new ConnectContext())->withTlsContext($context);
|
$context = (new ConnectContext())
|
||||||
|
->withTcpNoDelay()
|
||||||
|
->withTlsContext($context);
|
||||||
|
|
||||||
if ($options['bindto']) {
|
if ($options['bindto']) {
|
||||||
if (file_exists($options['bindto'])) {
|
if (file_exists($options['bindto'])) {
|
||||||
|
@ -12,18 +12,18 @@
|
|||||||
namespace Symfony\Component\HttpClient\Tests;
|
namespace Symfony\Component\HttpClient\Tests;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\HttpClient\AmpHttpClient;
|
||||||
use Symfony\Component\HttpClient\CurlHttpClient;
|
use Symfony\Component\HttpClient\CurlHttpClient;
|
||||||
use Symfony\Component\HttpClient\HttpClient;
|
use Symfony\Component\HttpClient\HttpClient;
|
||||||
use Symfony\Component\HttpClient\NativeHttpClient;
|
|
||||||
|
|
||||||
class HttpClientTest extends TestCase
|
class HttpClientTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testCreateClient()
|
public function testCreateClient()
|
||||||
{
|
{
|
||||||
if (\extension_loaded('curl') && ('\\' !== \DIRECTORY_SEPARATOR || ini_get('curl.cainfo') || ini_get('openssl.cafile') || ini_get('openssl.capath'))) {
|
if (\extension_loaded('curl') && ('\\' !== \DIRECTORY_SEPARATOR || ini_get('curl.cainfo') || ini_get('openssl.cafile') || ini_get('openssl.capath')) && 0x073d00 <= curl_version()['version_number']) {
|
||||||
$this->assertInstanceOf(CurlHttpClient::class, HttpClient::create());
|
$this->assertInstanceOf(CurlHttpClient::class, HttpClient::create());
|
||||||
} else {
|
} else {
|
||||||
$this->assertInstanceOf(NativeHttpClient::class, HttpClient::create());
|
$this->assertInstanceOf(AmpHttpClient::class, HttpClient::create());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
"symfony/service-contracts": "^1.0|^2"
|
"symfony/service-contracts": "^1.0|^2"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"amphp/http-client": "^4.2",
|
"amphp/http-client": "^4.2.1",
|
||||||
"amphp/http-tunnel": "^1.0",
|
"amphp/http-tunnel": "^1.0",
|
||||||
"amphp/socket": "^1.1",
|
"amphp/socket": "^1.1",
|
||||||
"guzzlehttp/promises": "^1.3.1",
|
"guzzlehttp/promises": "^1.3.1",
|
||||||
|
Reference in New Issue
Block a user