Proyectos de Subversion Moodle

Rev

Rev 1 | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 1 Rev 1441
Línea 23... Línea 23...
23
     * valid URI.
23
     * valid URI.
24
     */
24
     */
25
    private const HTTP_DEFAULT_HOST = 'localhost';
25
    private const HTTP_DEFAULT_HOST = 'localhost';
Línea 26... Línea 26...
26
 
26
 
27
    private const DEFAULT_PORTS = [
27
    private const DEFAULT_PORTS = [
28
        'http'  => 80,
28
        'http' => 80,
29
        'https' => 443,
29
        'https' => 443,
30
        'ftp' => 21,
30
        'ftp' => 21,
31
        'gopher' => 70,
31
        'gopher' => 70,
32
        'nntp' => 119,
32
        'nntp' => 119,
Línea 39... Línea 39...
39
    ];
39
    ];
Línea 40... Línea 40...
40
 
40
 
41
    /**
41
    /**
42
     * Unreserved characters for use in a regex.
42
     * Unreserved characters for use in a regex.
43
     *
43
     *
44
     * @link https://tools.ietf.org/html/rfc3986#section-2.3
44
     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-2.3
45
     */
45
     */
Línea 46... Línea 46...
46
    private const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~';
46
    private const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~';
47
 
47
 
48
    /**
48
    /**
49
     * Sub-delims for use in a regex.
49
     * Sub-delims for use in a regex.
50
     *
50
     *
51
     * @link https://tools.ietf.org/html/rfc3986#section-2.2
51
     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-2.2
52
     */
52
     */
Línea 53... Línea 53...
53
    private const CHAR_SUB_DELIMS = '!\$&\'\(\)\*\+,;=';
53
    private const CHAR_SUB_DELIMS = '!\$&\'\(\)\*\+,;=';
Línea 85... Línea 85...
85
                throw new MalformedUriException("Unable to parse URI: $uri");
85
                throw new MalformedUriException("Unable to parse URI: $uri");
86
            }
86
            }
87
            $this->applyParts($parts);
87
            $this->applyParts($parts);
88
        }
88
        }
89
    }
89
    }
-
 
90
 
90
    /**
91
    /**
91
     * UTF-8 aware \parse_url() replacement.
92
     * UTF-8 aware \parse_url() replacement.
92
     *
93
     *
93
     * The internal function produces broken output for non ASCII domain names
94
     * The internal function produces broken output for non ASCII domain names
94
     * (IDN) when used with locales other than "C".
95
     * (IDN) when used with locales other than "C".
Línea 119... Línea 120...
119
                return urlencode($matches[0]);
120
                return urlencode($matches[0]);
120
            },
121
            },
121
            $url
122
            $url
122
        );
123
        );
Línea 123... Línea 124...
123
 
124
 
Línea 124... Línea 125...
124
        $result = parse_url($prefix . $encodedUrl);
125
        $result = parse_url($prefix.$encodedUrl);
125
 
126
 
126
        if ($result === false) {
127
        if ($result === false) {
Línea 159... Línea 160...
159
     * for the "file" scheme. This is because PHP stream functions like `file_get_contents` only work with
160
     * for the "file" scheme. This is because PHP stream functions like `file_get_contents` only work with
160
     * `file:///myfile` but not with `file:/myfile` although they are equivalent according to RFC 3986. But
161
     * `file:///myfile` but not with `file:/myfile` although they are equivalent according to RFC 3986. But
161
     * `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to
162
     * `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to
162
     * that format).
163
     * that format).
163
     *
164
     *
164
     * @link https://tools.ietf.org/html/rfc3986#section-5.3
165
     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-5.3
165
     */
166
     */
166
    public static function composeComponents(?string $scheme, ?string $authority, string $path, ?string $query, ?string $fragment): string
167
    public static function composeComponents(?string $scheme, ?string $authority, string $path, ?string $query, ?string $fragment): string
