Forum Moderators: phranque
I have a problem that I have been working on for awhile now and cannot seem to get straight. Hopefully, someone here might be able to help out.
I am simply trying to redirect url requests to subdirectories dependent on the requested domain. It is sort of a pseudo virtual hosting under a single user account since I don't have access to httpd.conf on this server.
Here is my .htaccess file:
RewriteEngine on
RewriteRule ^(.*) /%{HTTP_HOST}/$1 [L] This works exactly as it should to redirect a request for [domain.com...] to [domain.com...] while displaying the url in the browser simply as [domain.com....]
As a side note, it was necessary for me to add another .htaccess file in each domain's subdirectory to turn the RewriteEngine off to avoid the infinite loops that occur.
My problem is that I cannot browse directly to any subdirectories of the domain itself. For example, if I try to go to [domain.com...] I get a "forbidden" page.
I am not sure if it is looking for testdir at the root of the site and ignoring the .htaccess file or if it is looking inside the domain.com subdirectory and, perhaps, is being shutdown by the .htaccess file I put in the subdirectory?
Any help is greatly appreciated.
Welcome to WebmasterWorld [webmasterworld.com]!
With your posted rule, a request for http://domain.com/testdir will be redirected to http://domain.com/domain.com/testdir
You could stop the "infinite looping" you describe by several means, some possibly simpler and less restrictive that giving up mod_rewrite capability in each subdirectory.
First, you could make a list of subdomain/subdirectories, and exclude those from the rule:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/subdomain1
RewriteCond %{REQUEST_URI} !^/subdomain2
RewriteCond %{REQUEST_URI} !^/subdomain3
RewriteRule ^(.*) /%{HTTP_HOST}/$1 [L]
Aside: To save you some time, the following doesn't work:
RewriteCond %{REQUEST_URI}!^%{HTTP_HOST} Another way to do it would be to bypass the rule. This only works if this code is placed as the last mod_rewrite section in your .htaccess file:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/(subdomain1¦subdomain2¦subdomain3)
RewriteRule .* - [L]
RewriteRule ^(.*) /%{HTTP_HOST}/$1 [L]
There are many variations on the above method. The following method may be easier:
RewriteCond %{REQUEST_URI} !^/subs
RewriteRule (.*) /subs/%{HTTP_HOST}/$1 [L]
I haven't yet found a slick way to use a variable in the pattern of a RewriteCond or RewriteRule -- mod_rewrite's just not designed that way. A free beer for the first to tell me (deliverable in N. Texas).
Anyway, it's too late for me to be doing any more intense technical stuff, so I hope that helps you out.
Jim
First off, I like your suggestion of the subs/ directory, so I have implemented it. I believe that it should help keep things organized a bit better.
I changed the .htaccess as you suggested:
RewriteCond %{REQUEST_URI}!^/subs
RewriteRule (.*) /subs/%{HTTP_HOST}/$1 [L]
and I removed the .htaccess files in the subdirectories, but it seems to be behaving in the same manner. It correctly redirects to the root of the domain, but won't let me enter the subdirectories.
I cannot go to domain.com/testdir, but I can browse directly to domain.com/subs/domain.com/testdir.
Thanks again for your help.
Well, that is strange... Let me ask a couple of questions - really related to each other...
Do you redirect all requests to www.domain.com to domain.com or vice-versa before applying the above rules?
Do you redirect all uppercase and mixed-case domain requests to the all-lowercase domain before applying the rule?
The reason I'm asking is that/subs/domain.com/testdir/ and /subs/www.domain.com/testdir/ will be two different subdirectories, and on *nix, each capitalization variant will also be a separate subdirectory unless you take steps to "standardize" the requested domain names before you look up their subdirectories.
Another tip I should mention is that when doing rewrites like this, it is critical to flush your browser cache before each new version is tested - otherwise, your browser may cache the previous 404 response, leading you to believe that nothing has changed!
BTW, I think it's a very good idea to mark all test pages and error responses as non-cacheable using mod_headers while testing rewrites of this nature, and even for normal operation, leaving the expiry time short on error pages. This minimizes the possibility of affecting a user who caches a faulty response while you are testing and the function of your site is what I like to call "non-optimal." :)
A quick way to fool caches if you are testing on a static site is to append a query string to the URL, such as "?1143" (the current time). This means nothing to the server on a static site, but will make each request unique, and avoid cache-related side-effects.
One more suggestion: Since you've already got the loop-prevention in place, you can test this as an external redirect to see where it thinks it is going, and then change it back to an internal rewrite once all the bugs are worked out.
Jim
Do you redirect all requests to www.domain.com to domain.com or vice-versa before applying the above rules?
drwxr-sr-x domain.com
lrwxrwxrwx www.domain.com -> domain.com
Do you redirect all uppercase and mixed-case domain requests to the all-lowercase domain before applying the rule?
--
I will follow your suggestions for these test pages. Be assured that I have been clearing the cache, though.
I am not positive about what you are getting at when you say that I should do an "external" redirect. But, I believe it has to do with adding the [R]:
RewriteEngine on
RewriteCond %{REQUEST_URI}!^/subs
RewriteRule (.*) /subs/%{HTTP_HOST}/$1 [R,L] Even if not, doing the above has shown me something. When I put [domain.com...] in my browser, it now redirects to [domain.com...] However, if I put [domain.com...] in my browser, no redirection occurs and I get the "forbidden" page.
This is what has been driving me crazy. All of the reading and research that I have done on this lastly states that this *should* be working. I must be missing something here. Could there be something server-side that is affecting this?
Well technically, all of this mod_rewrite stuff is server-side, but yes, there may be a directive in a higher-level http.conf or .htaccess file that is grabbing the request and changing it before you get it, thus interfering with your code's expected behaviour.
A simple way test this would be to comment out your RewriteEngine on directive, thus disabling all of your code, and then request that particular path again and see what happens.
<added>
External redirect for testing:
RewriteEngine on
RewriteCond %{REQUEST_URI}!^/subs
RewriteRule (.*) http://%{HTTP_HOST}/subs/%{HTTP_HOST}/$1 [R,L]
Jim