Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

this is a pain in the ass-problem! Whicever genius solves this riddle will receive paypal donation to eat diner for two. Now lets get started. Given: most proxies, do not cache resources with a "?" in their URL even if a Cache-control: public header is present in the response. To enable proxy caching for these resources, i have to remove query strings from references to static resources, and instead encode the parameters into the file names themselves.*

PREVIOUSLY HAD

 <img src="/imgcpu?src=folder1/photo_citty.jpg&w=3500&h=10&c=p&q=90" />
 <img src="/imgcpu?src=folder2/photo_doggy.jpg&w=100&h=200&c=p" />
 <img src="/imgcpu?src=folder3/photo_birds.jpg&w=200&h=500&f=bw" />
 <img src="/imgcpu?src=folder3/photo_frogs.jpg&h=200" />

NOW WORKING

<img src"/IMG-folder/photo_w100_h100_cf_q60.jpg"/>
  • The images will reside in 1 folder deep on the root (never deeper)
  • the img.php?src= or img?src= will be consistently named this forever
  • after the ....jpg &w,&h,&q,&m, &f and &c are the only letters that call for variables (e.g.: &w=200&h&=50&c=p&f=bw&q=90) but all should be optional

AT THE COST OF THIS UN-ELEGANT CODE

# Rewrite imgcpu?src= thumbnail maker to nice static urls
RewriteCond %{REQUEST_URI} ^IMG.*$
RewriteRule ^IMG-(.+)_w(.+)_h(.+)_c(.+)_q(.+).jpg$ imgcpu\?src=$1\.jpg&w=$2&h=$3&c=$4&q=$5 [L]
RewriteRule ^IMG-(.+)_w(.+)_h(.+)_c(.+)_f(.+)_q(.+).jpg$ imgcpu\?src=$1\.jpg&w=$2&h=$3&c=$4&f=$5&q=$6 [L]
RewriteRule ^IMG-(.+)_w(.+)_h(.+)_c(.+)_f(.+).jpg$ imgcpu\?src=$1\.jpg&w=$2&h=$3&c=$4&f=$5 [L]
RewriteRule ^IMG-(.+)_w(.+)_h(.+)_c(.+)_q(.+).jpg$ imgcpu\?src=$1\.jpg&w=$2&h=$3&c=$4&q=$5 [L]
RewriteRule ^IMG-(.+)_w(.+)_h(.+)_c(.+).jpg$ imgcpu\?src=$1\.jpg&w=$2&h=$3&c=$4 [L]
RewriteRule ^IMG-(.+)_w(.+)_h(.+)_f(.+).jpg$ imgcpu\?src=$1\.jpg&w=$2&h=$3&f=$4 [L]
RewriteRule ^IMG-(.+)_w(.+)_h(.+).jpg$ imgcpu\?src=$1\.jpg&w=$2&h=$3 [L]
RewriteRule ^IMG-(.+)_w(.+).jpg$ imgcpu\?src=$1\.jpg&w=$2 [L]
RewriteRule ^IMG-(.+)_h(.+).jpg$ imgcpu\?src=$1\.jpg&h=$3 [L]

However, endless other possibilities are still uncovered: e.g. doesnt cover the cases where first the height is given the width etc No this shall not work! How can I redirect OPTIONALLY ALL parameter? &w= or &h= with something like &[a-z]=(.*) sothat _h or _w or _m are all universal and optional and when given intervepted by the rewritten, proxy friendly urls?

So the assignment Now is:
Rewrite any or all of the queries that follow [photo123.jpg]&[a-z]=(.*)&[a-z]=(.*)etcettera into photo123_X-x_Y-y(optionally more queries).jpg

share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

I would suggest progressively replacing fields. Something along the lines of:

(untested)

# Rewrite imgcpu?src= thumbnail maker to nice static urls
RewriteCond %{REQUEST_URI} ^IMG.*$
RewriteRule ^IMG-(.+)_w([^_]+)(_.*)$ imgcpu\?src=$1\.jpg&w=$2$3 [C]
RewriteRule ^(imgcpu[^_]*)_h([^_]+)(_.*)$ $1&h=$2$3 [C]
RewriteRule ^(imgcpu[^_]*)_q([^_]+)(_.*)$ $1&q=$2$3

and so on until you get all the fields converted one by one instead of trying to do them all at once. Each rule will be applied successively. This should work for fields in any order and allow for them to be optional.

Leave the [C] off the last of this Chain of rules.

Edit:

This is more likely to work than any of the nonsense I've posted so far:

# Rewrite imgcpu?src= thumbnail maker to nice static urls
RewriteCond %{REQUEST_URI} ^IMG.*$
RewriteRule ^IMG-(.+\/photo_[^_]+)(_.*)*(\.[^.]+)$ imgcpu\?src=$1$3$2/ [C]
RewriteRule ^(imgcpu.*\..+)_w([^_]+)(_.*)*$ $1&w=$2$3 [C]
RewriteRule ^(imgcpu.*\..+)_h([^_]+)(_.*)*$ $1&h=$2$3 [C]
RewriteRule ^(imgcpu.*\..+)_q([^_]+)(_.*)*$ $1&q=$2$3 [C]
RewriteRule ^(imgcpu.*\..+)_c([^_]+)(_.*)*$ $1&c=$2$3 [C]
RewriteRule ^(imgcpu.*\..+)_m([^_]+)(_.*)*$ $1&m=$2$3 [C]
RewriteRule ^(imgcpu.*\..+)_f([^_]+)(_.*)*$ $1&f=$2$3 [C]

