PluginProbe
Media Cloud Sync / 1.4.2
Media Cloud Sync v1.4.2
1.4.2 1.4.1 1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 All 36 releases
← All changes | includes/sdk/s3/Aws/S3/BucketEndpointMiddleware.php +34 -47 1.2.13 → 1.4.2 View file →
@@ -2,8 +2,9 @@
2 2
3 3 namespace Dudlewebs\WPMCS\s3\Aws\S3;
4 4
5 5 use Dudlewebs\WPMCS\s3\Aws\CommandInterface;
6 +use Dudlewebs\WPMCS\s3\GuzzleHttp\Psr7\Uri;
6 7 use Dudlewebs\WPMCS\s3\Psr\Http\Message\RequestInterface;
7 8 /**
8 9 * Used to update the host used for S3 requests in the case of using a
9 10 * "bucket endpoint" or CNAME bucket.
@@ -15,22 +16,29 @@
15 16 class BucketEndpointMiddleware
16 17 {
17 18 private static $exclusions = ['GetBucketLocation' => \true];
18 19 private $nextHandler;
20 + private bool $useEndpointV2;
21 + private ?string $endpoint;
19 22 /**
20 23 * Create a middleware wrapper function.
21 24 *
25 + * @param bool $useEndpointV2
26 + * @param string|null $endpoint
27 + *
22 28 * @return callable
23 29 */
24 - public static function wrap()
30 + public static function wrap(bool $useEndpointV2 = \false, ?string $endpoint = null) : callable
25 31 {
26 - return function (callable $handler) {
27 - return new self($handler);
32 + return function (callable $handler) use($useEndpointV2, $endpoint) {
33 + return new self($handler, $useEndpointV2, $endpoint);
28 34 };
29 35 }
30 - public function __construct(callable $nextHandler)
36 + public function __construct(callable $nextHandler, bool $useEndpointV2, ?string $endpoint = null)
31 37 {
32 38 $this->nextHandler = $nextHandler;
39 + $this->useEndpointV2 = $useEndpointV2;
40 + $this->endpoint = $endpoint;
33 41 }
34 42 public function __invoke(CommandInterface $command, RequestInterface $request)
35 43 {
36 44 $nextHandler = $this->nextHandler;
@@ -40,63 +48,42 @@
40 48 }
41 49 return $nextHandler($command, $request);
42 50 }
43 51 /**
44 - * Performs a one-time removal of Bucket from path, then if
45 - * the bucket name is duplicated in the path, performs additional
46 - * removal which is dependent on the number of occurrences of the bucket
47 - * name in a path-like format in the key name.
52 + * @param string $path
53 + * @param string $bucket
48 54 *
49 55 * @return string
50 56 */
51 - private function removeBucketFromPath($path, $bucket, $key)
57 + private function removeBucketFromPath(string $path, string $bucket) : string
52 58 {
53 - $occurrencesInKey = $this->getBucketNameOccurrencesInKey($key, $bucket);
54 - do {
55 - $len = \strlen($bucket) + 1;
56 - if (\substr($path, 0, $len) === "/{$bucket}") {
57 - $path = \substr($path, $len);
58 - }
59 - } while (\substr_count($path, "/{$bucket}") > $occurrencesInKey + 1);
59 + $len = \strlen($bucket) + 1;
60 + if (\str_starts_with($path, "/{$bucket}")) {
61 + $path = \substr($path, $len);
62 + }
60 63 return $path ?: '/';
61 64 }
62 - private function removeDuplicateBucketFromHost($host, $bucket)
65 + /**
66 + * @param RequestInterface $request
67 + * @param CommandInterface $command
68 + *
69 + * @return RequestInterface
70 + */
71 + private function modifyRequest(RequestInterface $request, CommandInterface $command) : RequestInterface
63 72 {
64 - if (\substr_count($host, $bucket) > 1) {
65 - while (\strpos($host, "{$bucket}.{$bucket}") === 0) {
66 - $hostArr = \explode('.', $host);
67 - \array_shift($hostArr);
68 - $host = \implode('.', $hostArr);
69 - }
70 - }
71 - return $host;
72 - }
73 - private function getBucketNameOccurrencesInKey($key, $bucket)
74 - {
75 - $occurrences = 0;
76 - if (empty($key)) {
77 - return $occurrences;
78 - }
79 - $segments = \explode('/', $key);
80 - foreach ($segments as $segment) {
81 - if (\strpos($segment, $bucket) === 0) {
82 - $occurrences++;
83 - }
84 - }
85 - return $occurrences;
86 - }
87 - private function modifyRequest(RequestInterface $request, CommandInterface $command)
88 - {
89 - $key = isset($command['Key']) ? $command['Key'] : null;
90 73 $uri = $request->getUri();
91 74 $path = $uri->getPath();
92 75 $host = $uri->getHost();
93 76 $bucket = $command['Bucket'];
94 - $path = $this->removeBucketFromPath($path, $bucket, $key);
95 - $host = $this->removeDuplicateBucketFromHost($host, $bucket);
77 + if ($this->useEndpointV2 && !empty($this->endpoint)) {
78 + // V2 provider adds bucket name to host by default
79 + // preserve original host
80 + $host = (new Uri($this->endpoint))->getHost();
81 + }
82 + $path = $this->removeBucketFromPath($path, $bucket);
96 83 // Modify the Key to make sure the key is encoded, but slashes are not.
97 - if ($key) {
84 + if ($command['Key']) {
98 85 $path = S3Client::encodeKey(\rawurldecode($path));
99 86 }
100 - return $request->withUri($uri->withHost($host)->withPath($path));
87 + return $request->withUri($uri->withPath($path)->withHost($host));
101 88 }
102 89 }