mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Remove "url" query param reliance, use index.php
See https://github.com/silverstripe/silverstripe-framework/issues/7430
This commit is contained in:
parent
cc99b2ec19
commit
4a94dfe55b
@ -81,20 +81,32 @@ as a standard first point of upgrade.
|
||||
#### Upgrade your rewrite rules
|
||||
|
||||
The location of SilverStripe's "entry file" has changed. Your project and server environment will need
|
||||
to adjust the path to this file from `framework/main.php` to `vendor/silverstripe/framework/main.php`.
|
||||
to adjust the path to this file from `framework/main.php` to `index.php`.
|
||||
If you are running Apache, adjust your `.htaccess` file. For other webservers,
|
||||
please consult the [installation guides](getting_started/installation/).
|
||||
|
||||
For websites served by Apache, here's an adjusted `.htaccess` excerpt:
|
||||
The `index.php` file should already exist in your project,
|
||||
but needs its content replaced:
|
||||
|
||||
```diff
|
||||
+RewriteCond %{REQUEST_URI} !^/vendor/silverstripe/framework/main\.php
|
||||
RewriteRule ^vendor(/|$) - [F,L,NC]
|
||||
```php
|
||||
<?php
|
||||
|
||||
# ...
|
||||
use SilverStripe\Control\HTTPApplication;
|
||||
use SilverStripe\Control\HTTPRequestBuilder;
|
||||
use SilverStripe\Core\CoreKernel;
|
||||
use SilverStripe\Core\Startup\ErrorControlChainMiddleware;
|
||||
|
||||
-RewriteRule .* framework/main.php?url=%1 [QSA]
|
||||
+RewriteRule .* vendor/silverstripe/framework/main.php?url=%1 [QSA]
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
// Build request and detect flush
|
||||
$request = HTTPRequestBuilder::createFromEnvironment();
|
||||
|
||||
// Default application
|
||||
$kernel = new CoreKernel(BASE_PATH);
|
||||
$app = new HTTPApplication($kernel);
|
||||
$app->addMiddleware(new ErrorControlChainMiddleware($app));
|
||||
$response = $app->handle($request);
|
||||
$response->output();
|
||||
```
|
||||
|
||||
#### Upgrade references to renamed and namespaced classes
|
||||
|
18
main.php
18
main.php
@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
use SilverStripe\Control\HTTPApplication;
|
||||
use SilverStripe\Control\HTTPRequestBuilder;
|
||||
use SilverStripe\Core\CoreKernel;
|
||||
use SilverStripe\Core\Startup\ErrorControlChainMiddleware;
|
||||
|
||||
require __DIR__ . '/src/includes/autoload.php';
|
||||
|
||||
// Build request and detect flush
|
||||
$request = HTTPRequestBuilder::createFromEnvironment();
|
||||
|
||||
// Default application
|
||||
$kernel = new CoreKernel(BASE_PATH);
|
||||
$app = new HTTPApplication($kernel);
|
||||
$app->addMiddleware(new ErrorControlChainMiddleware($app));
|
||||
$response = $app->handle($request);
|
||||
$response->output();
|
@ -404,11 +404,7 @@ class HTTPRequest implements ArrayAccess
|
||||
$url = ($this->getExtension()) ? $this->url . '.' . $this->getExtension() : $this->url;
|
||||
|
||||
if ($includeGetVars) {
|
||||
// if we don't unset $vars['url'] we end up with /my/url?url=my/url&foo=bar etc
|
||||
|
||||
$vars = $this->getVars();
|
||||
unset($vars['url']);
|
||||
|
||||
if (count($vars)) {
|
||||
$url .= '?' . http_build_query($vars);
|
||||
}
|
||||
|
@ -17,10 +17,16 @@ class HTTPRequestBuilder
|
||||
{
|
||||
// Clean and update live global variables
|
||||
$variables = static::cleanEnvironment(Environment::getVariables());
|
||||
Environment::setVariables($variables); // Currently necessary for SSViewer, etc to work
|
||||
|
||||
// Health-check prior to creating environment
|
||||
return static::createFromVariables($variables, @file_get_contents('php://input'));
|
||||
$req = static::createFromVariables($variables, @file_get_contents('php://input'));
|
||||
|
||||
// Normalise URL
|
||||
$variables['_SERVER']['REQUEST_URI'] = $req->getURL();
|
||||
|
||||
Environment::setVariables($variables); // Currently necessary for SSViewer, etc to work
|
||||
|
||||
return $req;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -32,9 +38,7 @@ class HTTPRequestBuilder
|
||||
*/
|
||||
public static function createFromVariables(array $variables, $input)
|
||||
{
|
||||
// Strip `url` out of querystring
|
||||
$url = $variables['_GET']['url'];
|
||||
unset($variables['_GET']['url']);
|
||||
$url = self::getRequestUri($variables);
|
||||
|
||||
// Build request
|
||||
$request = new HTTPRequest(
|
||||
@ -100,7 +104,6 @@ class HTTPRequestBuilder
|
||||
|
||||
/**
|
||||
* Clean up HTTP global vars for $_GET / $_REQUEST prior to bootstrapping
|
||||
* Will also populate the $_GET['url'] var safely
|
||||
*
|
||||
* @param array $variables
|
||||
* @return array Cleaned variables
|
||||
@ -117,33 +120,6 @@ class HTTPRequestBuilder
|
||||
$variables['_SERVER']['REQUEST_METHOD'] = $variables['_SERVER']['X-HTTP-Method-Override'];
|
||||
}
|
||||
|
||||
// Prevent injection of url= querystring argument by prioritising any leading url argument
|
||||
if (isset($variables['_SERVER']['QUERY_STRING']) &&
|
||||
preg_match('/^(?<url>url=[^&?]*)(?<query>.*[&?]url=.*)$/', $variables['_SERVER']['QUERY_STRING'], $results)
|
||||
) {
|
||||
$queryString = $results['query'].'&'.$results['url'];
|
||||
parse_str($queryString, $variables['_GET']);
|
||||
}
|
||||
|
||||
// Decode url from REQUEST_URI if not passed via $_GET['url']
|
||||
if (!isset($variables['_GET']['url'])) {
|
||||
$url = $variables['_SERVER']['REQUEST_URI'];
|
||||
|
||||
// Querystring args need to be explicitly parsed
|
||||
if (strpos($url, '?') !== false) {
|
||||
list($url, $queryString) = explode('?', $url, 2);
|
||||
parse_str($queryString);
|
||||
}
|
||||
|
||||
// Ensure $_GET['url'] is set
|
||||
$variables['_GET']['url'] = urldecode($url);
|
||||
}
|
||||
|
||||
// Remove base folders from the URL if webroot is hosted in a subfolder
|
||||
if (substr(strtolower($variables['_GET']['url']), 0, strlen(BASE_URL)) === strtolower(BASE_URL)) {
|
||||
$variables['_GET']['url'] = substr($variables['_GET']['url'], strlen(BASE_URL));
|
||||
}
|
||||
|
||||
// Merge $_FILES into $_POST
|
||||
$variables['_POST'] = array_merge((array)$variables['_POST'], (array)$variables['_FILES']);
|
||||
|
||||
@ -156,4 +132,52 @@ class HTTPRequestBuilder
|
||||
|
||||
return $variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $variables
|
||||
* @return string
|
||||
*/
|
||||
protected static function getRequestUri(array $variables)
|
||||
{
|
||||
$server = $variables['_SERVER'];
|
||||
|
||||
$ruLen = strlen($server['REQUEST_URI']);
|
||||
$snLen = strlen($server['SCRIPT_NAME']);
|
||||
|
||||
$isIIS = (strpos($server['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false);
|
||||
|
||||
// IIS will populate server variables using one of these two ways
|
||||
if ($isIIS) {
|
||||
if ($server['REQUEST_URI'] == $server['SCRIPT_NAME']) {
|
||||
$url = "";
|
||||
} elseif ($ruLen > $snLen && substr($server['REQUEST_URI'], 0, $snLen + 1) == ($server['SCRIPT_NAME'] . '/')) {
|
||||
$url = substr($server['REQUEST_URI'], $snLen + 1);
|
||||
$url = strtok($url, '?');
|
||||
} else {
|
||||
$url = $server['REQUEST_URI'];
|
||||
if ($url[0] == '/') {
|
||||
$url = substr($url, 1);
|
||||
}
|
||||
$url = strtok($url, '?');
|
||||
}
|
||||
|
||||
// Apache will populate the server variables this way
|
||||
} else {
|
||||
// Remove query parameters (they're retained separately through $server['_GET']
|
||||
$url = parse_url($server['REQUEST_URI'], PHP_URL_PATH);
|
||||
// if ($ruLen > $snLen && substr($server['REQUEST_URI'], 0, $snLen + 1) == ($server['SCRIPT_NAME'] . '/')) {
|
||||
// $url = substr($server['REQUEST_URI'], $snLen + 1);
|
||||
// $url = strtok($url, '?');
|
||||
// } else {
|
||||
// $url = "";
|
||||
// }
|
||||
}
|
||||
|
||||
// Remove base folders from the URL if webroot is hosted in a subfolder
|
||||
if (substr(strtolower($url), 0, strlen(BASE_URL)) === strtolower(BASE_URL)) {
|
||||
$url = substr($url, strlen(BASE_URL));
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
@ -442,7 +442,7 @@ class ClassManifest
|
||||
$finder = new ManifestFileFinder();
|
||||
$finder->setOptions(array(
|
||||
'name_regex' => '/^[^_].*\\.php$/',
|
||||
'ignore_files' => array('index.php', 'main.php', 'cli-script.php'),
|
||||
'ignore_files' => array('index.php', 'cli-script.php'),
|
||||
'ignore_tests' => !$includeTests,
|
||||
'file_callback' => function ($basename, $pathname, $depth) use ($includeTests, $finder) {
|
||||
$this->handleFile($basename, $pathname, $includeTests);
|
||||
|
@ -15,7 +15,7 @@ use Exception;
|
||||
* $chain = new ErrorControlChain();
|
||||
* $chain->then($callback1)->then($callback2)->thenIfErrored($callback3)->execute();
|
||||
*
|
||||
* WARNING: This class is experimental and designed specifically for use pre-startup in main.php
|
||||
* WARNING: This class is experimental and designed specifically for use pre-startup.
|
||||
* It will likely be heavily refactored before the release of 3.2
|
||||
*/
|
||||
class ErrorControlChain
|
||||
|
@ -16,7 +16,7 @@ use SilverStripe\Security\RandomGenerator;
|
||||
* established, this class takes care of allowing some other code of confirming the parameter,
|
||||
* by generating a one-time-use token & redirecting with that token included in the redirected URL
|
||||
*
|
||||
* WARNING: This class is experimental and designed specifically for use pre-startup in main.php
|
||||
* WARNING: This class is experimental and designed specifically for use pre-startup.
|
||||
* It will likely be heavily refactored before the release of 3.2
|
||||
*/
|
||||
class ParameterConfirmationToken
|
||||
|
@ -439,12 +439,8 @@ ErrorDocument 500 /assets/error-500.html
|
||||
$baseClause
|
||||
$cgiClause
|
||||
|
||||
# Deny access to vendor, unless you're requesting main.php
|
||||
# Not restricting to the start of the path to support RewriteBase
|
||||
RewriteCond %{REQUEST_URI} !^/vendor/silverstripe/framework/main\.php
|
||||
RewriteRule ^vendor(/|$) - [F,L,NC]
|
||||
|
||||
# Deny access to potentially sensitive files and folders
|
||||
RewriteRule ^vendor(/|$) - [F,L,NC]
|
||||
RewriteRule ^\.env - [F,L,NC]
|
||||
RewriteRule silverstripe-cache(/|$) - [F,L,NC]
|
||||
RewriteRule composer\.(json|lock) - [F,L,NC]
|
||||
@ -455,7 +451,7 @@ ErrorDocument 500 /assets/error-500.html
|
||||
# Try finding framework in the vendor folder first
|
||||
RewriteCond %{REQUEST_URI} ^(.*)$
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule .* vendor/silverstripe/framework/main.php?url=%1 [QSA]
|
||||
RewriteRule .* index.php
|
||||
</IfModule>
|
||||
TEXT;
|
||||
|
||||
@ -510,9 +506,8 @@ TEXT;
|
||||
<match url="^(.*)$" />
|
||||
<conditions>
|
||||
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
|
||||
<add input="vendor/silverstripe/framework/main.php" matchType="IsFile" />
|
||||
</conditions>
|
||||
<action type="Rewrite" url="vendor/silverstripe/framework/main.php?url={R:1}" appendQueryString="true" />
|
||||
<action type="Rewrite" url="index.php" appendQueryString="true" />
|
||||
</rule>
|
||||
</rules>
|
||||
</rewrite>
|
||||
|
@ -94,9 +94,8 @@ class DetailedErrorFormatter implements FormatterInterface
|
||||
$httpRequest = null;
|
||||
if (isset($_SERVER['REQUEST_URI'])) {
|
||||
$httpRequest = $_SERVER['REQUEST_URI'];
|
||||
} elseif (isset($_REQUEST['url'])) {
|
||||
$httpRequest = $_REQUEST['url'];
|
||||
}
|
||||
|
||||
if (isset($_SERVER['REQUEST_METHOD'])) {
|
||||
$httpRequest = $_SERVER['REQUEST_METHOD'] . ' ' . $httpRequest;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user