Skip to content

Commit

Permalink
BUG Fix forceWWW and forceSSL not working in _config.php
Browse files Browse the repository at this point in the history
API Introduce CanonicalURLMiddleware
  • Loading branch information
Damian Mooyman committed Oct 27, 2017
1 parent 2a9d1ff commit 3c3e94f
Show file tree
Hide file tree
Showing 4 changed files with 448 additions and 58 deletions.
10 changes: 10 additions & 0 deletions _config/requestprocessors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ SilverStripe\Core\Injector\Injector:
SessionMiddleware: '%$SilverStripe\Control\Middleware\SessionMiddleware'
RequestProcessorMiddleware: '%$SilverStripe\Control\RequestProcessor'
FlushMiddleware: '%$SilverStripe\Control\Middleware\FlushMiddleware'
CanonicalURLMiddleware: '%$SilverStripe\Control\Middleware\CanonicalURLMiddleware'
SilverStripe\Control\Middleware\AllowedHostsMiddleware:
properties:
AllowedHosts: '`SS_ALLOWED_HOSTS`'
Expand All @@ -37,3 +38,12 @@ After:
SilverStripe\Core\Injector\Injector:
# Note: If Director config changes, take note it will affect this config too
SilverStripe\Core\Startup\ErrorDirector: '%$SilverStripe\Control\Director'
---
Name: canonicalurls
---
SilverStripe\Core\Injector\Injector:
SilverStripe\Control\Middleware\CanonicalURLMiddleware:
properties:
ForceSSL: false
ForceWWW: false

68 changes: 18 additions & 50 deletions src/Control/Director.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace SilverStripe\Control;

use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Control\Middleware\CanonicalURLMiddleware;
use SilverStripe\Control\Middleware\HTTPMiddlewareAware;
use SilverStripe\Core\Config\Configurable;
use SilverStripe\Core\Environment;
Expand Down Expand Up @@ -242,7 +243,7 @@ public static function mockRequest(

// If a port is mentioned in the absolute URL, be sure to add that into the HTTP host
$newVars['_SERVER']['HTTP_HOST'] = isset($bits['port'])
? $bits['host'].':'.$bits['port']
? $bits['host'] . ':' . $bits['port']
: $bits['host'];
}

Expand Down Expand Up @@ -697,10 +698,10 @@ public static function is_absolute_url($url)
{
// Strip off the query and fragment parts of the URL before checking
if (($queryPosition = strpos($url, '?')) !== false) {
$url = substr($url, 0, $queryPosition-1);
$url = substr($url, 0, $queryPosition - 1);
}
if (($hashPosition = strpos($url, '#')) !== false) {
$url = substr($url, 0, $hashPosition-1);
$url = substr($url, 0, $hashPosition - 1);
}
$colonPosition = strpos($url, ':');
$slashPosition = strpos($url, '/');
Expand Down Expand Up @@ -809,7 +810,7 @@ public static function absoluteBaseURLWithAuth(HTTPRequest $request = null)
$login = "$_SERVER[PHP_AUTH_USER]:$_SERVER[PHP_AUTH_PW]@";
}

return Director::protocol($request) . $login . static::host($request) . Director::baseURL();
return Director::protocol($request) . $login . static::host($request) . Director::baseURL();
}

/**
Expand Down Expand Up @@ -855,62 +856,29 @@ protected static function force_redirect($destURL)
*
* @param array $patterns Array of regex patterns to match URLs that should be HTTPS.
* @param string $secureDomain Secure domain to redirect to. Defaults to the current domain.
* @return bool true if already on SSL, false if doesn't match patterns (or cannot redirect)
* @throws HTTPResponse_Exception Throws exception with redirect, if successful
* @param HTTPRequest|null $request Request object to check
*/
public static function forceSSL($patterns = null, $secureDomain = null)
public static function forceSSL($patterns = null, $secureDomain = null, HTTPRequest $request = null)
{
// Already on SSL
if (static::is_https()) {
return true;
}

// Can't redirect without a url
if (!isset($_SERVER['REQUEST_URI'])) {
return false;
}

$handler = CanonicalURLMiddleware::singleton()->setForceSSL(true);
if ($patterns) {
$matched = false;
$relativeURL = self::makeRelative(Director::absoluteURL($_SERVER['REQUEST_URI']));

// protect portions of the site based on the pattern
foreach ($patterns as $pattern) {
if (preg_match($pattern, $relativeURL)) {
$matched = true;
break;
}
}
if (!$matched) {
return false;
}
$handler->setForceSSLPatterns($patterns);
}

// if an domain is specified, redirect to that instead of the current domain
if (!$secureDomain) {
$secureDomain = static::host();
if ($secureDomain) {
$handler->setForceSSLDomain($secureDomain);
}
$url = 'https://' . $secureDomain . $_SERVER['REQUEST_URI'];

// Force redirect
self::force_redirect($url);
return true;
$handler->throwRedirectIfNeeded($request);
}

/**
* Force a redirect to a domain starting with "www."
*
* @param HTTPRequest $request
*/
public static function forceWWW()
public static function forceWWW(HTTPRequest $request = null)
{
if (!Director::isDev() && !Director::isTest() && strpos(static::host(), 'www') !== 0) {
$destURL = str_replace(
Director::protocol(),
Director::protocol() . 'www.',
Director::absoluteURL($_SERVER['REQUEST_URI'])
);

self::force_redirect($destURL);
}
$handler = CanonicalURLMiddleware::singleton()->setForceWWW(true);
$handler->throwRedirectIfNeeded($request);
}

/**
Expand Down Expand Up @@ -947,7 +915,7 @@ public static function is_cli()
* Can also be checked with {@link Director::isDev()}, {@link Director::isTest()}, and
* {@link Director::isLive()}.
*
* @return bool
* @return string
*/
public static function get_environment_type()
{
Expand Down
Loading

0 comments on commit 3c3e94f

Please sign in to comment.