FIX Double slashes in ParameterConfirmationToken

This commit is contained in:
Hamish Friedlander 2013-08-19 11:35:34 +12:00
parent 810f505924
commit 4a7aef0e25
2 changed files with 71 additions and 5 deletions

View File

@ -70,7 +70,10 @@ class ParameterConfirmationToken {
);
}
public function reloadWithToken() {
/** What to use instead of BASE_URL. Must not contain protocol or host. @var string */
static public $alternateBaseURL = null;
protected function currentAbsoluteURL() {
global $url;
// Are we http or https?
@ -83,15 +86,27 @@ class ParameterConfirmationToken {
if((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')) $proto = 'https';
if(isset($_SERVER['SSL'])) $proto = 'https';
// What's our host
$host = $_SERVER['HTTP_HOST'];
$parts = array_filter(array(
// What's our host
$_SERVER['HTTP_HOST'],
// SilverStripe base
self::$alternateBaseURL !== null ? self::$alternateBaseURL : BASE_URL,
// And URL
$url
));
// Join together with protocol into our current absolute URL, avoiding duplicated "/" characters
return "$proto://" . preg_replace('#/{2,}#', '/', implode('/', $parts));
}
public function reloadWithToken() {
$location = $this->currentAbsoluteURL();
// What's our GET params (ensuring they include the original parameter + a new token)
$params = array_merge($_GET, $this->params());
unset($params['url']);
// Join them all together into the original URL
$location = "$proto://" . $host . '/' . ltrim(BASE_URL, '/') . $url . ($params ? '?'.http_build_query($params) : '');
if ($params) $location .= '?'.http_build_query($params);
// And redirect
if (headers_sent()) {

View File

@ -0,0 +1,51 @@
<?php
class ParameterConfirmationTokenTest_Token extends ParameterConfirmationToken {
public function currentAbsoluteURL() {
return parent::currentAbsoluteURL();
}
}
class ParameterConfirmationTokenTest extends SapphireTest {
private function addPart($answer, $slash, $part) {
$bare = str_replace('/', '', $part);
if ($bare) $answer = array_merge($answer, array($bare));
if ($part) $slash = (substr($part, -1) == '/') ? '/' : '';
return array($answer, $slash);
}
/**
* currentAbsoluteURL needs to handle base or url being missing, or any combination of slashes.
*
* There should always be exactly one slash between each part in the result, and any trailing slash
* should be preserved.
*/
function testCurrentAbsoluteURLHandlesSlashes() {
global $url;
$token = new ParameterConfirmationTokenTest_Token('parameterconfirmationtokentest_parameter');
foreach(array('foo','foo/') as $host) {
list($hostAnswer, $hostSlash) = $this->addPart(array(), '', $host);
foreach(array('', '/', 'bar', 'bar/', '/bar', '/bar/') as $base) {
list($baseAnswer, $baseSlash) = $this->addPart($hostAnswer, $hostSlash, $base);
foreach(array('', '/', 'baz', 'baz/', '/baz', '/baz/') as $url) {
list($urlAnswer, $urlSlash) = $this->addPart($baseAnswer, $baseSlash, $url);
$_SERVER['HTTP_HOST'] = $host;
ParameterConfirmationToken::$alternateBaseURL = $base;
$this->assertEquals('http://'.implode('/', $urlAnswer) . $urlSlash, $token->currentAbsoluteURL());
}
}
}
}
}