PluginProbe
Media Cloud Sync / 1.3.11
Media Cloud Sync v1.3.11
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 1.2.9 All 35 releases
media-cloud-sync / includes / sdk / s3 / Aws / S3 / S3UriParser.php

S3UriParser.php in Media Cloud Sync 1.3.11, at includes/sdk/s3/Aws/S3/S3UriParser.php

126 lines 4.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Dudlewebs\WPMCS\s3\Aws\S3;
4
5 use Dudlewebs\WPMCS\s3\Aws\Arn\Exception\InvalidArnException;
6 use Dudlewebs\WPMCS\s3\Aws\Arn\S3\AccessPointArn;
7 use Dudlewebs\WPMCS\s3\Aws\Arn\ArnParser;
8 use Dudlewebs\WPMCS\s3\GuzzleHttp\Psr7;
9 use Dudlewebs\WPMCS\s3\Psr\Http\Message\UriInterface;
10 /**
11 * Extracts a region, bucket, key, and and if a URI is in path-style
12 */
13 class S3UriParser
14 {
15 private $pattern = '/^(.+\\.)?s3[.-]([A-Za-z0-9-]+)\\./';
16 private $streamWrapperScheme = 's3';
17 private static $defaultResult = ['path_style' => \true, 'bucket' => null, 'key' => null, 'region' => null];
18 /**
19 * Parses a URL or S3 StreamWrapper Uri (s3://) into an associative array
20 * of Amazon S3 data including:
21 *
22 * - bucket: The Amazon S3 bucket (null if none)
23 * - key: The Amazon S3 key (null if none)
24 * - path_style: Set to true if using path style, or false if not
25 * - region: Set to a string if a non-class endpoint is used or null.
26 *
27 * @param string|UriInterface $uri
28 *
29 * @return array
30 * @throws \InvalidArgumentException|InvalidArnException
31 */
32 public function parse($uri)
33 {
34 // Attempt to parse host component of uri as an ARN
35 $components = $this->parseS3UrlComponents($uri);
36 if (!empty($components)) {
37 if (ArnParser::isArn($components['host'])) {
38 $arn = new AccessPointArn($components['host']);
39 return ['bucket' => $components['host'], 'key' => $components['path'], 'path_style' => \false, 'region' => $arn->getRegion()];
40 }
41 }
42 $url = Psr7\Utils::uriFor($uri);
43 if ($url->getScheme() == $this->streamWrapperScheme) {
44 return $this->parseStreamWrapper($url);
45 }
46 if (!$url->getHost()) {
47 throw new \InvalidArgumentException('No hostname found in URI: ' . $uri);
48 }
49 if (!\preg_match($this->pattern, $url->getHost(), $matches)) {
50 return $this->parseCustomEndpoint($url);
51 }
52 // Parse the URI based on the matched format (path / virtual)
53 $result = empty($matches[1]) ? $this->parsePathStyle($url) : $this->parseVirtualHosted($url, $matches);
54 // Add the region if one was found and not the classic endpoint
55 $result['region'] = $matches[2] == 'amazonaws' ? null : $matches[2];
56 return $result;
57 }
58 private function parseS3UrlComponents($uri)
59 {
60 \preg_match("/^([a-zA-Z0-9]*):\\/\\/([a-zA-Z0-9:-]*)\\/(.*)/", $uri, $components);
61 if (empty($components)) {
62 return [];
63 }
64 return ['scheme' => $components[1], 'host' => $components[2], 'path' => $components[3]];
65 }
66 private function parseStreamWrapper(UriInterface $url)
67 {
68 $result = self::$defaultResult;
69 $result['path_style'] = \false;
70 $result['bucket'] = $url->getHost();
71 if ($url->getPath()) {
72 $key = \ltrim($url->getPath(), '/ ');
73 if (!empty($key)) {
74 $result['key'] = $key;
75 }
76 }
77 return $result;
78 }
79 private function parseCustomEndpoint(UriInterface $url)
80 {
81 $result = self::$defaultResult;
82 $path = \ltrim($url->getPath(), '/ ');
83 $segments = \explode('/', $path, 2);
84 if (isset($segments[0])) {
85 $result['bucket'] = $segments[0];
86 if (isset($segments[1])) {
87 $result['key'] = $segments[1];
88 }
89 }
90 return $result;
91 }
92 private function parsePathStyle(UriInterface $url)
93 {
94 $result = self::$defaultResult;
95 if ($url->getPath() != '/') {
96 $path = \ltrim($url->getPath(), '/');
97 if ($path) {
98 $pathPos = \strpos($path, '/');
99 if ($pathPos === \false) {
100 // https://s3.amazonaws.com/bucket
101 $result['bucket'] = $path;
102 } elseif ($pathPos == \strlen($path) - 1) {
103 // https://s3.amazonaws.com/bucket/
104 $result['bucket'] = \substr($path, 0, -1);
105 } else {
106 // https://s3.amazonaws.com/bucket/key
107 $result['bucket'] = \substr($path, 0, $pathPos);
108 $result['key'] = \substr($path, $pathPos + 1) ?: null;
109 }
110 }
111 }
112 return $result;
113 }
114 private function parseVirtualHosted(UriInterface $url, array $matches)
115 {
116 $result = self::$defaultResult;
117 $result['path_style'] = \false;
118 // Remove trailing "." from the prefix to get the bucket
119 $result['bucket'] = \substr($matches[1], 0, -1);
120 $path = $url->getPath();
121 // Check if a key was present, and if so, removing the leading "/"
122 $result['key'] = !$path || $path == '/' ? null : \substr($path, 1);
123 return $result;
124 }
125 }
126