[HttpFoundation] Added support for partial ranges in the BinaryFileResponse.
Valid ranges include: * bytes=0-499 * bytes=500-999 * bytes=-500 * bytes=9500- * bytes=0-0
This commit is contained in:
parent
d9b91458f1
commit
381bd7e235
@ -195,19 +195,27 @@ class BinaryFileResponse extends Response
|
||||
// Process the range headers.
|
||||
if (!$request->headers->has('If-Range') || $this->getEtag() == $request->headers->get('If-Range')) {
|
||||
$range = $request->headers->get('Range');
|
||||
$fileSize = $this->file->getSize();
|
||||
|
||||
list($start, $end) = array_map('intval', explode('-', substr($range, 6), 2)) + array(0);
|
||||
list($start, $end) = explode('-', substr($range, 6), 2) + array(0);
|
||||
|
||||
if ('' !== $end) {
|
||||
$this->maxlen = $end - $start + 1;
|
||||
$end = ('' === $end) ? $fileSize - 1 : (int) $end;
|
||||
|
||||
if ('' === $start) {
|
||||
$start = $fileSize - $end;
|
||||
$end = $fileSize - 1;
|
||||
} else {
|
||||
$end = $this->file->getSize() - 1;
|
||||
$start = (int) $start;
|
||||
}
|
||||
|
||||
$start = max($start, 0);
|
||||
$end = min($end, $fileSize - 1);
|
||||
|
||||
$this->maxlen = $end < $fileSize ? $end - $start + 1 : -1;
|
||||
$this->offset = $start;
|
||||
|
||||
$this->setStatusCode(206);
|
||||
$this->headers->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $this->file->getSize()));
|
||||
$this->headers->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $fileSize));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,10 @@ class BinaryFileResponseTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertFalse($response->getContent());
|
||||
}
|
||||
|
||||
public function testRequests()
|
||||
/**
|
||||
* @dataProvider provideRanges
|
||||
*/
|
||||
public function testRequests($requestRange, $offset, $length, $responseRange)
|
||||
{
|
||||
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif')->setAutoEtag();
|
||||
|
||||
@ -59,14 +62,35 @@ class BinaryFileResponseTest extends \PHPUnit_Framework_TestCase
|
||||
// prepare a request for a range of the testing file
|
||||
$request = Request::create('/');
|
||||
$request->headers->set('If-Range', $etag);
|
||||
$request->headers->set('Range', 'bytes=1-4');
|
||||
$request->headers->set('Range', $requestRange);
|
||||
|
||||
$this->expectOutputString('IF87');
|
||||
$file = fopen(__DIR__.'/File/Fixtures/test.gif', 'r');
|
||||
fseek($file, $offset);
|
||||
$data = fread($file, $length);
|
||||
fclose($file);
|
||||
|
||||
$this->expectOutputString($data);
|
||||
$response = clone $response;
|
||||
$response->prepare($request);
|
||||
$response->sendContent();
|
||||
|
||||
$this->assertEquals(206, $response->getStatusCode());
|
||||
$this->assertEquals('binary', $response->headers->get('Content-Transfer-Encoding'));
|
||||
$this->assertEquals($responseRange, $response->headers->get('Content-Range'));
|
||||
}
|
||||
|
||||
public function provideRanges()
|
||||
{
|
||||
return array(
|
||||
array('bytes=1-4', 1, 4, 'bytes 1-4/35'),
|
||||
array('bytes=-5', 30, 5, 'bytes 30-34/35'),
|
||||
array('bytes=-35', 0, 35, 'bytes 0-34/35'),
|
||||
array('bytes=-40', 0, 35, 'bytes 0-34/35'),
|
||||
array('bytes=30-', 30, 5, 'bytes 30-34/35'),
|
||||
array('bytes=30-30', 30, 1, 'bytes 30-30/35'),
|
||||
array('bytes=30-34', 30, 5, 'bytes 30-34/35'),
|
||||
array('bytes=30-40', 30, 5, 'bytes 30-34/35')
|
||||
);
|
||||
}
|
||||
|
||||
public function testXSendfile()
|
||||
|
Reference in New Issue
Block a user