BucketEndpointMiddleware.php 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. <?php
  2. namespace Aws\S3;
  3. use Aws\CommandInterface;
  4. use Psr\Http\Message\RequestInterface;
  5. /**
  6. * Used to update the host used for S3 requests in the case of using a
  7. * "bucket endpoint" or CNAME bucket.
  8. *
  9. * IMPORTANT: this middleware must be added after the "build" step.
  10. *
  11. * @internal
  12. */
  13. class BucketEndpointMiddleware
  14. {
  15. private static $exclusions = ['GetBucketLocation' => true];
  16. private $nextHandler;
  17. /**
  18. * Create a middleware wrapper function.
  19. *
  20. * @return callable
  21. */
  22. public static function wrap()
  23. {
  24. return function (callable $handler) {
  25. return new self($handler);
  26. };
  27. }
  28. public function __construct(callable $nextHandler)
  29. {
  30. $this->nextHandler = $nextHandler;
  31. }
  32. public function __invoke(CommandInterface $command, RequestInterface $request)
  33. {
  34. $nextHandler = $this->nextHandler;
  35. $bucket = $command['Bucket'];
  36. if ($bucket && !isset(self::$exclusions[$command->getName()])) {
  37. $request = $this->modifyRequest($request, $command);
  38. }
  39. return $nextHandler($command, $request);
  40. }
  41. private function removeBucketFromPath($path, $bucket)
  42. {
  43. $len = strlen($bucket) + 1;
  44. if (substr($path, 0, $len) === "/{$bucket}") {
  45. $path = substr($path, $len);
  46. }
  47. return $path ?: '/';
  48. }
  49. private function modifyRequest(
  50. RequestInterface $request,
  51. CommandInterface $command
  52. ) {
  53. $uri = $request->getUri();
  54. $path = $uri->getPath();
  55. $bucket = $command['Bucket'];
  56. $path = $this->removeBucketFromPath($path, $bucket);
  57. // Modify the Key to make sure the key is encoded, but slashes are not.
  58. if ($command['Key']) {
  59. $path = S3Client::encodeKey(rawurldecode($path));
  60. }
  61. return $request->withUri($uri->withPath($path));
  62. }
  63. }