Skip to content

Commit 2ffe5e1

Browse files
committed
WIP: upgrade php-http integration
1 parent ae8fd48 commit 2ffe5e1

17 files changed

+485
-434
lines changed

composer.json

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,18 @@
2020
"homepage": "https://github.com/friendsofsymfony/FOSHttpCache/contributors"
2121
}
2222
],
23+
"minimum-stability": "dev",
2324
"require": {
2425
"php": ">=5.4.8",
2526
"symfony/event-dispatcher": "~2.3",
2627
"symfony/options-resolver": "~2.3",
27-
"psr/http-message-implementation": "~1.0",
28-
"php-http/adapter-implementation": "^0.1.0",
29-
"php-http/discovery": "^0.1.1",
30-
"php-http/message-decorator": "^0.1.0"
28+
"php-http/client-implementation": "^1.0.0",
29+
"php-http/discovery": "^0.3.0"
3130
},
3231
"require-dev": {
3332
"mockery/mockery": "~0.9.1",
3433
"monolog/monolog": "~1.0",
35-
"php-http/guzzle6-adapter": "^0.1.0",
36-
"guzzlehttp/psr7": "^1.0",
34+
"php-http/guzzle6-adapter": "^0.2.0",
3735
"symfony/process": "~2.3",
3836
"symfony/http-kernel": "~2.3"
3937
},

src/Exception/ProxyUnreachableException.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
namespace FOS\HttpCache\Exception;
1313

14-
use Http\Adapter\Exception\HttpAdapterException;
14+
use Http\Client\Exception\RequestException;
1515

