getScheme() !== $modified->getScheme()) { return true; } if (self::computePort($original) !== self::computePort($modified)) { return true; } return false; } private static function normalizeHost(UriInterface $uri): string { $host = $uri->getHost(); if (!str_starts_with($host, '[') || !str_ends_with($host, ']')) { return $host; } // Foreign UriInterface implementations may carry non-canonical IPv6 // spellings; canonicalize what is unambiguously an IPv6 address so // equivalent literals compare as same-origin, and leave IPvFuture, // zone-identifier, and invalid text to the caseless textual // comparison. Validation is platform-independent, so a spelling only // some OS parsers accept, such as zero-padded dotted octets, is // cross-origin everywhere instead of same-origin on some systems. $canonical = Rfc3986::tryCanonicalizeIpv6(substr($host, 1, -1)); if ($canonical === null) { return $host; } return '['.$canonical.']'; } private static function computePort(UriInterface $uri): ?int { $port = $uri->getPort(); if (null !== $port) { return $port; } if (\in_array($uri->getScheme(), ['http', 'ws'], true)) { return 80; } if (\in_array($uri->getScheme(), ['https', 'wss'], true)) { return 443; } return null; } private function __construct() { // cannot be instantiated } }