protected $deleteFileAfterSend = false;
/**
- * Constructor.
- *
* @param \SplFileInfo|string $file The file to stream
* @param int $status The response status code
* @param array $headers An array of response headers
*/
public function setAutoEtag()
{
- $this->setEtag(sha1_file($this->file->getPathname()));
+ $this->setEtag(base64_encode(hash_file('sha256', $this->file->getPathname(), true)));
return $this;
}
* Sets the Content-Disposition header with the given filename.
*
* @param string $disposition ResponseHeaderBag::DISPOSITION_INLINE or ResponseHeaderBag::DISPOSITION_ATTACHMENT
- * @param string $filename Optionally use this filename instead of the real name of the file
+ * @param string $filename Optionally use this UTF-8 encoded filename instead of the real name of the file
* @param string $filenameFallback A fallback filename, containing only ASCII characters. Defaults to an automatically encoded filename
*
* @return $this
*/
public function setContentDisposition($disposition, $filename = '', $filenameFallback = '')
{
- if ($filename === '') {
+ if ('' === $filename) {
$filename = $this->file->getFilename();
}
if ('' === $filenameFallback && (!preg_match('/^[\x20-\x7e]*$/', $filename) || false !== strpos($filename, '%'))) {
- $encoding = mb_detect_encoding($filename, null, true);
+ $encoding = mb_detect_encoding($filename, null, true) ?: '8bit';
for ($i = 0, $filenameLength = mb_strlen($filename, $encoding); $i < $filenameLength; ++$i) {
$char = mb_substr($filename, $i, 1, $encoding);
*/
public function prepare(Request $request)
{
- $this->headers->set('Content-Length', $this->file->getSize());
-
- if (!$this->headers->has('Accept-Ranges')) {
- // Only accept ranges on safe HTTP methods
- $this->headers->set('Accept-Ranges', $request->isMethodSafe(false) ? 'bytes' : 'none');
- }
-
if (!$this->headers->has('Content-Type')) {
$this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream');
}
$this->offset = 0;
$this->maxlen = -1;
+ if (false === $fileSize = $this->file->getSize()) {
+ return $this;
+ }
+ $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(false) ? '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');
if (false === $path) {
$path = $this->file->getPathname();
}
- if (strtolower($type) === 'x-accel-redirect') {
+ if ('x-accel-redirect' === strtolower($type)) {
// Do X-Accel-Mapping substitutions.
// @link http://wiki.nginx.org/X-accel#X-Accel-Redirect
foreach (explode(',', $request->headers->get('X-Accel-Mapping', '')) as $mapping) {
// Process the range headers.
if (!$request->headers->has('If-Range') || $this->hasValidIfRangeHeader($request->headers->get('If-Range'))) {
$range = $request->headers->get('Range');
- $fileSize = $this->file->getSize();
list($start, $end) = explode('-', substr($range, 6), 2) + array(0);
if ($start < 0 || $end > $fileSize - 1) {
$this->setStatusCode(416);
$this->headers->set('Content-Range', sprintf('bytes */%s', $fileSize));
- } elseif ($start !== 0 || $end !== $fileSize - 1) {
+ } elseif (0 !== $start || $end !== $fileSize - 1) {
$this->maxlen = $end < $fileSize ? $end - $start + 1 : -1;
$this->offset = $start;