[HttpFoundation] Fix Range Requests
This commit is contained in:
parent
f3e496f56f
commit
681804ba1a
@ -239,11 +239,12 @@ class BinaryFileResponse extends Response
|
||||
$this->headers->set($type, $path);
|
||||
$this->maxlen = 0;
|
||||
}
|
||||
} elseif ($request->headers->has('Range')) {
|
||||
} elseif ($request->headers->has('Range') && $request->isMethod('GET')) {
|
||||
// Process the range headers.
|
||||
if (!$request->headers->has('If-Range') || $this->hasValidIfRangeHeader($request->headers->get('If-Range'))) {
|
||||
$range = $request->headers->get('Range');
|
||||
|
||||
if (0 === strpos($range, 'bytes=')) {
|
||||
list($start, $end) = explode('-', substr($range, 6), 2) + [0];
|
||||
|
||||
$end = ('' === $end) ? $fileSize - 1 : (int) $end;
|
||||
@ -256,10 +257,11 @@ class BinaryFileResponse extends Response
|
||||
}
|
||||
|
||||
if ($start <= $end) {
|
||||
if ($start < 0 || $end > $fileSize - 1) {
|
||||
$end = min($end, $fileSize - 1);
|
||||
if ($start < 0 || $start > $end) {
|
||||
$this->setStatusCode(416);
|
||||
$this->headers->set('Content-Range', sprintf('bytes */%s', $fileSize));
|
||||
} elseif (0 !== $start || $end !== $fileSize - 1) {
|
||||
} elseif ($end - $start < $fileSize - 1) {
|
||||
$this->maxlen = $end < $fileSize ? $end - $start + 1 : -1;
|
||||
$this->offset = $start;
|
||||
|
||||
@ -270,6 +272,7 @@ class BinaryFileResponse extends Response
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -149,6 +149,7 @@ class BinaryFileResponseTest extends ResponseTestCase
|
||||
['bytes=30-', 30, 5, 'bytes 30-34/35'],
|
||||
['bytes=30-30', 30, 1, 'bytes 30-30/35'],
|
||||
['bytes=30-34', 30, 5, 'bytes 30-34/35'],
|
||||
['bytes=30-40', 30, 5, 'bytes 30-34/35'],
|
||||
];
|
||||
}
|
||||
|
||||
@ -203,9 +204,31 @@ class BinaryFileResponseTest extends ResponseTestCase
|
||||
// Syntactical invalid range-request should also return the full resource
|
||||
['bytes=20-10'],
|
||||
['bytes=50-40'],
|
||||
// range units other than bytes must be ignored
|
||||
['unknown=10-20'],
|
||||
];
|
||||
}
|
||||
|
||||
public function testRangeOnPostMethod()
|
||||
{
|
||||
$request = Request::create('/', 'POST');
|
||||
$request->headers->set('Range', 'bytes=10-20');
|
||||
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, ['Content-Type' => 'application/octet-stream']);
|
||||
|
||||
$file = fopen(__DIR__.'/File/Fixtures/test.gif', 'r');
|
||||
$data = fread($file, 35);
|
||||
fclose($file);
|
||||
|
||||
$this->expectOutputString($data);
|
||||
$response = clone $response;
|
||||
$response->prepare($request);
|
||||
$response->sendContent();
|
||||
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
$this->assertSame('35', $response->headers->get('Content-Length'));
|
||||
$this->assertNull($response->headers->get('Content-Range'));
|
||||
}
|
||||
|
||||
public function testUnpreparedResponseSendsFullFile()
|
||||
{
|
||||
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200);
|
||||
@ -242,7 +265,7 @@ class BinaryFileResponseTest extends ResponseTestCase
|
||||
{
|
||||
return [
|
||||
['bytes=-40'],
|
||||
['bytes=30-40'],
|
||||
['bytes=40-50'],
|
||||
];
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user