You are here

class ResponseHeaderBag in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 vendor/symfony/http-foundation/ResponseHeaderBag.php \Symfony\Component\HttpFoundation\ResponseHeaderBag

ResponseHeaderBag is a container for Response HTTP headers.

@author Fabien Potencier <fabien@symfony.com>

Hierarchy

  • class \Symfony\Component\HttpFoundation\HeaderBag implements \Symfony\Component\HttpFoundation\IteratorAggregate, \Symfony\Component\HttpFoundation\Countable

Expanded class hierarchy of ResponseHeaderBag

3 files declare their use of ResponseHeaderBag
BinaryFileResponseTest.php in vendor/symfony/http-foundation/Tests/BinaryFileResponseTest.php
RequestDataCollector.php in vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php
ResponseHeaderBagTest.php in vendor/symfony/http-foundation/Tests/ResponseHeaderBagTest.php

File

vendor/symfony/http-foundation/ResponseHeaderBag.php, line 19

Namespace

Symfony\Component\HttpFoundation
View source
class ResponseHeaderBag extends HeaderBag {
  const COOKIES_FLAT = 'flat';
  const COOKIES_ARRAY = 'array';
  const DISPOSITION_ATTACHMENT = 'attachment';
  const DISPOSITION_INLINE = 'inline';

  /**
   * @var array
   */
  protected $computedCacheControl = array();

  /**
   * @var array
   */
  protected $cookies = array();

  /**
   * @var array
   */
  protected $headerNames = array();

  /**
   * Constructor.
   *
   * @param array $headers An array of HTTP headers
   */
  public function __construct(array $headers = array()) {
    parent::__construct($headers);
    if (!isset($this->headers['cache-control'])) {
      $this
        ->set('Cache-Control', '');
    }
  }

  /**
   * {@inheritdoc}
   */
  public function __toString() {
    $cookies = '';
    foreach ($this
      ->getCookies() as $cookie) {
      $cookies .= 'Set-Cookie: ' . $cookie . "\r\n";
    }
    ksort($this->headerNames);
    return parent::__toString() . $cookies;
  }

  /**
   * Returns the headers, with original capitalizations.
   *
   * @return array An array of headers
   */
  public function allPreserveCase() {
    return array_combine($this->headerNames, $this->headers);
  }

  /**
   * {@inheritdoc}
   */
  public function replace(array $headers = array()) {
    $this->headerNames = array();
    parent::replace($headers);
    if (!isset($this->headers['cache-control'])) {
      $this
        ->set('Cache-Control', '');
    }
  }

