Skip to content

Commit 62d40d5

Browse files
bug symfony#38518 [HttpClient] fix decorating timeout errors (nicolas-grekas)
This PR was merged into the 5.x branch. Discussion ---------- [HttpClient] fix decorating timeout errors | Q | A | ------------- | --- | Branch? | 5.x | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Replaces symfony#38501 | License | MIT | Doc PR | - /cc @jderusse Commits ------- 84cda3f [HttpClient] fix decorating timeout errors
2 parents 87920d2 + 84cda3f commit 62d40d5

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

src/Symfony/Component/HttpClient/Response/AsyncResponse.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,25 @@ public function __construct(HttpClientInterface $client, string $method, string
4545
$this->response = $client->request($method, $url, ['buffer' => false] + $options);
4646
$this->passthru = $passthru;
4747
$this->initializer = static function (self $response) {
48-
return null !== $response->shouldBuffer;
48+
if (null === $response->shouldBuffer) {
49+
return false;
50+
}
51+
52+
foreach (self::stream([$response]) as $chunk) {
53+
if ($chunk->isTimeout() && $response->passthru) {
54+
foreach (self::passthru($response->client, $response, new ErrorChunk($response->offset, new TransportException($chunk->getError()))) as $chunk) {
55+
return !$chunk->isFirst();
56+
}
57+
58+
return true;
59+
}
60+
61+
if ($chunk->isFirst()) {
62+
break;
63+
}
64+
}
65+
66+
return false;
4967
};
5068
if (\array_key_exists('user_data', $options)) {
5169
$this->info['user_data'] = $options['user_data'];

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,22 @@ public function testBufferPurePassthru()
212212
$this->assertStringContainsString('SERVER_PROTOCOL', $response->getContent());
213213
$this->assertStringContainsString('HTTP_HOST', $response->getContent());
214214
}
215+
216+
public function testRetryTimeout()
217+
{
218+
$client = $this->getHttpClient(__FUNCTION__, function (ChunkInterface $chunk, AsyncContext $context) {
219+
try {
220+
$this->assertTrue($chunk->isTimeout());
221+
yield $chunk;
222+
} catch (TransportExceptionInterface $e) {
223+
$context->passthru();
224+
$context->getResponse()->cancel();
225+
$context->replaceRequest('GET', 'http://localhost:8057/timeout-header', ['timeout' => 1]);
226+
}
227+
});
228+
229+
$response = $client->request('GET', 'http://localhost:8057/timeout-header', ['timeout' => 0.1]);
230+
231+
$this->assertSame(200, $response->getStatusCode());
232+
}
215233
}

0 commit comments

Comments
 (0)