EventBridgeEndpointMiddleware.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <?php
  2. namespace Aws\EventBridge;
  3. use Aws\CommandInterface;
  4. use Aws\Endpoint\EndpointProvider;
  5. use Aws\Endpoint\PartitionEndpointProvider;
  6. use InvalidArgumentException;
  7. use Psr\Http\Message\RequestInterface;
  8. /**
  9. * Reroutes an eventbridge request to the proper endpoint
  10. * @internal
  11. */
  12. class EventBridgeEndpointMiddleware
  13. {
  14. private $nextHandler;
  15. private $region;
  16. private $config;
  17. private $endpointProvider;
  18. private $isCustomEndpoint;
  19. /**
  20. * Provide the URI scheme of the client sending requests.
  21. * @param EndpointProvider $endpointProvider
  22. * @return callable
  23. */
  24. public static function wrap($region, $config, $endpointProvider, $isCustomEndpoint)
  25. {
  26. return function (callable $handler) use (
  27. $region,
  28. $config,
  29. $endpointProvider,
  30. $isCustomEndpoint
  31. ) {
  32. return new self(
  33. $handler,
  34. $region,
  35. $config,
  36. $endpointProvider,
  37. $isCustomEndpoint
  38. );
  39. };
  40. }
  41. public function __construct(
  42. callable $nextHandler,
  43. $region,
  44. $config,
  45. $endpointProvider,
  46. $isCustomEndpoint
  47. ) {
  48. $this->nextHandler = $nextHandler;
  49. $this->region = $region;
  50. $this->config = $config;
  51. $this->endpointProvider = is_null($endpointProvider)
  52. ? PartitionEndpointProvider::defaultProvider()
  53. : $endpointProvider;
  54. $this->isCustomEndpoint = $isCustomEndpoint;
  55. }
  56. public function __invoke(CommandInterface $cmd, RequestInterface $req) {
  57. $sigV4aCommands = ['PutEvents'];
  58. if (in_array($cmd->getName(), $sigV4aCommands)) {
  59. if (isset($cmd['EndpointId'])) {
  60. $endpointID = $cmd['EndpointId'];
  61. $this->validateEndpointId($endpointID);
  62. if (!$this->isCustomEndpoint) {
  63. $dnsSuffix = $this->endpointProvider
  64. ->getPartition($this->region, 'eventbridge')
  65. ->getDnsSuffix();
  66. $newUri = "{$endpointID}.endpoint.events.{$dnsSuffix}";
  67. $oldUri = $req->getUri();
  68. $req = $req->withUri($oldUri->withHost($newUri));
  69. }
  70. $cmd['@context']['signature_version'] = 'v4a';
  71. }
  72. }
  73. $f = $this->nextHandler;
  74. return $f($cmd, $req);
  75. }
  76. protected static function isValidHostLabel($string)
  77. {
  78. if (empty($string) || strlen($string) > 63) {
  79. return false;
  80. }
  81. if ($value = preg_match("/^[a-zA-Z0-9-.]+$/", $string)) {
  82. return true;
  83. }
  84. return false;
  85. }
  86. /**
  87. * @param $endpointID
  88. * @param CommandInterface $cmd
  89. */
  90. private function validateEndpointId($endpointID)
  91. {
  92. if (empty($endpointID)) {
  93. throw new \InvalidArgumentException("EventId must be a non-empty string");
  94. }
  95. if (!self::isValidHostLabel($endpointID)) {
  96. throw new InvalidArgumentException("EventId must be a valid host");
  97. }
  98. if ($this->config['use_fips_endpoint']) {
  99. throw new InvalidArgumentException(
  100. "EventId is currently not compatible with FIPS pseudo regions"
  101. );
  102. }
  103. if ($this->config['dual_stack']) {
  104. throw new InvalidArgumentException(
  105. "EventId is currently not compatible with dualstack"
  106. );
  107. }
  108. }
  109. }