Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.55% covered (success)
97.55%
159 / 163
66.67% covered (warning)
66.67%
8 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
UrlUtils
97.55% covered (success)
97.55%
159 / 163
66.67% covered (warning)
66.67%
8 / 12
90
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
14
 expand
97.22% covered (success)
97.22%
35 / 36
0.00% covered (danger)
0.00%
0 / 1
20
 getServer
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 getCanonicalServer
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 assemble
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
1 / 1
11
 removeDotSegments
100.00% covered (success)
100.00%
39 / 39
100.00% covered (success)
100.00%
1 / 1
18
 validProtocols
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 validAbsoluteProtocols
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 validProtocolsInternal
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
5
 parse
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
10
 expandIRI
87.50% covered (warning)
87.50%
7 / 8
0.00% covered (danger)
0.00%
0 / 1
2.01
 matchesDomainList
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2
3namespace MediaWiki\Utils;
4
5use BadMethodCallException;
6use InvalidArgumentException;
7use MediaWiki\Debug\MWDebug;
8use MediaWiki\MainConfigSchema;
9
10/**
11 * A service to expand, parse, and otherwise manipulate URLs.
12 *
13 * @since 1.39
14 * @newable
15 */
16class UrlUtils {
17    public const SERVER = 'server';
18    public const CANONICAL_SERVER = 'canonicalServer';
19    public const INTERNAL_SERVER = 'internalServer';
20    public const FALLBACK_PROTOCOL = 'fallbackProtocol';
21    public const HTTPS_PORT = 'httpsPort';
22    public const VALID_PROTOCOLS = 'validProtocols';
23
24    /** @var ?string */
25    private $server = null;
26
27    /** @var ?string */
28    private $canonicalServer = null;
29
30    /** @var ?string */
31    private $internalServer = null;
32    /** @var string */
33    private $fallbackProtocol = 'http';
34
35    /** @var int */
36    private $httpsPort = 443;
37
38    /** @var array */
39    private $validProtocols = MainConfigSchema::UrlProtocols['default'];
40
41    /** @var ?string */
42    private $validProtocolsCache = null;
43
44    /** @var ?string */
45    private $validAbsoluteProtocolsCache = null;
46
47    /**
48     * @stable to call
49     * @param array $options All keys are optional, but if you omit SERVER then calling expand()
50     *   (and getServer(), expandIRI(), and matchesDomainList()) will throw. Recognized keys:
51     *     * self::SERVER: The protocol and server portion of the URLs to expand, with no other parts
52     *       (port, path, etc.). Example: 'https://example.com'. Protocol-relative URLs are
53     *       allowed.
54     *     * self::CANONICAL_SERVER: If SERVER is protocol-relative, this can be set to a
55     *       fully-qualified version for use when PROTO_CANONICAL is passed to expand(). Defaults
56     *       to SERVER, with 'http:' prepended if SERVER is protocol-relative.
57     *     * self::INTERNAL_SERVER: An alternative to SERVER that's used when PROTO_INTERNAL is
58     *       passed to expand(). It's intended for sites that have a different server name exposed
59     *       to CDNs. Defaults to SERVER.
60     *     * self::FALLBACK_PROTOCOL: Used by expand() when no $defaultProto parameter is provided.
61     *       Defaults to 'http'. The instance created by ServiceWiring sets this to 'https' if the
62     *       current request is detected to be via HTTPS, and 'http' otherwise.
63     *     * self::HTTPS_PORT: Defaults to 443. Used when a protocol-relative URL is expanded to
64     *       https.
65     *     * self::VALID_PROTOCOLS: An array of recognized URL protocols. The default can be found
66     *       in MainConfigSchema::UrlProtocols['default'].
67     */
68    public function __construct( array $options = [] ) {
69        foreach ( $options as $key => $value ) {
70            switch ( $key ) {
71                case self::SERVER:
72                case self::CANONICAL_SERVER:
73                case self::INTERNAL_SERVER:
74                case self::FALLBACK_PROTOCOL:
75                case self::HTTPS_PORT:
76                case self::VALID_PROTOCOLS:
77                    $this->$key = $value;
78                    break;
79
80                default:
81                    throw new InvalidArgumentException( "Unrecognized option \"$key\"" );
82            }
83        }
84
85        if ( $this->server !== null ) {
86            if ( $this->canonicalServer === null || $this->canonicalServer === false ) {
87                $this->canonicalServer = $this->expand( $this->server, PROTO_HTTP );
88            }