Skip to content
This repository was archived by the owner on Jan 6, 2024. It is now read-only.

Commit 825d7c8

Browse files
committed
Merge pull request #4 from php-http/internal_separation
Internal and client separation
2 parents b94b6be + 9c86a85 commit 825d7c8

File tree

3 files changed

+142
-106
lines changed

3 files changed

+142
-106
lines changed

.scrutinizer.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
filter:
22
paths: [src/*]
3+
checks:
4+
php:
5+
code_rating: true
6+
duplication: true
37
tools:
4-
php_analyzer: true
5-
php_mess_detector: true
6-
php_pdepend: true
7-
external_code_coverage:
8-
timeout: '600'
8+
external_code_coverage: true

composer.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,22 @@
88
{
99
"name": "Eric GELOEN",
1010
"email": "[email protected]"
11+
},
12+
{
13+
"name": "Márk Sági-Kazár",
14+
"email": "[email protected]"
1115
}
1216
],
1317
"require": {
1418
"php": ">=5.4",
15-
"php-http/adapter-core": "0.1.*@dev",
19+
"php-http/adapter": "^0.1@dev",
20+
"php-http/message-factory-guesser": "^0.1@dev",
1621
"guzzlehttp/guzzle": "~5.1",
1722
"guzzlehttp/ringphp": "^1.0.8@dev"
1823
},
1924
"require-dev": {
2025
"ext-curl": "*",
21-
"php-http/adapter-integration-tests": "0.1.*@dev"
26+
"php-http/adapter-integration-tests": "^0.1@dev"
2227
},
2328
"provide": {
2429
"php-http/adapter-implementation": "0.1"

src/Guzzle5HttpAdapter.php

Lines changed: 130 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -13,159 +13,190 @@
1313

1414
use GuzzleHttp\Client;
1515
use GuzzleHttp\ClientInterface;
16-
use GuzzleHttp\Event\CompleteEvent;
17-
use GuzzleHttp\Event\ErrorEvent;
1816
use GuzzleHttp\Exception\RequestException;
19-
use GuzzleHttp\Message\RequestInterface;
17+
use GuzzleHttp\Message\RequestInterface as GuzzleRequest;
18+
use GuzzleHttp\Message\ResponseInterface as GuzzleResponse;
2019
use GuzzleHttp\Pool;
21-
use Http\Adapter\Message\InternalRequestInterface;
22-
use Http\Adapter\Normalizer\BodyNormalizer;
20+
use Http\Message\MessageFactoryGuesser;
21+
use Http\Message\MessageFactory;
22+
use Psr\Http\Message\RequestInterface;
23+
use Psr\Http\Message\ResponseInterface;
2324

2425
/**
2526
* @author GeLo <[email protected]>
2627
*/
27-
class Guzzle5HttpAdapter extends CurlHttpAdapter
28+
class Guzzle5HttpAdapter implements HttpAdapter
2829
{
2930
/**
3031
* @var ClientInterface
3132
*/
3233
private $client;
3334

3435
/**
35-
*
36-
* @param ClientInterface|null $client
37-
* @param ConfigurationInterface|null $configuration
36+
* @var MessageFactory
3837
*/
39-
public function __construct(ClientInterface $client = null, ConfigurationInterface $configuration = null)
40-
{
41-
parent::__construct($configuration);
42-
43-
$this->client = $client ?: new Client();
44-
}
38+
private $messageFactory;
4539

4640
/**
47-
* {@inheritdoc}
41+
*
42+
* @param ClientInterface|null $client
43+
* @param MessageFactory|null $messageFactory
4844
*/
49-
public function getName()
45+
public function __construct(ClientInterface $client = null, MessageFactory $messageFactory = null)
5046
{
51-
return 'guzzle5';
47+
$this->client = $client ?: new Client();
48+
$this->messageFactory = $messageFactory ?: MessageFactoryGuesser::guess();
49+
5250
}
5351

5452
/**
5553
* {@inheritdoc}
5654
*/
57-
protected function sendInternalRequest(InternalRequestInterface $internalRequest)
55+
public function sendRequest(RequestInterface $request, array $options = [])
5856
{
57+
$guzzleRequest = $this->createRequest($request, $options);
58+
5959
try {
60-
$response = $this->client->send($this->createRequest($internalRequest));
60+
$response = $this->client->send($guzzleRequest);
6161
} catch (RequestException $e) {
62-
throw HttpAdapterException::cannotFetchUri(
63-
$e->getRequest()->getUrl(),
64-
$this->getName(),
65-
$e->getMessage()
66-
);
62+
throw $this->createException($e, $request);
6763
}
6864

69-
return $this->getConfiguration()->getMessageFactory()->createResponse(
70-
(integer) $response->getStatusCode(),
71-
$response->getProtocolVersion(),
72-
$response->getHeaders(),
73-
BodyNormalizer::normalize(
74-
function () use ($response) {
75-
return $response->getBody()->detach();
76-
},
77-
$internalRequest->getMethod()
78-
)
79-
);
65+
return $this->createResponse($response);
8066
}
8167

8268
/**
8369
* {@inheritdoc}
8470
*/
85-
protected function sendInternalRequests(array $internalRequests, $success, $error)
71+
public function sendRequests(array $requests, array $options = [])
8672
{
87-
$requests = [];
88-
foreach ($internalRequests as $internalRequest) {
89-
$requests[] = $this->createRequest($internalRequest, $success, $error);
73+
$requests = array_values($requests);
74+
$guzzleRequests = [];
75+
76+
foreach ($requests as $request) {
77+
$guzzleRequests[] = $this->createRequest($request, $options);
78+
}
79+
80+
$results = Pool::batch($this->client, $guzzleRequests);
81+
82+
$exceptions = [];
83+
$responses = [];
84+
85+
foreach ($guzzleRequests as $key => $guzzleRequest) {
86+
$result = $results->getResult($guzzleRequest);
87+
88+
if ($result instanceof GuzzleResponse) {
89+
$responses[] = $this->createResponse($result);
90+
} elseif ($result instanceof RequestException) {
91+
$exceptions[] = $this->createException($result, $requests[$key]);
92+
}
9093
}
9194

92-
Pool::batch($this->client, $requests);
95+
if (count($exceptions) > 0) {
96+
throw new Exception\MultiHttpAdapterException($exceptions, $responses);
97+
}
98+
99+
return $responses;
93100
}
94101

95102
/**
96103
* {@inheritdoc}
97104
*/
98-
protected function createFile($file)
105+
public function getName()
106+
{
107+
return 'guzzle5';
108+
}
109+
110+
/**
111+
* Converts a PSR request into a Guzzle request
112+
*
113+
* @param RequestInterface $request
114+
*
115+
* @return GuzzleRequest
116+
*/
117+
private function createRequest(RequestInterface $request, array $options = [])
99118
{
100-
return fopen($file, 'r');
119+
$options = $this->buildOptions($options);
120+
121+
$options['version'] = $request->getProtocolVersion();
122+
$options['headers'] = $request->getHeaders();
123+
$options['body'] = (string) $request->getBody();
124+
125+
return $this->client->createRequest(
126+
$request->getMethod(),
127+
(string) $request->getUri(),
128+
$options
129+
);
101130
}
102131

103132
/**
104-
* Creates a request.
133+
* Converts a Guzzle response into a PSR response
105134
*
106-
* @param InternalRequestInterface $internalRequest
107-
* @param callable|null $success
108-
* @param callable|null $error
135+
* @param GuzzleResponse $response
109136
*
110-
* @return RequestInterface
137+
* @return ResponseInterface
111138
*/
112-
private function createRequest(InternalRequestInterface $internalRequest, callable $success = null, callable $error = null)
139+
private function createResponse(GuzzleResponse $response)
113140
{
114-
$request = $this->client->createRequest(
115-
$internalRequest->getMethod(),
116-
(string) $internalRequest->getUri(),
117-
[
118-
'exceptions' => false,
119-
'allow_redirects' => false,
120-
'timeout' => $this->getConfiguration()->getTimeout(),
121-
'connect_timeout' => $this->getConfiguration()->getTimeout(),
122-
'version' => $internalRequest->getProtocolVersion(),
123-
'headers' => $this->prepareHeaders($internalRequest),
124-
'body' => $this->prepareContent($internalRequest),
125-
]
141+
$body = $response->getBody();
142+
143+
return $this->messageFactory->createResponse(
144+
$response->getStatusCode(),
145+
null,
146+
$response->getProtocolVersion(),
147+
$response->getHeaders(),
148+
isset($body) ? $body->detach() : null
126149
);
150+
}
127151

128-
if (isset($success)) {
129-
$messageFactory = $this->getConfiguration()->getMessageFactory();
130-
131-
$request->getEmitter()->on(
132-
'complete',
133-
function (CompleteEvent $event) use ($success, $internalRequest, $messageFactory) {
134-
$response = $messageFactory->createResponse(
135-
(integer) $event->getResponse()->getStatusCode(),
136-
$event->getResponse()->getProtocolVersion(),
137-
$event->getResponse()->getHeaders(),
138-
BodyNormalizer::normalize(
139-
function () use ($event) {
140-
return $event->getResponse()->getBody()->detach();
141-
},
142-
$internalRequest->getMethod()
143-
)
144-
);
145-
146-
$response = $response->withParameter('request', $internalRequest);
147-
call_user_func($success, $response);
148-
}
149-
);
152+
/**
153+
* Converts a Guzzle exception into an HttpAdapter exception
154+
*
155+
* @param RequestException $exception
156+
*
157+
* @return Exception\HttpAdapterException
158+
*/
159+
private function createException(
160+
RequestException $exception,
161+
RequestInterface $originalRequest
162+
) {
163+
$adapterException = new Exception\HttpAdapterException(
164+
$exception->getMessage(),
165+
0,
166+
$exception
167+
);
168+
169+
$response = null;
170+
171+
if ($exception->hasResponse()) {
172+
$response = $this->createResponse($exception->getResponse());
150173
}
151174

152-
if (isset($error)) {
153-
$httpAdapterName = $this->getName();
154-
155-
$request->getEmitter()->on(
156-
'error',
157-
function (ErrorEvent $event) use ($error, $internalRequest, $httpAdapterName) {
158-
$exception = HttpAdapterException::cannotFetchUri(
159-
$event->getException()->getRequest()->getUrl(),
160-
$httpAdapterName,
161-
$event->getException()->getMessage()
162-
);
163-
$exception->setRequest($internalRequest);
164-
call_user_func($error, $exception);
165-
}
166-
);
175+
$adapterException->setResponse($response);
176+
$adapterException->setRequest($originalRequest);
177+
178+
return $adapterException;
179+
}
180+
181+
/**
182+
* Builds options for Guzzle
183+
*
184+
* @param array $options
185+
*
186+
* @return array
187+
*/
188+
private function buildOptions(array $options)
189+
{
190+
$guzzleOptions = [
191+
'exceptions' => false,
192+
'allow_redirects' => false,
193+
];
194+
195+
if (isset($options['timeout'])) {
196+
$guzzleOptions['connect_timeout'] = $options['timeout'];
197+
$guzzleOptions['timeout'] = $options['timeout'];
167198
}
168199

169-
return $request;
200+
return $guzzleOptions;
170201
}
171202
}

0 commit comments

Comments
 (0)