  /**
   * {@inheritdoc}
   */
  public function set($key, $values, $replace = true) {
    parent::set($key, $values, $replace);
    $uniqueKey = strtr(strtolower($key), '_', '-');
    $this->headerNames[$uniqueKey] = $key;

    // ensure the cache-control header has sensible defaults
    if (in_array($uniqueKey, array(
      'cache-control',
      'etag',
      'last-modified',
      'expires',
    ))) {
      $computed = $this
        ->computeCacheControlValue();
      $this->headers['cache-control'] = array(
        $computed,
      );
      $this->headerNames['cache-control'] = 'Cache-Control';
      $this->computedCacheControl = $this
        ->parseCacheControl($computed);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function remove($key) {
    parent::remove($key);
    $uniqueKey = strtr(strtolower($key), '_', '-');
    unset($this->headerNames[$uniqueKey]);
    if ('cache-control' === $uniqueKey) {
      $this->computedCacheControl = array();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function hasCacheControlDirective($key) {
    return array_key_exists($key, $this->computedCacheControl);
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheControlDirective($key) {
    return array_key_exists($key, $this->computedCacheControl) ? $this->computedCacheControl[$key] : null;
  }

  /**
   * Sets a cookie.
   *
   * @param Cookie $cookie
   */
  public function setCookie(Cookie $cookie) {
    $this->cookies[$cookie
      ->getDomain()][$cookie
      ->getPath()][$cookie
      ->getName()] = $cookie;
  }

  /**
   * Removes a cookie from the array, but does not unset it in the browser.
   *
   * @param string $name
   * @param string $path
   * @param string $domain
   */
  public function removeCookie($name, $path = '/', $domain = null) {
    if (null === $path) {
      $path = '/';
    }
    unset($this->cookies[$domain][$path][$name]);
    if (empty($this->cookies[$domain][$path])) {
      unset($this->cookies[$domain][$path]);
      if (empty($this->cookies[$domain])) {
        unset($this->cookies[$domain]);
      }
    }
  }

  /**
   * Returns an array with all cookies.
   *
   * @param string $format
   *
   * @throws \InvalidArgumentException When the $format is invalid
   *
   * @return array
   */
  public function getCookies($format = self::COOKIES_FLAT) {
    if (!in_array($format, array(
      self::COOKIES_FLAT,
      self::COOKIES_ARRAY,
    ))) {
      throw new \InvalidArgumentException(sprintf('Format "%s" invalid (%s).', $format, implode(', ', array(
        self::COOKIES_FLAT,
        self::COOKIES_ARRAY,
      ))));
    }
    if (self::COOKIES_ARRAY === $format) {
      return $this->cookies;
    }
    $flattenedCookies = array();
    foreach ($this->cookies as $path) {
      foreach ($path as $cookies) {
        foreach ($cookies as $cookie) {
          $flattenedCookies[] = $cookie;
        }
      }
    }
    return $flattenedCookies;
  }

  /**
   * Clears a cookie in the browser.
   *
   * @param string $name
   * @param string $path
   * @param string $domain
   * @param bool   $secure
   * @param bool   $httpOnly
   */
  public function clearCookie($name, $path = '/', $domain = null, $secure = false, $httpOnly = true) {
    $this
      ->setCookie(new Cookie($name, null, 1, $path, $domain, $secure, $httpOnly));
  }

  /**
   * Generates a HTTP Content-Disposition field-value.
   *
   * @param string $disposition      One of "inline" or "attachment"
   * @param string $filename         A unicode string
   * @param string $filenameFallback A string containing only ASCII characters that
   *                                 is semantically equivalent to $filename. If the filename is already ASCII,
   *                                 it can be omitted, or just copied from $filename
   *
   * @return string A string suitable for use as a Content-Disposition field-value.
   *
   * @throws \InvalidArgumentException
   *
   * @see RFC 6266
   */
  public function makeDisposition($disposition, $filename, $filenameFallback = '') {
    if (!in_array($disposition, array(
      self::DISPOSITION_ATTACHMENT,
      self::DISPOSITION_INLINE,
    ))) {
      throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE));
    }
    if ('' == $filenameFallback) {
      $filenameFallback = $filename;
    }

    // filenameFallback is not ASCII.
    if (!preg_match('/^[\\x20-\\x7e]*$/', $filenameFallback)) {
      throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.');
    }

    // percent characters aren't safe in fallback.
    if (false !== strpos($filenameFallback, '%')) {
      throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.');
    }

    // path separators aren't allowed in either.
    if (false !== strpos($filename, '/') || false !== strpos($filename, '\\') || false !== strpos($filenameFallback, '/') || false !== strpos($filenameFallback, '\\')) {
      throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.');
    }
    $output = sprintf('%s; filename="%s"', $disposition, str_replace('"', '\\"', $filenameFallback));
    if ($filename !== $filenameFallback) {
      $output .= sprintf("; filename*=utf-8''%s", rawurlencode($filename));
    }
    return $output;
  }

  /**
   * Returns the calculated value of the cache-control header.
   *
   * This considers several other headers and calculates or modifies the
   * cache-control header to a sensible, conservative value.
   *
   * @return string
   */
  protected function computeCacheControlValue() {
    if (!$this->cacheControl && !$this
      ->has('ETag') && !$this
      ->has('Last-Modified') && !$this
      ->has('Expires')) {
      return 'no-cache';
    }
    if (!$this->cacheControl) {

      // conservative by default
      return 'private, must-revalidate';
    }
    $header = $this
      ->getCacheControlHeader();
    if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) {
      return $header;
    }

    // public if s-maxage is defined, private otherwise
    if (!isset($this->cacheControl['s-maxage'])) {
      return $header . ', private';
    }
    return $header;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
HeaderBag::$cacheControl protected property
HeaderBag::$headers protected property
HeaderBag::add public function Adds new headers the current HTTP headers set.
HeaderBag::addCacheControlDirective public function Adds a custom Cache-Control directive.
HeaderBag::all public function Returns the headers.
HeaderBag::contains public function Returns true if the given HTTP header contains the given value.
HeaderBag::count public function Returns the number of headers.
HeaderBag::get public function Returns a header value by name.
HeaderBag::getCacheControlHeader protected function
HeaderBag::getDate public function Returns the HTTP header value converted to a date.
HeaderBag::getIterator public function Returns an iterator for headers.
HeaderBag::has public function Returns true if the HTTP header is defined.
HeaderBag::keys public function Returns the parameter keys.
HeaderBag::parseCacheControl protected function Parses a Cache-Control HTTP header.
HeaderBag::removeCacheControlDirective public function Removes a Cache-Control directive.
ResponseHeaderBag::$computedCacheControl protected property
ResponseHeaderBag::$cookies protected property
ResponseHeaderBag::$headerNames protected property
ResponseHeaderBag::allPreserveCase public function Returns the headers, with original capitalizations.
ResponseHeaderBag::clearCookie public function Clears a cookie in the browser.
ResponseHeaderBag::computeCacheControlValue protected function Returns the calculated value of the cache-control header.
ResponseHeaderBag::COOKIES_ARRAY constant
ResponseHeaderBag::COOKIES_FLAT constant
ResponseHeaderBag::DISPOSITION_ATTACHMENT constant
ResponseHeaderBag::DISPOSITION_INLINE constant
ResponseHeaderBag::getCacheControlDirective public function Returns a Cache-Control directive value by name. Overrides HeaderBag::getCacheControlDirective
ResponseHeaderBag::getCookies public function Returns an array with all cookies.
ResponseHeaderBag::hasCacheControlDirective public function Returns true if the Cache-Control directive is defined. Overrides HeaderBag::hasCacheControlDirective
ResponseHeaderBag::makeDisposition public function Generates a HTTP Content-Disposition field-value.
ResponseHeaderBag::remove public function Removes a header. Overrides HeaderBag::remove
ResponseHeaderBag::removeCookie public function Removes a cookie from the array, but does not unset it in the browser.
ResponseHeaderBag::replace public function Replaces the current HTTP headers by a new set. Overrides HeaderBag::replace
ResponseHeaderBag::set public function Sets a header by name. Overrides HeaderBag::set
ResponseHeaderBag::setCookie public function Sets a cookie.
ResponseHeaderBag::__construct public function Constructor. Overrides HeaderBag::__construct
ResponseHeaderBag::__toString public function Returns the headers as a string. Overrides HeaderBag::__toString