Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
11 / 11
SecuredRedirectResponse
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
4 / 4
6
100.00% covered (success)
100.00%
11 / 11
 createFromRedirectResponse
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 fromResponse
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
5 / 5
 setTargetUrl
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 isSafe
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
0 / 0
<?php
/**
 * @file
 * Contains \Drupal\Component\HttpFoundation\SecuredRedirectResponse.
 */
namespace Drupal\Component\HttpFoundation;
use \Symfony\Component\HttpFoundation\RedirectResponse;
/**
 * Provides a common base class for safe redirects.
 *
 * In case you want to redirect to external URLs use
 * TrustedRedirectResponse.
 *
 * For local URLs we use LocalRedirectResponse which opts
 * out of external redirects.
 */
abstract class SecuredRedirectResponse extends RedirectResponse {
  /**
   * Copies an existing redirect response into a safe one.
   *
   * The safe one cannot accidentally redirect to an external URL, unless
   * actively wanted (see TrustedRedirectResponse).
   *
   * @param \Symfony\Component\HttpFoundation\RedirectResponse $response
   *   The original redirect.
   *
   * @return static
   */
  public static function createFromRedirectResponse(RedirectResponse $response) {
    $safe_response = new static($response->getTargetUrl(), $response->getStatusCode(), $response->headers->allPreserveCase());
    $safe_response->fromResponse($response);
    return $safe_response;
  }
  /**
   * Copies over the values from the given response.
   *
   * @param \Symfony\Component\HttpFoundation\RedirectResponse $response
   *   The redirect reponse object.
   */
  protected function fromResponse(RedirectResponse $response) {
    $this->setProtocolVersion($response->getProtocolVersion());
    $this->setCharset($response->getCharset());
    // Cookies are separate from other headers and have to be copied over
    // directly.
    foreach ($response->headers->getCookies() as $cookie) {
      $this->headers->setCookie($cookie);
    }
  }
  /**
   * {@inheritdoc}
   */
  public function setTargetUrl($url) {
    if (!$this->isSafe($url)) {
      throw new \InvalidArgumentException(sprintf('It is not safe to redirect to %s', $url));
    }
    return parent::setTargetUrl($url);
  }
  /**
   * Returns whether the URL is considered as safe to redirect to.
   *
   * @param string $url
   *   The URL checked for safety.
   *
   * @return bool
   */
  abstract protected function isSafe($url);
}