The main attempted improvements involve the asterisk before the first dollar sign which are intended to make things work if the field being rewritten is the last one in the query string and changing the first [^_]* to .*. Notice how I left mentioning the biggest screw-up 'til last - hoping it wouldn't be noticed? Wait ... what? Notice it attempting to be unnoticed? Speaking of not noticing ... I only just noticed that the filenames include underscores!

Edit: Fer realz dis time - fer shur!

Edit:

Try this in place of the first RewriteRule (all the other lines stay the same).

RewriteRule ^IMG-(.+\/.*?)(_[hw]\d+)([^.]*)(\.[^.]+)$/imgcpu\?src=$1$4$2$3/ [C]

This depends on either the height or width field being first among the fields. You could add more letters in [hw]. Note, however, that a filename like the contrived "/IMG-folder/santa_claus_w2_elves_w200_h100_q75.jpg" (Santa Claus w/ 2 elves) would not give correct results.

Edit (Dec 15):

RewriteCond %{QUERY_STRING} ^(.*\.[^_]*)_(.)([^_]*)(_.*)?$
RewriteRule ^/imgcpu /imgcpu?%1&%2=%3%4 [N]
RewriteCond %{REQUEST_URI} ^/IMG.*$
RewriteRule ^/IMG-(.+/.*?)(_[hw]\d+)([^.]*)(\.[^.]+)$ /imgcpu?src=$1$4$2$3 [N]
share|improve this answer
1  
Sam might also want to add a RewriteCond %{REQUEST_URI} ^IMG.*$ before that block so Apache isn't running every single request through all those RewriteRules needlessly. –  Chris S Dec 6 '10 at 14:33
1  
@Sam: See my edited answer. –  Dennis Williamson Dec 6 '10 at 16:18
1  
@Sam: I'm sorry, I left out a couple of parentheses. See my edited answer. –  Dennis Williamson Dec 8 '10 at 18:45
1  
@Sam: I have edited my answer with a feeble attempt at correcting my previous wrongs. You will see me claim to have been half-asleep and make other excuses and claim that this time for sure it will work. Don't believe me for a second! Take a look at the new information. This time it will work - I just know it. zzz...zzz –  Dennis Williamson Dec 10 '10 at 3:38
1  
@Sam: Weeeellll... no promises, but give it a try. –  Dennis Williamson Dec 10 '10 at 5:07
show 10 more comments

I had a regex that did something very similar once, but with a bit of a different format. I've mucked around with it a bit, but this is totally untested and unfinished (not to mention I frackin' HATE regex's), but hopefully it will set you on your way:

RewriteRule ^(.*?\IMG-)(.*)_(\?[^_]*)?_([^_]*)_([^_]*)(.*)$ /imgcpu?src=(?2$2&:\?)$4=$5$6 [LP]

Basically, it will pull out your first part of the URL and then keep looping until there are no more _ characters, appending them in the format of &$1=$2 onto the URL.

This will mean you'll have to use the format of /IMG-folder1/photo_citty_w_3500_h_10_c_p_q_90.jpg but I'm sure you could fix that to simply step one character rather than use the underscore.

May I suggest that you'll make you life so much easier if your delimiter (_) is not used in the filename part of the URL? There are plenty of other delimiters you could use (such as a -) that would reduce the complexity of your rewrite rules.

share|improve this answer
    
Thanks Mark for your completely new insight. Before i test it a quick question: what are besides ` - ` other valid normal-problem-free delimiters that proxy caches love? I CAN use other delimiters, BUT verymuch prefer the shorter -w350-h10-q90.jpg as oposed to -w-350-h-10-q-90.jpg –  Sam Dec 7 '10 at 5:53
    
@Sam: I think Mark meant only in the filename. So it would look like <img src="/IMG-folder1/photo-citty_w3500_h10_cp_q90.jpg" /> –  Dennis Williamson Dec 10 '10 at 3:42
1  
@Dennis - thanks, yes you're correct. @Sam - sorry I didn't see your comment there. The reason you want to avoid using _ in the filename is so that its easy to tell what's the filename and what's the delimiter. –  Mark Henderson Dec 10 '10 at 3:50
    
true, but what all file names do have in common, is that they have a width or height or both set no filenames will have _w[number] or _h[number] or both as part of the filename !! does this give me any credits for being consistent? –  Sam Dec 14 '10 at 3:40
    
@Sam - the advantage of using a different delimiter is that if you have them all the same, then you need to search for _w OR _h OR _c etc. etc. , and if you need to add a new type (say, _a) then you need to adjust all your rewriting rules to match. If you saved _ as a delimiter ONLY then you just need search for _ and you know that the next character is the parameter, and everything from then to the next _ is the value. –  Mark Henderson Dec 14 '10 at 3:46
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.