class BinaryFileResponse

BinaryFileResponse represents an HTTP response delivering a file.

@author Niklas Fiekas <niklas.fiekas@tu-clausthal.de> @author stealth35 <stealth35-php@live.fr> @author Igor Wiedler <igor@wiedler.ch> @author Jordan Alliot <jordan.alliot@gmail.com> @author Sergey Linnik <linniksa@gmail.com>

Hierarchy

Expanded class hierarchy of BinaryFileResponse

5 files declare their use of BinaryFileResponse
BinaryFileResponseTest.php in drupal/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php
file.inc in drupal/core/includes/file.inc
API for handling file uploads and server file management.
image.module in drupal/core/modules/image/image.module
Exposes global functionality for creating image styles.
locale.bulk.inc in drupal/core/modules/locale/locale.bulk.inc
Mass import-export and batch import functionality for Gettext .po files.
update_test.module in drupal/core/modules/update/tests/modules/update_test/update_test.module
Module for testing Update Manager functionality.

File

drupal/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/BinaryFileResponse.php, line 26

Namespace

Symfony\Component\HttpFoundation
View source
class BinaryFileResponse extends Response {
  protected static $trustXSendfileTypeHeader = false;
  protected $file;
  protected $offset;
  protected $maxlen;

  /**
   * Constructor.
   *
   * @param SplFileInfo|string $file               The file to stream
   * @param integer            $status             The response status code
   * @param array              $headers            An array of response headers
   * @param boolean            $public             Files are public by default
   * @param null|string        $contentDisposition The type of Content-Disposition to set automatically with the filename
   * @param boolean            $autoEtag           Whether the ETag header should be automatically set
   * @param boolean            $autoLastModified   Whether the Last-Modified header should be automatically set
   */
  public function __construct($file, $status = 200, $headers = array(), $public = true, $contentDisposition = null, $autoEtag = false, $autoLastModified = true) {
    parent::__construct(null, $status, $headers);
    $this
      ->setFile($file, $contentDisposition, $autoEtag, $autoLastModified);
    if ($public) {
      $this
        ->setPublic();
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function create($file = null, $status = 200, $headers = array(), $public = true, $contentDisposition = null, $autoEtag = false, $autoLastModified = true) {
    return new static($file, $status, $headers, $public, $contentDisposition, $autoEtag, $autoLastModified);
  }

  /**
   * Sets the file to stream.
   *
   * @param SplFileInfo|string $file The file to stream
   * @param string             $contentDisposition
   * @param Boolean            $autoEtag
   * @param Boolean            $autoLastModified
   *
   * @return BinaryFileResponse
   *
   * @throws FileException
   */
  public function setFile($file, $contentDisposition = null, $autoEtag = false, $autoLastModified = true) {
    $file = new File((string) $file);
    if (!$file
      ->isReadable()) {
      throw new FileException('File must be readable.');
    }
    $this->file = $file;
    if ($autoEtag) {
      $this
        ->setAutoEtag();
    }
    if ($autoLastModified) {
      $this
        ->setAutoLastModified();
    }
    if ($contentDisposition) {
      $this
        ->setContentDisposition($contentDisposition);
    }
    return $this;
  }

  /**
   * Gets the file.
   *
   * @return File The file to stream
   */
  public function getFile() {
    return $this->file;
  }

  /**
   * Automatically sets the Last-Modified header according the file modification date.
   */
  public function setAutoLastModified() {
    $this
      ->setLastModified(\DateTime::createFromFormat('U', $this->file
      ->getMTime()));
    return $this;
  }

  /**
   * Automatically sets the ETag header according to the checksum of the file.
   */
  public function setAutoEtag() {
    $this
      ->setEtag(sha1_file($this->file
      ->getPathname()));
    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 $filenameFallback A fallback filename, containing only ASCII characters. Defaults to an automatically encoded filename
   *
   * @return BinaryFileResponse
   */
  public function setContentDisposition($disposition, $filename = '', $filenameFallback = '') {
    if ($filename === '') {
      $filename = $this->file
        ->getFilename();
    }
    $dispositionHeader = $this->headers
      ->makeDisposition($disposition, $filename, $filenameFallback);
    $this->headers
      ->set('Content-Disposition', $dispositionHeader);
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function prepare(Request $request) {
    $this->headers
      ->set('Content-Length', $this->file
      ->getSize());
    $this->headers
      ->set('Accept-Ranges', 'bytes');
    $this->headers
      ->set('Content-Transfer-Encoding', 'binary');
    if (!$this->headers
      ->has('Content-Type')) {
      $this->headers
        ->set('Content-Type', $this->file
        ->getMimeType() ?: 'application/octet-stream');
    }
    if ('HTTP/1.0' != $request->server
      ->get('SERVER_PROTOCOL')) {
      $this
        ->setProtocolVersion('1.1');
    }
    $this
      ->ensureIEOverSSLCompatibility($request);
    $this->offset = 0;
    $this->maxlen = -1;
    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();
      if (strtolower($type) == 'x-accel-redirect') {

        // Do X-Accel-Mapping substitutions.
        foreach (explode(',', $request->headers
          ->get('X-Accel-Mapping', '')) as $mapping) {
          $mapping = explode('=', $mapping, 2);
          if (2 == count($mapping)) {
            $location = trim($mapping[0]);
            $pathPrefix = trim($mapping[1]);
            if (substr($path, 0, strlen($pathPrefix)) == $pathPrefix) {
              $path = $location . substr($path, strlen($pathPrefix));
              break;
            }
          }
        }
      }
      $this->headers
        ->set($type, $path);
      $this->maxlen = 0;
    }
    elseif ($request->headers
      ->has('Range')) {

      // Process the range headers.
      if (!$request->headers
        ->has('If-Range') || $this
        ->getEtag() == $request->headers
        ->get('If-Range')) {
        $range = $request->headers
          ->get('Range');
        $fileSize = $this->file
          ->getSize();
        list($start, $end) = explode('-', substr($range, 6), 2) + array(
          0,
        );
        $end = '' === $end ? $fileSize - 1 : (int) $end;
        if ('' === $start) {
          $start = $fileSize - $end;
          $end = $fileSize - 1;
        }
        else {
          $start = (int) $start;
        }
        $start = max($start, 0);
        $end = min($end, $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));
      }
    }
    return $this;
  }

  /**
   * Sends the file.
   */
  public function sendContent() {
    if (!$this
      ->isSuccessful()) {
      parent::sendContent();
      return;
    }
    if (0 === $this->maxlen) {
      return;
    }
    $out = fopen('php://output', 'wb');
    $file = fopen($this->file
      ->getPathname(), 'rb');
    stream_copy_to_stream($file, $out, $this->maxlen, $this->offset);
    fclose($out);
    fclose($file);
  }

  /**
   * {@inheritdoc}
   *
   * @throws \LogicException when the content is not null
   */
  public function setContent($content) {
    if (null !== $content) {
      throw new \LogicException('The content cannot be set on a BinaryFileResponse instance.');
    }
  }

  /**
   * {@inheritdoc}
   *
   * @return false
   */
  public function getContent() {
    return false;
  }

  /**
   * Trust X-Sendfile-Type header.
   */
  public static function trustXSendfileTypeHeader() {
    self::$trustXSendfileTypeHeader = true;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
BinaryFileResponse::$file protected property
BinaryFileResponse::$maxlen protected property
BinaryFileResponse::$offset protected property
BinaryFileResponse::$trustXSendfileTypeHeader protected static property
BinaryFileResponse::create public static function Factory method for chainability Overrides Response::create
BinaryFileResponse::getContent public function Overrides Response::getContent
BinaryFileResponse::getFile public function Gets the file.
BinaryFileResponse::prepare public function Prepares the Response before it is sent to the client. Overrides Response::prepare
BinaryFileResponse::sendContent public function Sends the file. Overrides Response::sendContent
BinaryFileResponse::setAutoEtag public function Automatically sets the ETag header according to the checksum of the file.
BinaryFileResponse::setAutoLastModified public function Automatically sets the Last-Modified header according the file modification date.
BinaryFileResponse::setContent public function Overrides Response::setContent
BinaryFileResponse::setContentDisposition public function Sets the Content-Disposition header with the given filename.
BinaryFileResponse::setFile public function Sets the file to stream.
BinaryFileResponse::trustXSendfileTypeHeader public static function Trust X-Sendfile-Type header.
BinaryFileResponse::__construct public function Constructor. Overrides Response::__construct
Response::$charset protected property
Response::$content protected property
Response::$headers public property
Response::$statusCode protected property
Response::$statusText protected property
Response::$statusTexts public static property Status codes translation table.
Response::$version protected property
Response::ensureIEOverSSLCompatibility protected function Check if we need to remove Cache-Control for ssl encrypted downloads when using IE < 9
Response::expire public function Marks the response stale by setting the Age header to be equal to the maximum age of the response.
Response::getAge public function Returns the age of the response.
Response::getCharset public function Retrieves the response charset.
Response::getDate public function Returns the Date header as a DateTime instance.
Response::getEtag public function Returns the literal value of the ETag HTTP header.
Response::getExpires public function Returns the value of the Expires header as a DateTime instance.
Response::getLastModified public function Returns the Last-Modified HTTP header as a DateTime instance.
Response::getMaxAge public function Returns the number of seconds after the time specified in the response's Date header when the response should no longer be considered fresh.
Response::getProtocolVersion public function Gets the HTTP protocol version.
Response::getStatusCode public function Retrieves the status code for the current web response.
Response::getTtl public function Returns the response's time-to-live in seconds.
Response::getVary public function Returns an array of header names given in the Vary header.
Response::hasVary public function Returns true if the response includes a Vary header.
Response::isCacheable public function Returns true if the response is worth caching under any circumstance.
Response::isClientError public function Is there a client error?
Response::isEmpty public function Is the response empty?
Response::isForbidden public function Is the response forbidden?
Response::isFresh public function Returns true if the response is "fresh".
Response::isInformational public function Is response informative?
Response::isInvalid public function Is response invalid?
Response::isNotFound public function Is the response a not found error?
Response::isNotModified public function Determines if the Response validators (ETag, Last-Modified) match a conditional value specified in the Request.
Response::isOk public function Is the response OK?
Response::isRedirect public function Is the response a redirect of some form?
Response::isRedirection public function Is the response a redirect?
Response::isServerError public function Was there a server side error?
Response::isSuccessful public function Is response successful?
Response::isValidateable public function Returns true if the response includes headers that can be used to validate the response with the origin server using a conditional GET request.
Response::mustRevalidate public function Returns true if the response must be revalidated by caches.
Response::send public function Sends HTTP headers and content.
Response::sendHeaders public function Sends HTTP headers.
Response::setCache public function Sets the response's cache headers (validation and/or expiration).
Response::setCharset public function Sets the response charset.
Response::setClientTtl public function Sets the response's time-to-live for private/client caches.
Response::setDate public function Sets the Date header.
Response::setEtag public function Sets the ETag value.
Response::setExpires public function Sets the Expires HTTP header with a DateTime instance.
Response::setLastModified public function Sets the Last-Modified HTTP header with a DateTime instance.
Response::setMaxAge public function Sets the number of seconds after which the response should no longer be considered fresh.
Response::setNotModified public function Modifies the response so that it conforms to the rules defined for a 304 status code.
Response::setPrivate public function Marks the response as "private".
Response::setProtocolVersion public function Sets the HTTP protocol version (1.0 or 1.1).
Response::setPublic public function Marks the response as "public".
Response::setSharedMaxAge public function Sets the number of seconds after which the response should no longer be considered fresh by shared caches.
Response::setStatusCode public function Sets the response status code.
Response::setTtl public function Sets the response's time-to-live for shared caches.
Response::setVary public function Sets the Vary header.
Response::__clone public function Clones the current Response instance.
Response::__toString public function Returns the Response as an HTTP string.