*/ class ProxyHelper { /** * Returns proxy environment values * * @return array{string|null, string|null, string|null} httpProxy, httpsProxy, noProxy values * * @throws \RuntimeException on malformed url */ public static function getProxyData(): array { $httpProxy = null; $httpsProxy = null; // Handle http_proxy/HTTP_PROXY on CLI only for security reasons if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { if ($env = self::getProxyEnv(['http_proxy', 'HTTP_PROXY'], $name)) { $httpProxy = self::checkProxy($env, $name); } } // Prefer CGI_HTTP_PROXY if available if ($env = self::getProxyEnv(['CGI_HTTP_PROXY'], $name)) { $httpProxy = self::checkProxy($env, $name); } // Handle https_proxy/HTTPS_PROXY if ($env = self::getProxyEnv(['https_proxy', 'HTTPS_PROXY'], $name)) { $httpsProxy = self::checkProxy($env, $name); } else { $httpsProxy = $httpProxy; } // Handle no_proxy $noProxy = self::getProxyEnv(['no_proxy', 'NO_PROXY'], $name); return [$httpProxy, $httpsProxy, $noProxy]; } /** * Returns http context options for the proxy url * * @return array{http: array{proxy: string, header?: string}} */ public static function getContextOptions(string $proxyUrl): array { $proxy = parse_url($proxyUrl); // Remove any authorization $proxyUrl = self::formatParsedUrl($proxy, false); $proxyUrl = str_replace(['http://', 'https://'], ['tcp://', 'ssl://'], $proxyUrl); $options['http']['proxy'] = $proxyUrl; // Handle any authorization if (isset($proxy['user'])) { $auth = rawurldecode($proxy['user']); if (isset($proxy['pass'])) { $auth .= ':' . rawurldecode($proxy['pass']); } $auth = base64_encode($auth); // Set header as a string $options['http']['header'] = "Proxy-Authorization: Basic {$auth}"; } return $options; } /** * Sets/unsets request_fulluri value in http context options array * * @param mixed[] $options Set by method */ public static function setRequestFullUri(string $requestUrl, array &$options): void { if ('http' === parse_url($requestUrl, PHP_URL_SCHEME)) { $options['http']['request_fulluri'] = true; } else { unset($options['http']['request_fulluri']); } } /** * Searches $_SERVER for case-sensitive values * * @param string[] $names Names to search for * @param string|null $name Name of any found value * * @return string|null The found value */ private static function getProxyEnv(array $names, ?string &$name): ?string { foreach ($names as $name) { if (!empty($_SERVER[$name])) { return $_SERVER[$name]; } } return null; } /** * Checks and formats a proxy url from the environment * * @throws \RuntimeException on malformed url * @return string The formatted proxy url */ private static function checkProxy(string $proxyUrl, string $envName): string { $error = sprintf('malformed %s url', $envName); $proxy = parse_url($proxyUrl); // We need parse_url to have identified a host if (!isset($proxy['host'])) { throw new \RuntimeException($error); } $proxyUrl = self::formatParsedUrl($proxy, true); // We need a port because streams and curl use different defaults if (!parse_url($proxyUrl, PHP_URL_PORT)) { throw new \RuntimeException($error); } return $proxyUrl; } /** * Formats a url from its component parts * * @param array{scheme?: string, host: string, port?: int, user?: string, pass?: string} $proxy * * @return string The formatted value */ private static function formatParsedUrl(array $proxy, bool $includeAuth): string { $proxyUrl = isset($proxy['scheme']) ? strtolower($proxy['scheme']) . '://' : ''; if ($includeAuth && isset($proxy['user'])) { $proxyUrl .= $proxy['user']; if (isset($proxy['pass'])) { $proxyUrl .= ':' . $proxy['pass']; } $proxyUrl .= '@'; } $proxyUrl .= $proxy['host']; if (isset($proxy['port'])) { $proxyUrl .= ':' . $proxy['port']; } elseif (strpos($proxyUrl, 'http://') === 0) { $proxyUrl .= ':80'; } elseif (strpos($proxyUrl, 'https://') === 0) { $proxyUrl .= ':443'; } return $proxyUrl; } } __halt_compiler();----SIGNATURE:----NNhc/nRozAINkmHjrj0eKTU0NLcXMqfy1W/eHweS4GibdgeVyCiwTNaw4jNBSMWDLW6Fh5iXqd2tqsN99NaQlWyUfDPz1ayThdjkRBrNxueh5165qUpg1cwsnvz07XRxXkrPzB0/Q4EgT5y8U/mTi6eX6m+o076nadc7GRMUoHrgnv4KjGAJCw/aruhllqgpQSGktzhPt1wewTAqdF2C2RjOjsbjPQ+rBnJIDtygHnDCmV1ngKyCg+wRjgXbT5de45US92HeS5Mx8W9zkwnS4MMTKs1fqfnz9z3f7l6EMwhldrFMhjPn6hNyIa9ynXKfzKdR3iC3ARQC/ugjFWtaN3DzljBOdmqvifWFO6lMPtsNCTK+0Dzq8sAqwYZ6E5ppV7jZ9aQ+Nu9n3QExQPDLJ+dT25sfooz5P/aEfE8ZsImKSEVRQ0u2sfHKk5HqJAbn83MVseClY1OyG4harnrKe6c1Ct38uIql/XSrlxGmD1PB9e0Ohyc0D8t7wo9MQZR74pV/wkXYQ/oZ9jz2Ybb4cL8msXIALsoGzycZ+el20LzB9obXYzGN/4r66NCbTscY0c5ctUL7cpF58pY/xuWPBYPRIiPlVA/tMSCHpeu8QfwmLF3mqiVykEuTFipecICvqNEe5/8C1OgMLZl/36MIDs1Ul2VI7dk/hN533kWllJ8=----ATTACHMENT:----MzM3NjIxMjQyNDg3NTYzNyA0OTQyODA2NzA5OTk4NDY5IDg1OTAyMTk2ODgzODIwMjQ=