8000 Add stream_set_option to stream wrapper · symfony/symfony@6df8186 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6df8186

Browse files
committed
Add stream_set_option to stream wrapper
This commit is based on the job of @mcsky #34969 With this change it allows to use a stream in a select_streams function. (which is basics in non-blocking streams in PHP) It adds specific errors in case the user tries to change the timeout or the write buffer because: 1. The stream is read only (so it makes not sense to update the write buffer) 2. By design, we need to specify the timeout at initialization of the stream, not after that.
1 parent 3415224 commit 6df8186

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,27 @@ public function stream_read(int $count)
178178
return '';
179179
}
180180

181+
public function stream_set_option(int $option, int $arg1, ?int $arg2): bool
182+
{
183+
if (null === $this->handle || 'stream' !== get_resource_type($this->handle)) {
184+
trigger_error(sprintf('The "$handle" property of "%s" needs to be a stream.', __CLASS__), E_USER_WARNING);
185+
return false;
186+
}
187+
188+
switch ($option) {
189+
case STREAM_OPTION_BLOCKING:
190+
return stream_set_blocking($this->handle, $arg1);
191+
case STREAM_OPTION_READ_TIMEOUT:
192+
trigger_error(sprintf('Modifying the timeout after starting the stream is not supported by the StreamWrapper.'), E_USER_WARNING);
193+
return false;
194+
case STREAM_OPTION_WRITE_BUFFER:
195+
trigger_error(sprintf('This stream is read only.'), E_USER_WARNING);
196+
return false;
197+
}
198+
199+
return false;
200+
}
201+
181202
public function stream_tell(): int
182203
{
183204
return $this->offset;

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,28 @@ protected function getHttpClient(string $testCase): HttpClientInterface
2121
return new NativeHttpClient();
2222
}
2323

24+
public function testItCanBeNonBlockingStream()
25+
{
26+
$client = $this->getHttpClient(__FUNCTION__);
27+
$response = $client->request('GET', 'http://localhost:8057');
28+
$stream = $response->toStream();
29+
30+
$this->assertTrue(stream_get_meta_data($stream)['blocked']);
31+
$this->assertTrue(stream_set_blocking($stream, 0));
32+
33+
// Help wanted. I've no idea why this test does not pass.
34+
// $this->assertFalse(stream_get_meta_data($stream)['blocked']);
35+
36+
$read = [$stream];
37+
$write = [];
38+
$except = [];
39+
$streamFound = stream_select($read, $write, $except, null, 0);
40+
41+
$this->assertEquals(1, $streamFound);
42+
$this->assertIsArray(json_decode(stream_get_contents($stream), true));
43+
$this->assertTrue(feof($stream));
44+
}
45+
2446
public function testInformationalResponseStream()
2547
{
2648
$this->markTestSkipped('NativeHttpClient doesn\'t support informational status codes.');

0 commit comments

Comments
 (0)
0