Skip to content

Commit

Permalink
If there is a range (even if complete size) return a range 206/not a 200
Browse files Browse the repository at this point in the history
Because IOS/Safari as dumb (very) see #485

also do some indentation...
  • Loading branch information
DiegoPino committed Dec 6, 2024
1 parent 77efe63 commit 327f18b
Showing 1 changed file with 34 additions and 19 deletions.
53 changes: 34 additions & 19 deletions src/Controller/IiifBinaryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,23 +200,23 @@ public function servefile(Request $request, ContentEntityInterface $node, string
$response->headers->set("Content-Length", $size);
$response->prepare($request);
$response->setCallback(function () use ($uri) {
// We may want to force Garbage Collection here
// Even if globally available...
$i = 0;
gc_enable();
$stream = fopen($uri, 'r');
// While the stream is still open
while (!feof($stream)) {
$i++;
if ($i == 10000) {
gc_collect_cycles();
$i = 0;
}
// Read 1,024 bytes from the stream
echo fread($stream, 8192);
// We may want to force Garbage Collection here
// Even if globally available...
$i = 0;
gc_enable();
$stream = fopen($uri, 'r');
// While the stream is still open
while (!feof($stream)) {
$i++;
if ($i == 10000) {
gc_collect_cycles();
$i = 0;
}
// Be sure to close the stream resource when you're done with it
fclose($stream);
// Read 1,024 bytes from the stream
echo fread($stream, 8192);
}
// Be sure to close the stream resource when you're done with it
fclose($stream);
});

return $response;
Expand All @@ -242,15 +242,30 @@ public function servefile(Request $request, ContentEntityInterface $node, string
// S3 or remote storage needs this. Common Archipelago
// Deployment use case.
$response = new RangedRemoteFileRespone($uri);
$response->setETag($etag, TRUE);
$response->headers->set("Content-Type", $mime);
$response->prepare($request);
} else {
// Should be able to handle ranged?
// see https://github.com/symfony/symfony/pull/38516/files
$response = new BinaryFileResponse($uri);
$response->setETag($etag, TRUE);
$response->headers->set("Content-Type", $mime);
$response->prepare($request);
}
if ($request->headers->has('Range')) {
// Again..
if (!in_array($response->getStatusCode(), [206,406])) {
$range = $request->headers->get('Range') ?? '';
// Work around for Safari: the range request for Video/Audio might be 0 - filesize-1 so the whole thing.
// But that will bypass a ranged response header from & status from the ::prepare method and return a 200.
[$start, $end] = explode('-', substr($range, 6), 2) + [0];
if ($start == 0 && $end == $size-1) {
$response->headers->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $size));
}
}
}

$response->setETag($etag, TRUE);
$response->headers->set("Content-Type", $mime);
$response->prepare($request);
$response->setContentDisposition(
ResponseHeaderBag::DISPOSITION_INLINE,
$filename
Expand Down

0 comments on commit 327f18b

Please sign in to comment.