Monday, March 28, 2011

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

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>   |
From stackoverflow
  • Try this

     RewriteCond %{REQUEST_URI} !^/favicon\.ico [NC] # if not already going to favicon.ico
     RewriteCond %{REQUEST_URI} favicon\.ico [NC] # edit this line to match your favicon matching regex
     RewriteRule (.*) http://www.domain.com.au/favicon.ico [R=301,L] #redirect to the real address
    
    nickf : hey thanks alex!
    alex : no worries, you've answered enough of my questions :)
    Dscoduc : I made some suggestions to this excellent answer in my own answer.
    Alexsander Akers : Look at Dscoduc's response! (More detailed.)
    alex : @Alexsander did mine deserve a downvote though?
  • I would use this rule:

    RewriteCond %{REQUEST_URI} !^/favicon\.ico$
    RewriteRule favicon /favicon.ico [L,R=301]
    
  • 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 %3 (representing the 3rd condition):

    RewriteRule (.*) http://%3/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://%3/favicon.ico [R=301,L]
    

    Hope this helps someone...

    alex : +1 good detailed answer!
    alex : Something I did the other day, is to change the extension checker to .(ico|gif|png|jpe?g) for good measure :)

0 comments:

Post a Comment