diff --git a/docs/en/00_Getting_Started/01_Installation/03_Windows.md b/docs/en/00_Getting_Started/01_Installation/03_Windows.md index 3cddfb1dd..31493254e 100644 --- a/docs/en/00_Getting_Started/01_Installation/03_Windows.md +++ b/docs/en/00_Getting_Started/01_Installation/03_Windows.md @@ -62,7 +62,9 @@ control. 3. Apache rewrite (mod_rewrite) isn't working and it's installed (prior to SilverStripe 3.1.11) -Due to some changes to `mod_dir` in [Apache 2.4](http://httpd.apache.org/docs/current/mod/mod_dir.html#DirectoryCheckHandler) (precedence of handlers), index.php gets added to the URLs as soon as you navigate to the homepage of your site. Further requests are then handled by index.php rather than `mod_rewrite` (`main.php`). To fix this place the following within the `mod_rewrite` section of your .htaccess file: +Due to some changes to `mod_dir` in [Apache 2.4](http://httpd.apache.org/docs/current/mod/mod_dir.html#DirectoryCheckHandler) (precedence of handlers), +index.php gets added to the URLs as soon as you navigate to the homepage of your site. +To fix this place the following within the `mod_rewrite` section of your .htaccess file: ``` diff --git a/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md b/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md index 6b2d318e5..bafa3f60b 100644 --- a/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md +++ b/docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md @@ -24,7 +24,6 @@ On "live" environments, the `?isDev=1` solution is preferred, as it means that y Due to some changes to `mod_dir` in [Apache 2.4](http://httpd.apache.org/docs/current/mod/mod_dir.html#DirectoryCheckHandler) (precedence of handlers), index.php gets added to the URLs as soon as you navigate to the homepage of your site. -Further requests are then handled by index.php rather than `mod_rewrite` (`main.php`). To fix this place the following within the `mod_rewrite` section of your .htaccess file: ``` diff --git a/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Lighttpd.md b/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Lighttpd.md index 5d60a35d6..2de07d466 100644 --- a/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Lighttpd.md +++ b/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Lighttpd.md @@ -27,11 +27,11 @@ Silverstripe. Replace "yoursite.com" and "/home/yoursite/public_html/" below. # Rewrite URLs so they are nicer url.rewrite-once = ( "^/.*\.[A-Za-z0-9]+.*?$" => "$0", - "^/(.*?)(\?|$)(.*)" => "/vendor/silverstripe/framework/main.php?url=$1&$3" + "^/(.*?)(\?|$)(.*)" => "/index.php?$3" ) # Show SilverStripe error page - server.error-handler-404 = "/vendor/silverstripe/framework/main.php" + server.error-handler-404 = "/index.php" } @@ -53,14 +53,14 @@ of Silverstripe on the same host, you can use something like this (be warned, it url.rewrite-once = ( "(?i)(/copy1/.*\.([A-Za-z0-9]+))(.*?)$" => "$0", "(?i)(/copy2/.*\.([A-Za-z0-9]+))(.*?)$" => "$0", - "^/copy1/(.*?)(\?|$)(.*)" => "/copy1/vendor/silverstripe/framework/main.php?url=$1&$3", - "^/copy2/(.*?)(\?|$)(.*)" => "/copy2/vendor/silverstripe/framework/main.php?url=$1&$3" + "^/copy1/(.*?)(\?|$)(.*)" => "/copy1/index.php?$3", + "^/copy2/(.*?)(\?|$)(.*)" => "/copy2/index.php?$3" ) $HTTP["url"] =~ "^/copy1/" { - server.error-handler-404 = "/copy1/vendor/silverstripe/framework/main.php" + server.error-handler-404 = "/copy1/index.php" } $HTTP["url"] =~ "^/copy2/" { - server.error-handler-404 = "/copy2/vendor/silverstripe/framework/main.php" + server.error-handler-404 = "/copy2/index.php" } } diff --git a/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Nginx.md b/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Nginx.md index d9a247f82..35c499f21 100644 --- a/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Nginx.md +++ b/docs/en/00_Getting_Started/01_Installation/How_To/Configure_Nginx.md @@ -30,7 +30,7 @@ But enough of the disclaimer, on to the actual configuration — typically in `n } location / { - try_files $uri vendor/silverstripe/framework/main.php?url=$uri&$query_string; + try_files $uri index.php?$query_string; } error_page 404 /assets/error-404.html; @@ -41,7 +41,7 @@ But enough of the disclaimer, on to the actual configuration — typically in `n deny all; } sendfile on; - try_files $uri vendor/silverstripe/framework/main.php?url=$uri&$query_string; + try_files $uri index.php?$query_string; } location ~ /framework/.*(main|rpc|tiny_mce_gzip)\.php$ { diff --git a/docs/en/00_Getting_Started/01_Installation/How_To/Setup_Nginx_and_HHVM.md b/docs/en/00_Getting_Started/01_Installation/How_To/Setup_Nginx_and_HHVM.md index f5b93a7c7..eab1096c4 100644 --- a/docs/en/00_Getting_Started/01_Installation/How_To/Setup_Nginx_and_HHVM.md +++ b/docs/en/00_Getting_Started/01_Installation/How_To/Setup_Nginx_and_HHVM.md @@ -48,7 +48,7 @@ Create `/etc/nginx/silverstripe.conf` and add this configuration: fastcgi_buffers 4 32k; location / { - try_files $uri /vendor/silverstripe/framework/main.php?url=$uri&$query_string; + try_files $uri /index.php?$query_string; } error_page 404 /assets/error-404.html; @@ -87,7 +87,7 @@ Create `/etc/nginx/silverstripe.conf` and add this configuration: deny all; } -The above script passes all non-static file requests to `/framework/main.php` in the webroot which relies on +The above script passes all non-static file requests to `/index.php` in the webroot which relies on `hhvm.conf` being included prior so that php requests are handled. Now in your nginx `server` configuration you can then include the `hhvm.conf` and `silverstripe.conf` files diff --git a/docs/en/02_Developer_Guides/14_Files/03_File_Security.md b/docs/en/02_Developer_Guides/14_Files/03_File_Security.md index 660f39b5e..a5795a7f6 100644 --- a/docs/en/02_Developer_Guides/14_Files/03_File_Security.md +++ b/docs/en/02_Developer_Guides/14_Files/03_File_Security.md @@ -362,7 +362,7 @@ bypasses PHP requests for files that do exist. The default template # Non existant files passed to requesthandler RewriteCond %{REQUEST_URI} ^(.*)$ RewriteCond %{REQUEST_FILENAME} !-f -RewriteRule .* ../vendor/silverstripe/framework/main.php?url=%1 [QSA] +RewriteRule .* ../index.php [QSA] ``` You will need to ensure that your core apache configuration has the necessary `AllowOverride` @@ -381,9 +381,9 @@ The default rule for IIS is as below (only partial configuration displayed): - + - + ``` @@ -402,6 +402,6 @@ dynamic requests are processed via the Framework: ``` location ^~ /assets/ { sendfile on; - try_files $uri vendor/silverstripe/framework/main.php?url=$uri&$query_string; + try_files $uri index.php?$query_string; } ``` diff --git a/docs/en/02_Developer_Guides/16_Execution_Pipeline/03_App_Object_and_Kernel.md b/docs/en/02_Developer_Guides/16_Execution_Pipeline/03_App_Object_and_Kernel.md index 930158066..1c1f785fe 100644 --- a/docs/en/02_Developer_Guides/16_Execution_Pipeline/03_App_Object_and_Kernel.md +++ b/docs/en/02_Developer_Guides/16_Execution_Pipeline/03_App_Object_and_Kernel.md @@ -65,56 +65,29 @@ The role of the application is to: The HTTPApplication provides a specialised application implementation for handling HTTP Requests. This class provides basic support for HTTP Middleware, such as [ErrorControlChainMiddleware](api:SilverStripe\Core\Startup\ErrorControlChainMiddleware). -`main.php` contains the default application implementation. +The `index.php` file in your project root contains the default application implementation. +You can customise it as required. ```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(); -``` + - # ... - RewriteCond %{REQUEST_URI} ^(.*)$ - RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule .* mysite/main.php?url=%1 [QSA] - # ... - +require __DIR__ . '/vendor/autoload.php'; +// Build request and detect flush +$request = HTTPRequestBuilder::createFromEnvironment(); -Note: This config must also be duplicated in the below template which provide asset routing: - -`silverstripe-assets/templates/SilverStripe/Assets/Flysystem/PublicAssetAdapter_HTAccess.ss`: - - -```ss - - - # ... - # Non existant files passed to requesthandler - RewriteCond %{REQUEST_URI} ^(.*)$ - RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule .* ../mysite/main.php?url=%1 [QSA] - +// Default application +$kernel = new CoreKernel(BASE_PATH); +$app = new HTTPApplication($kernel); +$app->addMiddleware(new ErrorControlChainMiddleware($app)); +$response = $app->handle($request); +$response->output(); ``` ## Custom application actions diff --git a/docs/en/02_Developer_Guides/16_Execution_Pipeline/index.md b/docs/en/02_Developer_Guides/16_Execution_Pipeline/index.md index 9d249beab..173f98181 100644 --- a/docs/en/02_Developer_Guides/16_Execution_Pipeline/index.md +++ b/docs/en/02_Developer_Guides/16_Execution_Pipeline/index.md @@ -18,63 +18,7 @@ Check our [installation guides](/getting_started/installation) on how other web The standard SilverStripe project ships with a `.htaccess` file in your webroot for this purpose. By default, requests will be passed through for files existing on the filesystem. Some access control is in place to deny access to potentially sensitive files in the webroot, such as YAML configuration files. -If no file can be directly matched, control is handed off to `framework/main.php`. - - ### SILVERSTRIPE START ### - - # Deny access to templates (but allow from localhost) - - Order deny,allow - Deny from all - Allow from 127.0.0.1 - - - # Deny access to IIS configuration - - Order deny,allow - Deny from all - - - # Deny access to YAML configuration files which might include sensitive information - - Order allow,deny - Deny from all - - - # Route errors to static pages automatically generated by SilverStripe - ErrorDocument 404 /assets/error-404.html - ErrorDocument 500 /assets/error-500.html - - - SetEnv HTTP_MOD_REWRITE On - RewriteEngine On - - # Deny access to potentially sensitive files and folders - RewriteRule ^vendor(/|$) - [F,L,NC] - RewriteRule silverstripe-cache(/|$) - [F,L,NC] - RewriteRule composer\.(json|lock) - [F,L,NC] - - # Non existant files passed to requesthandler - # Try finding the module in the vendor folder first - RewriteCond %{REQUEST_URI} ^(.*)$ - RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule .* ../vendor/silverstripe/framework/main.php?url=%1 [QSA] - - # If requesting the main script directly, rewrite to the installer - RewriteCond %{REQUEST_URI} ^(.*)/framework/main.php$ - RewriteCond %{REQUEST_FILENAME} !-f - RewriteRule . %1/install.php? [R,L] - - - ### SILVERSTRIPE END ### - -SilverStripe can also operate without this level of rewriting, in which case all dynamic requests go -through an `index.php` script in the webroot. - -
-Running SilverStripe without web server based rewriting is not recommended since it -can leave sensitive files exposed to public access (the `RewriteRule` conditions from above don't apply). -
+If no file can be directly matched, control is handed off to `index.php`. ## Bootstrap @@ -86,7 +30,7 @@ tasks silently in the background. [configuration file](/getting_started/environment_management) in the webroot. * Sets constants based on the filesystem structure (e.g. `BASE_URL`, `BASE_PATH` and `TEMP_PATH`) -All requests go through `main.php`, which sets up the core [Kernel](api:SilverStripe\Core\Kernel) and [HTTPApplication](api:SilverStripe\Control\HTTPApplication) +All requests go through `index.php`, which sets up the core [Kernel](api:SilverStripe\Core\Kernel) and [HTTPApplication](api:SilverStripe\Control\HTTPApplication) objects. See [/developer_guides/execution_pipeline/app_object_and_kernel] for details on this. The main process follows: @@ -101,13 +45,12 @@ The main process follows: While you usually don't need to modify the bootstrap on this level, some deeper customizations like adding your own manifests or a performance-optimized routing might require it. -An example of this can be found in the ["staticpublisher" module](https://github.com/silverstripe-labs/silverstripe-staticpublisher/blob/master/main.php). -The modules instructs web servers to route through its own `main.php` to determine which requests can be cached -before handing control off to SilverStripe's own `main.php`. +An example of this can be found in the ["staticpublisher" module](https://github.com/silverstripe-labs/silverstripe-staticpublisher/). ## Routing and Request Handling -The `main.php` script relies on [Director](api:SilverStripe\Control\Director) to work out which [controller](../controllers/) should handle this request. It parses the URL, matching it to one of a number of patterns, +The `index.php` script relies on [Director](api:SilverStripe\Control\Director) to work out which [controller](../controllers/) +should handle this request. It parses the URL, matching it to one of a number of patterns, and determines the controller, action and any argument to be used ([Routing](../controllers/routing)). * Creates a [HTTPRequest](api:SilverStripe\Control\HTTPRequest) object containing all request and environment information diff --git a/docs/en/04_Changelogs/4.0.0.md b/docs/en/04_Changelogs/4.0.0.md index 18717b25b..e3bebf8ca 100644 --- a/docs/en/04_Changelogs/4.0.0.md +++ b/docs/en/04_Changelogs/4.0.0.md @@ -81,20 +81,34 @@ 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/). +Since 4.0, URL rewrite capabilities are required, +unless you PHP's built-in webserver through [silverstripe/serve](https://github.com/silverstripe/silverstripe-serve). -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 +addMiddleware(new ErrorControlChainMiddleware($app)); +$response = $app->handle($request); +$response->output(); ``` #### Upgrade references to renamed and namespaced classes diff --git a/main.php b/main.php deleted file mode 100644 index ae38ff532..000000000 --- a/main.php +++ /dev/null @@ -1,18 +0,0 @@ -addMiddleware(new ErrorControlChainMiddleware($app)); -$response = $app->handle($request); -$response->output(); diff --git a/src/Control/Director.php b/src/Control/Director.php index 109135cf1..2514e155b 100644 --- a/src/Control/Director.php +++ b/src/Control/Director.php @@ -255,7 +255,7 @@ class Director implements TemplateGlobalProvider } else { $newVars['_GET'] = []; } - $newVars['_SERVER']['REQUEST_URI'] = Director::baseURL() . $url; + $newVars['_SERVER']['REQUEST_URI'] = Director::baseURL() . ltrim($url, '/'); $newVars['_REQUEST'] = array_merge($newVars['_GET'], $newVars['_POST']); // Normalise vars diff --git a/src/Control/HTTPRequest.php b/src/Control/HTTPRequest.php index b77bf0d5e..150bcb733 100644 --- a/src/Control/HTTPRequest.php +++ b/src/Control/HTTPRequest.php @@ -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); } diff --git a/src/Control/HTTPRequestBuilder.php b/src/Control/HTTPRequestBuilder.php index c1d039cdc..7bdad706e 100644 --- a/src/Control/HTTPRequestBuilder.php +++ b/src/Control/HTTPRequestBuilder.php @@ -32,9 +32,13 @@ class HTTPRequestBuilder */ public static function createFromVariables(array $variables, $input) { - // Strip `url` out of querystring - $url = $variables['_GET']['url']; - unset($variables['_GET']['url']); + // Remove query parameters (they're retained separately through $server['_GET'] + $url = parse_url($variables['_SERVER']['REQUEST_URI'], PHP_URL_PATH); + + // 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)); + } // 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=.*)$/', $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']); diff --git a/src/Core/Manifest/ClassManifest.php b/src/Core/Manifest/ClassManifest.php index 3d6eba408..9b64c8c4c 100644 --- a/src/Core/Manifest/ClassManifest.php +++ b/src/Core/Manifest/ClassManifest.php @@ -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); diff --git a/src/Core/Startup/ErrorControlChain.php b/src/Core/Startup/ErrorControlChain.php index 3f75d9040..f34a2c802 100644 --- a/src/Core/Startup/ErrorControlChain.php +++ b/src/Core/Startup/ErrorControlChain.php @@ -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 diff --git a/src/Core/Startup/ParameterConfirmationToken.php b/src/Core/Startup/ParameterConfirmationToken.php index 6162ebee1..9b8d236d4 100644 --- a/src/Core/Startup/ParameterConfirmationToken.php +++ b/src/Core/Startup/ParameterConfirmationToken.php @@ -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 diff --git a/src/Dev/Install/InstallRequirements.php b/src/Dev/Install/InstallRequirements.php index 896047ca8..a349bb3a6 100644 --- a/src/Dev/Install/InstallRequirements.php +++ b/src/Dev/Install/InstallRequirements.php @@ -881,7 +881,7 @@ class InstallRequirements if ($this->testApacheRewriteExists()) { return true; } else { - $this->warning($testDetails); + $this->error($testDetails); return false; } } diff --git a/src/Dev/Install/Installer.php b/src/Dev/Install/Installer.php index 4806c3299..4811bbb31 100644 --- a/src/Dev/Install/Installer.php +++ b/src/Dev/Install/Installer.php @@ -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 TEXT; @@ -510,9 +506,8 @@ TEXT; - - + diff --git a/src/Logging/DetailedErrorFormatter.php b/src/Logging/DetailedErrorFormatter.php index 370285823..c55cc8bf1 100644 --- a/src/Logging/DetailedErrorFormatter.php +++ b/src/Logging/DetailedErrorFormatter.php @@ -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; }