You are here

class BinaryFileResponse in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 vendor/symfony/http-foundation/BinaryFileResponse.php \Symfony\Component\HttpFoundation\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

8 files declare their use of BinaryFileResponse
BinaryFileResponseTest.php in vendor/symfony/http-foundation/Tests/BinaryFileResponseTest.php
DiactorosFactory.php in vendor/symfony/psr-http-message-bridge/Factory/DiactorosFactory.php
DiactorosFactoryTest.php in vendor/symfony/psr-http-message-bridge/Tests/Factory/DiactorosFactoryTest.php
ExportForm.php in core/modules/locale/src/Form/ExportForm.php
Contains \Drupal\locale\Form\ExportForm.
FileDownloadController.php in core/modules/system/src/FileDownloadController.php
Contains \Drupal\system\FileDownloadController.

... See full list

File

vendor/symfony/http-foundation/BinaryFileResponse.php, line 26

Namespace

Symfony\Component\HttpFoundation
View source
class BinaryFileResponse extends Response {
  protected static $trustXSendfileTypeHeader = false;
  protected $file;
  protected $offset;
  protected $maxlen;
  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
   * @param bool                $public             Files are public by default
   * @param null|string         $contentDisposition The type of Content-Disposition to set automatically with the filename
   * @param bool                $autoEtag           Whether the ETag header should be automatically set
   * @param bool                $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();
    }
  }

  /**
   * @param \SplFileInfo|string $file               The file to stream
   * @param int                 $status             The response status code
   * @param array               $headers            An array of response headers
   * @param bool                $public             Files are public by default
   * @param null|string         $contentDisposition The type of Content-Disposition to set automatically with the filename
   * @param bool                $autoEtag           Whether the ETag header should be automatically set
   * @param bool                $autoLastModified   Whether the Last-Modified header should be automatically set
   *
   * @return BinaryFileResponse The created response
   */
  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 bool                $autoEtag
   * @param bool                $autoLastModified
   *
   * @return BinaryFileResponse
   *
   * @throws FileException
   */
  public function setFile($file, $contentDisposition = null, $autoEtag = false, $autoLastModified = true) {
    if (!$file instanceof File) {
      if ($file instanceof \SplFileInfo) {
        $file = new File($file
          ->getPathname());
      }
      else {
        $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());
    if (!$this->headers
      ->has('Accept-Ranges')) {

      // Only accept ranges on safe HTTP methods
      $this->headers
        ->set('Accept-Ranges', $request
        ->isMethodSafe() ? 'bytes' : 'none');
    }
    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.
        // @link http://wiki.nginx.org/X-accel#X-Accel-Redirect
        foreach (explode(',', $request->headers
          ->get('X-Accel-Mapping', '')) as $mapping) {
          $mapping = explode('=', $mapping, 2);
          if (2 == count($mapping)) {
            $pathPrefix = trim($mapping[0]);
            $location = 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;
        }
        if ($start <= $end) {
          if ($start < 0 || $end > $fileSize - 1) {
            $this
              ->setStatusCode(416);
          }
          elseif ($start !== 0 || $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));
            $this->headers
              ->set('Content-Length', $end - $start + 1);
          }
        }
      }
    }
    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);
    if ($this->deleteFileAfterSend) {
      unlink($this->file
        ->getPathname());
    }
  }

  /**
   * {@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;
  }

  /**
   * If this is set to true, the file will be unlinked after the request is send
   * Note: If the X-Sendfile header is used, the deleteFileAfterSend setting will not be used.
   *
   * @param bool $shouldDelete
   *
   * @return BinaryFileResponse
   */
  public function deleteFileAfterSend($shouldDelete) {
    $this->deleteFileAfterSend = $shouldDelete;
    return $this;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
BinaryFileResponse::$deleteFileAfterSend protected property
BinaryFileResponse::$file protected property
BinaryFileResponse::$maxlen protected property
BinaryFileResponse::$offset protected property
BinaryFileResponse::$trustXSendfileTypeHeader protected static property
BinaryFileResponse::create public static function Overrides Response::create
BinaryFileResponse::deleteFileAfterSend public function If this is set to true, the file will be unlinked after the request is send Note: If the X-Sendfile header is used, the deleteFileAfterSend setting will not be used.
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::closeOutputBuffers public static function Cleans or flushes output buffers up to target level.
Response::ensureIEOverSSLCompatibility protected function Checks 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::HTTP_ACCEPTED constant
Response::HTTP_ALREADY_REPORTED constant
Response::HTTP_BAD_GATEWAY constant
Response::HTTP_BAD_REQUEST constant
Response::HTTP_CONFLICT constant
Response::HTTP_CONTINUE constant
Response::HTTP_CREATED constant
Response::HTTP_EXPECTATION_FAILED constant
Response::HTTP_FAILED_DEPENDENCY constant
Response::HTTP_FORBIDDEN constant
Response::HTTP_FOUND constant
Response::HTTP_GATEWAY_TIMEOUT constant
Response::HTTP_GONE constant
Response::HTTP_IM_USED constant
Response::HTTP_INSUFFICIENT_STORAGE constant
Response::HTTP_INTERNAL_SERVER_ERROR constant
Response::HTTP_I_AM_A_TEAPOT constant
Response::HTTP_LENGTH_REQUIRED constant
Response::HTTP_LOCKED constant
Response::HTTP_LOOP_DETECTED constant
Response::HTTP_METHOD_NOT_ALLOWED constant
Response::HTTP_MOVED_PERMANENTLY constant
Response::HTTP_MULTIPLE_CHOICES constant
Response::HTTP_MULTI_STATUS constant
Response::HTTP_NETWORK_AUTHENTICATION_REQUIRED constant
Response::HTTP_NON_AUTHORITATIVE_INFORMATION constant
Response::HTTP_NOT_ACCEPTABLE constant
Response::HTTP_NOT_EXTENDED constant
Response::HTTP_NOT_FOUND constant
Response::HTTP_NOT_IMPLEMENTED constant
Response::HTTP_NOT_MODIFIED constant
Response::HTTP_NO_CONTENT constant
Response::HTTP_OK constant
Response::HTTP_PARTIAL_CONTENT constant
Response::HTTP_PAYMENT_REQUIRED constant
Response::HTTP_PERMANENTLY_REDIRECT constant
Response::HTTP_PRECONDITION_FAILED constant
Response::HTTP_PRECONDITION_REQUIRED constant
Response::HTTP_PROCESSING constant
Response::HTTP_PROXY_AUTHENTICATION_REQUIRED constant
Response::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE constant
Response::HTTP_REQUEST_ENTITY_TOO_LARGE constant
Response::HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE constant
Response::HTTP_REQUEST_TIMEOUT constant
Response::HTTP_REQUEST_URI_TOO_LONG constant
Response::HTTP_RESERVED constant
Response::HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL constant
Response::HTTP_RESET_CONTENT constant
Response::HTTP_SEE_OTHER constant
Response::HTTP_SERVICE_UNAVAILABLE constant
Response::HTTP_SWITCHING_PROTOCOLS constant
Response::HTTP_TEMPORARY_REDIRECT constant
Response::HTTP_TOO_MANY_REQUESTS constant
Response::HTTP_UNAUTHORIZED constant
Response::HTTP_UNPROCESSABLE_ENTITY constant
Response::HTTP_UNSUPPORTED_MEDIA_TYPE constant
Response::HTTP_UPGRADE_REQUIRED constant
Response::HTTP_USE_PROXY constant
Response::HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL constant
Response::HTTP_VERSION_NOT_SUPPORTED constant
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.