Forum Moderators: phranque

Message Too Old, No Replies

Severe help with .htaccess creation

redirecting images to a script

         

booyabazooka

10:54 pm on Apr 15, 2004 (gmt 0)

10+ Year Member



I just got .htaccess functioning and have tested it with an anti-hotlinking script I copied from somewhere. Now I'm faced with writing my own file, and I'm not familiar with the syntax.

My aim: to run every gif file through a php script which modifies it (adds a copyright notice to the comment field) before sending it out. So, when a request is made for <http://www.mysite.com/graphics/abc/image.gif>, I need it to redirect to <http://www.mysite.com/secure.php?url=graphics~abc~image.gif>.

Here's my start, for what it's worth (not much), which for some reason or other just doesn't do anything:

RewriteEngine on
RewriteCond %{REQUEST_URI} (.*)\.gif
RewriteRule ^/(.*)\.gif /secure.php?url=$0 [L,NE]

Aside from it not working, of course, I have also yet to take into consideration replacing slashes with tildes, or making sure the file requested doesn't have ".php" in it, to prevent looping.

Any help would be appreciated.

jdMorgan

6:05 am on Apr 16, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



booyaB,

Welcome to WebmasterWorld [webmasterworld.com]!

This recent thread [webmasterworld.com] illustrates a method to accomplish what you want to do.

Jim

booyabazooka

6:48 pm on Apr 21, 2004 (gmt 0)

10+ Year Member



Thanks for the link; while not amazingly relevant, I did get some help out of it.

Some reading of the Apache manual did me well... for the record, here's what I ended up getting to work:

RewriteEngine on
RewriteCond %{REQUEST_URI} ^(.*).gif$
ReWriteRule ^(.*)?/(.*)?$ $1~$2
ReWriteRule ^(.*).gif$ secure.php?url=$1.gif

jdMorgan

1:05 am on Apr 22, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



booyabazooka,

Glad that link at least got you started... Since almost all cases posted here are different, citing a related example is usually the best we can do without writing your code for you - a practice which is discouraged here because it often leads to dependence instead of learning.

Here's a compact, speedier version of your code:


RewriteEngine on
ReWriteRule ^([^/]*)/([^.]*\.gif)$ $1~$2
ReWriteRule \.gif$ secure.php?url=$1.gif [L]

This eliminates an unneeded RewriteCond, and uses less-ambiguous regular-expression patterns which can be processed faster. In addition, the [L] flag is used to prevent mod_rewrite from continuing to process further rules after the second rewrite takes place; In many if not almost all cases, once a rewriterule is invoked, further rules need not be processed.

Jim

booyabazooka

10:59 pm on Apr 23, 2004 (gmt 0)

10+ Year Member



Thank you for the revision; obviously, my grasp on regular expressions is very weak. The removal of RewriteCond makes sense, but some of your optimizations confuse me...

On line 2, [^/]* and [^.]* specify that the characters "/" and "." respectively cannot be present, right? Why are those in there?

What's the difference in how line 3 operates between your version and mine? Why did you rewrite it? Why is there no start anchor ("^")?

What's the purpose of the [L] flag? There are no more rules after this (this is the only thing in the .htaccess file). Won't Apache just stop when it reaches the end of the file? Why do I need to tell it to stop?

You escaped periods. I didn't. Mine worked anyway. Why escape periods? Just in case it happens to confuse Apache in some other situation?

jdMorgan

2:07 am on Apr 24, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



> On line 2, [^/]* and [^.]* specify that the characters "/" and "." respectively cannot be present, right? Why are those in there?

Because it is much faster. The subpattern ([^/]*) says, "grab as many characters as possible up to the first slash and put that in $1. It is less ambiguous than having (.*) in there. If you use (.*), mod_rewrite grabs the whole string and puts it into $1, and then has to "back up" into it to find the match for the slash and for the rest of the pattern. If you put enough (.*) elements in a pattern, you can get very unpredictable results because mod_rewrite has trouble trying to find the "boundaries" between the fixed and variable parts of your pattern.

The default will be to match as much of the input string as possible to the first (.*) and work from there. If the rest of the pattern can't be satisfied, mod_rewrite will "back up" into the first match, and see if it can find a match by taking some of the previously-matched text out of the first subpattern match. It does this backing-up one character at a time, so the number of required matching attempts then becomes proportional to the length of the input string. It is simply faster to work forward until a positive stop is reached, put that into the first back-reference and carry on from there. I hope that makes sense. The main point is to use the most unambiguous pattern possible. This applies to regular expressions used in other languages, too -- Not just mod_rewrite.

> What's the difference in how line 3 operates between your version and mine? Why did you rewrite it? Why is there no start anchor ("^")?

Hah! The difference is that mine has a bug! I dropped your back-reference! Teach me to code when I'm tired...

How about:


RewriteRule ^([^.]*)\.gif$ secure.php?url=$1.gif [L]
instead?

> What's the purpose of the [L] flag? There are no more rules after this (this is the only thing in the .htaccess file). Won't Apache just stop when it reaches the end of the file? Why do I need to tell it to stop?

Habit, pure habit. And a good habit. Your .htaccess contains only one rule today. Tomorrow, who knows? Always use [L] unless you have a known good reason not to. :)

> You escaped periods. I didn't. Mine worked anyway. Why escape periods? Just in case it happens to confuse Apache in some other situation?

In regular expressions an unescaped period means "match any single character." That could lead to a very hard-to-find ambiguity in your pattern. You need to escape the following characters in regex patterns in mod_rewrite:
$^*.+?(){}[]¦\ <space> and "-" under certain circumstances when used within character classes inside []
...and I may have forgotten a few.

Jim

booyabazooka

3:36 am on Apr 25, 2004 (gmt 0)

10+ Year Member



Excellent. It all makes sense.