|
13 | 13 |
|
14 | 14 | use Symfony\Component\HttpClient\AsyncDecoratorTrait;
|
15 | 15 | use Symfony\Component\HttpClient\DecoratorTrait;
|
| 16 | +use Symfony\Component\HttpClient\Exception\TransportException; |
16 | 17 | use Symfony\Component\HttpClient\HttpClient;
|
17 | 18 | use Symfony\Component\HttpClient\Response\AsyncContext;
|
18 | 19 | use Symfony\Component\HttpClient\Response\AsyncResponse;
|
@@ -339,4 +340,28 @@ public function request(string $method, string $url, array $options = []): Respo
|
339 | 340 | $this->expectExceptionMessage('Instance of "Symfony\Component\HttpClient\Response\NativeResponse" is already consumed and cannot be managed by "Symfony\Component\HttpClient\Response\AsyncResponse". A decorated client should not call any of the response\'s methods in its "request()" method.');
|
340 | 341 | $response->getStatusCode();
|
341 | 342 | }
|
| 343 | + |
| 344 | + public function testMaxDuration() |
| 345 | + { |
| 346 | + $sawFirst = false; |
| 347 | + $client = $this->getHttpClient(__FUNCTION__, function (ChunkInterface $chunk, AsyncContext $context) use (&$sawFirst) { |
| 348 | + try { |
| 349 | + if (!$chunk->isFirst() || !$sawFirst) { |
| 350 | + $sawFirst = $sawFirst || $chunk->isFirst(); |
| 351 | + yield $chunk; |
| 352 | + } |
| 353 | + } catch (TransportExceptionInterface $e) { |
| 354 | + $context->getResponse()->cancel(); |
| 355 | + $context->replaceRequest('GET', 'http://localhost:8057/timeout-body', ['timeout' => 0.4]); |
| 356 | + } |
| 357 | + }); |
| 358 | + |
| 359 | + $response = $client->request('GET', 'http://localhost:8057/timeout-body', ['max_duration' => 0.75, 'timeout' => 0.4]); |
| 360 | + |
| 361 | + $this->assertSame(0.75, $response->getInfo('max_duration')); |
| 362 | + |
| 363 | + $this->expectException(TransportException::class); |
| 364 | + $this->expectExceptionMessage('Max duration was reached for "http://localhost:8057/timeout-body".'); |
| 365 | + $response->getContent(); |
| 366 | + } |
342 | 367 | }
|
0 commit comments