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