Skip to content

Commit

Permalink
PSR actualization
Browse files Browse the repository at this point in the history
  • Loading branch information
zelenin committed Oct 31, 2018
1 parent ff61f80 commit 3cc354e
Show file tree
Hide file tree
Showing 16 changed files with 154 additions and 41 deletions.
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# HTTP client [![Build Status](https://travis-ci.org/zelenin/http-client.svg?branch=master)](https://travis-ci.org/zelenin/http-client) [![Coverage Status](https://coveralls.io/repos/github/zelenin/http-client/badge.svg?branch=master)](https://coveralls.io/github/zelenin/http-client?branch=master)

[PSR-18](http://www.php-fig.org/psr/psr-18/) compatible HTTP client with middleware support.
[PSR-18](http://www.php-fig.org/psr/psr-18/) compatible low-level HTTP client with middleware support.

## Installation

Expand Down Expand Up @@ -47,17 +47,22 @@ use Zelenin\HttpClient\MiddlewareClient;
use Zelenin\HttpClient\RequestConfig;
use Zelenin\HttpClient\Transport\CurlTransport;
use Zend\Diactoros\Request;
use Zend\Diactoros\ResponseFactory;
use Zend\Diactoros\StreamFactory;
use Zend\Diactoros\Uri;

$streamFactory = new StreamFactory();
$responseFactory = new ResponseFactory();

$cookieStorage = new FileStorage('/tmp/http-client/cookies.storage');

$client = new MiddlewareClient([
new CookieRequest($cookieStorage),
new UserAgent(sprintf('HttpClient PHP/%s', PHP_VERSION)),
new Deflate(),
new Deflate($streamFactory),
new CookieResponse($cookieStorage),
new CurlTransport(new RequestConfig()),
]);
new CurlTransport($streamFactory, $responseFactory, new RequestConfig()),
], $responseFactory);

$request = new Request(new Uri('https://example.com/'), 'GET');
$response = $client->sendRequest($request);
Expand Down
7 changes: 4 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@
},
"require": {
"php": ">=7.0",
"psr/http-client": "~0.1",
"zendframework/zend-diactoros": "~1.0",
"psr/http-client": "~1.0",
"psr/http-factory": "~1.0",
"dflydev/fig-cookies": "~1.0.2"
},
"require-dev": {
"phpunit/phpunit": "~6.0",
"satooshi/php-coveralls": "~1.0.0"
"satooshi/php-coveralls": "~1.0.0",
"zendframework/zend-diactoros":"~2.0"
},
"autoload": {
"psr-4": {
Expand Down
10 changes: 7 additions & 3 deletions src/ClientFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use Zelenin\HttpClient\Middleware\Deflate;
use Zelenin\HttpClient\Middleware\UserAgent;
use Zelenin\HttpClient\Transport\CurlTransport;
use Zend\Diactoros\ResponseFactory;
use Zend\Diactoros\StreamFactory;

final class ClientFactory
{
Expand All @@ -18,11 +20,13 @@ final class ClientFactory
public function create(RequestConfig $requestConfig = null): ClientInterface
{
$requestConfig = $requestConfig ?: new RequestConfig();
$streamFactory = new StreamFactory();
$responseFactory = new ResponseFactory();

return new MiddlewareClient([
new UserAgent(),
new Deflate(),
new CurlTransport($requestConfig),
]);
new Deflate($streamFactory),
new CurlTransport($streamFactory, $responseFactory, $requestConfig),
], $responseFactory);
}
}
4 changes: 3 additions & 1 deletion src/Exception/NetworkException.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

namespace Zelenin\HttpClient\Exception;

final class NetworkException extends RequestException implements \Psr\Http\Client\Exception\NetworkException
use Psr\Http\Client\NetworkExceptionInterface;

final class NetworkException extends RequestException implements NetworkExceptionInterface
{
}
3 changes: 2 additions & 1 deletion src/Exception/RequestException.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
namespace Zelenin\HttpClient\Exception;

use Exception;
use Psr\Http\Client\RequestExceptionInterface;
use Psr\Http\Message\RequestInterface;
use RuntimeException;

