PluginProbe
Media Cloud Sync / 1.2.7
Media Cloud Sync v1.2.7
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
media-cloud-sync / includes / sdk / s3 / GuzzleHttp / Psr7 / Utils.php

Utils.php in Media Cloud Sync 1.2.7, at includes/sdk/s3/GuzzleHttp/Psr7/Utils.php

356 lines 14.0 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\GuzzleHttp\Psr7;
4
5 use Dudlewebs\WPMCS\s3\Psr\Http\Message\RequestInterface;
6 use Dudlewebs\WPMCS\s3\Psr\Http\Message\ServerRequestInterface;
7 use Dudlewebs\WPMCS\s3\Psr\Http\Message\StreamInterface;
8 use Dudlewebs\WPMCS\s3\Psr\Http\Message\UriInterface;
9 final class Utils
10 {
11 /**
12 * Remove the items given by the keys, case insensitively from the data.
13 *
14 * @param iterable<string> $keys
15 *
16 * @return array
17 */
18 public static function caselessRemove($keys, array $data)
19 {
20 $result = [];
21 foreach ($keys as &$key) {
22 $key = \strtolower($key);
23 }
24 foreach ($data as $k => $v) {
25 if (!\in_array(\strtolower($k), $keys)) {
26 $result[$k] = $v;
27 }
28 }
29 return $result;
30 }
31 /**
32 * Copy the contents of a stream into another stream until the given number
33 * of bytes have been read.
34 *
35 * @param StreamInterface $source Stream to read from
36 * @param StreamInterface $dest Stream to write to
37 * @param int $maxLen Maximum number of bytes to read. Pass -1
38 * to read the entire stream.
39 *
40 * @throws \RuntimeException on error.
41 */
42 public static function copyToStream(StreamInterface $source, StreamInterface $dest, $maxLen = -1)
43 {
44 $bufferSize = 8192;
45 if ($maxLen === -1) {
46 while (!$source->eof()) {
47 if (!$dest->write($source->read($bufferSize))) {
48 break;
49 }
50 }
51 } else {
52 $remaining = $maxLen;
53 while ($remaining > 0 && !$source->eof()) {
54 $buf = $source->read(\min($bufferSize, $remaining));
55 $len = \strlen($buf);
56 if (!$len) {
57 break;
58 }
59 $remaining -= $len;
60 $dest->write($buf);
61 }
62 }
63 }
64 /**
65 * Copy the contents of a stream into a string until the given number of
66 * bytes have been read.
67 *
68 * @param StreamInterface $stream Stream to read
69 * @param int $maxLen Maximum number of bytes to read. Pass -1
70 * to read the entire stream.
71 *
72 * @return string
73 *
74 * @throws \RuntimeException on error.
75 */
76 public static function copyToString(StreamInterface $stream, $maxLen = -1)
77 {
78 $buffer = '';
79 if ($maxLen === -1) {
80 while (!$stream->eof()) {
81 $buf = $stream->read(1048576);
82 // Using a loose equality here to match on '' and false.
83 if ($buf == null) {
84 break;
85 }
86 $buffer .= $buf;
87 }
88 return $buffer;
89 }
90 $len = 0;
91 while (!$stream->eof() && $len < $maxLen) {
92 $buf = $stream->read($maxLen - $len);
93 // Using a loose equality here to match on '' and false.
94 if ($buf == null) {
95 break;
96 }
97 $buffer .= $buf;
98 $len = \strlen($buffer);
99 }
100 return $buffer;
101 }
102 /**
103 * Calculate a hash of a stream.
104 *
105 * This method reads the entire stream to calculate a rolling hash, based
106 * on PHP's `hash_init` functions.
107 *
108 * @param StreamInterface $stream Stream to calculate the hash for
109 * @param string $algo Hash algorithm (e.g. md5, crc32, etc)
110 * @param bool $rawOutput Whether or not to use raw output
111 *
112 * @return string Returns the hash of the stream
113 *
114 * @throws \RuntimeException on error.
115 */
116 public static function hash(StreamInterface $stream, $algo, $rawOutput = \false)
117 {
118 $pos = $stream->tell();
119 if ($pos > 0) {
120 $stream->rewind();
121 }
122 $ctx = \hash_init($algo);
123 while (!$stream->eof()) {
124 \hash_update($ctx, $stream->read(1048576));
125 }
126 $out = \hash_final($ctx, (bool) $rawOutput);
127 $stream->seek($pos);
128 return $out;
129 }
130 /**
131 * Clone and modify a request with the given changes.
132 *
133 * This method is useful for reducing the number of clones needed to mutate
134 * a message.
135 *
136 * The changes can be one of:
137 * - method: (string) Changes the HTTP method.
138 * - set_headers: (array) Sets the given headers.
139 * - remove_headers: (array) Remove the given headers.
140 * - body: (mixed) Sets the given body.
141 * - uri: (UriInterface) Set the URI.
142 * - query: (string) Set the query string value of the URI.
143 * - version: (string) Set the protocol version.
144 *
145 * @param RequestInterface $request Request to clone and modify.
146 * @param array $changes Changes to apply.
147 *
148 * @return RequestInterface
149 */
150 public static function modifyRequest(RequestInterface $request, array $changes)
151 {
152 if (!$changes) {
153 return $request;
154 }
155 $headers = $request->getHeaders();
156 if (!isset($changes['uri'])) {
157 $uri = $request->getUri();
158 } else {
159 // Remove the host header if one is on the URI
160 if ($host = $changes['uri']->getHost()) {
161 $changes['set_headers']['Host'] = $host;
162 if ($port = $changes['uri']->getPort()) {
163 $standardPorts = ['http' => 80, 'https' => 443];
164 $scheme = $changes['uri']->getScheme();
165 if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
166 $changes['set_headers']['Host'] .= ':' . $port;
167 }
168 }
169 }
170 $uri = $changes['uri'];
171 }
172 if (!empty($changes['remove_headers'])) {
173 $headers = self::caselessRemove($changes['remove_headers'], $headers);
174 }
175 if (!empty($changes['set_headers'])) {
176 $headers = self::caselessRemove(\array_keys($changes['set_headers']), $headers);
177 $headers = $changes['set_headers'] + $headers;
178 }
179 if (isset($changes['query'])) {
180 $uri = $uri->withQuery($changes['query']);
181 }
182 if ($request instanceof ServerRequestInterface) {
183 $new = (new ServerRequest(isset($changes['method']) ? $changes['method'] : $request->getMethod(), $uri, $headers, isset($changes['body']) ? $changes['body'] : $request->getBody(), isset($changes['version']) ? $changes['version'] : $request->getProtocolVersion(), $request->getServerParams()))->withParsedBody($request->getParsedBody())->withQueryParams($request->getQueryParams())->withCookieParams($request->getCookieParams())->withUploadedFiles($request->getUploadedFiles());
184 foreach ($request->getAttributes() as $key => $value) {
185 $new = $new->withAttribute($key, $value);
186 }
187 return $new;
188 }
189 return new Request(isset($changes['method']) ? $changes['method'] : $request->getMethod(), $uri, $headers, isset($changes['body']) ? $changes['body'] : $request->getBody(), isset($changes['version']) ? $changes['version'] : $request->getProtocolVersion());
190 }
191 /**
192 * Read a line from the stream up to the maximum allowed buffer length.
193 *
194 * @param StreamInterface $stream Stream to read from
195 * @param int|null $maxLength Maximum buffer length
196 *
197 * @return string
198 */
199 public static function readLine(StreamInterface $stream, $maxLength = null)
200 {
201 $buffer = '';
202 $size = 0;
203 while (!$stream->eof()) {
204 // Using a loose equality here to match on '' and false.
205 if (null == ($byte = $stream->read(1))) {
206 return $buffer;
207 }
208 $buffer .= $byte;
209 // Break when a new line is found or the max length - 1 is reached
210 if ($byte === "\n" || ++$size === $maxLength - 1) {
211 break;
212 }
213 }
214 return $buffer;
215 }
216 /**
217 * Create a new stream based on the input type.
218 *
219 * Options is an associative array that can contain the following keys:
220 * - metadata: Array of custom metadata.
221 * - size: Size of the stream.
222 *
223 * This method accepts the following `$resource` types:
224 * - `Psr\Http\Message\StreamInterface`: Returns the value as-is.
225 * - `string`: Creates a stream object that uses the given string as the contents.
226 * - `resource`: Creates a stream object that wraps the given PHP stream resource.
227 * - `Iterator`: If the provided value implements `Iterator`, then a read-only
228 * stream object will be created that wraps the given iterable. Each time the
229 * stream is read from, data from the iterator will fill a buffer and will be
230 * continuously called until the buffer is equal to the requested read size.
231 * Subsequent read calls will first read from the buffer and then call `next`
232 * on the underlying iterator until it is exhausted.
233 * - `object` with `__toString()`: If the object has the `__toString()` method,
234 * the object will be cast to a string and then a stream will be returned that
235 * uses the string value.
236 * - `NULL`: When `null` is passed, an empty stream object is returned.
237 * - `callable` When a callable is passed, a read-only stream object will be
238 * created that invokes the given callable. The callable is invoked with the
239 * number of suggested bytes to read. The callable can return any number of
240 * bytes, but MUST return `false` when there is no more data to return. The
241 * stream object that wraps the callable will invoke the callable until the
242 * number of requested bytes are available. Any additional bytes will be
243 * buffered and used in subsequent reads.
244 *
245 * @param resource|string|int|float|bool|StreamInterface|callable|\Iterator|null $resource Entity body data
246 * @param array $options Additional options
247 *
248 * @return StreamInterface
249 *
250 * @throws \InvalidArgumentException if the $resource arg is not valid.
251 */
252 public static function streamFor($resource = '', array $options = [])
253 {
254 if (\is_scalar($resource)) {
255 $stream = self::tryFopen('php://temp', 'r+');
256 if ($resource !== '') {
257 \fwrite($stream, $resource);
258 \fseek($stream, 0);
259 }
260 return new Stream($stream, $options);
261 }
262 switch (\gettype($resource)) {
263 case 'resource':
264 /*
265 * The 'php://input' is a special stream with quirks and inconsistencies.
266 * We avoid using that stream by reading it into php://temp
267 */
268 $metaData = \stream_get_meta_data($resource);
269 if (isset($metaData['uri']) && $metaData['uri'] === 'php://input') {
270 $stream = self::tryFopen('php://temp', 'w+');
271 \fwrite($stream, \stream_get_contents($resource));
272 \fseek($stream, 0);
273 $resource = $stream;
274 }
275 return new Stream($resource, $options);
276 case 'object':
277 if ($resource instanceof StreamInterface) {
278 return $resource;
279 } elseif ($resource instanceof \Iterator) {
280 return new PumpStream(function () use($resource) {
281 if (!$resource->valid()) {
282 return \false;
283 }
284 $result = $resource->current();
285 $resource->next();
286 return $result;
287 }, $options);
288 } elseif (\method_exists($resource, '__toString')) {
289 return Utils::streamFor((string) $resource, $options);
290 }
291 break;
292 case 'NULL':
293 return new Stream(self::tryFopen('php://temp', 'r+'), $options);
294 }
295 if (\is_callable($resource)) {
296 return new PumpStream($resource, $options);
297 }
298 throw new \InvalidArgumentException('Invalid resource type: ' . \gettype($resource));
299 }
300 /**
301 * Safely opens a PHP stream resource using a filename.
302 *
303 * When fopen fails, PHP normally raises a warning. This function adds an
304 * error handler that checks for errors and throws an exception instead.
305 *
306 * @param string $filename File to open
307 * @param string $mode Mode used to open the file
308 *
309 * @return resource
310 *
311 * @throws \RuntimeException if the file cannot be opened
312 */
313 public static function tryFopen($filename, $mode)
314 {
315 $ex = null;
316 \set_error_handler(function () use($filename, $mode, &$ex) {
317 $ex = new \RuntimeException(\sprintf('Unable to open "%s" using mode "%s": %s', $filename, $mode, \func_get_args()[1]));
318 return \true;
319 });
320 try {
321 $handle = \fopen($filename, $mode);
322 } catch (\Throwable $e) {
323 $ex = new \RuntimeException(\sprintf('Unable to open "%s" using mode "%s": %s', $filename, $mode, $e->getMessage()), 0, $e);
324 }
325 \restore_error_handler();
326 if ($ex) {
327 /** @var $ex \RuntimeException */
328 throw $ex;
329 }
330 return $handle;
331 }
332 /**
333 * Returns a UriInterface for the given value.
334 *
335 * This function accepts a string or UriInterface and returns a
336 * UriInterface for the given value. If the value is already a
337 * UriInterface, it is returned as-is.
338 *
339 * @param string|UriInterface $uri
340 *
341 * @return UriInterface
342 *
343 * @throws \InvalidArgumentException
344 */
345 public static function uriFor($uri)
346 {
347 if ($uri instanceof UriInterface) {
348 return $uri;
349 }
350 if (\is_string($uri)) {
351 return new Uri($uri);
352 }
353 throw new \InvalidArgumentException('URI must be a string or UriInterface');
354 }
355 }
356