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:
Fabien Potencier 2020-03-16 07:03:39 +01:00
commit d5c4ba980b
5 changed files with 32 additions and 5 deletions

View File

@ -7,6 +7,7 @@ CHANGELOG
* added `NoPrivateNetworkHttpClient` decorator
* added `AmpHttpClient`, a portable HTTP/2 implementation based on Amp
* 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
-----

View File

@ -11,6 +11,7 @@
namespace Symfony\Component\HttpClient;
use Amp\Http\Client\Connection\ConnectionLimitingPool;
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
{
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 ('\\' !== \DIRECTORY_SEPARATOR || ini_get('curl.cainfo') || ini_get('openssl.cafile') || ini_get('openssl.capath')) {
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);
}
if ($amp) {
return new AmpHttpClient($defaultOptions, null, $maxHostConnections, $maxPendingPushes);
}
return new NativeHttpClient($defaultOptions, $maxHostConnections);
}

View File

@ -161,7 +161,9 @@ final class AmpClientState extends ClientState
};
$connector->connector = new DnsConnector(new AmpResolver($this->dnsCache));
$context = (new ConnectContext())->withTlsContext($context);
$context = (new ConnectContext())
->withTcpNoDelay()
->withTlsContext($context);
if ($options['bindto']) {
if (file_exists($options['bindto'])) {

View File

@ -12,18 +12,18 @@
namespace Symfony\Component\HttpClient\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpClient\AmpHttpClient;
use Symfony\Component\HttpClient\CurlHttpClient;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpClient\NativeHttpClient;
class HttpClientTest extends TestCase
{
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());
} else {
$this->assertInstanceOf(NativeHttpClient::class, HttpClient::create());
$this->assertInstanceOf(AmpHttpClient::class, HttpClient::create());
}
}
}

View File

@ -28,7 +28,7 @@
"symfony/service-contracts": "^1.0|^2"
},
"require-dev": {
"amphp/http-client": "^4.2",
"amphp/http-client": "^4.2.1",
"amphp/http-tunnel": "^1.0",
"amphp/socket": "^1.1",
"guzzlehttp/promises": "^1.3.1",