views:

19

answers:

1

I'm working through a problem where I want to select a different static content file based on the incoming Host header. The simple example is a mapping from URLs to files like this:

  • www.example.com/images/logo.gif -> \images\logo.gif
  • skin2.example.com/images/logo.gif -> \images\skin2\logo.gif
  • skin3.example.com/images/logo.gif -> \images\skin3\logo.gif

I have this working with the following RewriteRules, but I don't like how I have to repeat myself so much. Each host has the same set of rules, and each RewriteCond and RewriteRule has the same path. I'd like to use the RewriteMap, but I don't know how to use it to map the %{HTTP_HOST} to the path.

<VirtualHost *:80>
    DocumentRoot "C:/Program Files/Apache Software Foundation/Apache2.2/htdocs"
    ServerName www.example.com
    ServerAlias skin2.example.com
    ServerAlias skin3.example.com

    RewriteEngine On

    RewriteCond %{HTTP_HOST} skin2.example.com
    RewriteCond %{DOCUMENT_ROOT}$1/skin2/$2 -f
    RewriteRule ^(.*)/(.*) $1/skin2/$2 [L]

    RewriteCond %{HTTP_HOST} skin3.example.com
    RewriteCond %{DOCUMENT_ROOT}$1/skin3/$2 -f
    RewriteRule ^(.*)/(.*) $1/skin3/$2 [L]
</VirtualHost>

The concept behind the rules is if the same filename exists in a subdirectory for that host, use it instead of the direct targeted file. This uses host based subdirectories at the lowest level, and not a top level subdirectory to separate content.

Update: I want to revise the question to assume the hostname doesn't match the subdirectory exactly, but does exist as a 1-1 map. Here would be the revised URL to file mapping.

  • www.example.com/images/logo.gif -> \images\logo.gif
  • skin2.example.com/images/logo.gif -> \images\s2\logo.gif
  • skin3.example.com/images/logo.gif -> \images\s3\logo.gif

For use with RewriteMap, I created this data file:

##  hostmap.txt -- hostname to subdirectory map
skin2.example.com    s2   # map skin2 to s2 directory
skin3.example.com    s3   # map skin2 to s3 directory

And changed the RewriteRules to use %{HTTP_HOST} directly in the map call, which seems to be working.

RewriteEngine On
RewriteMap hostmap txt:conf/hostmap.txt 
RewriteCond %{DOCUMENT_ROOT}$1/${hostmap:%{HTTP_HOST}}/$2 -f
RewriteRule ^(.*)/(.*) $1/${hostmap:%{HTTP_HOST}}/$2 [L]
+2  A: 

Try this rule:

RewriteCond %{HTTP_HOST} ^(skin\d+)\.example\.com$
RewriteCond %{DOCUMENT_ROOT}$1/%1/$2 -f
RewriteRule ^([^/]+)/([^/]+)$ $1/%1/$2 [L]
Gumbo
This would work, but I realized I need to update my question. Also, this got me to my answer.
Kevin Hakanson
@Kevin Hakanson: You can avoid one additional lookup by storing the value this way:`RewriteCond ${hostmap:%{HTTP_HOST}} .+ RewriteCond %{DOCUMENT_ROOT}$1/%0/$2 -f RewriteRule ^([^/]+)/([^/]+)$ $1/%0/$2 [L]`
Gumbo
Does this use the first RewriteCond as a side effect to set %0? With RewriteLogLevel 9, I was seeing these lookups were cached. cache lookup OK: map=hostmap[txt] key=skin3.example.com -> val=s3
Kevin Hakanson