/** * Chunk the request into parts as * desired by the request range header. * * @param Response $response * @param FileInterface $file */ protected function chunk(Response $response, FileInterface $file) { $size = $chunkStart = $file->getSize(); $end = $chunkEnd = $size; $response->headers->set('Content-length', $size); $response->headers->set('Content-Range', "bytes 0-{$end}/{$size}"); if (!($range = array_get($_SERVER, 'HTTP_RANGE'))) { return; } list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2); if (strpos($range, ',') !== false) { $response->setStatusCode(416, 'Requested Range Not Satisfiable'); $response->headers->set('Content-Range', "bytes 0-{$end}/{$size}"); } if ($range == '-') { $chunkStart = $size - substr($range, 1); } else { $range = explode('-', $range); $chunkStart = $range[0]; $chunkEnd = isset($range[1]) && is_numeric($range[1]) ? $range[1] : $size; } $chunkEnd = $chunkEnd > $end ? $end : $chunkEnd; if ($chunkStart > $chunkEnd || $chunkStart > $size || $chunkEnd >= $size) { $response->setStatusCode(416, 'Requested Range Not Satisfiable'); $response->headers->set('Content-Range', "bytes 0-{$end}/{$size}"); } }
/** * Return the size in a readable format. * * @param string $unit * @param int $decimals * @return string */ public function readableSize($unit = null, $decimals = 2) { $bytes = $this->object->getSize(); if (!$unit) { $size = ['B', 'KB', 'MB', 'GB']; $factor = floor((strlen($bytes) - 1) / 3); return (double) sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . ' ' . @$size[(int) $factor]; } if ($bytes >= 1 << 30 || $unit == "GB" || $unit == "G") { return number_format($bytes / (1 << 30), 2) . " {$unit}"; } if ($bytes >= 1 << 20 || $unit == "MB" || $unit == "M") { return number_format($bytes / (1 << 20), 2) . " {$unit}"; } if ($bytes >= 1 << 10 || $unit == "KB" || $unit == "K") { return number_format($bytes / (1 << 10), 2) . " {$unit}"; } return number_format($bytes) . " B"; }
/** * Make the response. * * @param FileInterface $file * @return Response */ public function make(FileInterface $file) { // Start the response. $response = $this->response->make(); $response->headers->set('Pragma', 'public'); $response->headers->set('Etag', $file->hash()); $response->headers->set('Content-Length', $file->getSize()); $response->headers->set('Content-Type', $file->getMimetype()); $response->headers->set('Cache-Control', 'public,max-age=300,s-maxage=900'); // Should be configurable $response->headers->set('Last-Modified', $file->lastModified()->setTimezone('GMT')->format('D, d M Y H:i:s')); return $response; }
/** * Return the size in a readable format. * * @param int $decimals * @return string */ public function readableSize($decimals = 2) { $size = [' B', ' KB', ' MB', ' GB']; $factor = floor((strlen($bytes = $this->object->getSize()) - 1) / 3); return (double) sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$size[(int) $factor]; }