Regex – mod_rewrite regex to match only if a certain string does NOT exist

apachemod-rewriteregex

Looking through my server logs, I see that a lot of pages on my site are requesting favicon.ico, favicon.jpg, favicon.png, etc in a variety of different directories.

Instead of wading through each page to try to figure out where each incorrect request is coming from, I'm writing some apache redirect rules to change a request for any url containing "favicon" to redirect to /favicon.ico

My initial naive attempt was this:

RewriteRule favicon /favicon.ico [R=301,L]

But that meant that when you actually requested /favicon.ico it would send you into an infinite redirect loop.

Basically what I think I need is a regex which has this effect:

| Request                | Response     |
|------------------------|--------------|
| favicon.png            | /favicon.ico |
| directory/favicon.png  | /favicon.ico |
| directory/favicon.ico  | /favicon.ico |
| favicon.ico            | <no match>   |

Best Solution

Couple of changes I would suggest to alter Alex's excellent answer:

Keep this section the same:

RewriteCond %{REQUEST_URI} !^/favicon\.ico [NC]

Check for more than just the .ico extension at the end of the request:

RewriteCond %{REQUEST_URI} favicon\.(ico|png|gif)$ [NC]

Add a 3rd condition that grabs the current request host name:

RewriteCond %{HTTP_HOST} (.+)

Finally change the last RewriteRule to use a %1 (a backreference representing the last matched condition):

RewriteRule (.*) http://%1/favicon.ico [R=301,L]

The final result would look like:

RewriteCond %{REQUEST_URI} !^/favicon\.ico [NC]
RewriteCond %{REQUEST_URI} favicon\.(ico|png|gif)$ [NC]
RewriteCond %{HTTP_HOST} (.+)
RewriteRule (.*) http://%1/favicon.ico [R=301,L]

Hope this helps someone...