![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/laminas/laminas-view/src/Helper/ |
<?php declare(strict_types=1); namespace Laminas\View\Helper; use function array_pop; use function explode; use function in_array; use function is_string; use function preg_match; use function strpos; use function strtolower; use function trim; /** * Helper for returning the current server URL (optionally with request URI) */ class ServerUrl extends AbstractHelper { /** * Host (including port) * * @var string|null */ protected $host; /** * Port * * @var int|null */ protected $port; /** * Scheme * * @var string|null */ protected $scheme; /** * Whether or not to query proxy servers for address * * @var bool */ protected $useProxy = false; /** * View helper entry point: * Returns the current host's URL like http://site.com * * @param string|bool $requestUri [optional] if true, the request URI * found in $_SERVER will be appended * as a path. If a string is given, it * will be appended as a path. Default * is to not append any path. * @return string */ public function __invoke($requestUri = null) { if ($requestUri === true) { $path = $_SERVER['REQUEST_URI']; } elseif (is_string($requestUri)) { $path = $requestUri; } else { $path = ''; } return $this->getScheme() . '://' . $this->getHost() . (string) $path; } /** * Detect the host based on headers * * @return void */ protected function detectHost() { if ($this->setHostFromProxy()) { return; } if (isset($_SERVER['HTTP_HOST']) && ! empty($_SERVER['HTTP_HOST'])) { // Detect if the port is set in SERVER_PORT and included in HTTP_HOST if ( isset($_SERVER['SERVER_PORT']) && preg_match('/^(?P<host>.*?):(?P<port>\d+)$/', $_SERVER['HTTP_HOST'], $matches) ) { // If they are the same, set the host to just the hostname // portion of the Host header. if ((int) $matches['port'] === (int) $_SERVER['SERVER_PORT']) { $this->setHost($matches['host']); return; } // At this point, we have a SERVER_PORT that differs from the // Host header, indicating we likely have a port-forwarding // situation. As such, we'll set the host and port from the // matched values. $this->setPort((int) $matches['port']); $this->setHost($matches['host']); return; } $this->setHost($_SERVER['HTTP_HOST']); return; } if (! isset($_SERVER['SERVER_NAME']) || ! isset($_SERVER['SERVER_PORT'])) { return; } $name = $_SERVER['SERVER_NAME']; $this->setHost($name); } /** * Detect the port */ protected function detectPort(): void { if ($this->setPortFromProxy()) { return; } if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT']) { if ($this->isReversedProxy()) { $this->setPort(443); return; } $this->setPort($_SERVER['SERVER_PORT']); } } /** * Detect the scheme */ protected function detectScheme(): void { if ($this->setSchemeFromProxy()) { return; } switch (true) { case isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] === true): case isset($_SERVER['HTTP_SCHEME']) && ($_SERVER['HTTP_SCHEME'] === 'https'): case 443 === $this->getPort(): case $this->isReversedProxy(): $scheme = 'https'; break; default: $scheme = 'http'; break; } $this->setScheme($scheme); } protected function isReversedProxy(): bool { return isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https'; } /** * Detect if a proxy is in use, and, if so, set the host based on it * * @return bool */ protected function setHostFromProxy() { if (! $this->useProxy) { return false; } if (! isset($_SERVER['HTTP_X_FORWARDED_HOST']) || empty($_SERVER['HTTP_X_FORWARDED_HOST'])) { return false; } $host = $_SERVER['HTTP_X_FORWARDED_HOST']; if (strpos($host, ',') !== false) { $hosts = explode(',', $host); $host = trim(array_pop($hosts)); } if (empty($host)) { return false; } $this->setHost($host); return true; } /** * Set port based on detected proxy headers * * @return bool */ protected function setPortFromProxy() { if (! $this->useProxy) { return false; } if (! isset($_SERVER['HTTP_X_FORWARDED_PORT']) || empty($_SERVER['HTTP_X_FORWARDED_PORT'])) { return false; } $port = $_SERVER['HTTP_X_FORWARDED_PORT']; $this->setPort($port); return true; } /** * Set the current scheme based on detected proxy headers * * @return bool */ protected function setSchemeFromProxy() { if (! $this->useProxy) { return false; } if (isset($_SERVER['SSL_HTTPS'])) { $sslHttps = strtolower($_SERVER['SSL_HTTPS']); if (in_array($sslHttps, ['on', 1])) { $this->setScheme('https'); return true; } } if (! isset($_SERVER['HTTP_X_FORWARDED_PROTO']) || empty($_SERVER['HTTP_X_FORWARDED_PROTO'])) { return false; } $scheme = trim(strtolower($_SERVER['HTTP_X_FORWARDED_PROTO'])); if (empty($scheme)) { return false; } $this->setScheme($scheme); return true; } /** * Sets host * * @param string $host * @return ServerUrl */ public function setHost($host) { $port = $this->getPort(); $scheme = $this->getScheme(); if ( ($scheme === 'http' && (null === $port || $port === 80)) || ($scheme === 'https' && (null === $port || $port === 443)) ) { $this->host = $host; return $this; } $this->host = $host . ':' . (string) $port; return $this; } /** * Returns host * * @return string */ public function getHost() { if (null === $this->host) { $this->detectHost(); } return $this->host; } /** * Set server port * * @param int|numeric-string $port * @return ServerUrl */ public function setPort($port) { $this->port = (int) $port; return $this; } /** * Retrieve the server port * * @return int|null */ public function getPort() { if (null === $this->port) { $this->detectPort(); } return $this->port; } /** * Sets scheme (typically http or https) * * @param string $scheme * @return ServerUrl */ public function setScheme($scheme) { $this->scheme = $scheme; return $this; } /** * Returns scheme (typically http or https) * * @return string */ public function getScheme() { if (null === $this->scheme) { $this->detectScheme(); } return $this->scheme; } /** * Set flag indicating whether or not to query proxy servers * * @param bool $useProxy * @return ServerUrl */ public function setUseProxy($useProxy = false) { $this->useProxy = (bool) $useProxy; return $this; } }