Skip to content

Commit ec810f1

Browse files
authored
Remove dependency to http-client (#325)
* Remove dependency to http-client * Use "minimum-stability":"dev"
1 parent 30a372e commit ec810f1

17 files changed

+232
-192
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Change Log
22

3+
## 0.5.0
4+
5+
### Changed
6+
7+
- The `StreamableBodyInterface::getChunks` now returns a iterrable of string.
8+
39
## 0.4.0
410

511
### Added

src/AbstractApi.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
use Psr\Log\NullLogger;
2020
use Symfony\Component\HttpClient\HttpClient;
2121
use Symfony\Contracts\HttpClient\HttpClientInterface;
22-
use Symfony\Contracts\HttpClient\ResponseInterface;
2322

2423
/**
2524
* Base class most APIs are inheriting.
@@ -31,22 +30,22 @@ abstract class AbstractApi
3130
/**
3231
* @var HttpClientInterface
3332
*/
34-
protected $httpClient;
33+
private $httpClient;
3534

3635
/**
3736
* @var Configuration
3837
*/
39-
protected $configuration;
38+
private $configuration;
4039

4140
/**
4241
* @var CredentialProvider
4342
*/
44-
protected $credentialProvider;
43+
private $credentialProvider;
4544

4645
/**
4746
* @var LoggerInterface|null
4847
*/
49-
protected $logger;
48+
private $logger;
5049

5150
/**
5251
* @var Signer
@@ -86,7 +85,7 @@ abstract protected function getSignatureVersion(): string;
8685

8786
abstract protected function getSignatureScopeName(): string;
8887

89-
final protected function getResponse(Request $request): ResponseInterface
88+
final protected function getResponse(Request $request): Response
9089
{
9190
$request->setEndpoint($this->getEndpoint($request->getUri(), $request->getQuery()));
9291

@@ -103,7 +102,9 @@ final protected function getResponse(Request $request): ResponseInterface
103102
$requestBody = $requestBody->stringify();
104103
}
105104

106-
return $this->httpClient->request($request->getMethod(), $request->getEndpoint(), ['headers' => $request->getHeaders(), 'body' => 0 === $length ? null : $requestBody]);
105+
$response = $this->httpClient->request($request->getMethod(), $request->getEndpoint(), ['headers' => $request->getHeaders(), 'body' => 0 === $length ? null : $requestBody]);
106+
107+
return new Response($response, $this->httpClient);
107108
}
108109

109110
/**

src/Response.php

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AsyncAws\Core;
6+
7+
use AsyncAws\Core\Exception\Http\ClientException;
8+
use AsyncAws\Core\Exception\Http\HttpException;
9+
use AsyncAws\Core\Exception\Http\NetworkException;
10+
use AsyncAws\Core\Exception\Http\RedirectionException;
11+
use AsyncAws\Core\Exception\Http\ServerException;
12+
use AsyncAws\Core\Exception\RuntimeException;
13+
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
14+
use Symfony\Contracts\HttpClient\HttpClientInterface;
15+
use Symfony\Contracts\HttpClient\ResponseInterface;
16+
17+
/**
18+
* The response provides a facade to manipulate HttpResponses.
19+
*
20+
* @author Jérémy Derussé <[email protected]>
21+
*
22+
* @internal
23+
*/
24+
class Response
25+
{
26+
private $response;
27+
28+
private $httpClient;
29+
30+
/**
31+
* A Result can be resolved many times. This variable contains the last resolve result.
32+
*
33+
* @var bool|NetworkException|HttpException|null
34+
*/
35+
private $resolveResult;
36+
37+
public function __construct(ResponseInterface $response, HttpClientInterface $httpClient)
38+
{
39+
$this->response = $response;
40+
$this->httpClient = $httpClient;
41+
}
42+
43+
public function __destruct()
44+
{
45+
if (null === $this->resolveResult) {
46+
$this->resolve();
47+
}
48+
}
49+
50+
/**
51+
* Make sure the actual request is executed.
52+
*
53+
* @param float|null $timeout Duration in seconds before aborting. When null wait until the end of execution.
54+
* @param bool $throw Whether an exception should be thrown on 3/4/5xx status codes
55+
*
56+
* @return bool whether the request is executed or not
57+
*
58+
* @throws NetworkException
59+
* @throws HttpException
60+
*/
61+
final public function resolve(?float $timeout = null, bool $throw = true): bool
62+
{
63+
if (null !== $this->resolveResult) {
64+
if ($this->resolveResult instanceof \Exception) {
65+
throw $this->resolveResult;
66+
}
67+
68+
if (\is_bool($this->resolveResult)) {
69+
return $this->resolveResult;
70+
}
71+
72+
throw new RuntimeException('Unexpected resolve state');
73+
}
74+
75+
try {
76+
foreach ($this->httpClient->stream($this->response, $timeout) as $chunk) {
77+
if ($chunk->isTimeout()) {
78+
return false;
79+
}
80+
if ($chunk->isFirst()) {
81+
break;
82+
}
83+
}
84+
85+
$statusCode = $this->response->getStatusCode();
86+
} catch (TransportExceptionInterface $e) {
87+
throw $this->resolveResult = new NetworkException('Could not contact remote server.', 0, $e);
88+
}
89+
90+
if ($throw) {
91+
if (500 <= $statusCode) {
92+
throw $this->resolveResult = new ServerException($this->response);
93+
}
94+
95+
if (400 <= $statusCode) {
96+
throw $this->resolveResult = new ClientException($this->response);
97+
}
98+
99+
if (300 <= $statusCode) {
100+
throw $this->resolveResult = new RedirectionException($this->response);
101+
}
102+
}
103+
104+
return $this->resolveResult = true;
105+
}
106+
107+
/**
108+
* Returns info on the current request.
109+
*
110+
* @return array{
111+
* resolved: bool,
112+
* response?: ?ResponseInterface,
113+
* status?: int
114+
* }
115+
*/
116+
final public function info(): array
117+
{
118+
return [
119+
'resolved' => null !== $this->resolveResult,
120+
'response' => $this->response,
121+
'status' => (int) $this->response->getInfo('http_code'),
122+
];
123+
}
124+
125+
final public function cancel(): void
126+
{
127+
$this->response->cancel();
128+
$this->resolveResult = false;
129+
}
130+
131+
final public function getHeaders(): array
132+
{
133+
$this->resolve();
134+
135+
return $this->response->getHeaders(false);
136+
}
137+
138+
final public function getContent(): string
139+
{
140+
$this->resolve();
141+
142+
return $this->response->getContent(false);
143+
}
144+
145+
final public function toArray(): array
146+
{
147+
$this->resolve();
148+
149+
return $this->response->toArray(false);
150+
}
151+
152+
final public function getStatusCode(): int
153+
{
154+
return $this->response->getStatusCode();
155+
}
156+
157+
final public function toStream(): StreamableBody
158+
{
159+
return new StreamableBody($this->httpClient->stream($this->response));
160+
}
161+
}

0 commit comments

Comments
 (0)