function BinaryFileResponse::prepare
Overrides Response::prepare
File
-
vendor/
symfony/ http-foundation/ BinaryFileResponse.php, line 181
Class
- BinaryFileResponse
- BinaryFileResponse represents an HTTP response delivering a file.
Namespace
Symfony\Component\HttpFoundationCode
public function prepare(Request $request) : static {
if ($this->isInformational() || $this->isEmpty()) {
parent::prepare($request);
$this->maxlen = 0;
return $this;
}
if (!$this->headers
->has('Content-Type')) {
$this->headers
->set('Content-Type', $this->file
->getMimeType() ?: 'application/octet-stream');
}
parent::prepare($request);
$this->offset = 0;
$this->maxlen = -1;
if ($this->tempFileObject) {
$fileSize = $this->tempFileObject
->fstat()['size'];
}
elseif (false === ($fileSize = $this->file
->getSize())) {
return $this;
}
$this->headers
->remove('Transfer-Encoding');
$this->headers
->set('Content-Length', $fileSize);
if (!$this->headers
->has('Accept-Ranges')) {
// Only accept ranges on safe HTTP methods
$this->headers
->set('Accept-Ranges', $request->isMethodSafe() ? 'bytes' : 'none');
}
if (self::$trustXSendfileTypeHeader && $request->headers
->has('X-Sendfile-Type')) {
// Use X-Sendfile, do not send any content.
$type = $request->headers
->get('X-Sendfile-Type');
$path = $this->file
->getRealPath();
// Fall back to scheme://path for stream wrapped locations.
if (false === $path) {
$path = $this->file
->getPathname();
}
if ('x-accel-redirect' === strtolower($type)) {
// Do X-Accel-Mapping substitutions.
// @link https://github.com/rack/rack/blob/main/lib/rack/sendfile.rb
// @link https://mattbrictson.com/blog/accelerated-rails-downloads
if (!$request->headers
->has('X-Accel-Mapping')) {
throw new \LogicException('The "X-Accel-Mapping" header must be set when "X-Sendfile-Type" is set to "X-Accel-Redirect".');
}
$parts = HeaderUtils::split($request->headers
->get('X-Accel-Mapping'), ',=');
foreach ($parts as $part) {
[
$pathPrefix,
$location,
] = $part;
if (str_starts_with($path, $pathPrefix)) {
$path = $location . substr($path, \strlen($pathPrefix));
// Only set X-Accel-Redirect header if a valid URI can be produced
// as nginx does not serve arbitrary file paths.
$this->headers
->set($type, $path);
$this->maxlen = 0;
break;
}
}
}
else {
$this->headers
->set($type, $path);
$this->maxlen = 0;
}
}
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 (str_starts_with($range, 'bytes=')) {
[
$start,
$end,
] = explode('-', substr($range, 6), 2) + [
1 => 0,
];
$end = '' === $end ? $fileSize - 1 : (int) $end;
if ('' === $start) {
$start = $fileSize - $end;
$end = $fileSize - 1;
}
else {
$start = (int) $start;
}
if ($start <= $end) {
$end = min($end, $fileSize - 1);
if ($start < 0 || $start > $end) {
$this->setStatusCode(416);
$this->headers
->set('Content-Range', \sprintf('bytes */%s', $fileSize));
}
elseif ($end - $start < $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, $fileSize));
$this->headers
->set('Content-Length', $end - $start + 1);
}
}
}
}
}
if ($request->isMethod('HEAD')) {
$this->maxlen = 0;
}
return $this;
}