167
    {
168
    {
168
        $uri = '';
169
        $uri = '';
Línea 169... Línea 170...
169
 
170
 
170
        // weak type checks to also accept null until we can add scalar type hints
171
        // weak type checks to also accept null until we can add scalar type hints
171
        if ($scheme != '') {
172
        if ($scheme != '') {
172
            $uri .= $scheme . ':';
173
            $uri .= $scheme.':';
Línea 173... Línea 174...
173
        }
174
        }
174
 
175
 
175
        if ($authority != '' || $scheme === 'file') {
176
        if ($authority != '' || $scheme === 'file') {
Línea 176... Línea 177...
176
            $uri .= '//' . $authority;
177
            $uri .= '//'.$authority;
177
        }
178
        }
178
 
179
 
Línea 179... Línea 180...
179
        if ($authority != '' && $path != '' && $path[0] != '/') {
180
        if ($authority != '' && $path != '' && $path[0] != '/') {
Línea 180... Línea 181...
180
            $path = '/' . $path;
181
            $path = '/'.$path;
181
        }
182
        }
182
 
183
 
Línea 183... Línea 184...
183
        $uri .= $path;
184
        $uri .= $path;
184
 
185
 
185
        if ($query != '') {
186
        if ($query != '') {
Línea 186... Línea 187...
186
            $uri .= '?' . $query;
187
            $uri .= '?'.$query;
187
        }
188
        }
Línea 216... Línea 217...
216
     * - relative-path references, e.g. 'subpath'
217
     * - relative-path references, e.g. 'subpath'
217
     *
218
     *
218
     * @see Uri::isNetworkPathReference
219
     * @see Uri::isNetworkPathReference
219
     * @see Uri::isAbsolutePathReference
220
     * @see Uri::isAbsolutePathReference
220
     * @see Uri::isRelativePathReference
221
     * @see Uri::isRelativePathReference
221
     * @link https://tools.ietf.org/html/rfc3986#section-4
222
     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4
222
     */
223
     */
223
    public static function isAbsolute(UriInterface $uri): bool
224
    public static function isAbsolute(UriInterface $uri): bool
224
    {
225
    {
225
        return $uri->getScheme() !== '';
226
        return $uri->getScheme() !== '';
226
    }
227
    }
Línea 228... Línea 229...
228
    /**
229
    /**
229
     * Whether the URI is a network-path reference.
230
     * Whether the URI is a network-path reference.
230
     *
231
     *
231
     * A relative reference that begins with two slash characters is termed an network-path reference.
232
     * A relative reference that begins with two slash characters is termed an network-path reference.
232
     *
233
     *
233
     * @link https://tools.ietf.org/html/rfc3986#section-4.2
234
     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
234
     */
235
     */
235
    public static function isNetworkPathReference(UriInterface $uri): bool
236
    public static function isNetworkPathReference(UriInterface $uri): bool
236
    {
237
    {
237
        return $uri->getScheme() === '' && $uri->getAuthority() !== '';
238
        return $uri->getScheme() === '' && $uri->getAuthority() !== '';
238
    }
239
    }
Línea 240... Línea 241...
240
    /**
241
    /**
241
     * Whether the URI is a absolute-path reference.
242
     * Whether the URI is a absolute-path reference.
242
     *
243
     *
243
     * A relative reference that begins with a single slash character is termed an absolute-path reference.
244
     * A relative reference that begins with a single slash character is termed an absolute-path reference.
244
     *
245
     *
245
     * @link https://tools.ietf.org/html/rfc3986#section-4.2
246
     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
246
     */
247
     */
247
    public static function isAbsolutePathReference(UriInterface $uri): bool
248
    public static function isAbsolutePathReference(UriInterface $uri): bool
248
    {
249
    {
249
        return $uri->getScheme() === ''
250
        return $uri->getScheme() === ''
250
            && $uri->getAuthority() === ''
251
            && $uri->getAuthority() === ''
Línea 255... Línea 256...
255
    /**
256
    /**
256
     * Whether the URI is a relative-path reference.
257
     * Whether the URI is a relative-path reference.
257
     *
258
     *
258
     * A relative reference that does not begin with a slash character is termed a relative-path reference.
259
     * A relative reference that does not begin with a slash character is termed a relative-path reference.
259
     *
260
     *
260
     * @link https://tools.ietf.org/html/rfc3986#section-4.2
261
     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2
261
     */
262
     */
262
    public static function isRelativePathReference(UriInterface $uri): bool
263
    public static function isRelativePathReference(UriInterface $uri): bool
263
    {
264
    {
264
        return $uri->getScheme() === ''
265
        return $uri->getScheme() === ''
265
            && $uri->getAuthority() === ''
266
            && $uri->getAuthority() === ''
Línea 274... Línea 275...
274
     * URI reference (apart from its fragment) is considered a same-document reference.
275
     * URI reference (apart from its fragment) is considered a same-document reference.
275
     *
276
     *
276
     * @param UriInterface      $uri  The URI to check
277
     * @param UriInterface      $uri  The URI to check
277
     * @param UriInterface|null $base An optional base URI to compare against
278
     * @param UriInterface|null $base An optional base URI to compare against
278
     *
279
     *
279
     * @link https://tools.ietf.org/html/rfc3986#section-4.4
280
     * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.4
280
     */
281
     */
281
    public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null): bool
282
    public static function isSameDocumentReference(UriInterface $uri, ?UriInterface $base = null): bool
282
    {
283
    {
283
        if ($base !== null) {
284
        if ($base !== null) {
284
            $uri = UriResolver::resolve($base, $uri);
285
            $uri = UriResolver::resolve($base, $uri);
Línea 285... Línea 286...
285
 
286
 
Línea 333... Línea 334...
333
    /**
334
    /**
334
     * Creates a new URI with multiple specific query string values.
335
     * Creates a new URI with multiple specific query string values.
335
     *
336
     *
336
     * It has the same behavior as withQueryValue() but for an associative array of key => value.
337
     * It has the same behavior as withQueryValue() but for an associative array of key => value.
337
     *
338
     *
338
     * @param UriInterface               $uri           URI to use as a base.
339
     * @param UriInterface    $uri           URI to use as a base.
339
     * @param array<string, string|null> $keyValueArray Associative array of key and values
340
     * @param (string|null)[] $keyValueArray Associative array of key and values
340
     */
341
     */
341
    public static function withQueryValues(UriInterface $uri, array $keyValueArray): UriInterface
342
    public static function withQueryValues(UriInterface $uri, array $keyValueArray): UriInterface
342
    {
343
    {
343
        $result = self::getFilteredQueryString($uri, array_keys($keyValueArray));
344
        $result = self::getFilteredQueryString($uri, array_keys($keyValueArray));
Línea 350... Línea 351...
350
    }
351
    }
Línea 351... Línea 352...
351
 
352
 
352
    /**
353
    /**
353
     * Creates a URI from a hash of `parse_url` components.
354
     * Creates a URI from a hash of `parse_url` components.
354
     *
355
     *
355
     * @link http://php.net/manual/en/function.parse-url.php
356
     * @see https://www.php.net/manual/en/function.parse-url.php
356
     *
357
     *
357
     * @throws MalformedUriException If the components do not form a valid URI.
358
     * @throws MalformedUriException If the components do not form a valid URI.
358
     */
359
     */
359
    public static function fromParts(array $parts): UriInterface
360
    public static function fromParts(array $parts): UriInterface
Línea 372... Línea 373...
372
 
373
 
373
    public function getAuthority(): string
374
    public function getAuthority(): string
374
    {
375
    {
375
        $authority = $this->host;
376
        $authority = $this->host;
376
        if ($this->userInfo !== '') {
377
        if ($this->userInfo !== '') {
377
            $authority = $this->userInfo . '@' . $authority;
378
            $authority = $this->userInfo.'@'.$authority;
Línea 378... Línea 379...
378
        }
379
        }
379
 
380
 
380
        if ($this->port !== null) {
381
        if ($this->port !== null) {
Línea 381... Línea 382...
381
            $authority .= ':' . $this->port;
382
            $authority .= ':'.$this->port;
382
        }
383
        }
Línea 433... Línea 434...
433
 
434
 
434
    public function withUserInfo($user, $password = null): UriInterface
435
    public function withUserInfo($user, $password = null): UriInterface
435
    {
436
    {
436
        $info = $this->filterUserInfoComponent($user);
437
        $info = $this->filterUserInfoComponent($user);
437
        if ($password !== null) {
438
        if ($password !== null) {
438
            $info .= ':' . $this->filterUserInfoComponent($password);
439
            $info .= ':'.$this->filterUserInfoComponent($password);
Línea 439... Línea 440...
439
        }
440
        }
440
 
441
 
441
        if ($this->userInfo === $info) {
442
        if ($this->userInfo === $info) {
Línea 561... Línea 562...
561
            : '';
562
            : '';
562
        $this->fragment = isset($parts['fragment'])
563
        $this->fragment = isset($parts['fragment'])
563
            ? $this->filterQueryAndFragment($parts['fragment'])
564
            ? $this->filterQueryAndFragment($parts['fragment'])
564
            : '';
565
            : '';
565
        if (isset($parts['pass'])) {
566
        if (isset($parts['pass'])) {
566
            $this->userInfo .= ':' . $this->filterUserInfoComponent($parts['pass']);
567
            $this->userInfo .= ':'.$this->filterUserInfoComponent($parts['pass']);
567
        }
568
        }
Línea 568... Línea 569...
568
 
569
 
569
        $this->removeDefaultPort();
570
        $this->removeDefaultPort();
Línea 593... Línea 594...
593
        if (!is_string($component)) {
594
        if (!is_string($component)) {
594
            throw new \InvalidArgumentException('User info must be a string');
595
            throw new \InvalidArgumentException('User info must be a string');
595
        }
596
        }
Línea 596... Línea 597...
596
 
597
 
597
        return preg_replace_callback(
598
        return preg_replace_callback(
598
            '/(?:[^%' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . ']+|%(?![A-Fa-f0-9]{2}))/',
599
            '/(?:[^%'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.']+|%(?![A-Fa-f0-9]{2}))/',
599
            [$this, 'rawurlencodeMatchZero'],
600
            [$this, 'rawurlencodeMatchZero'],
600
            $component
601
            $component
601
        );
602
        );
Línea 625... Línea 626...
625
        if ($port === null) {
626
        if ($port === null) {
626
            return null;
627
            return null;
627
        }
628
        }
Línea 628... Línea 629...
628
 
629
 
629
        $port = (int) $port;
630
        $port = (int) $port;
630
        if (0 > $port || 0xffff < $port) {
631
        if (0 > $port || 0xFFFF < $port) {
631
            throw new \InvalidArgumentException(
632
            throw new \InvalidArgumentException(
632
                sprintf('Invalid port: %d. Must be between 0 and 65535', $port)
633
                sprintf('Invalid port: %d. Must be between 0 and 65535', $port)
633
            );
634
            );
Línea 634... Línea 635...
634
        }
635
        }
635
 
636
 
Línea 636... Línea 637...
636
        return $port;
637
        return $port;
637
    }
638
    }
638
 
639
 
639
    /**
640
    /**
640
     * @param string[] $keys
641
     * @param (string|int)[] $keys
641
     *
642
     *
642
     * @return string[]
643
     * @return string[]
Línea 647... Línea 648...
647
 
648
 
648
        if ($current === '') {
649
        if ($current === '') {
649
            return [];
650
            return [];
Línea 650... Línea 651...
650
        }
651
        }
-
 
652
 
-
 
653
        $decodedKeys = array_map(function ($k): string {
Línea 651... Línea 654...
651
 
654
            return rawurldecode((string) $k);
652
        $decodedKeys = array_map('rawurldecode', $keys);
655
        }, $keys);
653
 
656
 
654
        return array_filter(explode('&', $current), function ($part) use ($decodedKeys) {
657
        return array_filter(explode('&', $current), function ($part) use ($decodedKeys) {
Línea 662... Línea 665...
662
        // (while preventing double-encoding) before setting the query string. All other
665
        // (while preventing double-encoding) before setting the query string. All other
663
        // chars that need percent-encoding will be encoded by withQuery().
666
        // chars that need percent-encoding will be encoded by withQuery().
664
        $queryString = strtr($key, self::QUERY_SEPARATORS_REPLACEMENT);
667
        $queryString = strtr($key, self::QUERY_SEPARATORS_REPLACEMENT);
Línea 665... Línea 668...
665
 
668
 
666
        if ($value !== null) {
669
        if ($value !== null) {
667
            $queryString .= '=' . strtr($value, self::QUERY_SEPARATORS_REPLACEMENT);
670
            $queryString .= '='.strtr($value, self::QUERY_SEPARATORS_REPLACEMENT);
Línea 668... Línea 671...
668
        }
671
        }
669
 
672
 
Línea 689... Línea 692...
689
        if (!is_string($path)) {
692
        if (!is_string($path)) {
690
            throw new \InvalidArgumentException('Path must be a string');
693
            throw new \InvalidArgumentException('Path must be a string');
691
        }
694
        }
Línea 692... Línea 695...
692
 
695
 
693
        return preg_replace_callback(
696
        return preg_replace_callback(
694
            '/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/',
697
            '/(?:[^'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.'%:@\/]++|%(?![A-Fa-f0-9]{2}))/',
695
            [$this, 'rawurlencodeMatchZero'],
698
            [$this, 'rawurlencodeMatchZero'],
696
            $path
699
            $path
697
        );
700
        );
Línea 709... Línea 712...
709
        if (!is_string($str)) {
712
        if (!is_string($str)) {
710
            throw new \InvalidArgumentException('Query and fragment must be a string');
713
            throw new \InvalidArgumentException('Query and fragment must be a string');
711
        }
714
        }
Línea 712... Línea 715...
712
 
715
 
713
        return preg_replace_callback(
716
        return preg_replace_callback(
714
            '/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/',
717
            '/(?:[^'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.'%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/',
715
            [$this, 'rawurlencodeMatchZero'],
718
            [$this, 'rawurlencodeMatchZero'],
716
            $str
719
            $str
717
        );
720
        );