Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

Caching images from RDBMS

by giulienk (Curate)
on Aug 08, 2002 at 09:51 UTC ( #188542=perlquestion: print w/replies, xml ) Need Help??
giulienk has asked for the wisdom of the Perl Monks concerning the following question:

I'm writing a modperl application (running under Apache::Registry) where i decided to serve images from the DB for various reasons. I got a simple CGI script to serve images, it looks like this:
use strict; use lib '/path/to/my/lib/'; use MyDBI; #export $dbh use CGI qw(header path_info); my ($id, $image) = path_info() =~ m{(\d+)_((?:image|thumb|mini)[1-3])(_.+)?\.jpe?g$} +i; exit unless $id and $image; my ($file) = $dbh->selectrow_array("SELECT $image from offerte WHERE +id=$id"); exit unless $file; print header(-type => 'image/jpeg', -Content_length => length $file), +$file;
This is working fine except for caching. Browsers keeps on asking conditional GETs sending If-Modified-Since fields.
As the filenames changes if the image changes all i want to do is just replying a 304 header if i receive a conditional GET.
Can i do it with a simple script like mine, do i have to use Apache API or do i have to install an Apache handler?


Replies are listed 'Best First'.
Re: Caching images from RDBMS
by tadman (Prior) on Aug 08, 2002 at 10:41 UTC
    As in Caching Web Pages, you probably want to look in to using Squid Cache to do the dirty work for you. Barring that, maybe you could store a date field in the DB and check if you need to resend. You can send your own "304" header using CGI, after all.

    By the way, you should probably be using placeholders, like this:
    my ($file) = $dbh->selectrow_array("SELECT $image FROM offerte WHERE id=?", {}, $id);
    It may not make a difference in your particular case, since you are using numeric data, but I'd argue it should be done out of principle. If you always use them, you don't have problems with mistyped data.
      Yeah, i always use placeholders. In this particular case i didn't cause the regexp is already purging everything that's undesired.

      What i didn't explain in my original post is the image name is unique and changes with date. Here is the sub that generates the URL

      sub image_path { my ($id, $image) = @_; my ($mydate) = $dbh->selectrow_array( "SELECT time FROM offerte WHERE id=$id" ); return "/images.cgi/${id}_${image}_${mydate}.jpg"; }

      As you can see i already have a time field :).

      Thanks for the suggestions.


Re: Caching images from RDBMS
by perrin (Chancellor) on Aug 08, 2002 at 12:03 UTC
    Just set an Expires header and you won't need to deal with the 304 case at all. It will be faster too.
      Thank you so much for the simplest, fastest and works like a charm solution ;)

      Here's the modified line that makes the trick:

      print header(-type => 'image/jpeg', -Content_length => length $file, -expires => '+30d', ), $file;


        +30d? If your images are that static, why store them in the db? Just curious… =)


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://188542]
Approved by tadman
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (7)
As of 2017-05-23 09:46 GMT
Find Nodes?
    Voting Booth?