Skip to content

Commit

Permalink
[HttpClient] Psr18Client: parse HTTP Reason Phrase for Response
Browse files Browse the repository at this point in the history
  • Loading branch information
Hanmac authored and nicolas-grekas committed Oct 29, 2023
1 parent 04784c6 commit 6cdf6cd
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 27 deletions.
2 changes: 1 addition & 1 deletion HttplugClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public function __construct(HttpClientInterface $client = null, ResponseFactoryI
public function sendRequest(RequestInterface $request): Psr7ResponseInterface
{
try {
return $this->waitLoop->createPsr7Response($this->sendPsr7Request($request));
return HttplugWaitLoop::createPsr7Response($this->responseFactory, $this->streamFactory, $this->client, $this->sendPsr7Request($request), true);
} catch (TransportExceptionInterface $e) {
throw new NetworkException($e->getMessage(), $request, $e);
}
Expand Down
20 changes: 14 additions & 6 deletions Internal/HttplugWaitLoop.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public function wait(?ResponseInterface $pendingResponse, float $maxDuration = n

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

public function createPsr7Response(ResponseInterface $response, bool $buffer = false): Psr7ResponseInterface
public static function createPsr7Response(ResponseFactoryInterface $responseFactory, StreamFactoryInterface $streamFactory, HttpClientInterface $client, ResponseInterface $response, bool $buffer): Psr7ResponseInterface
{
$psrResponse = $this->responseFactory->createResponse($response->getStatusCode());
$responseParameters = [$response->getStatusCode()];

foreach ($response->getInfo('response_headers') as $h) {
if (11 <= \strlen($h) && '/' === $h[4] && preg_match('#^HTTP/\d+(?:\.\d+)? (?:\d\d\d) (.+)#', $h, $m)) {
$responseParameters[1] = $m[1];
}
}

$psrResponse = $responseFactory->createResponse(...$responseParameters);

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

if ($response instanceof StreamableInterface) {
$body = $this->streamFactory->createStreamFromResource($response->toStream(false));
$body = $streamFactory->createStreamFromResource($response->toStream(false));
} elseif (!$buffer) {
$body = $this->streamFactory->createStreamFromResource(StreamWrapper::createResource($response, $this->client));
$body = $streamFactory->createStreamFromResource(StreamWrapper::createResource($response, $client));
} else {
$body = $this->streamFactory->createStream($response->getContent(false));
$body = $streamFactory->createStream($response->getContent(false));
}

if ($body->isSeekable()) {
Expand Down
23 changes: 3 additions & 20 deletions Psr18Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriFactoryInterface;
use Psr\Http\Message\UriInterface;
use Symfony\Component\HttpClient\Internal\HttplugWaitLoop;
use Symfony\Component\HttpClient\Response\StreamableInterface;
use Symfony\Component\HttpClient\Response\StreamWrapper;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface as HttpClientResponseInterface;
use Symfony\Contracts\Service\ResetInterface;

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

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

$psrResponse = $this->responseFactory->createResponse($response->getStatusCode());

foreach ($response->getHeaders(false) as $name => $values) {
foreach ($values as $value) {
try {
$psrResponse = $psrResponse->withAddedHeader($name, $value);
} catch (\InvalidArgumentException $e) {
// ignore invalid header
}
}
}

$body = $response instanceof StreamableInterface ? $response->toStream(false) : StreamWrapper::createResource($response, $this->client);
$body = $this->streamFactory->createStreamFromResource($body);

if ($body->isSeekable()) {
$body->seek(0);
}

return $psrResponse->withBody($body);
return HttplugWaitLoop::createPsr7Response($this->responseFactory, $this->streamFactory, $this->client, $response, false);
} catch (TransportExceptionInterface $e) {
if ($e instanceof \InvalidArgumentException) {
throw new Psr18RequestException($e, $request);
Expand Down
15 changes: 15 additions & 0 deletions Tests/HttplugClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,19 @@ public function testInvalidHeaderResponse()
$resultResponse = $client->sendRequest($request);
$this->assertCount(1, $resultResponse->getHeaders());
}

public function testResponseReasonPhrase()
{
$responseHeaders = [
'HTTP/1.1 103 Very Early Hints',
];
$response = new MockResponse('body', ['response_headers' => $responseHeaders]);

$client = new HttplugClient(new MockHttpClient($response));
$request = $client->createRequest('POST', 'http://localhost:8057/post')
->withBody($client->createStream('foo=0123456789'));

$resultResponse = $client->sendRequest($request);
$this->assertSame('Very Early Hints', $resultResponse->getReasonPhrase());
}
}
15 changes: 15 additions & 0 deletions Tests/Psr18ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,19 @@ public function testInvalidHeaderResponse()
$resultResponse = $client->sendRequest($request);
$this->assertCount(1, $resultResponse->getHeaders());
}

public function testResponseReasonPhrase()
{
$responseHeaders = [
'HTTP/1.1 103 Very Early Hints',
];
$response = new MockResponse('body', ['response_headers' => $responseHeaders]);

$client = new Psr18Client(new MockHttpClient($response));
$request = $client->createRequest('POST', 'http://localhost:8057/post')
->withBody($client->createStream('foo=0123456789'));

$resultResponse = $client->sendRequest($request);
$this->assertSame('Very Early Hints', $resultResponse->getReasonPhrase());
}
}

0 comments on commit 6cdf6cd

Please sign in to comment.