RewriteCond %{HTTP_HOST} ^(.*)\.example\.com
RewriteRule ^(.*)$ Subdomains/%1/$1 [L,NC,QSA]
Without any other directives to prevent it, the above will result in an internal rewrite loop, which will result in a 500 Internal Server Error response to the browser.
For example, if you request https://sub.example.com/foo
then...
- Request is rewritten to
/Subdomains/sub/foo
.
- In a directory context (ie.
htaccess
) the rewriting process starts over, passing /Subdomains/sub/foo
as in the input to the next round of processing...
- Request is rewritten to
/Subdomains/sub/Subdomains/sub/foo
.
- The rewriting process starts over...
- Request is rewritten to
/Subdomains/sub/Subdomains/sub/Subdomains/sub/foo
.
- The rewriting process starts over...
- etc. until the server gives up. (Default is after 10 internal rewrites.)
The L
flag does not stop all processing in a directory context (ie. htaccess
). It simply stops the current round of processing. The rewrite process continues until the URL passes through unchanged.
The quick fix on Apache 2.4 is to simply replace the L
flag with END
. This causes all processing to stop. No further passes through the rewrite engine occur.
For example:
RewriteCond %{HTTP_HOST} ^(.*)\.example\.com
RewriteRule (.*) Subdomains/%1/$1 [END]
The NC
and QSA
flags are superfluous here.
Note that the regex ^(.*)\.example\.com
matches any number of sub-subdomains, including www
itself, if that is a concern?
Without using the END
flag (Apache 2.4) then you would need to explicitly check that you have not already rewritten the URL. One way is to prevent any further rewrites if /Subdomains/....
has already been requested:
RewriteCond %{HTTP_HOST} ^(.*)\.example\.com
RewriteRule ^((?!Subdomains/).*)$ Subdomains/%1/$1 [L]
Note that if you have another .htaccess
file located in the /Subdomains/<sub>
subdirectory that also uses mod_rewrite then this will have also prevented a rewrite loop since mod_rewrite directives are not inherited by default.
UPDATE: Is there a way to check if the folder dosent exist then just redirect to domain.com?
Yes, you can do this, for example:
# If subdomain does not map to a subdirectory then redirect to root of main domain
RewriteCond %{HTTP_HOST} ^(.*)\.(example\.com)
RewriteCond %{DOCUMENT_ROOT}/Subdomains/%1 !-d
RewriteRule ^ https://%2/ [R=302,L]
# Otherwise, internally rewrite the request to subdirectory (if not already)
RewriteCond %{HTTP_HOST} ^(.*)\.example\.com
RewriteRule ^((?!Subdomains/).*)$ Subdomains/%1/$1 [L]
However, this is arguably detrimental to your users. A custom 404 response might be preferable.