| 1 |
<?php |
| 2 |
|
| 3 |
declare (strict_types=1); |
| 4 |
namespace WCPOS\Vendor\GuzzleHttp\Psr7; |
| 5 |
|
| 6 |
use WCPOS\Vendor\Psr\Http\Message\UriInterface; |
| 7 |
/** |
| 8 |
* Provides methods to determine if a modified URI should be considered |
| 9 |
* cross-origin. |
| 10 |
* |
| 11 |
* @author Graham Campbell |
| 12 |
*/ |
| 13 |
final class UriComparator |
| 14 |
{ |
| 15 |
/** |
| 16 |
* Determines if a modified URI should be considered cross-origin with |
| 17 |
* respect to an original URI. |
| 18 |
* |
| 19 |
* Two URIs are cross-origin when their scheme, host, or effective port |
| 20 |
* differ. Host comparison is case-insensitive, and bracketed IPv6 literals |
| 21 |
* are canonicalized to their RFC 5952 form from any PSR-7 implementation |
| 22 |
* before comparison, so equivalent spellings of the same address are |
| 23 |
* same-origin. IPvFuture literals and bracketed values that cannot be |
| 24 |
* parsed as an IPv6 address, such as those carrying zone identifiers, |
| 25 |
* still compare as case-insensitive text. Missing ports use the default |
| 26 |
* port for `http`, `https`, `ws`, or `wss`. Other schemes do not receive |
| 27 |
* implicit default ports. |
| 28 |
* |
| 29 |
* This helper only compares URI origins. It does not implement redirect |
| 30 |
* handling or credential policy. |
| 31 |
*/ |
| 32 |
public static function isCrossOrigin(UriInterface $original, UriInterface $modified) : bool |
| 33 |
{ |
| 34 |
if (!Utils::caselessEquals(self::normalizeHost($original), self::normalizeHost($modified))) { |
| 35 |
return \true; |
| 36 |
} |
| 37 |
if ($original->getScheme() !== $modified->getScheme()) { |
| 38 |
return \true; |
| 39 |
} |
| 40 |
if (self::computePort($original) !== self::computePort($modified)) { |
| 41 |
return \true; |
| 42 |
} |
| 43 |
return \false; |
| 44 |
} |
| 45 |
private static function normalizeHost(UriInterface $uri) : string |
| 46 |
{ |
| 47 |
$host = $uri->getHost(); |
| 48 |
if (!\str_starts_with($host, '[') || !\str_ends_with($host, ']')) { |
| 49 |
return $host; |
| 50 |
} |
| 51 |
// Foreign UriInterface implementations may carry non-canonical IPv6 |
| 52 |
// spellings; canonicalize what is unambiguously an IPv6 address so |
| 53 |
// equivalent literals compare as same-origin, and leave IPvFuture, |
| 54 |
// zone-identifier, and invalid text to the caseless textual |
| 55 |
// comparison. Validation is platform-independent, so a spelling only |
| 56 |
// some OS parsers accept, such as zero-padded dotted octets, is |
| 57 |
// cross-origin everywhere instead of same-origin on some systems. |
| 58 |
$canonical = Rfc3986::tryCanonicalizeIpv6(\substr($host, 1, -1)); |
| 59 |
if ($canonical === null) { |
| 60 |
return $host; |
| 61 |
} |
| 62 |
return '[' . $canonical . ']'; |
| 63 |
} |
| 64 |
private static function computePort(UriInterface $uri) : ?int |
| 65 |
{ |
| 66 |
$port = $uri->getPort(); |
| 67 |
if (null !== $port) { |
| 68 |
return $port; |
| 69 |
} |
| 70 |
if (\in_array($uri->getScheme(), ['http', 'ws'], \true)) { |
| 71 |
return 80; |
| 72 |
} |
| 73 |
if (\in_array($uri->getScheme(), ['https', 'wss'], \true)) { |
| 74 |
return 443; |
| 75 |
} |
| 76 |
return null; |
| 77 |
} |
| 78 |
private function __construct() |
| 79 |
{ |
| 80 |
// cannot be instantiated |
| 81 |
} |
| 82 |
} |
| 83 |
|