8000 bug #17602 [HttpFoundation] Fix BinaryFileResponse incorrect behavior… · symfony/symfony@be30748 · GitHub
[go: up one dir, main page]

Skip to content

Commit be30748

Browse files
committed
bug #17602 [HttpFoundation] Fix BinaryFileResponse incorrect behavior with if-range header (bburnichon)
This PR was merged into the 2.3 branch. Discussion ---------- [HttpFoundation] Fix BinaryFileResponse incorrect behavior with if-range header | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #16540 | License | MIT | Doc PR | - Commits ------- aaad5bd Add check on If-Range header
2 parents 8ae5dc3 + aaad5bd commit be30748

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

src/Symfony/Component/HttpFoundation/BinaryFileResponse.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ public function prepare(Request $request)
220220
$this->maxlen = 0;
221221
} elseif ($request->headers->has('Range')) {
222222
// Process the range headers.
223-
if (!$request->headers->has('If-Range') || $this->getEtag() === $request->headers->get('If-Range')) {
223+
if (!$request->headers->has('If-Range') || $this->hasValidIfRangeHeader($request->headers->get('If-Range'))) {
224224
$range = $request->headers->get('Range');
225225
$fileSize = $this->file->getSize();
226226

@@ -253,6 +253,19 @@ public function prepare(Request $request)
253253
return $this;
254254
}
255255

256+
private function hasValidIfRangeHeader($header)
257+
{
258+
if ($this->getEtag() === $header) {
259+
return true;
260+
}
261+
262+
if (null === $lastModified = $this->getLastModified()) {
263+
return false;
264+
}
265+
266+
return $lastModified->format('D, d M Y H:i:s').' GMT' === $header;
267+
}
268+
256269
/**
257270
* Sends the file.
258271
*

src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,37 @@ public function testRequests($requestRange, $offset, $length, $responseRange)
8080
$this->assertEquals($responseRange, $response->headers->get('Content-Range'));
8181
}
8282

83+
/**
84+
* @dataProvider provideRanges
85+
*/
86+
public function testRequestsWithoutEtag($requestRange, $offset, $length, $responseRange)
87+
{
88+
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'));
89+
90+
// do a request to get the LastModified
91+
$request = Request::create('/');
92+
$response->prepare($request);
93+
$lastModified = $response->headers->get('Last-Modified');
94+
95+
// prepare a request for a range of the testing file
96+
$request = Request::create('/');
97+
$request->headers->set('If-Range', $lastModified);
98+
$request->headers->set('Range', $requestRange);
99+
100+
$file = fopen(__DIR__.'/File/Fixtures/test.gif', 'r');
101+
fseek($file, $offset);
102+
$data = fread($file, $length);
103+
fclose($file);
104+
105+
$this->expectOutputString($data);
106+
$response = clone $response;
107+
$response->prepare($request);
108+
$response->sendContent();
109+
110+
$this->assertEquals(206, $response->getStatusCode());
111+
$this->assertEquals($responseRange, $response->headers->get('Content-Range'));
112+
}
113+
83114
public function provideRanges()
84115
{
85116
return array(
@@ -91,6 +122,25 @@ public function provideRanges()
91122
);
92123
}
93124

125+
public function testRangeRequestsWithoutLastModifiedDate()
126+
{
127+
// prevent auto last modified
128+
$response = BinaryFileResponse::create(__DIR__.'/File/Fixtures/test.gif', 200, array('Content-Type' => 'application/octet-stream'), true, null, false, false);
129+
130+
// prepare a request for a range of the testing file
131+
$request = Request::create('/');
132+
$request->headers->set('If-Range', date('D, d M Y H:i:s').' GMT');
133+
$request->headers->set('Range', 'bytes=1-4');
134+
135+
$this->expectOutputString(file_get_contents(__DIR__.'/File/Fixtures/test.gif'));
136+
$response = clone $response;
137+
$response->prepare($request);
138+
$response->sendContent();
139+
140+
$this->assertEquals(200, $response->getStatusCode());
141+
$this->assertNull($response->headers->get('Content-Range'));
142+
}
143+
94144
/**
95145
* @dataProvider provideFullFileRanges
96146
*/

0 commit comments

Comments
 (0)
0