问题
Problems with mod_rewrite
I am having more trouble than I thought when it comes to Apache's mod_rewrite
. I've already posted one question on the
matter, and that has been clarified, but I continue to get errors where I cannot see any logical fault in the
configuration. Any help would be greatly appreciated!
The .htaccess
I am using is the following:
# Begin Rewrite Module for http://*.example.com/
# ==============================================
<IfModule mod_rewrite.c>
# Turn the rewrite engine on and set the base path.
RewriteEngine On
RewriteBase /
# Map subdomains to their respective directories.
RewriteCond %{HTTP_HOST} ^([^\.]+)\.example\.com$ [NC]
RewriteRule ^(.*)$ public_subdomains/%1/$1 [L]
</IfModule>
This doesn't work because of too many internal redirects, resulting in a 500 Internal Server Error
- here is the debug log for it:
[Fri Feb 15 16:49:30.318509 2013] [core:error] [pid 2316:tid 1708] [client 127.0.0.1:9141] AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
[Fri Feb 15 16:49:30.318509 2013] [core:debug] [pid 2316:tid 1708] core.c(3502): [client 127.0.0.1:9141] AH00121: r->uri = /public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/index.php
[Fri Feb 15 16:49:30.318509 2013] [core:debug] [pid 2316:tid 1708] core.c(3508): [client 127.0.0.1:9141] AH00122: redirected from r->uri = /public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/index.php
[Fri Feb 15 16:49:30.318509 2013] [core:debug] [pid 2316:tid 1708] core.c(3508): [client 127.0.0.1:9141] AH00122: redirected from r->uri = /public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/index.php
[Fri Feb 15 16:49:30.318509 2013] [core:debug] [pid 2316:tid 1708] core.c(3508): [client 127.0.0.1:9141] AH00122: redirected from r->uri = /public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/index.php
[Fri Feb 15 16:49:30.318509 2013] [core:debug] [pid 2316:tid 1708] core.c(3508): [client 127.0.0.1:9141] AH00122: redirected from r->uri = /public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/index.php
[Fri Feb 15 16:49:30.318509 2013] [core:debug] [pid 2316:tid 1708] core.c(3508): [client 127.0.0.1:9141] AH00122: redirected from r->uri = /public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/index.php
[Fri Feb 15 16:49:30.318509 2013] [core:debug] [pid 2316:tid 1708] core.c(3508): [client 127.0.0.1:9141] AH00122: redirected from r->uri = /public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/index.php
[Fri Feb 15 16:49:30.318509 2013] [core:debug] [pid 2316:tid 1708] core.c(3508): [client 127.0.0.1:9141] AH00122: redirected from r->uri = /public_subdomains/sub1/public_subdomains/sub1/public_subdomains/sub1/index.php
[Fri Feb 15 16:49:30.318509 2013] [core:debug] [pid 2316:tid 1708] core.c(3508): [client 127.0.0.1:9141] AH00122: redirected from r->uri = /public_subdomains/sub1/public_subdomains/sub1/index.php
[Fri Feb 15 16:49:30.318509 2013] [core:debug] [pid 2316:tid 1708] core.c(3508): [client 127.0.0.1:9141] AH00122: redirected from r->uri = /public_subdomains/sub1/index.php
[Fri Feb 15 16:49:30.318509 2013] [core:debug] [pid 2316:tid 1708] core.c(3508): [client 127.0.0.1:9141] AH00122: redirected from r->uri = /
I found a sort-of solution for it, by replacing the [L]
flag for the [END]
flag on the RewriteRule, and it works perfectly mapping the request URI exactly to the corresponding file in the sub-domain directory.
Unfortunately it works too perfectly. A call to subdomain.example.com/folder/
interally rewrites to example.com/public_subdomains/subdomain/folder/
without taking into account the DirectoryIndex, when it should rewrite as example.com/public_subdomains/subdomain/folder/index.php
(assuming that index.php
is set as the DirectoryIndex).
If anyone can help me shed light on this, I would be eternally grateful!
回答1:
Well, there is a logic error all right. Let me refer you to the wonderful control flow diagram from the docs:
You see, an internal redirect is a request too, so it's once again processed by any and all rewrite rules. So, suppose a user requests something.example.com/x: RewriteRule macthes, RewriteCond is fulfilled, so an internal redirect to public_subdomains/something/x is made. The new request is to something.example.com/public_subdomains/something/x: RewriteRule matches, RewriteCond is fulfilled... And there you have the endless loop.
The [L] flag only stops processing of the current request: the request will be processed in the second pass anyway. The [END] flag does stop the loop, but it's a brute-force thing, as you've noticed it has side effects, so it'd be better to incorporate a condition that stops the recursion. Something like this:
RewriteCond %{HTTP_HOST} ^([^\.]+)\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/public_subdomains/%1
RewriteRule ^(.*)$ public_subdomains/%1/$1 [L]
The added RewriteCond would check to see if the requested uri already begins with "public_subdomains/something".
It's untested, so may have issues, but this is the basic idea.
来源:https://stackoverflow.com/questions/14805267/mod-rewrite-error-whilst-rewriting-subdomain-to-directory-via-http-host