Skip to content

Commit aaf0a18

Browse files
authored
Merge pull request #30 from php-http/Nyholm-rewind
Make sure we rewind streams
2 parents 3f9ff1f + 59ad156 commit aaf0a18

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

src/Client.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,10 @@ private function addRequestBodyOptions(RequestInterface $request, array $options
278278
$body = $request->getBody();
279279
$bodySize = $body->getSize();
280280
if ($bodySize !== 0) {
281+
if ($body->isSeekable()) {
282+
$body->rewind();
283+
}
284+
281285
// Message has non empty body.
282286
if (null === $bodySize || $bodySize > 1024 * 1024) {
283287
// Avoid full loading large or unknown size body into memory

tests/ClientTest.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22
namespace Http\Client\Curl\Tests;
33

4+
use GuzzleHttp\Psr7\Stream;
45
use Http\Client\Curl\Client;
56
use Zend\Diactoros\Request;
67

@@ -31,6 +32,46 @@ public function testExpectHeader()
3132
static::assertContains('Expect:', $headers);
3233
}
3334

35+
36+
37+
public function testRewindStream()
38+
{
39+
$client = $this->getMockBuilder(Client::class)->disableOriginalConstructor()
40+
->setMethods(['__none__'])->getMock();
41+
42+
$bodyOptions = new \ReflectionMethod(Client::class, 'addRequestBodyOptions');
43+
$bodyOptions->setAccessible(true);
44+
45+
$body = \GuzzleHttp\Psr7\stream_for('abcdef');
46+
$body->seek(3);
47+
$request = new Request('http://foo.com', 'POST', $body);
48+
$options = $bodyOptions->invoke($client, $request, []);
49+
50+
static::assertEquals('abcdef', $options[CURLOPT_POSTFIELDS]);
51+
}
52+
53+
public function testRewindLargeStream()
54+
{
55+
$client = $this->getMockBuilder(Client::class)->disableOriginalConstructor()
56+
->setMethods(['__none__'])->getMock();
57+
58+
$bodyOptions = new \ReflectionMethod(Client::class, 'addRequestBodyOptions');
59+
$bodyOptions->setAccessible(true);
60+
61+
$content = 'abcdef';
62+
while (strlen($content) < 1024*1024+100) {
63+
$content .= '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890';
64+
}
65+
66+
$length = strlen($content);
67+
$body = \GuzzleHttp\Psr7\stream_for($content);
68+
$body->seek(40);
69+
$request = new Request('http://foo.com', 'POST', $body);
70+
$options = $bodyOptions->invoke($client, $request, []);
71+
72+
static::assertTrue(false !== strstr($options[CURLOPT_READFUNCTION](null, null, $length), 'abcdef'), 'Steam was not rewinded');
73+
}
74+
3475
/**
3576
* Discovery should be used if no factory given.
3677
*/

0 commit comments

Comments
 (0)