*/ public static function provideForeignOrigin(): \Generator { $origins = [ // Any unrelated site embedding or fetching php.net. 'https://example.com', // Browsers send a literal "null" origin for sandboxed iframes, // documents from data:/file: URLs, and some cross-origin redirects. 'null', // Must not be treated as php.net just because it contains it. 'https://evil-php.net.attacker.com', 'https://notphp.net', ]; foreach ($origins as $origin) { yield $origin => [$origin]; } } /** * @return \Generator */ public static function provideAllowedOrigin(): \Generator { $origins = [ 'no Origin header' => null, 'https://www.php.net' => 'https://www.php.net', 'https://php.net' => 'https://php.net', 'https://qa.php.net' => 'https://qa.php.net', ]; foreach ($origins as $name => $origin) { yield $name => [$origin]; } } /** * @return \Generator */ public static function providePath(): \Generator { $paths = [ '/', '/downloads.php', '/contact.php', '/manual/en/function.str-replace.php', '/releases/', ]; foreach ($paths as $path) { yield $path => [$path]; } } /** * @return array{status: int, body: string, vary: string} */ private static function post(string $path, string $origin): array { return self::get($path, $origin, ['vote' => 'up']); } /** * @param ?array $postFields * * @return array{status: int, body: string, vary: string} */ private static function get( string $path, ?string $origin = null, ?array $postFields = null, ): array { $httpHost = getenv('HTTP_HOST'); if (!is_string($httpHost)) { throw new \RuntimeException('Environment variable "HTTP_HOST" is not set.'); } $headers = []; if (is_string($origin)) { $headers[] = sprintf('Origin: %s', $origin); } $vary = ''; $handle = curl_init(); if (is_array($postFields)) { curl_setopt($handle, CURLOPT_POST, true); curl_setopt($handle, CURLOPT_POSTFIELDS, http_build_query($postFields)); } curl_setopt_array($handle, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => $headers, CURLOPT_URL => sprintf('http://%s%s', $httpHost, $path), CURLOPT_HEADERFUNCTION => static function ($handle, string $header) use (&$vary): int { if (stripos($header, 'vary:') === 0) { $vary = trim(substr($header, strlen('vary:'))); } return strlen($header); }, ]); $body = curl_exec($handle); $status = curl_getinfo($handle, CURLINFO_HTTP_CODE); curl_close($handle); if (!is_string($body)) { throw new \RuntimeException(sprintf('Failed to request "%s".', $path)); } return [ 'status' => $status, 'body' => $body, 'vary' => $vary, ]; } }