I have dug high and low around Google and StackOverflow to try and figure out my problem, trying countless solutions but nothing has completely worked.
I\'m looking to m
Jon Lin's answer was very helpful in determining what was causing the problem in my very similar setup. For completeness I will include the relevant information from his answer:
This is probably happening because mod_dir (the module that automatically redirects the browser if a request for a directory is missing a trailing slash to the same thing with a trailing slash. See the DirectorySlash directive in mod_dir
What's happening is:
- You request:
mydomain.com/Contact
- mod_dir doesn't touch this since
/Contact
isn't a directory/Contact
gets rewritten to/subdir/Contact
and internally redirected- mod_dir sees that
/subdir/Contact
is a directory and missing the trailing slash so it redirects the browser tomydomain.com/subdir/Contact/
- So now, your browser's location bar has the /subdir/ in it.
In my case, I had requests being redirected to /subdir
with a few exceptions and didn't want to have to re-enable DirectorySlash for each of those exceptions.
By allowing RewriteEngine to continue after the initial redirect to /subdir
, it's possible to mimic what mod_dir would be doing while also taking /subdir
into account, before mod_dir gets to see it.
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/exception1|exception2|...
RewriteRule ^(.*)$ /subdir/$1
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^subdir/(.*) $1/ [R,L]
Note: You may need to be careful about allowing RewriteEngine to continue if there are further rules. Not matching the second rule will continue on to any further rules which may produce a different result.
This can be avoided by using a third rule to stop RewriteEngine processing if the redirect into /subdir
has happened:
RewriteCond %{REQUEST_URI} ^subdir
RewriteRule .* - [L]
This is probably happening because mod_dir (the module that automatically redirects the browser if a request for a directory is missing a trailing slash to the same thing with a trailing slash. See the DirectorySlash directive in mod_dir
What's happening is:
mydomain.com/Contact
/Contact
isn't a directory/Contact
gets rewritten to /subdir/Contact
and internally redirected/subdir/Contact
is a directory and missing the trailing slash so it redirects the browser to mydomain.com/subdir/Contact/
You can add DirectorySlash off
in your .htaccess to turn off mod_dir from redirecting. But if you want directories to have trailing slashes, you can add a separate condition for it. Based on what you already have, we can expand it to this:
RewriteEngine on
# Has a trailing slash, don't append one when rewriting
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain\.com$
RewriteCond %{REQUEST_URI} !^/subdir/
RewriteCond %{THE_REQUEST} ./\ HTTP/1\.[01]$ [OR]
# OR if it's a file that ends with one of these extensions
RewriteCond %{REQUEST_URI} \.(php|html?|jpg|gif|css)$
RewriteRule ^(.*)$ /subdir/$1 [L]
# Missing trailing slash, append one
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain\.com$
RewriteCond %{REQUEST_URI} !^/subdir/
RewriteCond %{THE_REQUEST} [^/]\ HTTP/1\.[01]$
# But only if it's not a file that ends with one of these extensions
RewriteCond %{REQUEST_URI} !\.(php|html?|jpg|gif|css)$
RewriteRule ^(.*)$ /subdir/$1/ [L]
Note: I changed !^/mydomain/
to !^/subdir/
, figured it was a typo because without it, mod_rewrite would loop internally indefinitely (foo -> /subdir/foo -> /subdir/subdir/foo -> /subdir/subdir/subdir/foo, etc). If I got that wrong, you can change it back.
Edit: See my additions of RewriteCond's matching against \.(php|html?|jpg|gif|css)
. These are the file extensions that get passed through without getting trailing slashes added. You can add/remove to suit your needs.