Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9d4c98e

Browse files
bug #35209 [HttpClient] fix support for non-blocking resource streams (nicolas-grekas)
This PR was merged into the 4.4 branch. Discussion ---------- [HttpClient] fix support for non-blocking resource streams | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #35187, Fix #35187 | License | MIT | Doc PR | - Commits ------- c651f63 [HttpClient] fix support for non-blocking resource streams
2 parents 75c24bb + c651f63 commit 9d4c98e

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class StreamWrapper
3737
/** @var resource|null */
3838
private $handle;
3939

40+
private $blocking = true;
41+
private $timeout;
4042
private $eof = false;
4143
private $offset = 0;
4244

@@ -150,7 +152,7 @@ public function stream_read(int $count)
150152
return $data;
151153
}
152154

153-
foreach ($this->client->stream([$this->response]) as $chunk) {
155+
foreach ($this->client->stream([$this->response], $this->blocking ? $this->timeout : 0) as $chunk) {
154156
try {
155157
$this->eof = true;
156158
$this->eof = !$chunk->isTimeout();
@@ -181,6 +183,19 @@ public function stream_read(int $count)
181183
return '';
182184
}
183185

186+
public function stream_set_option(int $option, int $arg1, ?int $arg2): bool
187+
{
188+
if (STREAM_OPTION_BLOCKING === $option) {
189+
$this->blocking = (bool) $arg1;
190+
} elseif (STREAM_OPTION_READ_TIMEOUT === $option) {
191+
$this->timeout = $arg1 + $arg2 / 1e6;
192+
} else {
193+
return false;
194+
}
195+
196+
return true;
197+
}
198+
184199
public function stream_tell(): int
185200
{
186201
return $this->offset;

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,20 @@ public function testToStream404()
7575
$response = $client->request('GET', 'http://localhost:8057/404');
7676
$stream = $response->toStream();
7777
}
78+
79+
public function testNonBlockingStream()
80+
{
81+
$client = $this->getHttpClient(__FUNCTION__);
82+
$response = $client->request('GET', 'http://localhost:8057/timeout-body');
83+
$stream = $response->toStream();
84+
85+
$this->assertTrue(stream_set_blocking($stream, false));
86+
$this->assertSame('<1>', fread($stream, 8192));
87+
$this->assertFalse(feof($stream));
88+
89+
$this->assertTrue(stream_set_blocking($stream, true));
90+
$this->assertSame('<2>', fread($stream, 8192));
91+
$this->assertSame('', fread($stream, 8192));
92+
$this->assertTrue(feof($stream));
93+
}
7894
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ protected function getHttpClient(string $testCase): HttpClientInterface
171171

172172
return $client;
173173

174+
case 'testNonBlockingStream':
175+
$responses[] = new MockResponse((function () { yield '<1>'; yield ''; yield '<2>'; })(), ['response_headers' => $headers]);
176+
break;
177+
174178
case 'testMaxDuration':
175179
$mock = $this->getMockBuilder(ResponseInterface::class)->getMock();
176180
$mock->expects($this->any())

0 commit comments

Comments
 (0)