Skip to content

Commit

Permalink
Fix Content is larger than the available bytes in the stream (#138)
Browse files Browse the repository at this point in the history
  • Loading branch information
dpakach authored and staabm committed Nov 28, 2019
1 parent bd3958b commit 2f00e9e
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 3 deletions.
10 changes: 9 additions & 1 deletion lib/Sapi.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,15 @@ public static function sendResponse(ResponseInterface $response)
}
}
while ($left > 0) {
$left -= stream_copy_to_stream($body, $output, min($left, $chunk_size));
$copied = stream_copy_to_stream($body, $output, min($left, $chunk_size));
// stream_copy_to_stream($src, $dest, $maxLength) must return the number of bytes copied or false in case of failure
// But when the $maxLength is greater than the total number of bytes remaining in the stream,
// It returns the negative number of bytes copied
// So break the loop in such cases.
if ($copied <= 0) {
break;
}
$left -= $copied;
}
} else {
// workaround for 32 Bit systems to avoid stream_copy_to_stream
Expand Down
16 changes: 14 additions & 2 deletions tests/HTTP/SapiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,15 @@ public function testSendLimitedByContentLengthStream()
* @depends testSend
* @dataProvider sendContentRangeStreamData
*/
public function testSendContentRangeStream($ignoreAtStart, $sendText, $multiplier, $ignoreAtEnd)
public function testSendContentRangeStream($ignoreAtStart, $sendText, $multiplier, $ignoreAtEnd, $contentLength)
{
$partial = str_repeat($sendText, $multiplier);
$ignoreAtStartLength = strlen($ignoreAtStart);
$ignoreAtEndLength = strlen($ignoreAtEnd);
$body = fopen('php://memory', 'w');
if (!$contentLength) {
$contentLength = strlen($partial);
}
fwrite($body, $ignoreAtStart);
fwrite($body, $partial);
if ($ignoreAtEndLength > 0) {
Expand All @@ -194,7 +197,7 @@ public function testSendContentRangeStream($ignoreAtStart, $sendText, $multiplie
fread($body, $ignoreAtStartLength);
}
$response = new Response(200, [
'Content-Length' => strlen($partial),
'Content-Length' => $contentLength,
'Content-Range' => sprintf('bytes %d-%d/%d', $ignoreAtStartLength, $ignoreAtStartLength + strlen($partial) - 1, $ignoreAtStartLength + strlen($partial) + $ignoreAtEndLength),
]);
$response->setBody($body);
Expand Down Expand Up @@ -224,6 +227,15 @@ public function sendContentRangeStreamData()
['Ignore this. ', 'Send this.', 1000, ''],
['Ignore this. ', 'S', 4096, ''],
['Ig', 'S', 4094, ''],

// Provide contentLength greater than the bytes remaining in the stream.
['Ignore this. ', 'Send this.', 10, '', 101],
['Ignore this. ', 'Send this.', 1000, '', 10001],
['Ignore this. ', 'S', 4096, '', 5000000],
['I', 'S', 4094, '', 8095],
// Provide contentLength equal to the bytes remaining in the stream.
['', 'Send this.', 10, '', 100],
['Ignore this. ', 'Send this.', 1000, '', 10000],
];
}

Expand Down

0 comments on commit 2f00e9e

Please sign in to comment.