1616
/**
1717
* Thrown when a request to the reverse caching proxy fails to establish a
@@ -20,18 +20,18 @@
2020
class ProxyUnreachableException extends \RuntimeException implements HttpCacheExceptionInterface
2121
{
2222
/**
23-
* @param HttpAdapterException $adapterException
23+
* @param RequestException $adapterException
2424
*
2525
* @return ProxyUnreachableException
2626
*/
27-
public static function proxyUnreachable(HttpAdapterException $adapterException)
27+
public static function proxyUnreachable(RequestException $adapterException)
2828
{
2929
$message = sprintf(
3030
'Request to caching proxy at %s failed with message "%s"',
3131
$adapterException->getRequest()->getHeaderLine('Host'),
3232
$adapterException->getMessage()
3333
);
34-
34+
3535
return new ProxyUnreachableException(
3636
$message,
3737
0,

src/ProxyClient/AbstractProxyClient.php

Lines changed: 30 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,13 @@
1111

1212
namespace FOS\HttpCache\ProxyClient;
1313

14-
use FOS\HttpCache\Exception\ExceptionCollection;
15-
use FOS\HttpCache\Exception\ProxyResponseException;
16-
use FOS\HttpCache\Exception\ProxyUnreachableException;
17-
use FOS\HttpCache\ProxyClient\Request\InvalidationRequest;
18-
use FOS\HttpCache\ProxyClient\Request\RequestQueue;
19-
use Http\Adapter\Exception\MultiHttpAdapterException;
20-
use Http\Adapter\HttpAdapter;
21-
use Http\Discovery\HttpAdapterDiscovery;
22-
use Psr\Http\Message\ResponseInterface;
14+
use FOS\HttpCache\Exception\InvalidArgumentException;
15+
use FOS\HttpCache\ProxyClient\Http\HttpAdapter;
16+
use FOS\HttpCache\ProxyClient\Http\HttpAdapterInterface;
17+
use FOS\HttpCache\ProxyClient\Http\HttpAsyncAdapter;
18+
use Http\Client\HttpAsyncClient;
19+
use Http\Client\HttpClient;
20+
use Http\Discovery\HttpClientDiscovery;
2321

2422
/**
2523
* Abstract caching proxy client
@@ -31,123 +29,45 @@ abstract class AbstractProxyClient implements ProxyClientInterface
3129
/**
3230
* HTTP client
3331
*
34-
* @var HttpAdapter
32+
* @var HttpAdapterInterface
3533
*/
36-
private $httpAdapter;
37-
38-
/**
39-
* Request queue
40-
*
41-
* @var RequestQueue
42-
*/
43-
protected $queue;
34+
protected $httpAdapter;
4435

4536
/**
4637
* Constructor
4738
*
48-
* @param array $servers Caching proxy server hostnames or IP
49-
* addresses, including port if not port 80.
50-
* E.g. ['127.0.0.1:6081']
51-
* @param string $baseUri Default application hostname, optionally
52-
* including base URL, for purge and refresh
53-
* requests (optional). This is required if
54-
* you purge and refresh paths instead of
55-
* absolute URLs.
56-
* @param HttpAdapter $httpAdapter If no HTTP adapter is supplied, a default
57-
* one will be created.
39+
* @param array $servers Caching proxy server hostnames or IP
40+
* addresses, including port if not port 80.
41+
* E.g. ['127.0.0.1:6081']
42+
* @param string $baseUri Default application hostname, optionally
43+
* including base URL, for purge and refresh
44+
* requests (optional). This is required if
45+
* you purge and refresh paths instead of
46+
* absolute URLs.
47+
* @param HttpClient|HttpAsyncClient|null $httpClient If no HTTP client is supplied, a default
48+
* one will be created.
5849
*/
5950
public function __construct(
6051
array $servers,
6152
$baseUri = null,
62-
HttpAdapter $httpAdapter = null
53+
$httpClient = null
6354
) {
64-
$this->httpAdapter = $httpAdapter ?: HttpAdapterDiscovery::find();
65-
$this->initQueue($servers, $baseUri);
55+
if ($httpClient instanceof HttpClient) {
56+
$this->httpAdapter = new HttpAdapter($servers, $baseUri, $httpClient);
57+
} elseif ($httpClient instanceof HttpAsyncClient) {
58+
$this->httpAdapter = new HttpAsyncAdapter($servers, $baseUri, $httpClient);
59+
} elseif (null === $httpClient) {
60+
$this->httpAdapter = new HttpAdapter($servers, $baseUri, HttpClientDiscovery::find());
61+
} else {
62+
throw new InvalidArgumentException('client must either be null or implement HttpClient or HttpAsyncClient');
63+
}
6664
}
6765

6866
/**
6967
* {@inheritdoc}
7068
*/
7169
public function flush()
7270
{
73-
if (0 === $this->queue->count()) {
74-
return 0;
75-
}
76-
77-
$queue = clone $this->queue;
78-
$this->queue->clear();
79-
80-
try {
81-
$responses = $this->httpAdapter->sendRequests($queue->all());
82-
} catch (MultiHttpAdapterException $e) {
83-
// Handle all networking errors: php-http only throws an exception
84-
// if no response is available.
85-
$collection = new ExceptionCollection();
86-
foreach ($e->getExceptions() as $exception) {
87-
// php-http only throws an exception if no response is available
88-
if (!$exception->getResponse()) {
89-
// Assume networking error if no response was returned.
90-
$collection->add(
91-
ProxyUnreachableException::proxyUnreachable($exception)
92-
);
93-
}
94-
}
95-
96-
foreach ($this->handleErrorResponses($e->getResponses()) as $exception) {
97-
$collection->add($exception);
98-
}
99-
100-
throw $collection;
101-
}
102-
103-
$exceptions = $this->handleErrorResponses($responses);
104-
if (count($exceptions) > 0) {
105-
throw new ExceptionCollection($exceptions);
106-
}
107-
108-
return count($queue);
109-
}
110-
111-
/**
112-
* Add invalidation reqest to the queue
113-
*
114-
* @param string $method HTTP method
115-
* @param string $url HTTP URL
116-
* @param array $headers HTTP headers
117-
*/
118-
protected function queueRequest($method, $url, array $headers = [])
119-
{
120-
$this->queue->add(new InvalidationRequest($method, $url, $headers));
121-
}
122-
123-
/**
124-
* Initialize the request queue
125-
*
126-
* @param array $servers
127-
* @param string $baseUri
128-
*/
129-
protected function initQueue(array $servers, $baseUri)
130-
{
131-
$this->queue = new RequestQueue($servers, $baseUri);
132-
}
133-
134-
/**
135-
* @param ResponseInterface[] $responses
136-
*
137-
* @return ProxyResponseException[]
138-
*/
139-
private function handleErrorResponses(array $responses)
140-
{
141-
$exceptions = [];
142-
143-
foreach ($responses as $response) {
144-
if ($response->getStatusCode() >= 400
145-
&& $response->getStatusCode() < 600
146-
) {
147-
$exceptions[] = ProxyResponseException::proxyResponse($response);
148-
}
149-
}
150-
151-
return $exceptions;
71+
return $this->httpAdapter->flush();
15272
}
15373
}

src/ProxyClient/Http/HttpAdapter.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
namespace FOS\HttpCache\ProxyClient\Http;
4+
5+
use FOS\HttpCache\Exception\ExceptionCollection;
6+
use FOS\HttpCache\Exception\InvalidArgumentException;
7+
use FOS\HttpCache\Exception\ProxyResponseException;
8+
use FOS\HttpCache\Exception\ProxyUnreachableException;
9+
use Http\Client\Exception;
10+
use Http\Client\Exception\HttpException;
11+
use Http\Client\Exception\RequestException;
12+
use Http\Client\HttpClient;
13+
14+
/**
15+
* An adapter to work with Httplug synchronous client.
16+
*
17+
* @author David Buchmann <[email protected]>
18+
*/
19+
class HttpAdapter extends HttpAdapterBase
20+
{
21+
/**
22+
* @var HttpClient
23+
*/
24+
private $httpClient;
25+
26+
/**
27+
* Request queue
28+
*
29+
* @var InvalidationRequest[]
30+
*/
31+
private $queue;
32+
33+
/**
34+
* {@inheritDoc}
35+
*
36+
* @param HttpClient $httpClient
37+
*/
38+
public function __construct(array $servers, $baseUri, HttpClient $httpClient)
39+
{
40+
parent::__construct($servers, $baseUri);
41+
42+
$this->httpClient = $httpClient;
43+
}
44+
45+
/**
46+
* {@inheritDoc}
47+
*
48+
* Queue the request until flush is called
49+
*/
50+
public function invalidate(InvalidationRequest $invalidationRequest)
51+
{
52+
$signature = $invalidationRequest->getSignature();
53+
54+
if (isset($this->queue[$signature])) {
55+
return;
56+
}
57+
58+
$this->queue[$signature] = $invalidationRequest;
59+
}
60+
61+
public function flush()
62+
{
63+
$queue = $this->queue;
64+
$this->queue = [];
65+
$exceptions = [];
66+
67+
foreach ($queue as $request) {
68+
foreach ($this->multiplex($request) as $proxyRequest) {
69+
try {
70+
$this->httpClient->sendRequest($proxyRequest);
71+
} catch (Exception $e) {
72+
if ($e instanceof HttpException) {
73+
ProxyResponseException::proxyResponse($e->getResponse());
74+
} elseif ($e instanceof RequestException) {
75+
$exceptions[] = ProxyUnreachableException::proxyUnreachable($e);
76+
} else {
77+
$exceptions[] = new InvalidArgumentException($e);
78+
}
79+
}
80+
}
81+
}
82+
83+
if (count($exceptions)) {
84+
throw new ExceptionCollection($exceptions);
85+
}
86+
87+
return count($queue);
88+
}
89+
}

0 commit comments

Comments
 (0)