TL;DR: My URL rewriting breaks if a subdirectory without a file is requested. Instead of loading a default home
page as expected, I'm getting a 403 Forbidden error.
I'm using Apache URL rewriting to build a site using the Front Controller pattern. So far, my .htaccess
looks like this:
Options -Indexes
RewriteCond %{REQUEST_URI} ^/(subdir|subdir/.*|subdir2|subdir2/.*).*$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+) index.php?request=$1 [QSA]
So this is working for all requests except requests for subdirectories:
mydomain.com/
results in ->mydomain.com/index.php
withhome.inc
content
mydomain.com/page1
results in ->mydomain.com/index.php
with/pages/page1.inc
content
mydomain.com/subdir/
results in ->403 Forbidden
mydomain.com/subdir/page1
results in ->mydomain.com/index.php
with/subdir/pages/page1.inc
content
More details below that probably don't matter, since the issue is likely in the .htaccess
.
In index.php
, I'm catching the request and using that to grab the corresponding include page from a directory /pages
which has files with the content of each page. Here's the (somewhat simplified) code from index.php
:
//grab the actual HTTP request
$request = $_GET['request'];
//if the request has slashes, isolate the directory part into $dir
$slashPos = strrpos($request, "/");
if($slashPos !== false){
$dir = substr($request, 0, $slashPos) . "/";
$page = basename($request, ".inc");
} else {
$dir = "";
$page = request;
}
//use "home" if no filename is specified.
if($page==""){$page="home";}
//build path to content include
$content = $dir . "pages/" . $page . ".inc";
//output page
require("header.php");
require($content );
require("footer.php");
This works perfect for the root directory. A request for mydomain.com/page1
results in mydomain.com/index.php
being served with the contents of mydomain.com/pages/page1
included.
It also works for pages within a subdirectory: a request for mydomain.com/subdir/page1
results in mydomain.com/index.php
being served with the contents of mydomain.com/subdir/pages/page1
included.
It all breaks when the request is for an actual directory. So mydomain.com/subdir/
returns 403 Forbidden. Why is it doing that? I expect it to load $dir
with subdir
and $page
with home
(I set as a default for when $page==""
).
Yes, Options -Indexes
is probably causing the 403
, but why only on subdirectories? It doesn't 403
on root. And the line RewriteCond %{REQUEST_URI} ^/(subdir|subdir/.*|subdir2|subdir2/.*).*$
in .htaccess
should catch it, right?