Skip to content

Commit 115a5a1

Browse files
Hanmacnicolas-grekas
authored andcommitted
[HttpClient] Psr18Client: parse HTTP Reason Phrase for Response
1 parent f45db03 commit 115a5a1

File tree

5 files changed

+48
-27
lines changed

5 files changed

+48
-27
lines changed

src/Symfony/Component/HttpClient/HttplugClient.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public function __construct(HttpClientInterface $client = null, ResponseFactoryI
101101
public function sendRequest(RequestInterface $request): Psr7ResponseInterface
102102
{
103103
try {
104-
return $this->waitLoop->createPsr7Response($this->sendPsr7Request($request));
104+
return HttplugWaitLoop::createPsr7Response($this->responseFactory, $this->streamFactory, $this->client, $this->sendPsr7Request($request), true);
105105
} catch (TransportExceptionInterface $e) {
106106
throw new NetworkException($e->getMessage(), $request, $e);
107107
}

src/Symfony/Component/HttpClient/Internal/HttplugWaitLoop.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public function wait(?ResponseInterface $pendingResponse, float $maxDuration = n
7979

8080
if ([, $promise] = $this->promisePool[$response] ?? null) {
8181
unset($this->promisePool[$response]);
82-
$promise->resolve($this->createPsr7Response($response, true));
82+
$promise->resolve(self::createPsr7Response($this->responseFactory, $this->streamFactory, $this->client, $response, true));
8383
}
8484
} catch (\Exception $e) {
8585
if ([$request, $promise] = $this->promisePool[$response] ?? null) {
@@ -114,9 +114,17 @@ public function wait(?ResponseInterface $pendingResponse, float $maxDuration = n
114114
return $count;
115115
}
116116

117-
public function createPsr7Response(ResponseInterface $response, bool $buffer = false): Psr7ResponseInterface
117+
public static function createPsr7Response(ResponseFactoryInterface $responseFactory, StreamFactoryInterface $streamFactory, HttpClientInterface $client, ResponseInterface $response, bool $buffer): Psr7ResponseInterface
118118
{
119-
$psrResponse = $this->responseFactory->createResponse($response->getStatusCode());
119+
$responseParameters = [$response->getStatusCode()];
120+
121+
foreach ($response->getInfo('response_headers') as $h) {
122+
if (11 <= \strlen($h) && '/' === $h[4] && preg_match('#^HTTP/\d+(?:\.\d+)? (?:\d\d\d) (.+)#', $h, $m)) {
123+
$responseParameters[1] = $m[1];
124+
}
125+
}
126+
127+
$psrResponse = $responseFactory->createResponse(...$responseParameters);
120128

121129
foreach ($response->getHeaders(false) as $name => $values) {
122130
foreach ($values as $value) {
@@ -129,11 +137,11 @@ public function createPsr7Response(ResponseInterface $response, bool $buffer = f
129137
}
130138

131139
if ($response instanceof StreamableInterface) {
132-
$body = $this->streamFactory->createStreamFromResource($response->toStream(false));
140+
$body = $streamFactory->createStreamFromResource($response->toStream(false));
133141
} elseif (!$buffer) {
134-
$body = $this->streamFactory->createStreamFromResource(StreamWrapper::createResource($response, $this->client));
142+
$body = $streamFactory->createStreamFromResource(StreamWrapper::createResource($response, $client));
135143
} else {
136-
$body = $this->streamFactory->createStream($response->getContent(false));
144+
$body = $streamFactory->createStream($response->getContent(false));
137145
}
138146

139147
if ($body->isSeekable()) {

src/Symfony/Component/HttpClient/Psr18Client.php

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@
2727
use Psr\Http\Message\StreamInterface;
2828
use Psr\Http\Message\UriFactoryInterface;
2929
use Psr\Http\Message\UriInterface;
30+
use Symfony\Component\HttpClient\Internal\HttplugWaitLoop;
3031
use Symfony\Component\HttpClient\Response\StreamableInterface;
3132
use Symfony\Component\HttpClient\Response\StreamWrapper;
3233
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
3334
use Symfony\Contracts\HttpClient\HttpClientInterface;
35+
use Symfony\Contracts\HttpClient\ResponseInterface as HttpClientResponseInterface;
3436
use Symfony\Contracts\Service\ResetInterface;
3537

3638
if (!interface_exists(RequestFactoryInterface::class)) {
@@ -102,26 +104,7 @@ public function sendRequest(RequestInterface $request): ResponseInterface
102104

103105
$response = $this->client->request($request->getMethod(), (string) $request->getUri(), $options);
104106

105-
$psrResponse = $this->responseFactory->createResponse($response->getStatusCode());
106-
107-
foreach ($response->getHeaders(false) as $name => $values) {
108-
foreach ($values as $value) {
109-
try {
110-
$psrResponse = $psrResponse->withAddedHeader($name, $value);
111-
} catch (\InvalidArgumentException $e) {
112-
// ignore invalid header
113-
}
114-
}
115-
}
116-
117-
$body = $response instanceof StreamableInterface ? $response->toStream(false) : StreamWrapper::createResource($response, $this->client);
118-
$body = $this->streamFactory->createStreamFromResource($body);
119-
120-
if ($body->isSeekable()) {
121-
$body->seek(0);
122-
}
123-
124-
return $psrResponse->withBody($body);
107+
return HttplugWaitLoop::createPsr7Response($this->responseFactory, $this->streamFactory, $this->client, $response, false);
125108
} catch (TransportExceptionInterface $e) {
126109
if ($e instanceof \InvalidArgumentException) {
127110
throw new Psr18RequestException($e, $request);

src/Symfony/Component/HttpClient/Tests/HttplugClientTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,4 +285,19 @@ public function testInvalidHeaderResponse()
285285
$resultResponse = $client->sendRequest($request);
286286
$this->assertCount(1, $resultResponse->getHeaders());
287287
}
288+
289+
public function testResponseReasonPhrase()
290+
{
291+
$responseHeaders = [
292+
'HTTP/1.1 103 Very Early Hints',
293+
];
294+
$response = new MockResponse('body', ['response_headers' => $responseHeaders]);
295+
296+
$client = new HttplugClient(new MockHttpClient($response));
297+
$request = $client->createRequest('POST', 'http://localhost:8057/post')
298+
->withBody($client->createStream('foo=0123456789'));
299+
300+
$resultResponse = $client->sendRequest($request);
301+
$this->assertSame('Very Early Hints', $resultResponse->getReasonPhrase());
302+
}
288303
}

src/Symfony/Component/HttpClient/Tests/Psr18ClientTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,19 @@ public function testInvalidHeaderResponse()
101101
$resultResponse = $client->sendRequest($request);
102102
$this->assertCount(1, $resultResponse->getHeaders());
103103
}
104+
105+
public function testResponseReasonPhrase()
106+
{
107+
$responseHeaders = [
108+
'HTTP/1.1 103 Very Early Hints',
109+
];
110+
$response = new MockResponse('body', ['response_headers' => $responseHeaders]);
111+
112+
$client = new Psr18Client(new MockHttpClient($response));
113+
$request = $client->createRequest('POST', 'http://localhost:8057/post')
114+
->withBody($client->createStream('foo=0123456789'));
115+
116+
$resultResponse = $client->sendRequest($request);
117+
$this->assertSame('Very Early Hints', $resultResponse->getReasonPhrase());
118+
}
104119
}

0 commit comments

Comments
 (0)