SecuredRedirectResponse.php 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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. $this->setCharset($response->getCharset());
  39. // Cookies are separate from other headers and have to be copied over
  40. // directly.
  41. foreach ($response->headers->getCookies() as $cookie) {
  42. $this->headers->setCookie($cookie);
  43. }
  44. }
  45. /**
  46. * {@inheritdoc}
  47. */
  48. public function setTargetUrl($url) {
  49. if (!$this->isSafe($url)) {
  50. throw new \InvalidArgumentException(sprintf('It is not safe to redirect to %s', $url));
  51. }
  52. return parent::setTargetUrl($url);
  53. }
  54. /**
  55. * Returns whether the URL is considered as safe to redirect to.
  56. *
  57. * @param string $url
  58. * The URL checked for safety.
  59. *
  60. * @return bool
  61. */
  62. abstract protected function isSafe($url);
  63. }