Okay so I have an idea on how I want to serve and cache my images. I don't know if this is the right way to do it but if it is, I'd like to know how to go about preventing abuse.
Situation:
index.php
<img src="images/cache/200x150-picture_001.jpg" />
images/cache/.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ images/image.php?f=$1 [L]
The above checks if the image exists, if not it will be rewritten to image.php
image.php PSEUDO code
get height and width from filename
resize and save image to cache folder
serve the image with content-type and readfile.
This way I'm trying to reduce HTTP requests and PHP load with readfiles. The browser gets the image/jpeg if it exists and if not it will be generated.
Eventually all images will be cached and served in the right height and width so browsers won't be downloading oversized images.
The only catch.. if you change the image url to different dimensions, you can fill up the server.
Am I doing it right, what's the right way to do it. Is there any chance of stopping this from happening?
I know this whole concept of caching has been refined a million times, please enlighten me.
I just do:
And here's how I do it. Note that this implementation scales images whether they're wider than taller or vice-versa, and does a decent job of scaling unlike most PHP attempts.
Caching is a distinctly non-trivial issue - your solution seems reasonable, but is indeed open to intentional and unintentional denial of service attacks. It also doesn't address what happens when the image changes - how do you remove all the resized images from the cache? It doesn't set cache headers to allow "downstream" caches. It doesn't deal with the risk of the entire cache being flushed at the same time, requiring all images to be re-generated in the context of an HTTP request, which could be a major performance drain..
Have you looked at "off the shelf" solutions such as Apache's caching module?
Not sure if I'm not too late with the answer, but why don't you simple use SLIR (Smart Lencioni Image Resizer) for that? It can do whatever you need (include caching and cache management), so you simple drop it in and use.
Some approaches:
Maintain an array of allowed resolutions, and check whether the requested resolution is in that array. Downside: you can't quickly add a resolution without editing the array.
If this is in a CMS context: allow the creation of new images (that are not in the cache yet) only by authenticated users; refuse the request otherwise. When an authenticated user adds an image in the CMS, they preview it, and doing that generates the resized image. Downside: not entirely easy to implement.