0

this is a pain in the ass-problem!! 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 removed query strings from references to static resources, at the expence of very ugly apache regex code!*

Part 1 DONE with clues from two geniuses Dennis Williamson & Mark Henderson
Part 2 HERE this question covers part II: making the code elegant and less tidious

PREVIOUSLY HAD

 <img src="/imgcpu?src=folder1/some_funny_kitty.jpg&w=3500&h=10&c=p&q=90" />
 <img src="/imgcpu?src=folder3/camels_ride_on_birds.jpg&w=200&h=500&f=bw&q=10" />
 <img src="/imgcpu?src=folder3/clay_loves_frogs.jpg&h=200" />

NOW WORKING

<img src="/IMG-folder1/some_funny_kitty_w3500_h10_cp_q90.jpg" />
<img src="/IMG-folder3/camels_ride_on_birds_w200_h500_fbw_q10.jpg" />
<img src="/IMG-folder3/clay_loves_frogs_h200.jpg" />

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(.+)_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(.+)_q(.+).jpg$ imgcpu\?src=$1\.jpg&w=$2&h=$3&q=$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]
+ many many other combinations etcettera!

notes: 1) imgcpu.php?src= can be modified if needed. 2) images will always be in one folder deep, never deeper 3) all files will end with .jpg after wich the delimiters start IMG-folder1/some_file_w100_h200.jpg (nice static .jpg url)
imgcpu?src=folder1/some_file.jpg&w=100&h=200 (ugly file url)

Sam
  • 423
  • 3
  • 7
  • 23
  • I'm late to the party here, but can we modify imgcpu? If so, then the right thing to do would be to move the processing into imgcpu where you can execute loops and do other nice things, eg `RewriteRule ^IMG-(.+)$ imgcpu\?parseme=$1 [L]` – DerfK Dec 15 '10 at 01:49
  • Hello! Change imgcpu ??? you mean in terms of its name or content? sure can do! p.s. now both work: `imgcpu.php?src= as well as imgcpu?src=` – Sam Dec 15 '10 at 02:02

1 Answers1

1

Since imgcpu[.php] can be changed, here's my answer for cleaning this up even though it's going to undo a lot of that work you've done

Within a program you can loop over all of the possible attributes and extract whichever ones are present (in any order!). You can replace all of those rules with a single rule:

RewriteRule ^IMG-(.*)$ imgcpu\?parse=$1 [L]

and then in the imgcpu script, you'd have "parse" as a variable containing folder1/some_funny_kitty_w3500_h10_cp_q90.jpg. Remove the extension from the end, the folder and file name from the beginning, and then you can loop through the various parameters and extract them from the string. Something like (PHP, but the concept can be done in any language. You might even save a few ms by doing it without regexes):

$values["q"]=50; // Set some defaults?
foreach (array("h","w","q","c","f") as $param) {
   if (preg_match("/_${param}([^_]+)/",$_REQUEST["parse"],$result)) {
     $values[$param]=$result[1];
   }
}

At the end $values["h"] would have the height. This would be a ton easier to maintain if you ever want to add new parameters. You'd need a little work to figure out what you're supposed to do with "my_w2000_desktop_w200_h100.jpg" (or worse: "my_w2000_desktop_h100.jpg", or even worse "desktop_for_w2000_h100.jpg") but if you ban people from having double underscores in filenames, you could use double underscores to separate the filename from the options (eg "my_w2000_desktop__h100.jpg") and split the string there (note that the regexes above require that each option start with the _ character)

Easier Option

If you can accept not having the parameters encoded in the filename itself (this could lead to everyone having images of completely different sizes all called "some_funny_kitty.jpg") then parsing can be made trivial. This would use a URL like http://example.com/IMG/w200/h100/folder1/my_w2000_desktop.jpg. Remove the "-" from the RewriteRule (just ^IMG(.*)$, and change the parsing in PHP:

$parts=explode("/",$_REQUEST["parse"]);
$filename=array_pop($parts);
$folder=array_pop($parts);
foreach ($parts as $field) {
  $param=substr($field,0,1);
  $setting=substr($field,1); // assuming settings are always one letter followed by value
  $values[$param]=$setting;
}

If that is acceptable, you may be able to eliminate mod_rewrite entirely: Use URLs of the form

http://example.com/imgcpu/w200/h100/folder1/my_w2000_desktop.jpg

and Apache will execute imgcpu with the PATH_INFO environment variable set to /w200/h100/folder1/my_w2000_desktop.jpg ($_SERVER["PATH_INFO"] in PHP). This works fine for me but I've seen some posts complaining that in certain environments PATH_INFO is broken.

DerfK
  • 19,493
  • 2
  • 38
  • 54
  • Dear DerfK! Astoungly clever as well as Creative options to solve my problem, from the php point of view. I will give your optiona s try! meanwhile the easiest would be (since as you said we are so far with the apache rewrite method) to fix that, but i will give both a try and check back soon here! – Sam Dec 17 '10 at 02:48