API: Add Director::is_https()

This commit is contained in:
Will Rossiter 2013-05-10 22:03:54 +12:00
parent 07b9bd8527
commit 1325d736a0
2 changed files with 99 additions and 15 deletions

View File

@ -418,33 +418,63 @@ class Director implements TemplateGlobalProvider {
} }
/** /**
* Return the current protocol that the site is running under * Return the current protocol that the site is running under.
* *
* @return String * @return string
*/ */
public static function protocol() { public static function protocol() {
if(isset($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])&&strtolower($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])=='https') { return (self::is_https()) ? 'https://' : 'http://';
return "https://"; }
/**
* Return whether the site is running as under HTTPS.
*
* @return boolean
*/
public static function is_https() {
if(isset($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])) {
if(strtolower($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) == 'https') {
return true;
}
} }
return (isset($_SERVER['SSL']) || (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off'))
? 'https://' : 'http://'; if((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')) {
return true;
}
else if(isset($_SERVER['SSL'])) {
return true;
}
return false;
} }
/** /**
* Returns the root URL for the site. * Returns the root URL for the site.
* It will be automatically calculated unless it is overridden with {@link setBaseURL()}. *
* It will be automatically calculated unless it is overridden with
* {@link setBaseURL()}.
*
* @return string
*/ */
public static function baseURL() { public static function baseURL() {
$alternate = Config::inst()->get('Director', 'alternate_base_url'); $alternate = Config::inst()->get('Director', 'alternate_base_url');
if($alternate) { if($alternate) {
return $alternate; return $alternate;
} else { } else {
$base = BASE_URL; $base = BASE_URL;
if($base == '/' || $base == '/.' || $base == '\\') $baseURL = '/';
else $baseURL = $base . '/';
if(defined('BASE_SCRIPT_URL')) return $baseURL . BASE_SCRIPT_URL; if($base == '/' || $base == '/.' || $base == '\\') {
else return $baseURL; $baseURL = '/';
} else {
$baseURL = $base . '/';
}
if(defined('BASE_SCRIPT_URL')) {
return $baseURL . BASE_SCRIPT_URL;
}
return $baseURL;
} }
} }
@ -737,9 +767,7 @@ class Director implements TemplateGlobalProvider {
$matched = true; $matched = true;
} }
if($matched && (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == 'off') if($matched && !self::is_https()) {
&& !(isset($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])
&& strtolower($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) == 'https')) {
// if an domain is specified, redirect to that instead of the current domain // if an domain is specified, redirect to that instead of the current domain
if($secureDomain) { if($secureDomain) {
@ -755,6 +783,7 @@ class Director implements TemplateGlobalProvider {
return $destURL; return $destURL;
} else { } else {
if(!headers_sent()) header("Location: $destURL"); if(!headers_sent()) header("Location: $destURL");
die("<h1>Your browser is not accepting header redirects</h1>" die("<h1>Your browser is not accepting header redirects</h1>"
. "<p>Please <a href=\"$destURL\">click here</a>"); . "<p>Please <a href=\"$destURL\">click here</a>");
} }

View File

@ -9,6 +9,8 @@ class DirectorTest extends SapphireTest {
protected static $originalRequestURI; protected static $originalRequestURI;
protected $originalProtocolHeaders = array();
public function setUp() { public function setUp() {
parent::setUp(); parent::setUp();
@ -24,6 +26,16 @@ class DirectorTest extends SapphireTest {
'Locale' => 'en_NZ' 'Locale' => 'en_NZ'
) )
)); ));
$headers = array(
'HTTP_X_FORWARDED_PROTOCOL', 'HTTPS', 'SSL'
);
foreach($headers as $header) {
if(isset($_SERVER[$header])) {
$this->originalProtocolHeaders[$header] = $_SERVER[$header];
}
}
} }
public function tearDown() { public function tearDown() {
@ -31,7 +43,13 @@ class DirectorTest extends SapphireTest {
// Reinstate the original REQUEST_URI after it was modified by some tests // Reinstate the original REQUEST_URI after it was modified by some tests
$_SERVER['REQUEST_URI'] = self::$originalRequestURI; $_SERVER['REQUEST_URI'] = self::$originalRequestURI;
if($this->originalProtocolHeaders) {
foreach($this->originalProtocolHeaders as $header => $value) {
$_SERVER[$header] = $value;
}
}
parent::tearDown(); parent::tearDown();
} }
@ -285,6 +303,43 @@ class DirectorTest extends SapphireTest {
$this->assertEquals(404, Director::test('no-route')->getStatusCode()); $this->assertEquals(404, Director::test('no-route')->getStatusCode());
} }
public function testIsHttps() {
// nothing available
$headers = array(
'HTTP_X_FORWARDED_PROTOCOL', 'HTTPS', 'SSL'
);
foreach($headers as $header) {
if(isset($_SERVER[$header])) {
unset($_SERVER['HTTP_X_FORWARDED_PROTOCOL']);
}
}
$this->assertFalse(Director::is_https());
$_SERVER['HTTP_X_FORWARDED_PROTOCOL'] = 'https';
$this->assertTrue(Director::is_https());
$_SERVER['HTTP_X_FORWARDED_PROTOCOL'] = 'http';
$this->assertFalse(Director::is_https());
$_SERVER['HTTP_X_FORWARDED_PROTOCOL'] = 'ftp';
$this->assertFalse(Director::is_https());
// https via HTTPS
$_SERVER['HTTPS'] = 'true';
$this->assertTrue(Director::is_https());
$_SERVER['HTTPS'] = '1';
$this->assertTrue(Director::is_https());
$_SERVER['HTTPS'] = 'off';
$this->assertFalse(Director::is_https());
// https via SSL
$_SERVER['SSL'] = '';
$this->assertTrue(Director::is_https());
}
} }
class DirectorTestRequest_Controller extends Controller implements TestOnly { class DirectorTestRequest_Controller extends Controller implements TestOnly {