Skip to content

Commit 8a3929c

Browse files
Merge branch '4.4' into 5.4
* 4.4: [HttpClient] Fix seeking in not-yet-initialized requests [Serializer] Allow getting discriminated type by class name
2 parents 596fd75 + a3cc0a6 commit 8a3929c

File tree

3 files changed

+29
-5
lines changed

3 files changed

+29
-5
lines changed

Response/StreamWrapper.php

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
*/
2323
class StreamWrapper
2424
{
25-
/** @var resource|string|null */
25+
/** @var resource|null */
2626
public $context;
2727

2828
/** @var HttpClientInterface */
@@ -31,7 +31,7 @@ class StreamWrapper
3131
/** @var ResponseInterface */
3232
private $response;
3333

34-
/** @var resource|null */
34+
/** @var resource|string|null */
3535
private $content;
3636

3737
/** @var resource|null */
@@ -89,6 +89,7 @@ public function bindHandles(&$handle, &$content): void
8989
{
9090
$this->handle = &$handle;
9191
$this->content = &$content;
92+
$this->offset = null;
9293
}
9394

9495
public function stream_open(string $path, string $mode, int $options): bool
@@ -133,7 +134,7 @@ public function stream_read(int $count)
133134
}
134135
}
135136

136-
if (0 !== fseek($this->content, $this->offset)) {
137+
if (0 !== fseek($this->content, $this->offset ?? 0)) {
137138
return false;
138139
}
139140

@@ -162,6 +163,11 @@ public function stream_read(int $count)
162163
try {
163164
$this->eof = true;
164165
$this->eof = !$chunk->isTimeout();
166+
167+
if (!$this->eof && !$this->blocking) {
168+
return '';
169+
}
170+
165171
$this->eof = $chunk->isLast();
166172

167173
if ($chunk->isFirst()) {
@@ -204,7 +210,7 @@ public function stream_set_option(int $option, int $arg1, ?int $arg2): bool
204210

205211
public function stream_tell(): int
206212
{
207-
return $this->offset;
213+
return $this->offset ?? 0;
208214
}
209215

210216
public function stream_eof(): bool
@@ -214,14 +220,19 @@ public function stream_eof(): bool
214220

215221
public function stream_seek(int $offset, int $whence = \SEEK_SET): bool
216222
{
223+
if (null === $this->content && null === $this->offset) {
224+
$this->response->getStatusCode();
225+
$this->offset = 0;
226+
}
227+
217228
if (!\is_resource($this->content) || 0 !== fseek($this->content, 0, \SEEK_END)) {
218229
return false;
219230
}
220231

221232
$size = ftell($this->content);
222233

223234
if (\SEEK_CUR === $whence) {
224-
$offset += $this->offset;
235+
$offset += $this->offset ?? 0;
225236
}
226237

227238
if (\SEEK_END === $whence || $size < $offset) {

Tests/HttpClientTestCase.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,18 @@ public function testNonBlockingStream()
131131
$this->assertTrue(feof($stream));
132132
}
133133

134+
public function testSeekAsyncStream()
135+
{
136+
$client = $this->getHttpClient(__FUNCTION__);
137+
$response = $client->request('GET', 'http://localhost:8057/timeout-body');
138+
$stream = $response->toStream(false);
139+
140+
$this->assertSame(0, fseek($stream, 0, \SEEK_CUR));
141+
$this->assertSame('<1>', fread($stream, 8192));
142+
$this->assertFalse(feof($stream));
143+
$this->assertSame('<2>', stream_get_contents($stream));
144+
}
145+
134146
public function testResponseStreamRewind()
135147
{
136148
$client = $this->getHttpClient(__FUNCTION__);

Tests/MockHttpClientTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ protected function getHttpClient(string $testCase): HttpClientInterface
443443
return $client;
444444

445445
case 'testNonBlockingStream':
446+
case 'testSeekAsyncStream':
446447
$responses[] = new MockResponse((function () { yield '<1>'; yield ''; yield '<2>'; })(), ['response_headers' => $headers]);
447448
break;
448449

0 commit comments

Comments
 (0)