Author: Kris.Wallsmith
Date: 2010-09-13 19:31:37 +0200 (Mon, 13 Sep 2010)
New Revision: 30900
Modified:
branches/1.3/lib/request/sfWebRequest.class.php
branches/1.3/test/unit/request/sfWebRequestTest.php
branches/1.4/lib/request/sfWebRequest.class.php
branches/1.4/test/unit/request/sfWebRequestTest.php
Log:
[1.3, 1.4] fixed getUriPrefix() when requested is forwarded from a secure one
(closes #4723)
Modified: branches/1.3/lib/request/sfWebRequest.class.php
===================================================================
--- branches/1.3/lib/request/sfWebRequest.class.php 2010-09-13 17:15:38 UTC
(rev 30899)
+++ branches/1.3/lib/request/sfWebRequest.class.php 2010-09-13 17:31:37 UTC
(rev 30900)
@@ -22,6 +22,10 @@
*/
class sfWebRequest extends sfRequest
{
+ const
+ PORT_HTTP = 80,
+ PORT_HTTPS = 443;
+
protected
$languages = null,
$charsets = null,
@@ -44,6 +48,8 @@
* * path_info_key: The path info key (default to PATH_INFO)
* * path_info_array: The path info array (default to SERVER)
* * relative_url_root: The relative URL root
+ * * http_port: The port to use for HTTP requests
+ * * https_port: The port to use for HTTPS requests
*
* @param sfEventDispatcher $dispatcher An sfEventDispatcher instance
* @param array $parameters An associative array of
initialization parameters
@@ -61,6 +67,8 @@
$options = array_merge(array(
'path_info_key' => 'PATH_INFO',
'path_info_array' => 'SERVER',
+ 'http_port' => null,
+ 'https_port' => null,
'default_format' => null, // to maintain bc
), $options);
parent::initialize($dispatcher, $parameters, $attributes, $options);
@@ -206,29 +214,38 @@
public function getUriPrefix()
{
$pathArray = $this->getPathInfoArray();
- if ($this->isSecure())
+ $secure = $this->isSecure();
+
+ $protocol = $secure ? 'https' : 'http';
+ $host = $this->getHost();
+ $port = null;
+
+ // extract port from host or environment variable
+ if (false !== strpos($host, ':'))
{
- $standardPort = '443';
- $protocol = 'https';
+ list($host, $port) = explode(':', $host, 2);
}
- else
+ else if (isset($this->options[$protocol.'_port']))
{
- $standardPort = '80';
- $protocol = 'http';
+ $port = $this->options[$protocol.'_port'];
}
-
- $host = explode(':', $this->getHost());
- if (count($host) == 1)
+ else if (isset($pathArray['SERVER_PORT']))
{
- $host[] = isset($pathArray['SERVER_PORT']) ? $pathArray['SERVER_PORT'] :
'';
+ $port = $pathArray['SERVER_PORT'];
}
- if ($host[1] == $standardPort || empty($host[1]))
+ // cleanup the port based on whether the current request is forwarded from
+ // a secure one and whether the introspected port matches the standard one
+ if ($this->isForwardedSecure())
{
- unset($host[1]);
+ $port = isset($this->options['https_port']) && self::PORT_HTTPS !=
$this->options['https_port'] ? $this->options['https_port'] : null;
}
+ elseif (($secure && self::PORT_HTTPS == $port) || (!$secure &&
self::PORT_HTTP == $port))
+ {
+ $port = null;
+ }
- return $protocol.'://'.implode(':', $host);
+ return sprintf('%s://%s%s', $protocol, $host, $port ? ':'.$port : '');
}
/**
@@ -553,7 +570,7 @@
}
/**
- * Returns true if the current request is secure (HTTPS protocol).
+ * Returns true if the current or forwarded request is secure (HTTPS
protocol).
*
* @return boolean
*/
@@ -561,16 +578,28 @@
{
$pathArray = $this->getPathInfoArray();
- return (
- (isset($pathArray['HTTPS']) && (strtolower($pathArray['HTTPS']) == 'on'
|| $pathArray['HTTPS'] == 1))
+ return
+ (isset($pathArray['HTTPS']) && ('on' == strtolower($pathArray['HTTPS'])
|| 1 == $pathArray['HTTPS']))
||
- (isset($pathArray['HTTP_SSL_HTTPS']) &&
(strtolower($pathArray['HTTP_SSL_HTTPS']) == 'on' ||
$pathArray['HTTP_SSL_HTTPS'] == 1))
+ (isset($pathArray['HTTP_SSL_HTTPS']) && ('on' ==
strtolower($pathArray['HTTP_SSL_HTTPS']) || 1 == $pathArray['HTTP_SSL_HTTPS']))
||
- (isset($pathArray['HTTP_X_FORWARDED_PROTO']) &&
strtolower($pathArray['HTTP_X_FORWARDED_PROTO']) == 'https')
- );
+ $this->isForwardedSecure()
+ ;
}
/**
+ * Returns true if the current request is forwarded from a request that is
secure.
+ *
+ * @return boolean
+ */
+ protected function isForwardedSecure()
+ {
+ $pathArray = $this->getPathInfoArray();
+
+ return isset($pathArray['HTTP_X_FORWARDED_PROTO']) && 'https' ==
strtolower($pathArray['HTTP_X_FORWARDED_PROTO']);
+ }
+
+ /**
* Retrieves relative root url.
*
* @return string URL
Modified: branches/1.3/test/unit/request/sfWebRequestTest.php
===================================================================
--- branches/1.3/test/unit/request/sfWebRequestTest.php 2010-09-13 17:15:38 UTC
(rev 30899)
+++ branches/1.3/test/unit/request/sfWebRequestTest.php 2010-09-13 17:31:37 UTC
(rev 30900)
@@ -10,7 +10,7 @@
require_once(dirname(__FILE__).'/../../bootstrap/unit.php');
-$t = new lime_test(65);
+$t = new lime_test(71);
class myRequest extends sfWebRequest
{
@@ -32,6 +32,11 @@
$this->resetPathInfoArray();
}
+ public function setOption($key, $value)
+ {
+ $this->options[$key] = $value;
+ }
+
public function resetPathInfoArray()
{
foreach (array_diff(array_keys($this->getPathInfoArray()),
self::$initialPathArrayKeys) as $key)
@@ -161,6 +166,7 @@
// ->getUriPrefix()
$t->diag('->getUriPrefix()');
+$request->resetPathInfoArray();
$_SERVER['SERVER_PORT'] = '80';
$_SERVER['HTTP_HOST'] = 'symfony-project.org:80';
$t->is($request->getUriPrefix(), 'http://symfony-project.org',
'->getUriPrefix() returns no port for standard http port');
@@ -169,6 +175,7 @@
$_SERVER['HTTP_HOST'] = 'symfony-project.org:8088';
$t->is($request->getUriPrefix(), 'http://symfony-project.org:8088',
'->getUriPrefix() works for nonstandard http ports');
+$request->resetPathInfoArray();
$_SERVER['HTTPS'] = 'on';
$_SERVER['SERVER_PORT'] = '443';
$_SERVER['HTTP_HOST'] = 'symfony-project.org:443';
@@ -178,6 +185,45 @@
$_SERVER['HTTP_HOST'] = 'symfony-project.org:8043';
$t->is($request->getUriPrefix(), 'https://symfony-project.org:8043',
'->getUriPrefix() works for nonstandard https ports');
+$request->resetPathInfoArray();
+$_SERVER['HTTP_HOST'] = 'symfony-project.org';
+$_SERVER['SERVER_PORT'] = '8080';
+$t->is($request->getUriPrefix(), 'http://symfony-project.org:8080',
'->getUriPrefix() uses the "SERVER_PORT" environment variable');
+
+$request->resetPathInfoArray();
+$_SERVER['HTTPS'] = 'on';
+$_SERVER['HTTP_HOST'] = 'symfony-project.org';
+$_SERVER['SERVER_PORT'] = '8043';
+$t->is($request->getUriPrefix(), 'https://symfony-project.org:8043',
'->getUriPrefix() uses the "SERVER_PORT" environment variable');
+
+$request->resetPathInfoArray();
+$request->setOption('http_port', '8080');
+$_SERVER['HTTP_HOST'] = 'symfony-project.org';
+$t->is($request->getUriPrefix(), 'http://symfony-project.org:8080',
'->getUriPrefix() uses the configured port');
+$request->setOption('http_port', null);
+
+$request->resetPathInfoArray();
+$request->setOption('https_port', '8043');
+$_SERVER['HTTPS'] = 'on';
+$_SERVER['HTTP_HOST'] = 'symfony-project.org';
+$t->is($request->getUriPrefix(), 'https://symfony-project.org:8043',
'->getUriPrefix() uses the configured port');
+$request->setOption('https_port', null);
+
+$request->resetPathInfoArray();
+$_SERVER['HTTP_HOST'] = 'symfony-project.org';
+$_SERVER['SERVER_PORT'] = '80';
+$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https';
+$t->is($request->getUriPrefix(), 'https://symfony-project.org',
'->getUriPrefix() works on secure requests forwarded as non-secure requests');
+
+$request->resetPathInfoArray();
+$request->setOption('https_port', '8043');
+$_SERVER['HTTP_HOST'] = 'symfony-project.org';
+$_SERVER['SERVER_PORT'] = '80';
+$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https';
+$t->is($request->getUriPrefix(), 'https://symfony-project.org:8043',
'->getUriPrefix() uses the configured port on secure requests forwarded as
non-secure requests');
+
+$request->resetPathInfoArray();
+
// ->getRemoteAddress()
$t->diag('->getRemoteAddress()');
Modified: branches/1.4/lib/request/sfWebRequest.class.php
===================================================================
--- branches/1.4/lib/request/sfWebRequest.class.php 2010-09-13 17:15:38 UTC
(rev 30899)
+++ branches/1.4/lib/request/sfWebRequest.class.php 2010-09-13 17:31:37 UTC
(rev 30900)
@@ -22,6 +22,10 @@
*/
class sfWebRequest extends sfRequest
{
+ const
+ PORT_HTTP = 80,
+ PORT_HTTPS = 443;
+
protected
$languages = null,
$charsets = null,
@@ -44,6 +48,8 @@
* * path_info_key: The path info key (default to PATH_INFO)
* * path_info_array: The path info array (default to SERVER)
* * relative_url_root: The relative URL root
+ * * http_port: The port to use for HTTP requests
+ * * https_port: The port to use for HTTPS requests
*
* @param sfEventDispatcher $dispatcher An sfEventDispatcher instance
* @param array $parameters An associative array of
initialization parameters
@@ -61,6 +67,8 @@
$options = array_merge(array(
'path_info_key' => 'PATH_INFO',
'path_info_array' => 'SERVER',
+ 'http_port' => null,
+ 'https_port' => null,
'default_format' => null, // to maintain bc
), $options);
parent::initialize($dispatcher, $parameters, $attributes, $options);
@@ -206,29 +214,38 @@
public function getUriPrefix()
{
$pathArray = $this->getPathInfoArray();
- if ($this->isSecure())
+ $secure = $this->isSecure();
+
+ $protocol = $secure ? 'https' : 'http';
+ $host = $this->getHost();
+ $port = null;
+
+ // extract port from host or environment variable
+ if (false !== strpos($host, ':'))
{
- $standardPort = '443';
- $protocol = 'https';
+ list($host, $port) = explode(':', $host, 2);
}
- else
+ else if (isset($this->options[$protocol.'_port']))
{
- $standardPort = '80';
- $protocol = 'http';
+ $port = $this->options[$protocol.'_port'];
}
-
- $host = explode(':', $this->getHost());
- if (count($host) == 1)
+ else if (isset($pathArray['SERVER_PORT']))
{
- $host[] = isset($pathArray['SERVER_PORT']) ? $pathArray['SERVER_PORT'] :
'';
+ $port = $pathArray['SERVER_PORT'];
}
- if ($host[1] == $standardPort || empty($host[1]))
+ // cleanup the port based on whether the current request is forwarded from
+ // a secure one and whether the introspected port matches the standard one
+ if ($this->isForwardedSecure())
{
- unset($host[1]);
+ $port = isset($this->options['https_port']) && self::PORT_HTTPS !=
$this->options['https_port'] ? $this->options['https_port'] : null;
}
+ elseif (($secure && self::PORT_HTTPS == $port) || (!$secure &&
self::PORT_HTTP == $port))
+ {
+ $port = null;
+ }
- return $protocol.'://'.implode(':', $host);
+ return sprintf('%s://%s%s', $protocol, $host, $port ? ':'.$port : '');
}
/**
@@ -538,7 +555,7 @@
}
/**
- * Returns true if the current request is secure (HTTPS protocol).
+ * Returns true if the current or forwarded request is secure (HTTPS
protocol).
*
* @return boolean
*/
@@ -546,16 +563,28 @@
{
$pathArray = $this->getPathInfoArray();
- return (
- (isset($pathArray['HTTPS']) && (strtolower($pathArray['HTTPS']) == 'on'
|| $pathArray['HTTPS'] == 1))
+ return
+ (isset($pathArray['HTTPS']) && ('on' == strtolower($pathArray['HTTPS'])
|| 1 == $pathArray['HTTPS']))
||
- (isset($pathArray['HTTP_SSL_HTTPS']) &&
(strtolower($pathArray['HTTP_SSL_HTTPS']) == 'on' ||
$pathArray['HTTP_SSL_HTTPS'] == 1))
+ (isset($pathArray['HTTP_SSL_HTTPS']) && ('on' ==
strtolower($pathArray['HTTP_SSL_HTTPS']) || 1 == $pathArray['HTTP_SSL_HTTPS']))
||
- (isset($pathArray['HTTP_X_FORWARDED_PROTO']) &&
strtolower($pathArray['HTTP_X_FORWARDED_PROTO']) == 'https')
- );
+ $this->isForwardedSecure()
+ ;
}
/**
+ * Returns true if the current request is forwarded from a request that is
secure.
+ *
+ * @return boolean
+ */
+ protected function isForwardedSecure()
+ {
+ $pathArray = $this->getPathInfoArray();
+
+ return isset($pathArray['HTTP_X_FORWARDED_PROTO']) && 'https' ==
strtolower($pathArray['HTTP_X_FORWARDED_PROTO']);
+ }
+
+ /**
* Retrieves relative root url.
*
* @return string URL
Modified: branches/1.4/test/unit/request/sfWebRequestTest.php
===================================================================
--- branches/1.4/test/unit/request/sfWebRequestTest.php 2010-09-13 17:15:38 UTC
(rev 30899)
+++ branches/1.4/test/unit/request/sfWebRequestTest.php 2010-09-13 17:31:37 UTC
(rev 30900)
@@ -10,7 +10,7 @@
require_once(dirname(__FILE__).'/../../bootstrap/unit.php');
-$t = new lime_test(65);
+$t = new lime_test(71);
class myRequest extends sfWebRequest
{
@@ -32,6 +32,11 @@
$this->resetPathInfoArray();
}
+ public function setOption($key, $value)
+ {
+ $this->options[$key] = $value;
+ }
+
public function resetPathInfoArray()
{
foreach (array_diff(array_keys($this->getPathInfoArray()),
self::$initialPathArrayKeys) as $key)
@@ -161,6 +166,7 @@
// ->getUriPrefix()
$t->diag('->getUriPrefix()');
+$request->resetPathInfoArray();
$_SERVER['SERVER_PORT'] = '80';
$_SERVER['HTTP_HOST'] = 'symfony-project.org:80';
$t->is($request->getUriPrefix(), 'http://symfony-project.org',
'->getUriPrefix() returns no port for standard http port');
@@ -169,6 +175,7 @@
$_SERVER['HTTP_HOST'] = 'symfony-project.org:8088';
$t->is($request->getUriPrefix(), 'http://symfony-project.org:8088',
'->getUriPrefix() works for nonstandard http ports');
+$request->resetPathInfoArray();
$_SERVER['HTTPS'] = 'on';
$_SERVER['SERVER_PORT'] = '443';
$_SERVER['HTTP_HOST'] = 'symfony-project.org:443';
@@ -178,6 +185,45 @@
$_SERVER['HTTP_HOST'] = 'symfony-project.org:8043';
$t->is($request->getUriPrefix(), 'https://symfony-project.org:8043',
'->getUriPrefix() works for nonstandard https ports');
+$request->resetPathInfoArray();
+$_SERVER['HTTP_HOST'] = 'symfony-project.org';
+$_SERVER['SERVER_PORT'] = '8080';
+$t->is($request->getUriPrefix(), 'http://symfony-project.org:8080',
'->getUriPrefix() uses the "SERVER_PORT" environment variable');
+
+$request->resetPathInfoArray();
+$_SERVER['HTTPS'] = 'on';
+$_SERVER['HTTP_HOST'] = 'symfony-project.org';
+$_SERVER['SERVER_PORT'] = '8043';
+$t->is($request->getUriPrefix(), 'https://symfony-project.org:8043',
'->getUriPrefix() uses the "SERVER_PORT" environment variable');
+
+$request->resetPathInfoArray();
+$request->setOption('http_port', '8080');
+$_SERVER['HTTP_HOST'] = 'symfony-project.org';
+$t->is($request->getUriPrefix(), 'http://symfony-project.org:8080',
'->getUriPrefix() uses the configured port');
+$request->setOption('http_port', null);
+
+$request->resetPathInfoArray();
+$request->setOption('https_port', '8043');
+$_SERVER['HTTPS'] = 'on';
+$_SERVER['HTTP_HOST'] = 'symfony-project.org';
+$t->is($request->getUriPrefix(), 'https://symfony-project.org:8043',
'->getUriPrefix() uses the configured port');
+$request->setOption('https_port', null);
+
+$request->resetPathInfoArray();
+$_SERVER['HTTP_HOST'] = 'symfony-project.org';
+$_SERVER['SERVER_PORT'] = '80';
+$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https';
+$t->is($request->getUriPrefix(), 'https://symfony-project.org',
'->getUriPrefix() works on secure requests forwarded as non-secure requests');
+
+$request->resetPathInfoArray();
+$request->setOption('https_port', '8043');
+$_SERVER['HTTP_HOST'] = 'symfony-project.org';
+$_SERVER['SERVER_PORT'] = '80';
+$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https';
+$t->is($request->getUriPrefix(), 'https://symfony-project.org:8043',
'->getUriPrefix() uses the configured port on secure requests forwarded as
non-secure requests');
+
+$request->resetPathInfoArray();
+
// ->getRemoteAddress()
$t->diag('->getRemoteAddress()');
--
You received this message because you are subscribed to the Google Groups
"symfony SVN" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/symfony-svn?hl=en.