From 15c6b67c29ce77564a23104536350041c2b879cb Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Wed, 2 Apr 2014 14:27:40 +1300 Subject: [PATCH] Docs / Tests for Director::absoluteURL --- control/Director.php | 7 ++++++- control/HTTPResponse.php | 2 +- tests/control/DirectorTest.php | 37 ++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/control/Director.php b/control/Director.php index dafa2340f..2648c541f 100644 --- a/control/Director.php +++ b/control/Director.php @@ -355,7 +355,12 @@ class Director implements TemplateGlobalProvider { /** * Turns the given URL into an absolute URL. - * @todo Document how relativeToSiteBase works + * By default non-site root relative urls will be evaluated relative to the current request. + * + * @param string $url URL To transform to absolute + * @param bool $relativeToSiteBase Flag indicating if non-site root relative urls should be + * evaluated relative to the site BaseURL instead of the current url. + * @return string The fully qualified URL */ public static function absoluteURL($url, $relativeToSiteBase = false) { if(!isset($_SERVER['REQUEST_URI'])) return false; diff --git a/control/HTTPResponse.php b/control/HTTPResponse.php index 6d0ee52b5..73b803b0e 100644 --- a/control/HTTPResponse.php +++ b/control/HTTPResponse.php @@ -213,7 +213,7 @@ class SS_HTTPResponse { } if(in_array($this->statusCode, self::$redirect_codes) && headers_sent($file, $line)) { - $url = (string)$this->headers['Location']; + $url = Director::absoluteURL($this->headers['Location'], true); $urlATT = Convert::raw2htmlatt($url); $urlJS = Convert::raw2js($url); echo diff --git a/tests/control/DirectorTest.php b/tests/control/DirectorTest.php index 48359bed3..cb3eeb454 100644 --- a/tests/control/DirectorTest.php +++ b/tests/control/DirectorTest.php @@ -29,6 +29,9 @@ class DirectorTest extends SapphireTest { public function tearDown() { // TODO Remove director rule, currently API doesnt allow this + // Remove base URL override (setting to false reverts to default behaviour) + Director::setBaseURL(false); + // Reinstate the original REQUEST_URI after it was modified by some tests $_SERVER['REQUEST_URI'] = self::$originalRequestURI; @@ -54,6 +57,40 @@ class DirectorTest extends SapphireTest { unlink($tempFilePath); } + + public function testAbsoluteURL() { + + $rootURL = Director::protocolAndHost(); + $_SERVER['REQUEST_URI'] = "$rootURL/mysite/sub-page/"; + Director::setBaseURL('/mysite/'); + + // Test already absolute url + $this->assertEquals($rootURL, Director::absoluteURL($rootURL)); + $this->assertEquals($rootURL, Director::absoluteURL($rootURL, true)); + $this->assertEquals('http://www.mytest.com', Director::absoluteURL('http://www.mytest.com')); + $this->assertEquals('http://www.mytest.com', Director::absoluteURL('http://www.mytest.com', true)); + $this->assertEquals("$rootURL/test", Director::absoluteURL("$rootURL/test")); + $this->assertEquals("$rootURL/test", Director::absoluteURL("$rootURL/test", true)); + + // Test relative to base + $this->assertEquals("$rootURL/mysite/test", Director::absoluteURL("test", true)); + $this->assertEquals("$rootURL/mysite/test/url", Director::absoluteURL("test/url", true)); + $this->assertEquals("$rootURL/root", Director::absoluteURL("/root", true)); + $this->assertEquals("$rootURL/root/url", Director::absoluteURL("/root/url", true)); + + // Test relative to requested page + $this->assertEquals("$rootURL/mysite/sub-page/test", Director::absoluteURL("test")); + // Legacy behaviour resolves this to $rootURL/mysite/test/url + //$this->assertEquals("$rootURL/mysite/sub-page/test/url", Director::absoluteURL("test/url")); + $this->assertEquals("$rootURL/root", Director::absoluteURL("/root")); + $this->assertEquals("$rootURL/root/url", Director::absoluteURL("/root/url")); + + // Test that javascript links are not left intact + $this->assertStringStartsNotWith('javascript', Director::absoluteURL('javascript:alert("attack")')); + $this->assertStringStartsNotWith('alert', Director::absoluteURL('javascript:alert("attack")')); + $this->assertStringStartsNotWith('javascript', Director::absoluteURL('alert("attack")')); + $this->assertStringStartsNotWith('alert', Director::absoluteURL('alert("attack")')); + } public function testAlternativeBaseURL() { // relative base URLs - you should end them in a /