From 636aa66eb2384ce98c17aeb27d258dfd6958f7a9 Mon Sep 17 00:00:00 2001 From: Jaime Perez Crespo <jaime.perez@uninett.no> Date: Wed, 8 Jun 2016 10:03:22 +0200 Subject: [PATCH] Change the implementation of SimpleSAML\Utils\HTTP::getSelfURL() and getSelfURLNoQuery() to honor the 'baseurlpath' configuration option instead of simply using the environment. They were actually broken since they were using it to build the scheme, host and port, but completely ignoring the path, rendering wrong URLs in between what was configured in 'baseurlpath' and the real information in the environment. This resolves #396, but also affects #5. The changes to getSelfURLNoQuery() in #391 are unnecessary now, since we now basically getting the full URL and remove the query afterwards. --- lib/SimpleSAML/Utils/HTTP.php | 44 ++++++--------- tests/lib/SimpleSAML/Utils/HTTPTest.php | 74 +++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 26 deletions(-) diff --git a/lib/SimpleSAML/Utils/HTTP.php b/lib/SimpleSAML/Utils/HTTP.php index b90a793c8..186ee6ed1 100644 --- a/lib/SimpleSAML/Utils/HTTP.php +++ b/lib/SimpleSAML/Utils/HTTP.php @@ -709,31 +709,30 @@ class HTTP /** - * Retrieve the current, complete URL. + * Retrieve the current URL using the base URL in the configuration. * * @return string The current URL, including query parameters. * * @author Andreas Solberg, UNINETT AS <andreas.solberg@uninett.no> * @author Olav Morken, UNINETT AS <olav.morken@uninett.no> + * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no> */ public static function getSelfURL() { - $url = self::getSelfURLHost(); - $requestURI = $_SERVER['REQUEST_URI']; - if ($requestURI[0] !== '/') { - // we probably have a URL of the form: http://server/ - if (preg_match('#^https?://[^/]*(/.*)#i', $requestURI, $matches)) { - $requestURI = $matches[1]; - } - } - return $url.$requestURI; + $url = self::getBaseURL(); + $cfg = \SimpleSAML_Configuration::getInstance(); + $baseDir = $cfg->getBaseDir(); + $rel_path = str_replace($baseDir.'www/', '', $_SERVER['SCRIPT_FILENAME']); + $pos = strpos($_SERVER['REQUEST_URI'], $rel_path) + strlen($rel_path); + return $url.$rel_path.substr($_SERVER['REQUEST_URI'], $pos); } /** - * Retrieve a URL containing the protocol, the current host and optionally, the port number. + * Retrieve the current URL using the base URL in the configuration, containing the protocol, the host and + * optionally, the port number. * - * @return string The current URL without a URL path or query parameters. + * @return string The current URL without path or query parameters. * * @author Andreas Solberg, UNINETT AS <andreas.solberg@uninett.no> * @author Olav Morken, UNINETT AS <olav.morken@uninett.no> @@ -748,28 +747,21 @@ class HTTP /** - * Retrieve the current URL without the query parameters. + * Retrieve the current URL using the base URL in the configuration, without the query parameters. * * @return string The current URL, not including query parameters. * * @author Andreas Solberg, UNINETT AS <andreas.solberg@uninett.no> + * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no> */ public static function getSelfURLNoQuery() { - $url = self::getSelfURLHost(); - $url .= $_SERVER['SCRIPT_NAME']; - - /* In some environments, $_SERVER['SCRIPT_NAME'] already ends with $_SERVER['PATH_INFO']. Only append - * $_SERVER['PATH_INFO'] if it's set and missing from script name. - * - * Contributed by Travis Hegner. - */ - if (isset($_SERVER['PATH_INFO']) && - $_SERVER['PATH_INFO'] !== substr($_SERVER['SCRIPT_NAME'], - strlen($_SERVER['PATH_INFO']))) - { - $url .= $_SERVER['PATH_INFO']; + $url = self::getSelfURL(); + $pos = strpos($url, '?'); + if (!$pos) { + return $url; } - return $url; + return substr($url, 0, $pos); } diff --git a/tests/lib/SimpleSAML/Utils/HTTPTest.php b/tests/lib/SimpleSAML/Utils/HTTPTest.php index 3962fb59c..ff7e69f8b 100644 --- a/tests/lib/SimpleSAML/Utils/HTTPTest.php +++ b/tests/lib/SimpleSAML/Utils/HTTPTest.php @@ -140,6 +140,80 @@ class HTTPTest extends \PHPUnit_Framework_TestCase $_SERVER = $original; } + + /** + * Test SimpleSAML\Utils\HTTP::getSelfURL(). + */ + public function testGetSelfURL() + { + $original = $_SERVER; + + // test a valid, full URL, based on a full URL in the configuration + $cfg = \SimpleSAML_Configuration::loadFromArray(array( + 'baseurlpath' => 'https://example.com/simplesaml/', + ), '[ARRAY]', 'simplesaml'); + $baseDir = $cfg->getBaseDir(); + $_SERVER['SCRIPT_FILENAME'] = $baseDir.'www/script.php'; + $_SERVER['REQUEST_URI'] = '/simplesaml/script.php/module/file.php?foo=bar#something'; + $this->assertEquals( + 'https://example.com/simplesaml/script.php/module/file.php?foo=bar#something', + HTTP::getSelfURL() + ); + + // test a valid, full URL, based on a full URL *without* a trailing slash in the configuration + \SimpleSAML_Configuration::loadFromArray(array( + 'baseurlpath' => 'https://example.com/simplesaml', + ), '[ARRAY]', 'simplesaml'); + $this->assertEquals( + 'https://example.com/simplesaml/script.php/module/file.php?foo=bar#something', + HTTP::getSelfURL() + ); + + // test a valid, full URL, based on a full URL *without* a path in the configuration + \SimpleSAML_Configuration::loadFromArray(array( + 'baseurlpath' => 'https://example.com', + ), '[ARRAY]', 'simplesaml'); + $this->assertEquals( + 'https://example.com/script.php/module/file.php?foo=bar#something', + HTTP::getSelfURL() + ); + + // test a valid, full URL, based on a relative path in the configuration + \SimpleSAML_Configuration::loadFromArray(array( + 'baseurlpath' => '/simplesaml/', + ), '[ARRAY]', 'simplesaml'); + $_SERVER['HTTP_HOST'] = 'example.org'; + unset($_SERVER['HTTPS']); + unset($_SERVER['SERVER_PORT']); + $this->assertEquals( + 'http://example.org/simplesaml/script.php/module/file.php?foo=bar#something', + HTTP::getSelfURL() + ); + + // test a valid, full URL, based on a relative path in the configuration and a non standard port + \SimpleSAML_Configuration::loadFromArray(array( + 'baseurlpath' => '/simplesaml/', + ), '[ARRAY]', 'simplesaml'); + $_SERVER['SERVER_PORT'] = '8080'; + $this->assertEquals( + 'http://example.org:8080/simplesaml/script.php/module/file.php?foo=bar#something', + HTTP::getSelfURL() + ); + + // test a valid, full URL, based on a relative path in the configuration, a non standard port and HTTPS + \SimpleSAML_Configuration::loadFromArray(array( + 'baseurlpath' => '/simplesaml/', + ), '[ARRAY]', 'simplesaml'); + $_SERVER['HTTPS'] = 'on'; + $this->assertEquals( + 'https://example.org:8080/simplesaml/script.php/module/file.php?foo=bar#something', + HTTP::getSelfURL() + ); + + $_SERVER = $original; + } + + /** * Test SimpleSAML\Utils\HTTP::checkURLAllowed(), without regex. */ -- GitLab