Forum Moderators: phranque

Message Too Old, No Replies

Need help with RewriteRule

this is seemingly simple.. but I just can't figure it out. please help.

         

dream3r quazar

6:50 am on Jul 7, 2006 (gmt 0)

10+ Year Member



--- .htaccess file ----

Options +FollowSymlinks
Options All -Indexes
RewriteEngine On

RewriteCond %{REQUEST_URI} !.*[0-9]{2}.*$
RewriteRule .* http://www.example.com/hotlink.gif [NC,L]
RewriteRule (.*)[0-9]{2}(.*)$ $1$2 [NC,L]

-----

I'm trying to get this simple logic to work before i can change it to something useful:

1. Let's say I have a picture at "images/pic.gif".

2. If the requested file does not contain 2 consecutive numbers (e.g. "http://example.com/images/pic.gif"), it will return a "hotlink" image.

3. If it does contain two consecutive numbers (e.g "http://example.com/images/12pic.gif"), it will remove the 2 numbers and return the right picture.

I keep getting the "hotlink.gif" displayed no matter if there are 2 consecutive numbers or not. Can anyone please enlighten me?

Thank you!

jdMorgan

2:10 pm on Jul 7, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yes, you're missing an essential fact: mod_rewrite in an .htaccess context behaves recursively. That is, once a rewrite is performed, mod_rewrite processing is re-invoked, so that file access restrictions can be checked on the newly-rewritten URL, and so that further rewrites can be done on it if needed.

Therefore as the code stands now, any (permitted) request containing two digits is rewritten to remove the digits, mod_rewrite is re-invoked, and the newly-rewritten URI will now be missing the digits, and so invoke the hotlink-protection rule... :(

Note that the [L] flag stops mod_rewrite processing only on a per-pass basis, and does not affect this recursive behaviour at all.

In order to solve your problem, you'll need to examine the URI requested by the client instead of examining the 'current' URI, which may or may not have alreay been rewritten. The client-requested URI is available as part of the server variable %{THE_REQUEST}.


# If clent-requested .gif URI does not contain two consecutive digits in resourcename
RewriteCond %{THE_REQUEST} ![0-9]{2}\.gif
# and request has not already been redirected to hotlink.gif
RewriteCond %{REQUEST_URI} !^/hotlink\.gif$
# redirect the no-digits .gif request to hotlink.gif
RewriteRule \.gif$ http://www.example.com/hotlink.gif [R=302,L]
#
# Else remove the last instance of two consecutive digits from the URI
RewriteRule ^(.*)[0-9]{2}([^.]*\.gif)$ /$1$2 [L]

Note that using "^.*" or ".*$" is redundant, unless these are needed (within parentheses) for back-reference formation; I have omitted these subpatterns in favor of simple unanchored patterns where applicable.

Also, the use of ".*" within a pattern should be avoided where it creates abiguity. For example, if your two-digit URIs are always of the form "photo<nn>\.gif" or "picture<nn>\.gif" then a better pattern would be:
^[^0-9]+[0-9]{2}\.gif$
-or-
^[a-z]+[0-9]{2}\.gif$

Here we are looking for one ore more characters not equal to a digit, followed by two digits, and then the "\.gif" extension, or we are looking for one or more letters, followed by two digits, and then the "\.gif" filetype.

In other words, make the regex as specific as possible to the URI-form(s) you intend to use, to avoid the need to use the ambiguous, greedy, and inefficient ".*" pattern.

For reference, the contents of {THE_REQUEST} is the entire HTTP request header sent by the browser, for example:

GET /photo23.gif?sid=03ca29f47&prod=123 HTTP/1.1

Jim

dream3r quazar

2:55 am on Jul 10, 2006 (gmt 0)

10+ Year Member



Thank you, Jim! It is exactly what I need.

I appreciate your quality reply. I finally managed to learn what I have all along been missing out on. The essential fact.

The Apache documentation should really make clear this point for the novices.