class RequestException extends RuntimeException implements \Psr\Http\Client\Exception\RequestException
class RequestException extends RuntimeException implements RequestExceptionInterface
{
/**
* @var RequestInterface
Expand Down
16 changes: 15 additions & 1 deletion src/FallbackMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,30 @@
namespace Zelenin\HttpClient;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Zend\Diactoros\Response;

final class FallbackMiddleware implements MiddlewareInterface
{
/**
* @var ResponseFactoryInterface
*/
private $responseFactory;

/**
* @param ResponseFactoryInterface $responseFactory
*/
public function __construct(ResponseFactoryInterface $responseFactory)
{
$this->responseFactory = $responseFactory;
}

/**
* @inheritdoc
*/
public function process(RequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
return new Response();
return $this->responseFactory->createResponse();
}
}
16 changes: 15 additions & 1 deletion src/Middleware/Deflate.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,26 @@

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Zelenin\HttpClient\MiddlewareInterface;
use Zelenin\HttpClient\RequestHandlerInterface;
use function Zelenin\HttpClient\inflateStream;

final class Deflate implements MiddlewareInterface
{
/**
* @var StreamFactoryInterface
*/
private $streamFactory;

/**
* @param StreamFactoryInterface $streamFactory
*/
public function __construct(StreamFactoryInterface $streamFactory)
{
$this->streamFactory = $streamFactory;
}

/**
* @inheritdoc
*/
Expand All @@ -21,7 +35,7 @@ public function process(RequestInterface $request, RequestHandlerInterface $hand
if ($response->hasHeader('Content-Encoding')) {
$encoding = $response->getHeader('Content-Encoding');
if ($encoding[0] === 'gzip' || $encoding[0] === 'deflate') {
$stream = inflateStream($response->getBody());
$stream = inflateStream($response->getBody(), $this->streamFactory);

$response = $response
->withBody($stream)
Expand Down
12 changes: 10 additions & 2 deletions src/MiddlewareClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;

final class MiddlewareClient implements ClientInterface
Expand All @@ -14,22 +15,29 @@ final class MiddlewareClient implements ClientInterface
*/
private $middlewares;

/**
* @var ResponseFactoryInterface
*/
private $responseFactory;

/**
* @param array|MiddlewareInterface[] $middlewares
* @param ResponseFactoryInterface $responseFactory
*/
public function __construct(array $middlewares)
public function __construct(array $middlewares, ResponseFactoryInterface $responseFactory)
{
$this->middlewares = array_map(function (MiddlewareInterface $middleware) {
return $middleware;
}, $middlewares);
$this->responseFactory = $responseFactory;
}

/**
* @inheritdoc
*/
public function sendRequest(RequestInterface $request): ResponseInterface
{
$requestHandler = new RequestHandler($this->middlewares, new FallbackMiddleware());
$requestHandler = new RequestHandler($this->middlewares, new FallbackMiddleware($this->responseFactory));

return $requestHandler->handle($request);
}
Expand Down
31 changes: 25 additions & 6 deletions src/Transport/CurlTransport.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,44 @@
namespace Zelenin\HttpClient\Transport;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Zelenin\HttpClient\Exception\ConnectException;
use Psr\Http\Message\StreamFactoryInterface;
use Zelenin\HttpClient\Exception\NetworkException;
use Zelenin\HttpClient\MiddlewareInterface;
use Zelenin\HttpClient\RequestConfig;
use Zelenin\HttpClient\RequestHandlerInterface;
use Zend\Diactoros\Response;
use function Zelenin\HttpClient\copyResourceToStream;
use function Zelenin\HttpClient\deserializeHeadersToPsr7Format;
use function Zelenin\HttpClient\filterLastResponseHeaders;
use function Zelenin\HttpClient\serializeHeadersFromPsr7Format;

final class CurlTransport implements Transport, MiddlewareInterface
{
/**
* @var StreamFactoryInterface
*/
private $streamFactory;

/**
* @var ResponseFactoryInterface
*/
private $responseFactory;

/**
* @var RequestConfig
*/
private $requestConfig;

/**
* @param StreamFactoryInterface $streamFactory
* @param ResponseFactoryInterface $responseFactory
* @param RequestConfig $requestConfig
*/
public function __construct(RequestConfig $requestConfig)
public function __construct(StreamFactoryInterface $streamFactory, ResponseFactoryInterface $responseFactory, RequestConfig $requestConfig)
{
$this->streamFactory = $streamFactory;
$this->responseFactory = $responseFactory;
$this->requestConfig = $requestConfig;
}

Expand Down Expand Up @@ -87,7 +101,7 @@ public function sendRequest(RequestInterface $request): ResponseInterface

curl_exec($curlResource);

$stream = copyResourceToStream($resource);
$stream = copyResourceToStream($resource, $this->streamFactory);

if ($this->requestConfig->followLocation()) {
$headers = filterLastResponseHeaders($headers);
Expand All @@ -108,8 +122,13 @@ public function sendRequest(RequestInterface $request): ResponseInterface

curl_close($curlResource);

$response = (new Response($stream, $status, deserializeHeadersToPsr7Format($headers)))
->withProtocolVersion($version);
$response = $this->responseFactory->createResponse($status)
->withProtocolVersion($version)
->withBody($stream);

foreach (deserializeHeadersToPsr7Format($headers) as $key => $value) {
$response = $response->withHeader($key, $value);
}

return $response;
}
Expand Down
31 changes: 25 additions & 6 deletions src/Transport/StreamTransport.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,45 @@
namespace Zelenin\HttpClient\Transport;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Zelenin\HttpClient\Exception\ConnectException;
use Psr\Http\Message\StreamFactoryInterface;
use Zelenin\HttpClient\Exception\NetworkException;
use Zelenin\HttpClient\Exception\RequestException;
use Zelenin\HttpClient\MiddlewareInterface;
use Zelenin\HttpClient\RequestConfig;
use Zelenin\HttpClient\RequestHandlerInterface;
use Zend\Diactoros\Response;
use function Zelenin\HttpClient\copyResourceToStream;
use function Zelenin\HttpClient\deserializeHeadersToPsr7Format;
use function Zelenin\HttpClient\filterLastResponseHeaders;
use function Zelenin\HttpClient\serializeHeadersFromPsr7Format;

final class StreamTransport implements Transport, MiddlewareInterface
{
/**
* @var StreamFactoryInterface
*/
private $streamFactory;

/**
* @var ResponseFactoryInterface
*/
private $responseFactory;

/**
* @var RequestConfig
*/
private $requestConfig;

/**
* @param StreamFactoryInterface $streamFactory
* @param ResponseFactoryInterface $responseFactory
* @param RequestConfig $requestConfig
*/
public function __construct(RequestConfig $requestConfig)
public function __construct(StreamFactoryInterface $streamFactory, ResponseFactoryInterface $responseFactory, RequestConfig $requestConfig)
{
$this->streamFactory = $streamFactory;
$this->responseFactory = $responseFactory;
$this->requestConfig = $requestConfig;
}

Expand Down Expand Up @@ -64,7 +78,7 @@ public function sendRequest(RequestInterface $request): ResponseInterface
throw $e;
}

$stream = copyResourceToStream($resource);
$stream = copyResourceToStream($resource, $this->streamFactory);

$headers = stream_get_meta_data($resource)['wrapper_data'] ?? [];

Expand All @@ -78,8 +92,13 @@ public function sendRequest(RequestInterface $request): ResponseInterface
$version = explode('/', $parts[0])[1];
$status = (int)$parts[1];

$response = (new Response($stream, $status, deserializeHeadersToPsr7Format($headers)))
->withProtocolVersion($version);
$response = $this->responseFactory->createResponse($status)
->withProtocolVersion($version)
->withBody($stream);

foreach (deserializeHeadersToPsr7Format($headers) as $key => $value) {
$response = $response->withHeader($key, $value);
}

return $response;
}
Expand Down
9 changes: 5 additions & 4 deletions src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace Zelenin\HttpClient;

use InvalidArgumentException;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\StreamInterface;
use Zend\Diactoros\Stream;

Expand Down Expand Up @@ -98,7 +99,7 @@ function copyStreamToResource(StreamInterface $stream)
*
* @return StreamInterface
*/
function copyResourceToStream($resource): StreamInterface
function copyResourceToStream($resource, StreamFactoryInterface $factory): StreamInterface
{
if (!is_resource($resource)) {
throw new InvalidArgumentException('Not resource.');
Expand All @@ -112,7 +113,7 @@ function copyResourceToStream($resource): StreamInterface

stream_copy_to_stream($resource, $tempResource);

$stream = new Stream($tempResource);
$stream = $factory->createStreamFromResource($tempResource);
$stream->rewind();

return $stream;
Expand All @@ -123,7 +124,7 @@ function copyResourceToStream($resource): StreamInterface
*
* @return StreamInterface
*/
function inflateStream(StreamInterface $stream): StreamInterface
function inflateStream(StreamInterface $stream, StreamFactoryInterface $factory): StreamInterface
{
$stream->rewind();

Expand All @@ -138,5 +139,5 @@ function inflateStream(StreamInterface $stream): StreamInterface

stream_filter_append($resource, "zlib.inflate", STREAM_FILTER_READ);

return copyResourceToStream($resource);
return copyResourceToStream($resource, $factory);
}
Loading

0 comments on commit 3cc354e

Please sign in to comment.