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() {
if(isset($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])&&strtolower($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])=='https') {
return "https://";
return (self::is_https()) ? 'https://' : 'http://';
}
return (isset($_SERVER['SSL']) || (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off'))
? 'https://' : 'http://';
/**
* 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;
}
}
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.
* 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() {
$alternate = Config::inst()->get('Director', 'alternate_base_url');
if($alternate) {
return $alternate;
} else {
$base = BASE_URL;
if($base == '/' || $base == '/.' || $base == '\\') $baseURL = '/';
else $baseURL = $base . '/';
if(defined('BASE_SCRIPT_URL')) return $baseURL . BASE_SCRIPT_URL;
else return $baseURL;
if($base == '/' || $base == '/.' || $base == '\\') {
$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;
}
if($matched && (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == 'off')
&& !(isset($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])
&& strtolower($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) == 'https')) {
if($matched && !self::is_https()) {
// if an domain is specified, redirect to that instead of the current domain
if($secureDomain) {
@ -755,6 +783,7 @@ class Director implements TemplateGlobalProvider {
return $destURL;
} else {
if(!headers_sent()) header("Location: $destURL");
die("<h1>Your browser is not accepting header redirects</h1>"
. "<p>Please <a href=\"$destURL\">click here</a>");
}

View File

@ -9,6 +9,8 @@ class DirectorTest extends SapphireTest {
protected static $originalRequestURI;
protected $originalProtocolHeaders = array();
public function setUp() {
parent::setUp();
@ -24,6 +26,16 @@ class DirectorTest extends SapphireTest {
'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() {
@ -32,6 +44,12 @@ class DirectorTest extends SapphireTest {
// Reinstate the original REQUEST_URI after it was modified by some tests
$_SERVER['REQUEST_URI'] = self::$originalRequestURI;
if($this->originalProtocolHeaders) {
foreach($this->originalProtocolHeaders as $header => $value) {
$_SERVER[$header] = $value;
}
}
parent::tearDown();
}
@ -285,6 +303,43 @@ class DirectorTest extends SapphireTest {
$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 {