In our previous blog post, we detailed a clever external redirect
solution to address the Apache 2.4 regression that broke automatic
directory handling when DirectorySlash Off was set. We teased the
question: Can we achieve the same behavior with an internal
redirect? Spoiler alert - Nope.
In this follow-up post, we’ll explore why internal rewrites fall short, our failed attempts to make them work, and why the external redirect remains the best and only solution.
/dir without a trailing slash, Apache
would automatically redirect them to /dir/.index.html (or any file
specified by DirectoryIndex).DirectorySlash Off is set, Apache stops auto-redirecting
directories./dir as /dir/, Apache tries to serve
/dir as a file, which leads to 403 Forbidden errors.DirectoryIndex no longer inherits globally from the document
root - each directory must be explicitly configured to serve an
index file.DirectoryIndex after an internal rewrite.Since Apache wasn’t redirecting directories automatically anymore, we thought we could internally rewrite requests like this:
RewriteEngine On
# If the request is missing a trailing slash and is a directory, rewrite it internally
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI} -d
RewriteRule ^(.*)$ /$1/ [L]
Why This Doesn’t Work:
DirectoryIndex after the rewrite.DirectoryIndex is not explicitly defined for each
directory, Apache still refuses to serve the file and throws a
403 Forbidden./dir as a raw file request instead of checking for an index page.To make it work, we tried to manually configure every directory:
<Directory "/var/www/vhosts/treasurersbriefcase/htdocs/setup/">
Require all granted
DirectoryIndex index.roc
</Directory>
DirectoryIndex after an internal
rewrite. Even though DirectoryIndex index.roc is explicitly set,
Apache never reaches this directive after rewriting /setup to /setup/./setup/ as an empty directory, leading to a 403
Forbidden error.This means that even if we were willing to configure every directory manually, it still wouldn’t work as expected.
We briefly considered whether FallbackResource could help by
redirecting requests for directories to their respective index files:
<Directory "/var/www/vhosts/treasurersbriefcase/htdocs/setup/">
DirectoryIndex index.roc
Options -Indexes
Require all granted
FallbackResource /setup/index.roc
</Directory>
FallbackResource is designed to handle 404 Not Found errors, not 403 Forbidden errors./setup/ as a valid directory but
refuses to serve it, FallbackResource is never triggered.DirectoryIndex after an internal rewrite.This was a red herring in our troubleshooting FallbackResource was
never a viable solution.
Another way to handle this issue would be to explicitly rewrite
directory requests to their corresponding index file, bypassing
Apache’s DirectoryIndex handling entirely:
RewriteEngine On
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI} -d
RewriteRule ^(.*)$ /$1/index.roc [L]
DirectoryIndex handling in Apache 2.4.DirectorySlash Off, since the request is rewritten directly to a file.index.html,
index.php, etc.), additional rules would be required.While this approach technically works, it reinforces our main conclusion: - Apache 2.4 no longer restarts the request cycle after a rewrite, so we need to account for it manually. - The external redirect remains the only scalable solution.
Instead of fighting Apache’s new behavior, we can work with it using an external redirect:
RewriteEngine On
RewriteCond %{REQUEST_URI} !/$
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI} -d
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [R=301,L]
/dir to /dir/ before Apache even tries to serve it.DirectoryIndex behavior globally, just like Apache 2.2.So, can we solve with an internal redirect?
DirectoryIndex after an internal rewrite.DirectoryIndex settings fail if Apache
has already decided the request is invalid.FallbackResource never applied, since Apache rejected the request with 403 Forbidden, not 404
Not Found.Does our external redirect solution still hold up?
Yes!!, and in fact, it’s not just the best solution - it’s the only reliable one.
DirectorySlash Off is set.If you haven’t read our original post yet, check it out here for the full explanation of our external redirect fix.
In part III of this series we’ll beat this dead horse and potentially explain why this was a problem in the first place…
Next post: How to Fix Apache 2.4 Broken Directory Requests (Part III)
Previous post: How to Fix Apache 2.4 Broken Directory Requests