[HttpClient] add HttplugClient for compat with libs that need httplug v1 or v2
This commit is contained in:
parent
e54b62c1e2
commit
28674b1e30
@ -111,6 +111,7 @@
|
|||||||
"monolog/monolog": "~1.11",
|
"monolog/monolog": "~1.11",
|
||||||
"nyholm/psr7": "^1.0",
|
"nyholm/psr7": "^1.0",
|
||||||
"ocramius/proxy-manager": "^2.1",
|
"ocramius/proxy-manager": "^2.1",
|
||||||
|
"php-http/httplug": "^1.0|^2.0",
|
||||||
"predis/predis": "~1.1",
|
"predis/predis": "~1.1",
|
||||||
"psr/http-client": "^1.0",
|
"psr/http-client": "^1.0",
|
||||||
"psr/simple-cache": "^1.0",
|
"psr/simple-cache": "^1.0",
|
||||||
|
@ -5,7 +5,7 @@ CHANGELOG
|
|||||||
-----
|
-----
|
||||||
|
|
||||||
* made `Psr18Client` implement relevant PSR-17 factories
|
* made `Psr18Client` implement relevant PSR-17 factories
|
||||||
* added `$response->cancel()`
|
* added `HttplugClient`
|
||||||
|
|
||||||
4.3.0
|
4.3.0
|
||||||
-----
|
-----
|
||||||
|
120
src/Symfony/Component/HttpClient/HttplugClient.php
Normal file
120
src/Symfony/Component/HttpClient/HttplugClient.php
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\HttpClient;
|
||||||
|
|
||||||
|
use Http\Client\Exception\NetworkException;
|
||||||
|
use Http\Client\Exception\RequestException;
|
||||||
|
use Http\Client\HttpClient;
|
||||||
|
use Http\Message\RequestFactory;
|
||||||
|
use Http\Message\StreamFactory;
|
||||||
|
use Http\Message\UriFactory;
|
||||||
|
use Psr\Http\Client\ClientInterface;
|
||||||
|
use Psr\Http\Client\NetworkExceptionInterface;
|
||||||
|
use Psr\Http\Client\RequestExceptionInterface;
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
|
use Psr\Http\Message\ResponseFactoryInterface;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\StreamFactoryInterface;
|
||||||
|
use Psr\Http\Message\StreamInterface;
|
||||||
|
use Psr\Http\Message\UriInterface;
|
||||||
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
|
|
||||||
|
if (!interface_exists(HttpClient::class)) {
|
||||||
|
throw new \LogicException('You cannot use "Symfony\Component\HttpClient\HttplugClient" as the "php-http/httplug" package is not installed. Try running "composer require php-http/httplug".');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!interface_exists(ClientInterface::class)) {
|
||||||
|
throw new \LogicException('You cannot use "Symfony\Component\HttpClient\HttplugClient" as the "psr/http-client" package is not installed. Try running "composer require psr/http-client".');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!interface_exists(RequestFactory::class)) {
|
||||||
|
throw new \LogicException('You cannot use "Symfony\Component\HttpClient\HttplugClient" as the "php-http/message-factory" package is not installed. Try running "composer require nyholm/psr7".');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An adapter to turn a Symfony HttpClientInterface into an Httplug client.
|
||||||
|
*
|
||||||
|
* Run "composer require psr/http-client" to install the base ClientInterface. Run
|
||||||
|
* "composer require nyholm/psr7" to install an efficient implementation of response
|
||||||
|
* and stream factories with flex-provided autowiring aliases.
|
||||||
|
*
|
||||||
|
* @author Nicolas Grekas <p@tchwork.com>
|
||||||
|
*/
|
||||||
|
final class HttplugClient implements HttpClient, RequestFactory, StreamFactory, UriFactory
|
||||||
|
{
|
||||||
|
private $client;
|
||||||
|
|
||||||
|
public function __construct(HttpClientInterface $client = null, ResponseFactoryInterface $responseFactory = null, StreamFactoryInterface $streamFactory = null)
|
||||||
|
{
|
||||||
|
$this->client = new Psr18Client($client, $responseFactory, $streamFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function sendRequest(RequestInterface $request): ResponseInterface
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return $this->client->sendRequest($request);
|
||||||
|
} catch (RequestExceptionInterface $e) {
|
||||||
|
throw new RequestException($e->getMessage(), $request, $e);
|
||||||
|
} catch (NetworkExceptionInterface $e) {
|
||||||
|
throw new NetworkException($e->getMessage(), $request, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function createRequest($method, $uri, array $headers = [], $body = null, $protocolVersion = '1.1'): RequestInterface
|
||||||
|
{
|
||||||
|
$request = $this->client
|
||||||
|
->createRequest($method, $uri)
|
||||||
|
->withProtocolVersion($protocolVersion)
|
||||||
|
->withBody($this->createStream($body))
|
||||||
|
;
|
||||||
|
|
||||||
|
foreach ($headers as $name => $value) {
|
||||||
|
$request = $request->withAddedHeader($name, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $request;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function createStream($body = null): StreamInterface
|
||||||
|
{
|
||||||
|
if ($body instanceof StreamInterface) {
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\is_string($body ?? '')) {
|
||||||
|
return $this->client->createStream($body ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\is_resource($body)) {
|
||||||
|
return $this->client->createStreamFromResource($body);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \InvalidArgumentException(sprintf('%s() expects string, resource or StreamInterface, %s given.', __METHOD__, \gettype($body)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function createUri($uri = ''): UriInterface
|
||||||
|
{
|
||||||
|
return $uri instanceof UriInterface ? $uri : $this->client->createUri($uri);
|
||||||
|
}
|
||||||
|
}
|
72
src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php
Normal file
72
src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\HttpClient\Tests;
|
||||||
|
|
||||||
|
use Http\Client\Exception\NetworkException;
|
||||||
|
use Http\Client\Exception\RequestException;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\HttpClient\HttplugClient;
|
||||||
|
use Symfony\Component\HttpClient\NativeHttpClient;
|
||||||
|
use Symfony\Contracts\HttpClient\Test\TestHttpServer;
|
||||||
|
|
||||||
|
class HttplugClientTest extends TestCase
|
||||||
|
{
|
||||||
|
private static $server;
|
||||||
|
|
||||||
|
public static function setUpBeforeClass()
|
||||||
|
{
|
||||||
|
TestHttpServer::start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSendRequest()
|
||||||
|
{
|
||||||
|
$client = new HttplugClient(new NativeHttpClient());
|
||||||
|
|
||||||
|
$response = $client->sendRequest($client->createRequest('GET', 'http://localhost:8057'));
|
||||||
|
|
||||||
|
$this->assertSame(200, $response->getStatusCode());
|
||||||
|
$this->assertSame('application/json', $response->getHeaderLine('content-type'));
|
||||||
|
|
||||||
|
$body = json_decode((string) $response->getBody(), true);
|
||||||
|
|
||||||
|
$this->assertSame('HTTP/1.1', $body['SERVER_PROTOCOL']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPostRequest()
|
||||||
|
{
|
||||||
|
$client = new HttplugClient(new NativeHttpClient());
|
||||||
|
|
||||||
|
$request = $client->createRequest('POST', 'http://localhost:8057/post')
|
||||||
|
->withBody($client->createStream('foo=0123456789'));
|
||||||
|
|
||||||
|
$response = $client->sendRequest($request);
|
||||||
|
$body = json_decode((string) $response->getBody(), true);
|
||||||
|
|
||||||
|
$this->assertSame(['foo' => '0123456789', 'REQUEST_METHOD' => 'POST'], $body);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNetworkException()
|
||||||
|
{
|
||||||
|
$client = new HttplugClient(new NativeHttpClient());
|
||||||
|
|
||||||
|
$this->expectException(NetworkException::class);
|
||||||
|
$client->sendRequest($client->createRequest('GET', 'http://localhost:8058'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRequestException()
|
||||||
|
{
|
||||||
|
$client = new HttplugClient(new NativeHttpClient());
|
||||||
|
|
||||||
|
$this->expectException(RequestException::class);
|
||||||
|
$client->sendRequest($client->createRequest('BAD.METHOD', 'http://localhost:8057'));
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"provide": {
|
"provide": {
|
||||||
|
"php-http/client-implementation": "*",
|
||||||
"psr/http-client-implementation": "1.0",
|
"psr/http-client-implementation": "1.0",
|
||||||
"symfony/http-client-implementation": "1.1"
|
"symfony/http-client-implementation": "1.1"
|
||||||
},
|
},
|
||||||
@ -26,6 +27,7 @@
|
|||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"nyholm/psr7": "^1.0",
|
"nyholm/psr7": "^1.0",
|
||||||
|
"php-http/httplug": "^1.0|^2.0",
|
||||||
"psr/http-client": "^1.0",
|
"psr/http-client": "^1.0",
|
||||||
"symfony/http-kernel": "^4.3|^5.0",
|
"symfony/http-kernel": "^4.3|^5.0",
|
||||||
"symfony/process": "^4.2|^5.0"
|
"symfony/process": "^4.2|^5.0"
|
||||||
|
Reference in New Issue
Block a user