origin = 'https://' . strtolower($parts['host']) . (isset($parts['port']) && $parts['port'] !== 443 ? ':' . $parts['port'] : ''); $this->url = $this->origin . rtrim($parts['path'] ?? '', '/'); } public function discoveryUrl(): string { return $this->url . '/hosting/discovery'; } public function assertTrustedAction(string $url): void { $plain = preg_replace('/<[^<>]*>/', '', $url); $parts = parse_url($plain); if ($parts === false || isset($parts['user']) || isset($parts['pass']) || isset($parts['fragment']) || preg_match('/[\x00-\x20\x7f\\\\<>]/', $plain) || filter_var($plain, FILTER_VALIDATE_URL) === false) { throw new InvalidArgumentException('Discovery contains an invalid action URL.'); } $origin = strtolower($parts['scheme'] ?? '') . '://' . strtolower($parts['host'] ?? '') . (isset($parts['port']) && $parts['port'] !== 443 ? ':' . $parts['port'] : ''); if ($origin !== $this->origin) { throw new InvalidArgumentException('Discovery action URL is outside the configured HTTPS server origin.'); } } }