John J. Camilleri
John J. Camilleri

Reputation: 4450

Match HTTP_HOST within a RewriteRule instead of using RewriteCond

I have a bunch of 301 redirects I need to make which contain varying domains all from within the same .htaccess file. I could write a RewriteCond for each rule as below and it works fine:

RewriteCond %{HTTP_HOST} www.domain1.com [NC]
RewriteRule old-url-1a.htm /new-url-1a [L,R=301]

RewriteCond %{HTTP_HOST} www.domain1.com [NC]
RewriteRule old-url-1b.htm /new-url-1b [L,R=301]

RewriteCond %{HTTP_HOST} www.domain2.com [NC]
RewriteRule old-url-2a.htm /new-url-2a [L,R=301]

RewriteCond %{HTTP_HOST} www.domain2.com [NC]
RewriteRule old-url-2b.htm /new-url-2b [L,R=301]

But using this method I need to have 2 lines of code for every single URL which gets very lengthy and repetitive (the same RewriteCond is repeated many times). Is there any way I can match the HTTP_HOST from within the RewriteRule directive itself? Something along these lines (conceptually):

RewriteRule www.domain1.com/old-url-1a.htm /new-url-1a [L,R=301]
RewriteRule www.domain1.com/old-url-1b.htm /new-url-1b [L,R=301]

RewriteRule www.domain2.com/old-url-2a.htm /new-url-2a [L,R=301]
RewriteRule www.domain2.com/old-url-2b.htm /new-url-2b [L,R=301]

Thanks.

Upvotes: 3

Views: 10040

Answers (2)

Bashman
Bashman

Reputation: 11

BTW mapping may be the only way to debug "what is really matched"

You can set RewriteLogLevel to 9, the logs don't show what is parsed with RewriteCond.
Instead it says whether "it matched" or not. Not very useful.

Using maps (RewriteMap), the logs clearly say what key is passed. Example :
(/var/log/http/rewrite.log) map lookup OK: map=host-redirects[txt] key=WHAT_IS_PARSED -> WHAT_IS_RETURNED
or
map lookup FAILED: map=host-redirects[txt] key=WHAT_IS_PARSED

Using RewriteRule, the right term after | designates the default returned value.
In most cases, a default 404.html page or somewhat. Very useful.

So in your httpd.conf, set
RewriteLog logs/rewrite.log RewriteLofLevel 9
in your virtualhost, and you're done :)

Upvotes: 1

heiko
heiko

Reputation: 454

The Apache Documentation says about RewriteRule:

What is matched?

The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string. If you wish to match against the hostname, port, or query string, use a RewriteCond with the %{HTTP_HOST}, %{SERVER_PORT}, or %{QUERY_STRING} variables respectively.

But if you are able to put the rules inside your apache-config, there is another shorthand way: You could use a RewriteMap.

RewriteMap     host-redirects   txt:/etc/apache2/host-redirects.map
RewriteRule ^/([^/]*).htm$ http://%{HTTP_HOST}/${host-redirects:%{HTTP_HOST}/$1|$1} [R,L]

The host-redirects.map would look like this:

www.domain1.com/old-url-1a.htm /new-url-1a/
www.domain1.com/old-url-1b.htm /new-url-1b/
www.domain2.com/old-url-2a.htm /new-url-2a/

Upvotes: 3

Related Questions