HttpMethodValidator.php 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. declare(strict_types=1);
  7. namespace Magento\Framework\App\Request;
  8. use Magento\Framework\App\ActionInterface;
  9. use Magento\Framework\App\RequestInterface;
  10. use Magento\Framework\Exception\NotFoundException;
  11. use Magento\Framework\Interception\InterceptorInterface;
  12. use Magento\Framework\Phrase;
  13. use Psr\Log\LoggerInterface;
  14. /**
  15. * Make sure that a request's method can be processed by an action.
  16. */
  17. class HttpMethodValidator implements ValidatorInterface
  18. {
  19. /**
  20. * @var HttpMethodMap
  21. */
  22. private $map;
  23. /**
  24. * @var LoggerInterface
  25. */
  26. private $log;
  27. /**
  28. * @param HttpMethodMap $map
  29. * @param LoggerInterface $logger
  30. */
  31. public function __construct(
  32. HttpMethodMap $map,
  33. LoggerInterface $logger
  34. ) {
  35. $this->map = $map;
  36. $this->log = $logger;
  37. }
  38. /**
  39. * Create exception when invalid HTTP method used.
  40. *
  41. * @param Http $request
  42. * @param ActionInterface $action
  43. * @throws InvalidRequestException
  44. *
  45. * @return void
  46. */
  47. private function throwException(
  48. Http $request,
  49. ActionInterface $action
  50. ): void {
  51. $uri = $request->getRequestUri();
  52. $method = $request->getMethod();
  53. if ($action instanceof InterceptorInterface) {
  54. $actionClass = get_parent_class($action);
  55. } else {
  56. $actionClass = get_class($action);
  57. }
  58. $this->log->debug(
  59. "URI '$uri'' cannot be accessed with $method method ($actionClass)"
  60. );
  61. throw new InvalidRequestException(
  62. new NotFoundException(new Phrase('Page not found.'))
  63. );
  64. }
  65. /**
  66. * @inheritDoc
  67. */
  68. public function validate(
  69. RequestInterface $request,
  70. ActionInterface $action
  71. ): void {
  72. if ($request instanceof Http) {
  73. $method = $request->getMethod();
  74. $map = $this->map->getMap();
  75. //If we don't have an interface for the HTTP method or
  76. //the action has HTTP method limitations and doesn't allow the
  77. //received one then the request is invalid.
  78. if (!array_key_exists($method, $map)
  79. || (array_intersect($map, class_implements($action, true))
  80. && !$action instanceof $map[$method]
  81. )
  82. ) {
  83. $this->throwException($request, $action);
  84. }
  85. }
  86. }
  87. }