SecuredRedirectResponse.php 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. <?php
  2. namespace Drupal\Component\HttpFoundation;
  3. use Symfony\Component\HttpFoundation\RedirectResponse;
  4. /**
  5. * Provides a common base class for safe redirects.
  6. *
  7. * In case you want to redirect to external URLs use
  8. * TrustedRedirectResponse.
  9. *
  10. * For local URLs we use LocalRedirectResponse which opts
  11. * out of external redirects.
  12. */
  13. abstract class SecuredRedirectResponse extends RedirectResponse {
  14. /**
  15. * Copies an existing redirect response into a safe one.
  16. *
  17. * The safe one cannot accidentally redirect to an external URL, unless
  18. * actively wanted (see TrustedRedirectResponse).
  19. *
  20. * @param \Symfony\Component\HttpFoundation\RedirectResponse $response
  21. * The original redirect.
  22. *
  23. * @return static
  24. */
  25. public static function createFromRedirectResponse(RedirectResponse $response) {
  26. $safe_response = new static($response->getTargetUrl(), $response->getStatusCode(), $response->headers->allPreserveCase());
  27. $safe_response->fromResponse($response);
  28. return $safe_response;
  29. }
  30. /**
  31. * Copies over the values from the given response.
  32. *
  33. * @param \Symfony\Component\HttpFoundation\RedirectResponse $response
  34. * The redirect response object.
  35. */
  36. protected function fromResponse(RedirectResponse $response) {
  37. $this->setProtocolVersion($response->getProtocolVersion());
  38. if ($response->getCharset()) {
  39. $this->setCharset($response->getCharset());
  40. }
  41. // Cookies are separate from other headers and have to be copied over
  42. // directly.
  43. foreach ($response->headers->getCookies() as $cookie) {
  44. $this->headers->setCookie($cookie);
  45. }
  46. }
  47. /**
  48. * {@inheritdoc}
  49. */
  50. public function setTargetUrl($url) {
  51. if (!$this->isSafe($url)) {
  52. throw new \InvalidArgumentException(sprintf('It is not safe to redirect to %s', $url));
  53. }
  54. return parent::setTargetUrl($url);
  55. }
  56. /**
  57. * Returns whether the URL is considered as safe to redirect to.
  58. *
  59. * @param string $url
  60. * The URL checked for safety.
  61. *
  62. * @return bool
  63. */
  64. abstract protected function isSafe($url);
  65. }