Skip to content

Commit

Permalink
Merge pull request #4 from gocanto/feature/on-demand--headers-handler
Browse files Browse the repository at this point in the history
Add header on demand
  • Loading branch information
gocanto authored Nov 14, 2019
2 parents d84f7ca + a2e713f commit 8e9a4f5
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 18 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "gocanto/http-client",
"homepage": "https://github.com/gocanto/http-client",
"type": "php-bundle",
"description": "Http client that handles retries & logging.",
"description": "Http client that handles retries, logging & dynamic headers.",
"minimum-stability": "dev",
"prefer-stable": true,
"keywords": [
Expand Down
65 changes: 52 additions & 13 deletions src/HttpClient.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Gocanto better-http-client
* This file is part of the Gocanto http-client package.
*
* (c) Gustavo Ocanto <gustavoocanto@gmail.com>
*
Expand All @@ -14,16 +17,17 @@
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\TransferStats;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;

class HttpClient extends Client
{
public const VERSION = '1.0.0';
public const VERSION = '1.1.0';

/** @var LoggerInterface */
private $logger;
Expand All @@ -48,7 +52,7 @@ public function __construct(array $config = [], LoggerInterface $logger = null)
private function addStatsListener() : callable
{
return function (TransferStats $stats) {
$this->logger->info('Request stats summary', [
$this->logger->info('Request stats summary.', [
'method' => $stats->getRequest()->getMethod(),
'stats' => $stats->getHandlerStats(),
]);
Expand Down Expand Up @@ -85,8 +89,8 @@ public function onRetry(callable $callback, array $options = []): HttpClient

$decider = function (
$retries,
Request $request,
Response $response = null,
RequestInterface $request,
ResponseInterface $response = null,
RequestException $exception = null
) use (
$callback,
Expand Down Expand Up @@ -116,8 +120,8 @@ private function decider($retryTotal): callable
{
return function (
$retries,
Request $request,
Response $response = null,
RequestInterface $request,
ResponseInterface $response = null,
RequestException $exception = null
) use (
$retryTotal
Expand Down Expand Up @@ -147,17 +151,17 @@ private function decider($retryTotal): callable
}

/**
* @param Request $request
* @param RequestInterface $request
* @param int $retries
* @param int $retryTotal
* @param Response|null $response
* @param ResponseInterface|null $response
* @param RequestException|null $exception
*/
private function warning(
Request $request,
RequestInterface $request,
int $retries,
int $retryTotal,
?Response $response,
?ResponseInterface $response,
?RequestException $exception
): void {
$this->getLogger()->warning(
Expand Down Expand Up @@ -197,6 +201,41 @@ private function delay(array $options): callable
};
}

/**
* @param array $headers
* @return HttpClient
*/
public function withHeaders(array $headers): HttpClient
{
$middleware = function (callable $handler) use ($headers) {
return function (
RequestInterface $request,
array $options
) use (
$handler,
$headers
) {
foreach ($headers as $name => $value) {
$request = $request->withHeader($name, $value);
}

return $handler($request, $options);
};
};

/** @var HandlerStack $handler */
$handler = $this->getConfig('handler');
$handler->push($middleware, 'dynamic_headers');

$config = $this->getConfig();
$config['handler'] = $handler;

$new = clone $this;
$new->config = $config;

return $new;
}

/**
* @param LoggerInterface $logger
*/
Expand Down
41 changes: 37 additions & 4 deletions tests/HttpClientTest.php
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Gocanto http-client package.
*
* (c) Gustavo Ocanto <gustavoocanto@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Tests\Unit\Http;

use Gocanto\HttpClient\HttpClient;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use Mockery;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;
use RuntimeException;

Expand Down Expand Up @@ -42,6 +54,27 @@ public function itAllowsDecidersCallback()
$this->assertInstanceOf(LoggerInterface::class, $client->getLogger());
}

/**
* @test
* @throws GuzzleException
*/
public function itAllowsSettingHeadersOnDemand()
{
$stream = fopen('php://temp', 'r+');
$client = new HttpClient(['debug' => $stream]);

$client->withHeaders([
'X-GUS-1' => 'gustavo',
'X-GUS-2' => 'ocanto',
])->head('google.com');

fseek($stream, 0);
$output = stream_get_contents($stream);

$this->assertStringContainsString('X-GUS-1: gustavo', $output);
$this->assertStringContainsString('X-GUS-2: ocanto', $output);
}

/**
* @return HttpClient
*/
Expand All @@ -67,8 +100,8 @@ private function decider(int $retryTotal) : callable
{
return function (
$retries,
Request $request,
Response $response = null,
RequestInterface $request,
ResponseInterface $response = null,
RequestException $exception = null
) use (
$retryTotal
Expand Down

0 comments on commit 8e9a4f5

Please sign in to comment.