Reputation: 1224
I know there are some similar questions about subdomain -> folder htaccess, but I already have a setup that works for me for that simple case.
What I want to add, is "rewrite to projects/subdomain/current/public/ if that current/public exists, else rewrite to projects/subdomain/"
It's because I'm hosting a laravel application, which is in 'public/', and I deployed it using a tool that symlinks 'current/' to its latest release.
My current setup is:
# Redirect everything non-www to /projects/...
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www.* [NC]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.mydomain\.com
RewriteCond /var/www/mydomain.com/projects/%1 -d
RewriteRule ^(.*) /projects/%1/$1 [L]
Which is something like:
How would I update this to have an "IF /projects/subdomain/current/public exists, then that, ELSE IF /projects/subdomain exists, then that, ELSE 404"?
Thanks in advance!
Upvotes: 1
Views: 102
Reputation: 45914
Just create another rule before the existing one. For example, following the same pattern as your existing rule:
RewriteEngine on
# Redirect to /projects/<subdomain>/current/public/
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.mydomain\.com
RewriteCond /var/www/mydomain.com/projects/%1/current/public -d
RewriteRule (.*) /projects/%1/current/public/$1 [L]
# Redirect everything non-www to /projects/...
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.mydomain\.com
RewriteCond /var/www/mydomain.com/projects/%1 -d
RewriteRule (.*) /projects/%1/$1 [L]
I removed the ^
from the RewriteRule
pattern (^(.*)
) since it was superfluous.
I also changed !^www.*
(matches any hostname that simply starts "www") to !^www\.
(any hostname that starts "www." - the subdomain only) to avoid potentially spurious matches.
Presumably /var/www/mydomain.com
is the document-root, so you could use the DOCUMENT_ROOT
server variable instead in the RewriteCond
TestString. For example:
RewriteCond %{DOCUMENT_ROOT}/projects/%1/current/public -d
However, by themselves, these directives will result in a rewrite-loop (500 error), so I assume you already have directives in place that prevent this. eg. Another .htaccess
file in the directory that you are rewriting to that contains mod_rewrite directives (relevant to the individual projects)? If not then you can either add another condition to each rule that checks against the REDIRECT_STATUS
environment variable, or include an exception at the top of the file that prevents further processing after the request is rewritten. For example:
RewriteEngine On
# Stop further processing if the request has already been rewritten
RewriteCond %{ENV:REDIRECT_STATUS} !^$
RewriteRule ^ - [L]
: Remaining directives follow...
UPDATE: If you are on Apache 2.4 you can instead simply change the L
flag to END
to halt all processing by the rewrite engine, to prevent a rewrite loop. The END
flag is a relatively recent addition and consequently often gets overlooked - but it's not strictly necessary as there are always other (perhaps more complex) ways to do this.
Why would it loop?
The L
flag does not stop all processing. It simply stops the current round of processing and then the rewrite engine effectively starts over, passing the rewritten URL back into the rewrite engine. In the above example, the rewritten URL also matches the same rules, so the URL would be rewritten again, and again, and again, ....
For example (for simplicity, just using your original rule that rewrites to /projects
):
subdomain.mydomain.com/foo
<doc-root>/projects/subdomain
directory exists/projects/subdomain/foo
subdomain.mydomain.com/projects/subdomain/foo
, back into the rewrite engine.<doc-root>/projects/subdomain
directory exists (as previous)/projects/subdomain/projects/subdomain/foo
The Rewriting process loops in this fashion until the URL passes through unchanged, unless something else steps in the way... for example, as mentioned above, if you have another .htaccess
file located at /projects/subdomain/.htaccess
that also contains mod_rewrite directives then control would pass to this .htaccess
file after the first round of rewrite processing and prevent further rewrites (since mod_rewrite directives are not inherited by default).
Upvotes: 3