Skip to content

Commit

Permalink
Do not use proxy by default
Browse files Browse the repository at this point in the history
- By default, does not search X-Forwarded-Host
  - If "use proxy" flag is enabled, it will
- Pushed header detection to last possible moment, to allow specifying
  the proxy flag
  • Loading branch information
weierophinney committed Nov 29, 2012
1 parent ada1fab commit 1040aca
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 22 deletions.
106 changes: 84 additions & 22 deletions library/Zend/View/Helper/ServerUrl.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ class ServerUrl extends AbstractHelper
*/
protected $host;

/**
* Whether or not to query proxy servers for address
*
* @var bool
*/
protected $useProxy = false;

/**
* Constructor
*
Expand All @@ -46,30 +53,10 @@ public function __construct()
$scheme = 'https';
break;
default:
$scheme = 'http';
$scheme = 'http';
break;
}
$this->setScheme($scheme);

if (isset($_SERVER['HTTP_X_FORWARDED_HOST']) && !empty($_SERVER['HTTP_X_FORWARDED_HOST'])) {
$host = $_SERVER['HTTP_X_FORWARDED_HOST'];
if (strpos($host, ',') !== false) {
$hosts = explode(',', $host);
$host = trim(array_pop($hosts));
}
$this->setHost($host);
} elseif (isset($_SERVER['HTTP_HOST']) && !empty($_SERVER['HTTP_HOST'])) {
$this->setHost($_SERVER['HTTP_HOST']);
} elseif (isset($_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'])) {
$name = $_SERVER['SERVER_NAME'];
$port = $_SERVER['SERVER_PORT'];

if (($scheme == 'http' && $port == 80) ||
($scheme == 'https' && $port == 443)) {
$this->setHost($name);
} else {
$this->setHost($name . ':' . $port);
}
}
}

/**
Expand Down Expand Up @@ -103,6 +90,9 @@ public function __invoke($requestUri = null)
*/
public function getHost()
{
if (null === $this->host) {
$this->detectHost();
}
return $this->host;
}

Expand Down Expand Up @@ -139,4 +129,76 @@ public function setScheme($scheme)
$this->scheme = $scheme;
return $this;
}

/**
* 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;
}

/**
* Detect the host based on headers
*
* @return void
*/
protected function detectHost()
{
if ($this->setHostFromProxy()) {
return;
}

if (isset($_SERVER['HTTP_HOST']) && !empty($_SERVER['HTTP_HOST'])) {
$this->setHost($_SERVER['HTTP_HOST']);
return;
}

if (!isset($_SERVER['SERVER_NAME']) || !isset($_SERVER['SERVER_PORT'])) {
return;
}

$scheme = $this->getScheme();
$name = $_SERVER['SERVER_NAME'];
$port = $_SERVER['SERVER_PORT'];

if (($scheme == 'http' && $port == 80) ||
($scheme == 'https' && $port == 443)) {
$this->setHost($name);
return;
}

$this->setHost($name . ':' . $port);
}

/**
* 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;
}
}
10 changes: 10 additions & 0 deletions tests/ZendTest/View/Helper/ServerUrlTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ public function testServerUrlWithProxy()
$_SERVER['HTTP_HOST'] = 'proxyserver.com';
$_SERVER['HTTP_X_FORWARDED_HOST'] = 'www.firsthost.org';
$url = new Helper\ServerUrl();
$url->setUseProxy(true);
$this->assertEquals('http://www.firsthost.org', $url->__invoke());
}

Expand All @@ -181,6 +182,15 @@ public function testServerUrlWithMultipleProxies()
$_SERVER['HTTP_HOST'] = 'proxyserver.com';
$_SERVER['HTTP_X_FORWARDED_HOST'] = 'www.firsthost.org, www.secondhost.org';
$url = new Helper\ServerUrl();
$url->setUseProxy(true);
$this->assertEquals('http://www.secondhost.org', $url->__invoke());
}

public function testDoesNotUseProxyByDefault()
{
$_SERVER['HTTP_HOST'] = 'proxyserver.com';
$_SERVER['HTTP_X_FORWARDED_HOST'] = 'www.firsthost.org, www.secondhost.org';
$url = new Helper\ServerUrl();
$this->assertEquals('http://proxyserver.com', $url->__invoke());
}
}

0 comments on commit 1040aca

Please sign in to comment.