From a27bd88c3daf13b22dc25abe8ac58e92b8326050 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Fri, 24 Mar 2023 16:15:12 +0100 Subject: [PATCH] [HttpClient] Fix not calling the on progress callback when canceling a MockResponse --- .../HttpClient/Response/MockResponse.php | 4 ++++ .../HttpClient/Tests/MockHttpClientTest.php | 21 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/Symfony/Component/HttpClient/Response/MockResponse.php b/src/Symfony/Component/HttpClient/Response/MockResponse.php index 6420aa05de79a..82b2cc172f0aa 100644 --- a/src/Symfony/Component/HttpClient/Response/MockResponse.php +++ b/src/Symfony/Component/HttpClient/Response/MockResponse.php @@ -110,6 +110,10 @@ public function cancel(): void } catch (TransportException $e) { // ignore errors when canceling } + + $onProgress = $this->requestOptions['on_progress'] ?? static function () {}; + $dlSize = isset($this->headers['content-encoding']) || 'HEAD' === $this->info['http_method'] || \in_array($this->info['http_code'], [204, 304], true) ? 0 : (int) ($this->headers['content-length'][0] ?? 0); + $onProgress($this->offset, $dlSize, $this->info); } /** diff --git a/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php b/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php index 8c697b4ee22c2..8d8b6af6227fb 100644 --- a/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php @@ -506,4 +506,25 @@ public function testResetsRequestCount() $client->reset(); $this->assertSame(0, $client->getRequestsCount()); } + + public function testCancellingMockResponseExecutesOnProgressWithUpdatedInfo() + { + $client = new MockHttpClient(new MockResponse(['foo', 'bar', 'ccc'])); + $canceled = false; + $response = $client->request('GET', 'https://example.com', [ + 'on_progress' => static function (int $dlNow, int $dlSize, array $info) use (&$canceled): void { + $canceled = $info['canceled']; + }, + ]); + + foreach ($client->stream($response) as $response => $chunk) { + if ('bar' === $chunk->getContent()) { + $response->cancel(); + + break; + } + } + + $this->assertTrue($canceled); + } }