Skip to content

Commit

Permalink
Fix bug related to HTTP content chunking (#292)
Browse files Browse the repository at this point in the history
  • Loading branch information
bzikarsky authored and trowski committed Jan 4, 2020
1 parent a4936b0 commit b1d83bc
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 11 deletions.
8 changes: 3 additions & 5 deletions src/Driver/Http1Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -660,15 +660,13 @@ function (int $bodySize) use (&$maxBodySize) {
if ($bufferLength >= $chunkLengthRemaining + 2) {
$buffer .= yield $emitter->emit(\substr($buffer, 0, $chunkLengthRemaining));
$buffer = \substr($buffer, $chunkLengthRemaining + 2);
} else {
$buffer = yield $emitter->emit($buffer);
$chunkLengthRemaining -= $bufferLength;
}

if ($bufferLength >= $chunkLengthRemaining + 2) {
$chunkLengthRemaining = null;
continue 2; // next chunk (chunked loop)
}

$buffer = yield $emitter->emit($buffer);
$chunkLengthRemaining -= $bufferLength;
}
}

Expand Down
27 changes: 21 additions & 6 deletions test/Driver/Http1DriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Amp\PHPUnit\TestCase;
use Amp\Promise;
use Amp\Success;
use Generator;
use League\Uri;

class Http1DriverTest extends TestCase
Expand Down Expand Up @@ -218,7 +219,21 @@ public function testIdentityBodyParseEmit()
$this->assertSame($originalBody, $body);
}

public function testChunkedBodyParseEmit()
/**
* provide multiple chunk-sizes to test with.
* @return Generator
*/
public function chunkSizeProvider()
{
for ($i = 1; $i < 11; $i++) {
yield [$i];
}
}

/**
* @dataProvider chunkSizeProvider
*/
public function testChunkedBodyParseEmit(int $chunkSize)
{
$msg =
"POST https://test.local:1337/post-endpoint HTTP/1.0\r\n" .
Expand Down Expand Up @@ -251,13 +266,13 @@ public function testChunkedBodyParseEmit()
$this->createCallback(0)
);

for ($i = 0, $c = \strlen($msg); $i < $c; $i++) {
$promise = $parser->send($msg[$i]);
foreach (\str_split($msg, $chunkSize) as $chunk) {
$promise = $parser->send($chunk);
while ($promise instanceof Promise) {
$promise = $parser->send("");
}
}

while ($promise instanceof Promise) {
$promise = $parser->send("");
}

$this->assertInstanceOf(Request::class, $request);

Expand Down

0 comments on commit b1d83bc

Please sign in to comment.