Falk Falk - 1 month ago 5
Apache Configuration Question

More simplistic way of doing OR rewrites in apache2?

Is there a shorter way to get the get the domainname in a regex and forward it in a rewrite than the example below?

Now I catch "every" domain and do a rewrite to www.domain[A|B|C].com.
And I need to catch "*.domain[A|B|C].com" and "domain[A|B|C].com" in every domain too.

<VirtualHost *:80>
RewriteEngine On

#domainA.com
RewriteCond %{http_host} ^domainA\.com$ [OR,NC]
RewriteCond %{http_host} ^(.+)\.domainA\.com$ [NC]
RewriteRule ^\/?(.*)$ http://www.domainA.com/$1 [R=301,L]

#domainB.com
RewriteCond %{http_host} ^domainB\.com$ [OR,NC]
RewriteCond %{http_host} ^(.+)\.domainB\.com$ [NC]
RewriteRule ^\/?(.*)$ http://www.domainB.com/$1 [R=301,L]

#domainC.com
RewriteCond %{http_host} ^domainC\.com$ [OR,NC]
RewriteCond %{http_host} ^(.+)\.domainC\.com$ [NC]
RewriteRule ^\/?(.*)$ http://www.domainC.com/$1 [R=301,L]

</VirtualHost>

<VirtualHost *:80>
Servername servername.com

ServerAlias www.domainA.com www.domainB.com www.domainC.com

# Server config stuffz here

</VirtualHost>


If this is fuzzy, I'll try to explain more :)

--

Regards Falk

Answer

You can rewrite your 3 rules in one:

    RewriteCond %{HTTP_HOST} (?:.+\.)?(domain[ABC]\.com)$ [NC]
    RewriteRule .* http://www.%1/$0 [R=permanent,L]
  • domainA.com or *.domainA.com can be written as (?:.+\.)?domainA\.com:
    • (.+\.)? makes subdomain part optional
    • the eventual subdomain part is not reused, so we can use a non capturing subpattern ((?: ... ))
  • domainA or domainB or domainC = domain[ABC] (if for real, it's foo, bar and doe, use (?:foo|bar|doe) instead)
  • we can reinject the capture from the last RewriteCond to Rewritule. The difference with captures from RewriteRule (its first argument) is that they are prefixed by a % instead of $. So %1 will correspond to domainA.com or domainB.com or domainC.com
  • I've also rewritten ^\/?(.*)$ + $1 to .* + $0:
    • no need to escape /, this is not a metacharacter and with Apache regexpes don't have any delimiter (not like preg_* from PHP)
    • $0 is a special capture which takes the substring that matches the whole pattern (the path - or part of it in a directory context)
Comments