Browse code

added appinfo/info.xml appinfo/signature.json CHANGELOG.txt lib/AppInfo/Application.php css/style.css providers/Plivo

DoubleBastionAdmin authored on 05/11/2025 13:35:09
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,743 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+namespace GuzzleHttp\Psr7;
6
+
7
+use GuzzleHttp\Psr7\Exception\MalformedUriException;
8
+use Psr\Http\Message\UriInterface;
9
+
10
+/**
11
+ * PSR-7 URI implementation.
12
+ *
13
+ * @author Michael Dowling
14
+ * @author Tobias Schultze
15
+ * @author Matthew Weier O'Phinney
16
+ */
17
+class Uri implements UriInterface, \JsonSerializable
18
+{
19
+    /**
20
+     * Absolute http and https URIs require a host per RFC 7230 Section 2.7
21
+     * but in generic URIs the host can be empty. So for http(s) URIs
22
+     * we apply this default host when no host is given yet to form a
23
+     * valid URI.
24
+     */
25
+    private const HTTP_DEFAULT_HOST = 'localhost';
26
+
27
+    private const DEFAULT_PORTS = [
28
+        'http' => 80,
29
+        'https' => 443,
30
+        'ftp' => 21,
31
+        'gopher' => 70,
32
+        'nntp' => 119,
33
+        'news' => 119,
34
+        'telnet' => 23,
35
+        'tn3270' => 23,
36
+        'imap' => 143,
37
+        'pop' => 110,
38
+        'ldap' => 389,
39
+    ];
40
+
41
+    /**
42
+     * Unreserved characters for use in a regex.
43
+     *
44
+     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-2.3
45
+     */
46
+    private const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~';
47
+
48
+    /**
49
+     * Sub-delims for use in a regex.
50
+     *
51
+     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-2.2
52
+     */
53
+    private const CHAR_SUB_DELIMS = '!\$&\'\(\)\*\+,;=';
54
+    private const QUERY_SEPARATORS_REPLACEMENT = ['=' => '%3D', '&' => '%26'];
55
+
56
+    /** @var string Uri scheme. */
57
+    private $scheme = '';
58
+
59
+    /** @var string Uri user info. */
60
+    private $userInfo = '';
61
+
62
+    /** @var string Uri host. */
63
+    private $host = '';
64
+
65
+    /** @var int|null Uri port. */
66
+    private $port;
67
+
68
+    /** @var string Uri path. */
69
+    private $path = '';
70
+
71
+    /** @var string Uri query string. */
72
+    private $query = '';
73
+
74
+    /** @var string Uri fragment. */
75
+    private $fragment = '';
76
+
77
+    /** @var string|null String representation */
78
+    private $composedComponents;
79
+
80
+    public function __construct(string $uri = '')
81
+    {
82
+        if ($uri !== '') {
83
+            $parts = self::parse($uri);
84
+            if ($parts === false) {
85
+                throw new MalformedUriException("Unable to parse URI: $uri");
86
+            }
87
+            $this->applyParts($parts);
88
+        }
89
+    }
90
+
91
+    /**
92
+     * UTF-8 aware \parse_url() replacement.
93
+     *
94
+     * The internal function produces broken output for non ASCII domain names
95
+     * (IDN) when used with locales other than "C".
96
+     *
97
+     * On the other hand, cURL understands IDN correctly only when UTF-8 locale
98
+     * is configured ("C.UTF-8", "en_US.UTF-8", etc.).
99
+     *
100
+     * @see https://bugs.php.net/bug.php?id=52923
101
+     * @see https://www.php.net/manual/en/function.parse-url.php#114817
102
+     * @see https://curl.haxx.se/libcurl/c/CURLOPT_URL.html#ENCODING
103
+     *
104
+     * @return array|false
105
+     */
106
+    private static function parse(string $url)
107
+    {
108
+        // If IPv6
109
+        $prefix = '';
110
+        if (preg_match('%^(.*://\[[0-9:a-fA-F]+\])(.*?)$%', $url, $matches)) {
111
+            /** @var array{0:string, 1:string, 2:string} $matches */
112
+            $prefix = $matches[1];
113
+            $url = $matches[2];
114
+        }
115
+
116
+        /** @var string */
117
+        $encodedUrl = preg_replace_callback(
118
+            '%[^:/@?&=#]+%usD',
119
+            static function ($matches) {
120
+                return urlencode($matches[0]);
121
+            },
122
+            $url
123
+        );
124
+
125
+        $result = parse_url($prefix.$encodedUrl);
126
+
127
+        if ($result === false) {
128
+            return false;
129
+        }
130
+
131
+        return array_map('urldecode', $result);
132
+    }
133
+
134
+    public function __toString(): string
135
+    {
136
+        if ($this->composedComponents === null) {
137
+            $this->composedComponents = self::composeComponents(
138
+                $this->scheme,
139
+                $this->getAuthority(),
140
+                $this->path,
141
+                $this->query,
142
+                $this->fragment
143
+            );
144
+        }
145
+
146
+        return $this->composedComponents;
147
+    }
148
+
149
+    /**
150
+     * Composes a URI reference string from its various components.
151
+     *
152
+     * Usually this method does not need to be called manually but instead is used indirectly via
153
+     * `Psr\Http\Message\UriInterface::__toString`.
154
+     *
155
+     * PSR-7 UriInterface treats an empty component the same as a missing component as
156
+     * getQuery(), getFragment() etc. always return a string. This explains the slight
157
+     * difference to RFC 3986 Section 5.3.
158
+     *
159
+     * Another adjustment is that the authority separator is added even when the authority is missing/empty
160
+     * for the "file" scheme. This is because PHP stream functions like `file_get_contents` only work with
161
+     * `file:///myfile` but not with `file:/myfile` although they are equivalent according to RFC 3986. But
162
+     * `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to
163
+     * that format).
164
+     *
165
+     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-5.3
166
+     */
167
+    public static function composeComponents(?string $scheme, ?string $authority, string $path, ?string $query, ?string $fragment): string
168
+    {
169
+        $uri = '';
170
+
171
+        // weak type checks to also accept null until we can add scalar type hints
172
+        if ($scheme != '') {
173
+            $uri .= $scheme.':';
174
+        }
175
+
176
+        if ($authority != '' || $scheme === 'file') {
177
+            $uri .= '//'.$authority;
178
+        }
179
+
180
+        if ($authority != '' && $path != '' && $path[0] != '/') {
181
+            $path = '/'.$path;
182
+        }
183
+
184
+        $uri .= $path;
185
+
186
+        if ($query != '') {
187
+            $uri .= '?'.$query;
188
+        }
189
+
190
+        if ($fragment != '') {
191
+            $uri .= '#'.$fragment;
192
+        }
193
+
194
+        return $uri;
195
+    }
196
+
197
+    /**
198
+     * Whether the URI has the default port of the current scheme.
199
+     *
200
+     * `Psr\Http\Message\UriInterface::getPort` may return null or the standard port. This method can be used
201
+     * independently of the implementation.
202
+     */
203
+    public static function isDefaultPort(UriInterface $uri): bool
204
+    {
205
+        return $uri->getPort() === null
206
+            || (isset(self::DEFAULT_PORTS[$uri->getScheme()]) && $uri->getPort() === self::DEFAULT_PORTS[$uri->getScheme()]);
207
+    }
208
+
209
+    /**
210
+     * Whether the URI is absolute, i.e. it has a scheme.
211
+     *
212
+     * An instance of UriInterface can either be an absolute URI or a relative reference. This method returns true
213
+     * if it is the former. An absolute URI has a scheme. A relative reference is used to express a URI relative
214
+     * to another URI, the base URI. Relative references can be divided into several forms:
215
+     * - network-path references, e.g. '//example.com/path'
216
+     * - absolute-path references, e.g. '/path'
217
+     * - relative-path references, e.g. 'subpath'
218
+     *
219
+     * @see Uri::isNetworkPathReference
220
+     * @see Uri::isAbsolutePathReference
221
+     * @see Uri::isRelativePathReference
222
+     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4
223
+     */
224
+    public static function isAbsolute(UriInterface $uri): bool
225
+    {
226
+        return $uri->getScheme() !== '';
227
+    }
228
+
229
+    /**
230
+     * Whether the URI is a network-path reference.
231
+     *
232
+     * A relative reference that begins with two slash characters is termed an network-path reference.
233
+     *
234
+     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
235
+     */
236
+    public static function isNetworkPathReference(UriInterface $uri): bool
237
+    {
238
+        return $uri->getScheme() === '' && $uri->getAuthority() !== '';
239
+    }
240
+
241
+    /**
242
+     * Whether the URI is a absolute-path reference.
243
+     *
244
+     * A relative reference that begins with a single slash character is termed an absolute-path reference.
245
+     *
246
+     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
247
+     */
248
+    public static function isAbsolutePathReference(UriInterface $uri): bool
249
+    {
250
+        return $uri->getScheme() === ''
251
+            && $uri->getAuthority() === ''
252
+            && isset($uri->getPath()[0])
253
+            && $uri->getPath()[0] === '/';
254
+    }
255
+
256
+    /**
257
+     * Whether the URI is a relative-path reference.
258
+     *
259
+     * A relative reference that does not begin with a slash character is termed a relative-path reference.
260
+     *
261
+     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
262
+     */
263
+    public static function isRelativePathReference(UriInterface $uri): bool
264
+    {
265
+        return $uri->getScheme() === ''
266
+            && $uri->getAuthority() === ''
267
+            && (!isset($uri->getPath()[0]) || $uri->getPath()[0] !== '/');
268
+    }
269
+
270
+    /**
271
+     * Whether the URI is a same-document reference.
272
+     *
273
+     * A same-document reference refers to a URI that is, aside from its fragment
274
+     * component, identical to the base URI. When no base URI is given, only an empty
275
+     * URI reference (apart from its fragment) is considered a same-document reference.
276
+     *
277
+     * @param UriInterface      $uri  The URI to check
278
+     * @param UriInterface|null $base An optional base URI to compare against
279
+     *
280
+     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.4
281
+     */
282
+    public static function isSameDocumentReference(UriInterface $uri, ?UriInterface $base = null): bool
283
+    {
284
+        if ($base !== null) {
285
+            $uri = UriResolver::resolve($base, $uri);
286
+
287
+            return ($uri->getScheme() === $base->getScheme())
288
+                && ($uri->getAuthority() === $base->getAuthority())
289
+                && ($uri->getPath() === $base->getPath())
290
+                && ($uri->getQuery() === $base->getQuery());
291
+        }
292
+
293
+        return $uri->getScheme() === '' && $uri->getAuthority() === '' && $uri->getPath() === '' && $uri->getQuery() === '';
294
+    }
295
+
296
+    /**
297
+     * Creates a new URI with a specific query string value removed.
298
+     *
299
+     * Any existing query string values that exactly match the provided key are
300
+     * removed.
301
+     *
302
+     * @param UriInterface $uri URI to use as a base.
303
+     * @param string       $key Query string key to remove.
304
+     */
305
+    public static function withoutQueryValue(UriInterface $uri, string $key): UriInterface
306
+    {
307
+        $result = self::getFilteredQueryString($uri, [$key]);
308
+
309
+        return $uri->withQuery(implode('&', $result));
310
+    }
311
+
312
+    /**
313
+     * Creates a new URI with a specific query string value.
314
+     *
315
+     * Any existing query string values that exactly match the provided key are
316
+     * removed and replaced with the given key value pair.
317
+     *
318
+     * A value of null will set the query string key without a value, e.g. "key"
319
+     * instead of "key=value".
320
+     *
321
+     * @param UriInterface $uri   URI to use as a base.
322
+     * @param string       $key   Key to set.
323
+     * @param string|null  $value Value to set
324
+     */
325
+    public static function withQueryValue(UriInterface $uri, string $key, ?string $value): UriInterface
326
+    {
327
+        $result = self::getFilteredQueryString($uri, [$key]);
328
+
329
+        $result[] = self::generateQueryString($key, $value);
330
+
331
+        return $uri->withQuery(implode('&', $result));
332
+    }
333
+
334
+    /**
335
+     * Creates a new URI with multiple specific query string values.
336
+     *
337
+     * It has the same behavior as withQueryValue() but for an associative array of key => value.
338
+     *
339
+     * @param UriInterface    $uri           URI to use as a base.
340
+     * @param (string|null)[] $keyValueArray Associative array of key and values
341
+     */
342
+    public static function withQueryValues(UriInterface $uri, array $keyValueArray): UriInterface
343
+    {
344
+        $result = self::getFilteredQueryString($uri, array_keys($keyValueArray));
345
+
346
+        foreach ($keyValueArray as $key => $value) {
347
+            $result[] = self::generateQueryString((string) $key, $value !== null ? (string) $value : null);
348
+        }
349
+
350
+        return $uri->withQuery(implode('&', $result));
351
+    }
352
+
353
+    /**
354
+     * Creates a URI from a hash of `parse_url` components.
355
+     *
356
+     * @see https://www.php.net/manual/en/function.parse-url.php
357
+     *
358
+     * @throws MalformedUriException If the components do not form a valid URI.
359
+     */
360
+    public static function fromParts(array $parts): UriInterface
361
+    {
362
+        $uri = new self();
363
+        $uri->applyParts($parts);
364
+        $uri->validateState();
365
+
366
+        return $uri;
367
+    }
368
+
369
+    public function getScheme(): string
370
+    {
371
+        return $this->scheme;
372
+    }
373
+
374
+    public function getAuthority(): string
375
+    {
376
+        $authority = $this->host;
377
+        if ($this->userInfo !== '') {
378
+            $authority = $this->userInfo.'@'.$authority;
379
+        }
380
+
381
+        if ($this->port !== null) {
382
+            $authority .= ':'.$this->port;
383
+        }
384
+
385
+        return $authority;
386
+    }
387
+
388
+    public function getUserInfo(): string
389
+    {
390
+        return $this->userInfo;
391
+    }
392
+
393
+    public function getHost(): string
394
+    {
395
+        return $this->host;
396
+    }
397
+
398
+    public function getPort(): ?int
399
+    {
400
+        return $this->port;
401
+    }
402
+
403
+    public function getPath(): string
404
+    {
405
+        return $this->path;
406
+    }
407
+
408
+    public function getQuery(): string
409
+    {
410
+        return $this->query;
411
+    }
412
+
413
+    public function getFragment(): string
414
+    {
415
+        return $this->fragment;
416
+    }
417
+
418
+    public function withScheme($scheme): UriInterface
419
+    {
420
+        $scheme = $this->filterScheme($scheme);
421
+
422
+        if ($this->scheme === $scheme) {
423
+            return $this;
424
+        }
425
+
426
+        $new = clone $this;
427
+        $new->scheme = $scheme;
428
+        $new->composedComponents = null;
429
+        $new->removeDefaultPort();
430
+        $new->validateState();
431
+
432
+        return $new;
433
+    }
434
+
435
+    public function withUserInfo($user, $password = null): UriInterface
436
+    {
437
+        $info = $this->filterUserInfoComponent($user);
438
+        if ($password !== null) {
439
+            $info .= ':'.$this->filterUserInfoComponent($password);
440
+        }
441
+
442
+        if ($this->userInfo === $info) {
443
+            return $this;
444
+        }
445
+
446
+        $new = clone $this;
447
+        $new->userInfo = $info;
448
+        $new->composedComponents = null;
449
+        $new->validateState();
450
+
451
+        return $new;
452
+    }
453
+
454
+    public function withHost($host): UriInterface
455
+    {
456
+        $host = $this->filterHost($host);
457
+
458
+        if ($this->host === $host) {
459
+            return $this;
460
+        }
461
+
462
+        $new = clone $this;
463
+        $new->host = $host;
464
+        $new->composedComponents = null;
465
+        $new->validateState();
466
+
467
+        return $new;
468
+    }
469
+
470
+    public function withPort($port): UriInterface
471
+    {
472
+        $port = $this->filterPort($port);
473
+
474
+        if ($this->port === $port) {
475
+            return $this;
476
+        }
477
+
478
+        $new = clone $this;
479
+        $new->port = $port;
480
+        $new->composedComponents = null;
481
+        $new->removeDefaultPort();
482
+        $new->validateState();
483
+
484
+        return $new;
485
+    }
486
+
487
+    public function withPath($path): UriInterface
488
+    {
489
+        $path = $this->filterPath($path);
490
+
491
+        if ($this->path === $path) {
492
+            return $this;
493
+        }
494
+
495
+        $new = clone $this;
496
+        $new->path = $path;
497
+        $new->composedComponents = null;
498
+        $new->validateState();
499
+
500
+        return $new;
501
+    }
502
+
503
+    public function withQuery($query): UriInterface
504
+    {
505
+        $query = $this->filterQueryAndFragment($query);
506
+
507
+        if ($this->query === $query) {
508
+            return $this;
509
+        }
510
+
511
+        $new = clone $this;
512
+        $new->query = $query;
513
+        $new->composedComponents = null;
514
+
515
+        return $new;
516
+    }
517
+
518
+    public function withFragment($fragment): UriInterface
519
+    {
520
+        $fragment = $this->filterQueryAndFragment($fragment);
521
+
522
+        if ($this->fragment === $fragment) {
523
+            return $this;
524
+        }
525
+
526
+        $new = clone $this;
527
+        $new->fragment = $fragment;
528
+        $new->composedComponents = null;
529
+
530
+        return $new;
531
+    }
532
+
533
+    public function jsonSerialize(): string
534
+    {
535
+        return $this->__toString();
536
+    }
537
+
538
+    /**
539
+     * Apply parse_url parts to a URI.
540
+     *
541
+     * @param array $parts Array of parse_url parts to apply.
542
+     */
543
+    private function applyParts(array $parts): void
544
+    {
545
+        $this->scheme = isset($parts['scheme'])
546
+            ? $this->filterScheme($parts['scheme'])
547
+            : '';
548
+        $this->userInfo = isset($parts['user'])
549
+            ? $this->filterUserInfoComponent($parts['user'])
550
+            : '';
551
+        $this->host = isset($parts['host'])
552
+            ? $this->filterHost($parts['host'])
553
+            : '';
554
+        $this->port = isset($parts['port'])
555
+            ? $this->filterPort($parts['port'])
556
+            : null;
557
+        $this->path = isset($parts['path'])
558
+            ? $this->filterPath($parts['path'])
559
+            : '';
560
+        $this->query = isset($parts['query'])
561
+            ? $this->filterQueryAndFragment($parts['query'])
562
+            : '';
563
+        $this->fragment = isset($parts['fragment'])
564
+            ? $this->filterQueryAndFragment($parts['fragment'])
565
+            : '';
566
+        if (isset($parts['pass'])) {
567
+            $this->userInfo .= ':'.$this->filterUserInfoComponent($parts['pass']);
568
+        }
569
+
570
+        $this->removeDefaultPort();
571
+    }
572
+
573
+    /**
574
+     * @param mixed $scheme
575
+     *
576
+     * @throws \InvalidArgumentException If the scheme is invalid.
577
+     */
578
+    private function filterScheme($scheme): string
579
+    {
580
+        if (!is_string($scheme)) {
581
+            throw new \InvalidArgumentException('Scheme must be a string');
582
+        }
583
+
584
+        return \strtr($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
585
+    }
586
+
587
+    /**
588
+     * @param mixed $component
589
+     *
590
+     * @throws \InvalidArgumentException If the user info is invalid.
591
+     */
592
+    private function filterUserInfoComponent($component): string
593
+    {
594
+        if (!is_string($component)) {
595
+            throw new \InvalidArgumentException('User info must be a string');
596
+        }
597
+
598
+        return preg_replace_callback(
599
+            '/(?:[^%'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.']+|%(?![A-Fa-f0-9]{2}))/',
600
+            [$this, 'rawurlencodeMatchZero'],
601
+            $component
602
+        );
603
+    }
604
+
605
+    /**
606
+     * @param mixed $host
607
+     *
608
+     * @throws \InvalidArgumentException If the host is invalid.
609
+     */
610
+    private function filterHost($host): string
611
+    {
612
+        if (!is_string($host)) {
613
+            throw new \InvalidArgumentException('Host must be a string');
614
+        }
615
+
616
+        return \strtr($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
617
+    }
618
+
619
+    /**
620
+     * @param mixed $port
621
+     *
622
+     * @throws \InvalidArgumentException If the port is invalid.
623
+     */
624
+    private function filterPort($port): ?int
625
+    {
626
+        if ($port === null) {
627
+            return null;
628
+        }
629
+
630
+        $port = (int) $port;
631
+        if (0 > $port || 0xFFFF < $port) {
632
+            throw new \InvalidArgumentException(
633
+                sprintf('Invalid port: %d. Must be between 0 and 65535', $port)
634
+            );
635
+        }
636
+
637
+        return $port;
638
+    }
639
+
640
+    /**
641
+     * @param (string|int)[] $keys
642
+     *
643
+     * @return string[]
644
+     */
645
+    private static function getFilteredQueryString(UriInterface $uri, array $keys): array
646
+    {
647
+        $current = $uri->getQuery();
648
+
649
+        if ($current === '') {
650
+            return [];
651
+        }
652
+
653
+        $decodedKeys = array_map(function ($k): string {
654
+            return rawurldecode((string) $k);
655
+        }, $keys);
656
+
657
+        return array_filter(explode('&', $current), function ($part) use ($decodedKeys) {
658
+            return !in_array(rawurldecode(explode('=', $part)[0]), $decodedKeys, true);
659
+        });
660
+    }
661
+
662
+    private static function generateQueryString(string $key, ?string $value): string
663
+    {
664
+        // Query string separators ("=", "&") within the key or value need to be encoded
665
+        // (while preventing double-encoding) before setting the query string. All other
666
+        // chars that need percent-encoding will be encoded by withQuery().
667
+        $queryString = strtr($key, self::QUERY_SEPARATORS_REPLACEMENT);
668
+
669
+        if ($value !== null) {
670
+            $queryString .= '='.strtr($value, self::QUERY_SEPARATORS_REPLACEMENT);
671
+        }
672
+
673
+        return $queryString;
674
+    }
675
+
676
+    private function removeDefaultPort(): void
677
+    {
678
+        if ($this->port !== null && self::isDefaultPort($this)) {
679
+            $this->port = null;
680
+        }
681
+    }
682
+
683
+    /**
684
+     * Filters the path of a URI
685
+     *
686
+     * @param mixed $path
687
+     *
688
+     * @throws \InvalidArgumentException If the path is invalid.
689
+     */
690
+    private function filterPath($path): string
691
+    {
692
+        if (!is_string($path)) {
693
+            throw new \InvalidArgumentException('Path must be a string');
694
+        }
695
+
696
+        return preg_replace_callback(
697
+            '/(?:[^'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.'%:@\/]++|%(?![A-Fa-f0-9]{2}))/',
698
+            [$this, 'rawurlencodeMatchZero'],
699
+            $path
700
+        );
701
+    }
702
+
703
+    /**
704
+     * Filters the query string or fragment of a URI.
705
+     *
706
+     * @param mixed $str
707
+     *
708
+     * @throws \InvalidArgumentException If the query or fragment is invalid.
709
+     */
710
+    private function filterQueryAndFragment($str): string
711
+    {
712
+        if (!is_string($str)) {
713
+            throw new \InvalidArgumentException('Query and fragment must be a string');
714
+        }
715
+
716
+        return preg_replace_callback(
717
+            '/(?:[^'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.'%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/',
718
+            [$this, 'rawurlencodeMatchZero'],
719
+            $str
720
+        );
721
+    }
722
+
723
+    private function rawurlencodeMatchZero(array $match): string
724
+    {
725
+        return rawurlencode($match[0]);
726
+    }
727
+
728
+    private function validateState(): void
729
+    {
730
+        if ($this->host === '' && ($this->scheme === 'http' || $this->scheme === 'https')) {
731
+            $this->host = self::HTTP_DEFAULT_HOST;
732
+        }
733
+
734
+        if ($this->getAuthority() === '') {
735
+            if (0 === strpos($this->path, '//')) {
736
+                throw new MalformedUriException('The path of a URI without an authority must not start with two slashes "//"');
737
+            }
738
+            if ($this->scheme === '' && false !== strpos(explode('/', $this->path, 2)[0], ':')) {
739
+                throw new MalformedUriException('A relative URI must not have a path beginning with a segment containing a colon');
740
+            }
741
+        }
742
+    }
743
+}
Browse code

removed appinfo/info.xml appinfo/signature.json CHANGELOG.txt lib/AppInfo/Application.php css/style.css providers/Plivo

DoubleBastionAdmin authored on 05/11/2025 13:12:22
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,761 +0,0 @@
1
-<?php
2
-
3
-namespace GuzzleHttp\Psr7;
4
-
5
-use Psr\Http\Message\UriInterface;
6
-
7
-/**
8
- * PSR-7 URI implementation.
9
- *
10
- * @author Michael Dowling
11
- * @author Tobias Schultze
12
- * @author Matthew Weier O'Phinney
13
- */
14
-class Uri implements UriInterface
15
-{
16
-    /**
17
-     * Absolute http and https URIs require a host per RFC 7230 Section 2.7
18
-     * but in generic URIs the host can be empty. So for http(s) URIs
19
-     * we apply this default host when no host is given yet to form a
20
-     * valid URI.
21
-     */
22
-    const HTTP_DEFAULT_HOST = 'localhost';
23
-
24
-    private static $defaultPorts = [
25
-        'http'  => 80,
26
-        'https' => 443,
27
-        'ftp' => 21,
28
-        'gopher' => 70,
29
-        'nntp' => 119,
30
-        'news' => 119,
31
-        'telnet' => 23,
32
-        'tn3270' => 23,
33
-        'imap' => 143,
34
-        'pop' => 110,
35
-        'ldap' => 389,
36
-    ];
37
-
38
-    private static $charUnreserved = 'a-zA-Z0-9_\-\.~';
39
-    private static $charSubDelims = '!\$&\'\(\)\*\+,;=';
40
-    private static $replaceQuery = ['=' => '%3D', '&' => '%26'];
41
-
42
-    /** @var string Uri scheme. */
43
-    private $scheme = '';
44
-
45
-    /** @var string Uri user info. */
46
-    private $userInfo = '';
47
-
48
-    /** @var string Uri host. */
49
-    private $host = '';
50
-
51
-    /** @var int|null Uri port. */
52
-    private $port;
53
-
54
-    /** @var string Uri path. */
55
-    private $path = '';
56
-
57
-    /** @var string Uri query string. */
58
-    private $query = '';
59
-
60
-    /** @var string Uri fragment. */
61
-    private $fragment = '';
62
-
63
-    /**
64
-     * @param string $uri URI to parse
65
-     */
66
-    public function __construct($uri = '')
67
-    {
68
-        // weak type check to also accept null until we can add scalar type hints
69
-        if ($uri != '') {
70
-            $parts = parse_url($uri);
71
-            if ($parts === false) {
72
-                throw new \InvalidArgumentException("Unable to parse URI: $uri");
73
-            }
74
-            $this->applyParts($parts);
75
-        }
76
-    }
77
-
78
-    public function __toString()
79
-    {
80
-        return self::composeComponents(
81
-            $this->scheme,
82
-            $this->getAuthority(),
83
-            $this->path,
84
-            $this->query,
85
-            $this->fragment
86
-        );
87
-    }
88
-
89
-    /**
90
-     * Composes a URI reference string from its various components.
91
-     *
92
-     * Usually this method does not need to be called manually but instead is used indirectly via
93
-     * `Psr\Http\Message\UriInterface::__toString`.
94
-     *
95
-     * PSR-7 UriInterface treats an empty component the same as a missing component as
96
-     * getQuery(), getFragment() etc. always return a string. This explains the slight
97
-     * difference to RFC 3986 Section 5.3.
98
-     *
99
-     * Another adjustment is that the authority separator is added even when the authority is missing/empty
100
-     * for the "file" scheme. This is because PHP stream functions like `file_get_contents` only work with
101
-     * `file:///myfile` but not with `file:/myfile` although they are equivalent according to RFC 3986. But
102
-     * `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to
103
-     * that format).
104
-     *
105
-     * @param string $scheme
106
-     * @param string $authority
107
-     * @param string $path
108
-     * @param string $query
109
-     * @param string $fragment
110
-     *
111
-     * @return string
112
-     *
113
-     * @link https://tools.ietf.org/html/rfc3986#section-5.3
114
-     */
115
-    public static function composeComponents($scheme, $authority, $path, $query, $fragment)
116
-    {
117
-        $uri = '';
118
-
119
-        // weak type checks to also accept null until we can add scalar type hints
120
-        if ($scheme != '') {
121
-            $uri .= $scheme . ':';
122
-        }
123
-
124
-        if ($authority != ''|| $scheme === 'file') {
125
-            $uri .= '//' . $authority;
126
-        }
127
-
128
-        $uri .= $path;
129
-
130
-        if ($query != '') {
131
-            $uri .= '?' . $query;
132
-        }
133
-
134
-        if ($fragment != '') {
135
-            $uri .= '#' . $fragment;
136
-        }
137
-
138
-        return $uri;
139
-    }
140
-
141
-    /**
142
-     * Whether the URI has the default port of the current scheme.
143
-     *
144
-     * `Psr\Http\Message\UriInterface::getPort` may return null or the standard port. This method can be used
145
-     * independently of the implementation.
146
-     *
147
-     * @param UriInterface $uri
148
-     *
149
-     * @return bool
150
-     */
151
-    public static function isDefaultPort(UriInterface $uri)
152
-    {
153
-        return $uri->getPort() === null
154
-            || (isset(self::$defaultPorts[$uri->getScheme()]) && $uri->getPort() === self::$defaultPorts[$uri->getScheme()]);
155
-    }
156
-
157
-    /**
158
-     * Whether the URI is absolute, i.e. it has a scheme.
159
-     *
160
-     * An instance of UriInterface can either be an absolute URI or a relative reference. This method returns true
161
-     * if it is the former. An absolute URI has a scheme. A relative reference is used to express a URI relative
162
-     * to another URI, the base URI. Relative references can be divided into several forms:
163
-     * - network-path references, e.g. '//example.com/path'
164
-     * - absolute-path references, e.g. '/path'
165
-     * - relative-path references, e.g. 'subpath'
166
-     *
167
-     * @param UriInterface $uri
168
-     *
169
-     * @return bool
170
-     * @see Uri::isNetworkPathReference
171
-     * @see Uri::isAbsolutePathReference
172
-     * @see Uri::isRelativePathReference
173
-     * @link https://tools.ietf.org/html/rfc3986#section-4
174
-     */
175
-    public static function isAbsolute(UriInterface $uri)
176
-    {
177
-        return $uri->getScheme() !== '';
178
-    }
179
-
180
-    /**
181
-     * Whether the URI is a network-path reference.
182
-     *
183
-     * A relative reference that begins with two slash characters is termed an network-path reference.
184
-     *
185
-     * @param UriInterface $uri
186
-     *
187
-     * @return bool
188
-     * @link https://tools.ietf.org/html/rfc3986#section-4.2
189
-     */
190
-    public static function isNetworkPathReference(UriInterface $uri)
191
-    {
192
-        return $uri->getScheme() === '' && $uri->getAuthority() !== '';
193
-    }
194
-
195
-    /**
196
-     * Whether the URI is a absolute-path reference.
197
-     *
198
-     * A relative reference that begins with a single slash character is termed an absolute-path reference.
199
-     *
200
-     * @param UriInterface $uri
201
-     *
202
-     * @return bool
203
-     * @link https://tools.ietf.org/html/rfc3986#section-4.2
204
-     */
205
-    public static function isAbsolutePathReference(UriInterface $uri)
206
-    {
207
-        return $uri->getScheme() === ''
208
-            && $uri->getAuthority() === ''
209
-            && isset($uri->getPath()[0])
210
-            && $uri->getPath()[0] === '/';
211
-    }
212
-
213
-    /**
214
-     * Whether the URI is a relative-path reference.
215
-     *
216
-     * A relative reference that does not begin with a slash character is termed a relative-path reference.
217
-     *
218
-     * @param UriInterface $uri
219
-     *
220
-     * @return bool
221
-     * @link https://tools.ietf.org/html/rfc3986#section-4.2
222
-     */
223
-    public static function isRelativePathReference(UriInterface $uri)
224
-    {
225
-        return $uri->getScheme() === ''
226
-            && $uri->getAuthority() === ''
227
-            && (!isset($uri->getPath()[0]) || $uri->getPath()[0] !== '/');
228
-    }
229
-
230
-    /**
231
-     * Whether the URI is a same-document reference.
232
-     *
233
-     * A same-document reference refers to a URI that is, aside from its fragment
234
-     * component, identical to the base URI. When no base URI is given, only an empty
235
-     * URI reference (apart from its fragment) is considered a same-document reference.
236
-     *
237
-     * @param UriInterface      $uri  The URI to check
238
-     * @param UriInterface|null $base An optional base URI to compare against
239
-     *
240
-     * @return bool
241
-     * @link https://tools.ietf.org/html/rfc3986#section-4.4
242
-     */
243
-    public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null)
244
-    {
245
-        if ($base !== null) {
246
-            $uri = UriResolver::resolve($base, $uri);
247
-
248
-            return ($uri->getScheme() === $base->getScheme())
249
-                && ($uri->getAuthority() === $base->getAuthority())
250
-                && ($uri->getPath() === $base->getPath())
251
-                && ($uri->getQuery() === $base->getQuery());
252
-        }
253
-
254
-        return $uri->getScheme() === '' && $uri->getAuthority() === '' && $uri->getPath() === '' && $uri->getQuery() === '';
255
-    }
256
-
257
-    /**
258
-     * Removes dot segments from a path and returns the new path.
259
-     *
260
-     * @param string $path
261
-     *
262
-     * @return string
263
-     *
264
-     * @deprecated since version 1.4. Use UriResolver::removeDotSegments instead.
265
-     * @see UriResolver::removeDotSegments
266
-     */
267
-    public static function removeDotSegments($path)
268
-    {
269
-        return UriResolver::removeDotSegments($path);
270
-    }
271
-
272
-    /**
273
-     * Converts the relative URI into a new URI that is resolved against the base URI.
274
-     *
275
-     * @param UriInterface        $base Base URI
276
-     * @param string|UriInterface $rel  Relative URI
277
-     *
278
-     * @return UriInterface
279
-     *
280
-     * @deprecated since version 1.4. Use UriResolver::resolve instead.
281
-     * @see UriResolver::resolve
282
-     */
283
-    public static function resolve(UriInterface $base, $rel)
284
-    {
285
-        if (!($rel instanceof UriInterface)) {
286
-            $rel = new self($rel);
287
-        }
288
-
289
-        return UriResolver::resolve($base, $rel);
290
-    }
291
-
292
-    /**
293
-     * Creates a new URI with a specific query string value removed.
294
-     *
295
-     * Any existing query string values that exactly match the provided key are
296
-     * removed.
297
-     *
298
-     * @param UriInterface $uri URI to use as a base.
299
-     * @param string       $key Query string key to remove.
300
-     *
301
-     * @return UriInterface
302
-     */
303
-    public static function withoutQueryValue(UriInterface $uri, $key)
304
-    {
305
-        $result = self::getFilteredQueryString($uri, [$key]);
306
-
307
-        return $uri->withQuery(implode('&', $result));
308
-    }
309
-
310
-    /**
311
-     * Creates a new URI with a specific query string value.
312
-     *
313
-     * Any existing query string values that exactly match the provided key are
314
-     * removed and replaced with the given key value pair.
315
-     *
316
-     * A value of null will set the query string key without a value, e.g. "key"
317
-     * instead of "key=value".
318
-     *
319
-     * @param UriInterface $uri   URI to use as a base.
320
-     * @param string       $key   Key to set.
321
-     * @param string|null  $value Value to set
322
-     *
323
-     * @return UriInterface
324
-     */
325
-    public static function withQueryValue(UriInterface $uri, $key, $value)
326
-    {
327
-        $result = self::getFilteredQueryString($uri, [$key]);
328
-
329
-        $result[] = self::generateQueryString($key, $value);
330
-
331
-        return $uri->withQuery(implode('&', $result));
332
-    }
333
-
334
-    /**
335
-     * Creates a new URI with multiple specific query string values.
336
-     *
337
-     * It has the same behavior as withQueryValue() but for an associative array of key => value.
338
-     *
339
-     * @param UriInterface $uri           URI to use as a base.
340
-     * @param array        $keyValueArray Associative array of key and values
341
-     *
342
-     * @return UriInterface
343
-     */
344
-    public static function withQueryValues(UriInterface $uri, array $keyValueArray)
345
-    {
346
-        $result = self::getFilteredQueryString($uri, array_keys($keyValueArray));
347
-
348
-        foreach ($keyValueArray as $key => $value) {
349
-            $result[] = self::generateQueryString($key, $value);
350
-        }
351
-
352
-        return $uri->withQuery(implode('&', $result));
353
-    }
354
-
355
-    /**
356
-     * Creates a URI from a hash of `parse_url` components.
357
-     *
358
-     * @param array $parts
359
-     *
360
-     * @return UriInterface
361
-     * @link http://php.net/manual/en/function.parse-url.php
362
-     *
363
-     * @throws \InvalidArgumentException If the components do not form a valid URI.
364
-     */
365
-    public static function fromParts(array $parts)
366
-    {
367
-        $uri = new self();
368
-        $uri->applyParts($parts);
369
-        $uri->validateState();
370
-
371
-        return $uri;
372
-    }
373
-
374
-    public function getScheme()
375
-    {
376
-        return $this->scheme;
377
-    }
378
-
379
-    public function getAuthority()
380
-    {
381
-        $authority = $this->host;
382
-        if ($this->userInfo !== '') {
383
-            $authority = $this->userInfo . '@' . $authority;
384
-        }
385
-
386
-        if ($this->port !== null) {
387
-            $authority .= ':' . $this->port;
388
-        }
389
-
390
-        return $authority;
391
-    }
392
-
393
-    public function getUserInfo()
394
-    {
395
-        return $this->userInfo;
396
-    }
397
-
398
-    public function getHost()
399
-    {
400
-        return $this->host;
401
-    }
402
-
403
-    public function getPort()
404
-    {
405
-        return $this->port;
406
-    }
407
-
408
-    public function getPath()
409
-    {
410
-        return $this->path;
411
-    }
412
-
413
-    public function getQuery()
414
-    {
415
-        return $this->query;
416
-    }
417
-
418
-    public function getFragment()
419
-    {
420
-        return $this->fragment;
421
-    }
422
-
423
-    public function withScheme($scheme)
424
-    {
425
-        $scheme = $this->filterScheme($scheme);
426
-
427
-        if ($this->scheme === $scheme) {
428
-            return $this;
429
-        }
430
-
431
-        $new = clone $this;
432
-        $new->scheme = $scheme;
433
-        $new->removeDefaultPort();
434
-        $new->validateState();
435
-
436
-        return $new;
437
-    }
438
-
439
-    public function withUserInfo($user, $password = null)
440
-    {
441
-        $info = $this->filterUserInfoComponent($user);
442
-        if ($password !== null) {
443
-            $info .= ':' . $this->filterUserInfoComponent($password);
444
-        }
445
-
446
-        if ($this->userInfo === $info) {
447
-            return $this;
448
-        }
449
-
450
-        $new = clone $this;
451
-        $new->userInfo = $info;
452
-        $new->validateState();
453
-
454
-        return $new;
455
-    }
456
-
457
-    public function withHost($host)
458
-    {
459
-        $host = $this->filterHost($host);
460
-
461
-        if ($this->host === $host) {
462
-            return $this;
463
-        }
464
-
465
-        $new = clone $this;
466
-        $new->host = $host;
467
-        $new->validateState();
468
-
469
-        return $new;
470
-    }
471
-
472
-    public function withPort($port)
473
-    {
474
-        $port = $this->filterPort($port);
475
-
476
-        if ($this->port === $port) {
477
-            return $this;
478
-        }
479
-
480
-        $new = clone $this;
481
-        $new->port = $port;
482
-        $new->removeDefaultPort();
483
-        $new->validateState();
484
-
485
-        return $new;
486
-    }
487
-
488
-    public function withPath($path)
489
-    {
490
-        $path = $this->filterPath($path);
491
-
492
-        if ($this->path === $path) {
493
-            return $this;
494
-        }
495
-
496
-        $new = clone $this;
497
-        $new->path = $path;
498
-        $new->validateState();
499
-
500
-        return $new;
501
-    }
502
-
503
-    public function withQuery($query)
504
-    {
505
-        $query = $this->filterQueryAndFragment($query);
506
-
507
-        if ($this->query === $query) {
508
-            return $this;
509
-        }
510
-
511
-        $new = clone $this;
512
-        $new->query = $query;
513
-
514
-        return $new;
515
-    }
516
-
517
-    public function withFragment($fragment)
518
-    {
519
-        $fragment = $this->filterQueryAndFragment($fragment);
520
-
521
-        if ($this->fragment === $fragment) {
522
-            return $this;
523
-        }
524
-
525
-        $new = clone $this;
526
-        $new->fragment = $fragment;
527
-
528
-        return $new;
529
-    }
530
-
531
-    /**
532
-     * Apply parse_url parts to a URI.
533
-     *
534
-     * @param array $parts Array of parse_url parts to apply.
535
-     */
536
-    private function applyParts(array $parts)
537
-    {
538
-        $this->scheme = isset($parts['scheme'])
539
-            ? $this->filterScheme($parts['scheme'])
540
-            : '';
541
-        $this->userInfo = isset($parts['user'])
542
-            ? $this->filterUserInfoComponent($parts['user'])
543
-            : '';
544
-        $this->host = isset($parts['host'])
545
-            ? $this->filterHost($parts['host'])
546
-            : '';
547
-        $this->port = isset($parts['port'])
548
-            ? $this->filterPort($parts['port'])
549
-            : null;
550
-        $this->path = isset($parts['path'])
551
-            ? $this->filterPath($parts['path'])
552
-            : '';
553
-        $this->query = isset($parts['query'])
554
-            ? $this->filterQueryAndFragment($parts['query'])
555
-            : '';
556
-        $this->fragment = isset($parts['fragment'])
557
-            ? $this->filterQueryAndFragment($parts['fragment'])
558
-            : '';
559
-        if (isset($parts['pass'])) {
560
-            $this->userInfo .= ':' . $this->filterUserInfoComponent($parts['pass']);
561
-        }
562
-
563
-        $this->removeDefaultPort();
564
-    }
565
-
566
-    /**
567
-     * @param string $scheme
568
-     *
569
-     * @return string
570
-     *
571
-     * @throws \InvalidArgumentException If the scheme is invalid.
572
-     */
573
-    private function filterScheme($scheme)
574
-    {
575
-        if (!is_string($scheme)) {
576
-            throw new \InvalidArgumentException('Scheme must be a string');
577
-        }
578
-
579
-        return strtolower($scheme);
580
-    }
581
-
582
-    /**
583
-     * @param string $component
584
-     *
585
-     * @return string
586
-     *
587
-     * @throws \InvalidArgumentException If the user info is invalid.
588
-     */
589
-    private function filterUserInfoComponent($component)
590
-    {
591
-        if (!is_string($component)) {
592
-            throw new \InvalidArgumentException('User info must be a string');
593
-        }
594
-
595
-        return preg_replace_callback(
596
-            '/(?:[^%' . self::$charUnreserved . self::$charSubDelims . ']+|%(?![A-Fa-f0-9]{2}))/',
597
-            [$this, 'rawurlencodeMatchZero'],
598
-            $component
599
-        );
600
-    }
601
-
602
-    /**
603
-     * @param string $host
604
-     *
605
-     * @return string
606
-     *
607
-     * @throws \InvalidArgumentException If the host is invalid.
608
-     */
609
-    private function filterHost($host)
610
-    {
611
-        if (!is_string($host)) {
612
-            throw new \InvalidArgumentException('Host must be a string');
613
-        }
614
-
615
-        return strtolower($host);
616
-    }
617
-
618
-    /**
619
-     * @param int|null $port
620
-     *
621
-     * @return int|null
622
-     *
623
-     * @throws \InvalidArgumentException If the port is invalid.
624
-     */
625
-    private function filterPort($port)
626
-    {
627
-        if ($port === null) {
628
-            return null;
629
-        }
630
-
631
-        $port = (int) $port;
632
-        if (0 > $port || 0xffff < $port) {
633
-            throw new \InvalidArgumentException(
634
-                sprintf('Invalid port: %d. Must be between 0 and 65535', $port)
635
-            );
636
-        }
637
-
638
-        return $port;
639
-    }
640
-
641
-    /**
642
-     * @param UriInterface $uri
643
-     * @param array        $keys
644
-     * 
645
-     * @return array
646
-     */
647
-    private static function getFilteredQueryString(UriInterface $uri, array $keys)
648
-    {
649
-        $current = $uri->getQuery();
650
-
651
-        if ($current === '') {
652
-            return [];
653
-        }
654
-
655
-        $decodedKeys = array_map('rawurldecode', $keys);
656
-
657
-        return array_filter(explode('&', $current), function ($part) use ($decodedKeys) {
658
-            return !in_array(rawurldecode(explode('=', $part)[0]), $decodedKeys, true);
659
-        });
660
-    }
661
-
662
-    /**
663
-     * @param string      $key
664
-     * @param string|null $value
665
-     * 
666
-     * @return string
667
-     */
668
-    private static function generateQueryString($key, $value)
669
-    {
670
-        // Query string separators ("=", "&") within the key or value need to be encoded
671
-        // (while preventing double-encoding) before setting the query string. All other
672
-        // chars that need percent-encoding will be encoded by withQuery().
673
-        $queryString = strtr($key, self::$replaceQuery);
674
-
675
-        if ($value !== null) {
676
-            $queryString .= '=' . strtr($value, self::$replaceQuery);
677
-        }
678
-
679
-        return $queryString;
680
-    }
681
-
682
-    private function removeDefaultPort()
683
-    {
684
-        if ($this->port !== null && self::isDefaultPort($this)) {
685
-            $this->port = null;
686
-        }
687
-    }
688
-
689
-    /**
690
-     * Filters the path of a URI
691
-     *
692
-     * @param string $path
693
-     *
694
-     * @return string
695
-     *
696
-     * @throws \InvalidArgumentException If the path is invalid.
697
-     */
698
-    private function filterPath($path)
699
-    {
700
-        if (!is_string($path)) {
701
-            throw new \InvalidArgumentException('Path must be a string');
702
-        }
703
-
704
-        return preg_replace_callback(
705
-            '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/',
706
-            [$this, 'rawurlencodeMatchZero'],
707
-            $path
708
-        );
709
-    }
710
-
711
-    /**
712
-     * Filters the query string or fragment of a URI.
713
-     *
714
-     * @param string $str
715
-     *
716
-     * @return string
717
-     *
718
-     * @throws \InvalidArgumentException If the query or fragment is invalid.
719
-     */
720
-    private function filterQueryAndFragment($str)
721
-    {
722
-        if (!is_string($str)) {
723
-            throw new \InvalidArgumentException('Query and fragment must be a string');
724
-        }
725
-
726
-        return preg_replace_callback(
727
-            '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/',
728
-            [$this, 'rawurlencodeMatchZero'],
729
-            $str
730
-        );
731
-    }
732
-
733
-    private function rawurlencodeMatchZero(array $match)
734
-    {
735
-        return rawurlencode($match[0]);
736
-    }
737
-
738
-    private function validateState()
739
-    {
740
-        if ($this->host === '' && ($this->scheme === 'http' || $this->scheme === 'https')) {
741
-            $this->host = self::HTTP_DEFAULT_HOST;
742
-        }
743
-
744
-        if ($this->getAuthority() === '') {
745
-            if (0 === strpos($this->path, '//')) {
746
-                throw new \InvalidArgumentException('The path of a URI without an authority must not start with two slashes "//"');
747
-            }
748
-            if ($this->scheme === '' && false !== strpos(explode('/', $this->path, 2)[0], ':')) {
749
-                throw new \InvalidArgumentException('A relative URI must not have a path beginning with a segment containing a colon');
750
-            }
751
-        } elseif (isset($this->path[0]) && $this->path[0] !== '/') {
752
-            @trigger_error(
753
-                'The path of a URI with an authority must start with a slash "/" or be empty. Automagically fixing the URI ' .
754
-                'by adding a leading slash to the path is deprecated since version 1.4 and will throw an exception instead.',
755
-                E_USER_DEPRECATED
756
-            );
757
-            $this->path = '/'. $this->path;
758
-            //throw new \InvalidArgumentException('The path of a URI with an authority must start with a slash "/" or be empty');
759
-        }
760
-    }
761
-}
Browse code

Added README.md appinfo/info.xml appinfo/signature.json lib/Controller/AuthorApiController.php and the providers directory

DoubleBastionAdmin authored on 20/08/2022 16:33:00
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,761 @@
1
+<?php
2
+
3
+namespace GuzzleHttp\Psr7;
4
+
5
+use Psr\Http\Message\UriInterface;
6
+
7
+/**
8
+ * PSR-7 URI implementation.
9
+ *
10
+ * @author Michael Dowling
11
+ * @author Tobias Schultze
12
+ * @author Matthew Weier O'Phinney
13
+ */
14
+class Uri implements UriInterface
15
+{
16
+    /**
17
+     * Absolute http and https URIs require a host per RFC 7230 Section 2.7
18
+     * but in generic URIs the host can be empty. So for http(s) URIs
19
+     * we apply this default host when no host is given yet to form a
20
+     * valid URI.
21
+     */
22
+    const HTTP_DEFAULT_HOST = 'localhost';
23
+
24
+    private static $defaultPorts = [
25
+        'http'  => 80,
26
+        'https' => 443,
27
+        'ftp' => 21,
28
+        'gopher' => 70,
29
+        'nntp' => 119,
30
+        'news' => 119,
31
+        'telnet' => 23,
32
+        'tn3270' => 23,
33
+        'imap' => 143,
34
+        'pop' => 110,
35
+        'ldap' => 389,
36
+    ];
37
+
38
+    private static $charUnreserved = 'a-zA-Z0-9_\-\.~';
39
+    private static $charSubDelims = '!\$&\'\(\)\*\+,;=';
40
+    private static $replaceQuery = ['=' => '%3D', '&' => '%26'];
41
+
42
+    /** @var string Uri scheme. */
43
+    private $scheme = '';
44
+
45
+    /** @var string Uri user info. */
46
+    private $userInfo = '';
47
+
48
+    /** @var string Uri host. */
49
+    private $host = '';
50
+
51
+    /** @var int|null Uri port. */
52
+    private $port;
53
+
54
+    /** @var string Uri path. */
55
+    private $path = '';
56
+
57
+    /** @var string Uri query string. */
58
+    private $query = '';
59
+
60
+    /** @var string Uri fragment. */
61
+    private $fragment = '';
62
+
63
+    /**
64
+     * @param string $uri URI to parse
65
+     */
66
+    public function __construct($uri = '')
67
+    {
68
+        // weak type check to also accept null until we can add scalar type hints
69
+        if ($uri != '') {
70
+            $parts = parse_url($uri);
71
+            if ($parts === false) {
72
+                throw new \InvalidArgumentException("Unable to parse URI: $uri");
73
+            }
74
+            $this->applyParts($parts);
75
+        }
76
+    }
77
+
78
+    public function __toString()
79
+    {
80
+        return self::composeComponents(
81
+            $this->scheme,
82
+            $this->getAuthority(),
83
+            $this->path,
84
+            $this->query,
85
+            $this->fragment
86
+        );
87
+    }
88
+
89
+    /**
90
+     * Composes a URI reference string from its various components.
91
+     *
92
+     * Usually this method does not need to be called manually but instead is used indirectly via
93
+     * `Psr\Http\Message\UriInterface::__toString`.
94
+     *
95
+     * PSR-7 UriInterface treats an empty component the same as a missing component as
96
+     * getQuery(), getFragment() etc. always return a string. This explains the slight
97
+     * difference to RFC 3986 Section 5.3.
98
+     *
99
+     * Another adjustment is that the authority separator is added even when the authority is missing/empty
100
+     * for the "file" scheme. This is because PHP stream functions like `file_get_contents` only work with
101
+     * `file:///myfile` but not with `file:/myfile` although they are equivalent according to RFC 3986. But
102
+     * `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to
103
+     * that format).
104
+     *
105
+     * @param string $scheme
106
+     * @param string $authority
107
+     * @param string $path
108
+     * @param string $query
109
+     * @param string $fragment
110
+     *
111
+     * @return string
112
+     *
113
+     * @link https://tools.ietf.org/html/rfc3986#section-5.3
114
+     */
115
+    public static function composeComponents($scheme, $authority, $path, $query, $fragment)
116
+    {
117
+        $uri = '';
118
+
119
+        // weak type checks to also accept null until we can add scalar type hints
120
+        if ($scheme != '') {
121
+            $uri .= $scheme . ':';
122
+        }
123
+
124
+        if ($authority != ''|| $scheme === 'file') {
125
+            $uri .= '//' . $authority;
126
+        }
127
+
128
+        $uri .= $path;
129
+
130
+        if ($query != '') {
131
+            $uri .= '?' . $query;
132
+        }
133
+
134
+        if ($fragment != '') {
135
+            $uri .= '#' . $fragment;
136
+        }
137
+
138
+        return $uri;
139
+    }
140
+
141
+    /**
142
+     * Whether the URI has the default port of the current scheme.
143
+     *
144
+     * `Psr\Http\Message\UriInterface::getPort` may return null or the standard port. This method can be used
145
+     * independently of the implementation.
146
+     *
147
+     * @param UriInterface $uri
148
+     *
149
+     * @return bool
150
+     */
151
+    public static function isDefaultPort(UriInterface $uri)
152
+    {
153
+        return $uri->getPort() === null
154
+            || (isset(self::$defaultPorts[$uri->getScheme()]) && $uri->getPort() === self::$defaultPorts[$uri->getScheme()]);
155
+    }
156
+
157
+    /**
158
+     * Whether the URI is absolute, i.e. it has a scheme.
159
+     *
160
+     * An instance of UriInterface can either be an absolute URI or a relative reference. This method returns true
161
+     * if it is the former. An absolute URI has a scheme. A relative reference is used to express a URI relative
162
+     * to another URI, the base URI. Relative references can be divided into several forms:
163
+     * - network-path references, e.g. '//example.com/path'
164
+     * - absolute-path references, e.g. '/path'
165
+     * - relative-path references, e.g. 'subpath'
166
+     *
167
+     * @param UriInterface $uri
168
+     *
169
+     * @return bool
170
+     * @see Uri::isNetworkPathReference
171
+     * @see Uri::isAbsolutePathReference
172
+     * @see Uri::isRelativePathReference
173
+     * @link https://tools.ietf.org/html/rfc3986#section-4
174
+     */
175
+    public static function isAbsolute(UriInterface $uri)
176
+    {
177
+        return $uri->getScheme() !== '';
178
+    }
179
+
180
+    /**
181
+     * Whether the URI is a network-path reference.
182
+     *
183
+     * A relative reference that begins with two slash characters is termed an network-path reference.
184
+     *
185
+     * @param UriInterface $uri
186
+     *
187
+     * @return bool
188
+     * @link https://tools.ietf.org/html/rfc3986#section-4.2
189
+     */
190
+    public static function isNetworkPathReference(UriInterface $uri)
191
+    {
192
+        return $uri->getScheme() === '' && $uri->getAuthority() !== '';
193
+    }
194
+
195
+    /**
196
+     * Whether the URI is a absolute-path reference.
197
+     *
198
+     * A relative reference that begins with a single slash character is termed an absolute-path reference.
199
+     *
200
+     * @param UriInterface $uri
201
+     *
202
+     * @return bool
203
+     * @link https://tools.ietf.org/html/rfc3986#section-4.2
204
+     */
205
+    public static function isAbsolutePathReference(UriInterface $uri)
206
+    {
207
+        return $uri->getScheme() === ''
208
+            && $uri->getAuthority() === ''
209
+            && isset($uri->getPath()[0])
210
+            && $uri->getPath()[0] === '/';
211
+    }
212
+
213
+    /**
214
+     * Whether the URI is a relative-path reference.
215
+     *
216
+     * A relative reference that does not begin with a slash character is termed a relative-path reference.
217
+     *
218
+     * @param UriInterface $uri
219
+     *
220
+     * @return bool
221
+     * @link https://tools.ietf.org/html/rfc3986#section-4.2
222
+     */
223
+    public static function isRelativePathReference(UriInterface $uri)
224
+    {
225
+        return $uri->getScheme() === ''
226
+            && $uri->getAuthority() === ''
227
+            && (!isset($uri->getPath()[0]) || $uri->getPath()[0] !== '/');
228
+    }
229
+
230
+    /**
231
+     * Whether the URI is a same-document reference.
232
+     *
233
+     * A same-document reference refers to a URI that is, aside from its fragment
234
+     * component, identical to the base URI. When no base URI is given, only an empty
235
+     * URI reference (apart from its fragment) is considered a same-document reference.
236
+     *
237
+     * @param UriInterface      $uri  The URI to check
238
+     * @param UriInterface|null $base An optional base URI to compare against
239
+     *
240
+     * @return bool
241
+     * @link https://tools.ietf.org/html/rfc3986#section-4.4
242
+     */
243
+    public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null)
244
+    {
245
+        if ($base !== null) {
246
+            $uri = UriResolver::resolve($base, $uri);
247
+
248
+            return ($uri->getScheme() === $base->getScheme())
249
+                && ($uri->getAuthority() === $base->getAuthority())
250
+                && ($uri->getPath() === $base->getPath())
251
+                && ($uri->getQuery() === $base->getQuery());
252
+        }
253
+
254
+        return $uri->getScheme() === '' && $uri->getAuthority() === '' && $uri->getPath() === '' && $uri->getQuery() === '';
255
+    }
256
+
257
+    /**
258
+     * Removes dot segments from a path and returns the new path.
259
+     *
260
+     * @param string $path
261
+     *
262
+     * @return string
263
+     *
264
+     * @deprecated since version 1.4. Use UriResolver::removeDotSegments instead.
265
+     * @see UriResolver::removeDotSegments
266
+     */
267
+    public static function removeDotSegments($path)
268
+    {
269
+        return UriResolver::removeDotSegments($path);
270
+    }
271
+
272
+    /**
273
+     * Converts the relative URI into a new URI that is resolved against the base URI.
274
+     *
275
+     * @param UriInterface        $base Base URI
276
+     * @param string|UriInterface $rel  Relative URI
277
+     *
278
+     * @return UriInterface
279
+     *
280
+     * @deprecated since version 1.4. Use UriResolver::resolve instead.
281
+     * @see UriResolver::resolve
282
+     */
283
+    public static function resolve(UriInterface $base, $rel)
284
+    {
285
+        if (!($rel instanceof UriInterface)) {
286
+            $rel = new self($rel);
287
+        }
288
+
289
+        return UriResolver::resolve($base, $rel);
290
+    }
291
+
292
+    /**
293
+     * Creates a new URI with a specific query string value removed.
294
+     *
295
+     * Any existing query string values that exactly match the provided key are
296
+     * removed.
297
+     *
298
+     * @param UriInterface $uri URI to use as a base.
299
+     * @param string       $key Query string key to remove.
300
+     *
301
+     * @return UriInterface
302
+     */
303
+    public static function withoutQueryValue(UriInterface $uri, $key)
304
+    {
305
+        $result = self::getFilteredQueryString($uri, [$key]);
306
+
307
+        return $uri->withQuery(implode('&', $result));
308
+    }
309
+
310
+    /**
311
+     * Creates a new URI with a specific query string value.
312
+     *
313
+     * Any existing query string values that exactly match the provided key are
314
+     * removed and replaced with the given key value pair.
315
+     *
316
+     * A value of null will set the query string key without a value, e.g. "key"
317
+     * instead of "key=value".
318
+     *
319
+     * @param UriInterface $uri   URI to use as a base.
320
+     * @param string       $key   Key to set.
321
+     * @param string|null  $value Value to set
322
+     *
323
+     * @return UriInterface
324
+     */
325
+    public static function withQueryValue(UriInterface $uri, $key, $value)
326
+    {
327
+        $result = self::getFilteredQueryString($uri, [$key]);
328
+
329
+        $result[] = self::generateQueryString($key, $value);
330
+
331
+        return $uri->withQuery(implode('&', $result));
332
+    }
333
+
334
+    /**
335
+     * Creates a new URI with multiple specific query string values.
336
+     *
337
+     * It has the same behavior as withQueryValue() but for an associative array of key => value.
338
+     *
339
+     * @param UriInterface $uri           URI to use as a base.
340
+     * @param array        $keyValueArray Associative array of key and values
341
+     *
342
+     * @return UriInterface
343
+     */
344
+    public static function withQueryValues(UriInterface $uri, array $keyValueArray)
345
+    {
346
+        $result = self::getFilteredQueryString($uri, array_keys($keyValueArray));
347
+
348
+        foreach ($keyValueArray as $key => $value) {
349
+            $result[] = self::generateQueryString($key, $value);
350
+        }
351
+
352
+        return $uri->withQuery(implode('&', $result));
353
+    }
354
+
355
+    /**
356
+     * Creates a URI from a hash of `parse_url` components.
357
+     *
358
+     * @param array $parts
359
+     *
360
+     * @return UriInterface
361
+     * @link http://php.net/manual/en/function.parse-url.php
362
+     *
363
+     * @throws \InvalidArgumentException If the components do not form a valid URI.
364
+     */
365
+    public static function fromParts(array $parts)
366
+    {
367
+        $uri = new self();
368
+        $uri->applyParts($parts);
369
+        $uri->validateState();
370
+
371
+        return $uri;
372
+    }
373
+
374
+    public function getScheme()
375
+    {
376
+        return $this->scheme;
377
+    }
378
+
379
+    public function getAuthority()
380
+    {
381
+        $authority = $this->host;
382
+        if ($this->userInfo !== '') {
383
+            $authority = $this->userInfo . '@' . $authority;
384
+        }
385
+
386
+        if ($this->port !== null) {
387
+            $authority .= ':' . $this->port;
388
+        }
389
+
390
+        return $authority;
391
+    }
392
+
393
+    public function getUserInfo()
394
+    {
395
+        return $this->userInfo;
396
+    }
397
+
398
+    public function getHost()
399
+    {
400
+        return $this->host;
401
+    }
402
+
403
+    public function getPort()
404
+    {
405
+        return $this->port;
406
+    }
407
+
408
+    public function getPath()
409
+    {
410
+        return $this->path;
411
+    }
412
+
413
+    public function getQuery()
414
+    {
415
+        return $this->query;
416
+    }
417
+
418
+    public function getFragment()
419
+    {
420
+        return $this->fragment;
421
+    }
422
+
423
+    public function withScheme($scheme)
424
+    {
425
+        $scheme = $this->filterScheme($scheme);
426
+
427
+        if ($this->scheme === $scheme) {
428
+            return $this;
429
+        }
430
+
431
+        $new = clone $this;
432
+        $new->scheme = $scheme;
433
+        $new->removeDefaultPort();
434
+        $new->validateState();
435
+
436
+        return $new;
437
+    }
438
+
439
+    public function withUserInfo($user, $password = null)
440
+    {
441
+        $info = $this->filterUserInfoComponent($user);
442
+        if ($password !== null) {
443
+            $info .= ':' . $this->filterUserInfoComponent($password);
444
+        }
445
+
446
+        if ($this->userInfo === $info) {
447
+            return $this;
448
+        }
449
+
450
+        $new = clone $this;
451
+        $new->userInfo = $info;
452
+        $new->validateState();
453
+
454
+        return $new;
455
+    }
456
+
457
+    public function withHost($host)
458
+    {
459
+        $host = $this->filterHost($host);
460
+
461
+        if ($this->host === $host) {
462
+            return $this;
463
+        }
464
+
465
+        $new = clone $this;
466
+        $new->host = $host;
467
+        $new->validateState();
468
+
469
+        return $new;
470
+    }
471
+
472
+    public function withPort($port)
473
+    {
474
+        $port = $this->filterPort($port);
475
+
476
+        if ($this->port === $port) {
477
+            return $this;
478
+        }
479
+
480
+        $new = clone $this;
481
+        $new->port = $port;
482
+        $new->removeDefaultPort();
483
+        $new->validateState();
484
+
485
+        return $new;
486
+    }
487
+
488
+    public function withPath($path)
489
+    {
490
+        $path = $this->filterPath($path);
491
+
492
+        if ($this->path === $path) {
493
+            return $this;
494
+        }
495
+
496
+        $new = clone $this;
497
+        $new->path = $path;
498
+        $new->validateState();
499
+
500
+        return $new;
501
+    }
502
+
503
+    public function withQuery($query)
504
+    {
505
+        $query = $this->filterQueryAndFragment($query);
506
+
507
+        if ($this->query === $query) {
508
+            return $this;
509
+        }
510
+
511
+        $new = clone $this;
512
+        $new->query = $query;
513
+
514
+        return $new;
515
+    }
516
+
517
+    public function withFragment($fragment)
518
+    {
519
+        $fragment = $this->filterQueryAndFragment($fragment);
520
+
521
+        if ($this->fragment === $fragment) {
522
+            return $this;
523
+        }
524
+
525
+        $new = clone $this;
526
+        $new->fragment = $fragment;
527
+
528
+        return $new;
529
+    }
530
+
531
+    /**
532
+     * Apply parse_url parts to a URI.
533
+     *
534
+     * @param array $parts Array of parse_url parts to apply.
535
+     */
536
+    private function applyParts(array $parts)
537
+    {
538
+        $this->scheme = isset($parts['scheme'])
539
+            ? $this->filterScheme($parts['scheme'])
540
+            : '';
541
+        $this->userInfo = isset($parts['user'])
542
+            ? $this->filterUserInfoComponent($parts['user'])
543
+            : '';
544
+        $this->host = isset($parts['host'])
545
+            ? $this->filterHost($parts['host'])
546
+            : '';
547
+        $this->port = isset($parts['port'])
548
+            ? $this->filterPort($parts['port'])
549
+            : null;
550
+        $this->path = isset($parts['path'])
551
+            ? $this->filterPath($parts['path'])
552
+            : '';
553
+        $this->query = isset($parts['query'])
554
+            ? $this->filterQueryAndFragment($parts['query'])
555
+            : '';
556
+        $this->fragment = isset($parts['fragment'])
557
+            ? $this->filterQueryAndFragment($parts['fragment'])
558
+            : '';
559
+        if (isset($parts['pass'])) {
560
+            $this->userInfo .= ':' . $this->filterUserInfoComponent($parts['pass']);
561
+        }
562
+
563
+        $this->removeDefaultPort();
564
+    }
565
+
566
+    /**
567
+     * @param string $scheme
568
+     *
569
+     * @return string
570
+     *
571
+     * @throws \InvalidArgumentException If the scheme is invalid.
572
+     */
573
+    private function filterScheme($scheme)
574
+    {
575
+        if (!is_string($scheme)) {
576
+            throw new \InvalidArgumentException('Scheme must be a string');
577
+        }
578
+
579
+        return strtolower($scheme);
580
+    }
581
+
582
+    /**
583
+     * @param string $component
584
+     *
585
+     * @return string
586
+     *
587
+     * @throws \InvalidArgumentException If the user info is invalid.
588
+     */
589
+    private function filterUserInfoComponent($component)
590
+    {
591
+        if (!is_string($component)) {
592
+            throw new \InvalidArgumentException('User info must be a string');
593
+        }
594
+
595
+        return preg_replace_callback(
596
+            '/(?:[^%' . self::$charUnreserved . self::$charSubDelims . ']+|%(?![A-Fa-f0-9]{2}))/',
597
+            [$this, 'rawurlencodeMatchZero'],
598
+            $component
599
+        );
600
+    }
601
+
602
+    /**
603
+     * @param string $host
604
+     *
605
+     * @return string
606
+     *
607
+     * @throws \InvalidArgumentException If the host is invalid.
608
+     */
609
+    private function filterHost($host)
610
+    {
611
+        if (!is_string($host)) {
612
+            throw new \InvalidArgumentException('Host must be a string');
613
+        }
614
+
615
+        return strtolower($host);
616
+    }
617
+
618
+    /**
619
+     * @param int|null $port
620
+     *
621
+     * @return int|null
622
+     *
623
+     * @throws \InvalidArgumentException If the port is invalid.
624
+     */
625
+    private function filterPort($port)
626
+    {
627
+        if ($port === null) {
628
+            return null;
629
+        }
630
+
631
+        $port = (int) $port;
632
+        if (0 > $port || 0xffff < $port) {
633
+            throw new \InvalidArgumentException(
634
+                sprintf('Invalid port: %d. Must be between 0 and 65535', $port)
635
+            );
636
+        }
637
+
638
+        return $port;
639
+    }
640
+
641
+    /**
642
+     * @param UriInterface $uri
643
+     * @param array        $keys
644
+     * 
645
+     * @return array
646
+     */
647
+    private static function getFilteredQueryString(UriInterface $uri, array $keys)
648
+    {
649
+        $current = $uri->getQuery();
650
+
651
+        if ($current === '') {
652
+            return [];
653
+        }
654
+
655
+        $decodedKeys = array_map('rawurldecode', $keys);
656
+
657
+        return array_filter(explode('&', $current), function ($part) use ($decodedKeys) {
658
+            return !in_array(rawurldecode(explode('=', $part)[0]), $decodedKeys, true);
659
+        });
660
+    }
661
+
662
+    /**
663
+     * @param string      $key
664
+     * @param string|null $value
665
+     * 
666
+     * @return string
667
+     */
668
+    private static function generateQueryString($key, $value)
669
+    {
670
+        // Query string separators ("=", "&") within the key or value need to be encoded
671
+        // (while preventing double-encoding) before setting the query string. All other
672
+        // chars that need percent-encoding will be encoded by withQuery().
673
+        $queryString = strtr($key, self::$replaceQuery);
674
+
675
+        if ($value !== null) {
676
+            $queryString .= '=' . strtr($value, self::$replaceQuery);
677
+        }
678
+
679
+        return $queryString;
680
+    }
681
+
682
+    private function removeDefaultPort()
683
+    {
684
+        if ($this->port !== null && self::isDefaultPort($this)) {
685
+            $this->port = null;
686
+        }
687
+    }
688
+
689
+    /**
690
+     * Filters the path of a URI
691
+     *
692
+     * @param string $path
693
+     *
694
+     * @return string
695
+     *
696
+     * @throws \InvalidArgumentException If the path is invalid.
697
+     */
698
+    private function filterPath($path)
699
+    {
700
+        if (!is_string($path)) {
701
+            throw new \InvalidArgumentException('Path must be a string');
702
+        }
703
+
704
+        return preg_replace_callback(
705
+            '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/',
706
+            [$this, 'rawurlencodeMatchZero'],
707
+            $path
708
+        );
709
+    }
710
+
711
+    /**
712
+     * Filters the query string or fragment of a URI.
713
+     *
714
+     * @param string $str
715
+     *
716
+     * @return string
717
+     *
718
+     * @throws \InvalidArgumentException If the query or fragment is invalid.
719
+     */
720
+    private function filterQueryAndFragment($str)
721
+    {
722
+        if (!is_string($str)) {
723
+            throw new \InvalidArgumentException('Query and fragment must be a string');
724
+        }
725
+
726
+        return preg_replace_callback(
727
+            '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/',
728
+            [$this, 'rawurlencodeMatchZero'],
729
+            $str
730
+        );
731
+    }
732
+
733
+    private function rawurlencodeMatchZero(array $match)
734
+    {
735
+        return rawurlencode($match[0]);
736
+    }
737
+
738
+    private function validateState()
739
+    {
740
+        if ($this->host === '' && ($this->scheme === 'http' || $this->scheme === 'https')) {
741
+            $this->host = self::HTTP_DEFAULT_HOST;
742
+        }
743
+
744
+        if ($this->getAuthority() === '') {
745
+            if (0 === strpos($this->path, '//')) {
746
+                throw new \InvalidArgumentException('The path of a URI without an authority must not start with two slashes "//"');
747
+            }
748
+            if ($this->scheme === '' && false !== strpos(explode('/', $this->path, 2)[0], ':')) {
749
+                throw new \InvalidArgumentException('A relative URI must not have a path beginning with a segment containing a colon');
750
+            }
751
+        } elseif (isset($this->path[0]) && $this->path[0] !== '/') {
752
+            @trigger_error(
753
+                'The path of a URI with an authority must start with a slash "/" or be empty. Automagically fixing the URI ' .
754
+                'by adding a leading slash to the path is deprecated since version 1.4 and will throw an exception instead.',
755
+                E_USER_DEPRECATED
756
+            );
757
+            $this->path = '/'. $this->path;
758
+            //throw new \InvalidArgumentException('The path of a URI with an authority must start with a slash "/" or be empty');
759
+        }
760
+    }
761
+}