Angel
Angel

Reputation: 155

.htaccess RewriteRule makes the address bar url changes when there isn't an end slash

I have an strange situation with .htaccess configuration. I have a multidomain hosting, with one directory per each domain. For example, I have:

http://www.domain1.com
http://www.domain2.com

and the following directory structure:

/domain1/
/domain1/index.php
/domain2/
/domain2/index.php
/domain2/subdirectory/
/domain2/subdirectory/index.php

and a .htaccess file with the following content:

RewriteEngine On

RewriteCond %{HTTP_HOST} ^(www\.)?domain1\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/domain1/.*$
RewriteRule ^(.*)$ domain1/$1 [L]

RewriteCond %{HTTP_HOST} ^(www\.)?domain2\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/domain2/.*$
RewriteRule ^(.*)$ domain2/$1 [L]

all works as I like with one exception: if I do:

http://www.domain2.com/subdirectory/

(with a slash at the end) the content is showed propertly and the url on the address bar keep unchanged, but if I do:

http://www.domain2.com/subdirectory

(without a slash at the end) the content is showed properly but the url on the address bar is changed to:

http://www.domain2.com/domain2/subdirectory/

(notice the subdirectory name and a slash is appended at the end) and I don't like the user see that change on the address bar, that's my problem

Upvotes: 1

Views: 1178

Answers (1)

Jon Lin
Jon Lin

Reputation: 143896

This is mod_dir and DirectorySlash interferring with the URI-file mapping pipeline. By default DirectorySlash is turned on, which makes it so when apache thinks a request is for a directory, and it's missing the trailing slash, then it 301 redirects to the URI with the trailing slash. There's a good reason for doing this because of a possible information disclosure security concern. If you don't allow for directory indexing, you could just turn it off:

DirectorySlash Off

And then Apache won't redirect to the trailing slash at all. Or you can do the redirecting yourself as part of the rewrite engine. The reason why your internally rewritten URL is exposed is because 2 modules are mangling the URI, mod_dir and mod_rewrite, and they're doing it without any awareness of each other. So the URI gets rewritten by mod_rewrite and then mod_dir comes along and says "this is a directory!", mangles the URI some more by adding a trailing slash and flags it for a redirect response. Eventually, what you get is a redirect with a mangled URI. By handling the redirect from within mod_rewrite, by the time it gets to mod_dir, everything's peachy.

These would need to be above your current rules

RewriteCond %{HTTP_HOST} ^(www\.)?domain1\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/domain1/.*$
RewriteCond %{DOCUMENT_ROOT}/domain1%{REQUEST_URI} -d
RewriteRule ^(.*[^/])$ /$1/ [L,R=301]

RewriteCond %{HTTP_HOST} ^(www\.)?domain2\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/domain2/.*$
RewriteCond %{DOCUMENT_ROOT}/domain2%{REQUEST_URI} -d
RewriteRule ^(.*[^/])$ /$1/ [L,R=301]

Upvotes: 1

Related Questions