]> git.donarmstrong.com Git - debbugs.git/blobdiff - cgi/libravatar.cgi
Use ETags; return timestamp not is_valid
[debbugs.git] / cgi / libravatar.cgi
index 33aa90a7d5b09c8a3d8296e77dbd93bf336983d0..81f9c73855a141dd46ed58158355d8f20c7e5926 100755 (executable)
@@ -13,6 +13,7 @@ use Libravatar::URL;
 
 use CGI::Simple;
 use Cwd qw(abs_path);
+use Digest::MD5 qw(md5_hex);
 
 my $q = CGI::Simple->new();
 
@@ -25,45 +26,64 @@ my %param =
                   );
 # if avatar is no, serve the empty png
 if ($param{avatar} ne 'yes' or not defined $param{email} or not length $param{email}) {
-    serve_cache('',$q);
+    serve_cache('',$q,0);
     exit 0;
 }
 
-my ($cache_location, $is_valid) = cache_location(email => lc($param{email}));
+my ($cache_location, $timestamp) = cache_location(email => lc($param{email}));
 # if we've got it, and it's less than one hour old, return it.
-if ($is_valid) {
-    serve_cache($cache_location,$q);
+if ($timestamp) {
+    serve_cache($cache_location,$q,$timestamp);
     exit 0;
 }
 # if we don't have it, get it, and store it in the cache
-$cache_location = retrieve_libravatar(location => $cache_location,
-                                      email => lc($param{email}),
-                                     );
+($cache_location,$timestamp) =
+    retrieve_libravatar(location => $cache_location,
+                       email => lc($param{email}),
+                      );
 if (not defined $cache_location) {
     # failure, serve the default image
-    serve_cache('',$q);
+    serve_cache('',$q,0);
     exit 0;
 } else {
-    serve_cache($cache_location,$q);
+    serve_cache($cache_location,$q,$timestamp);
     exit 0;
 }
 
 
 sub serve_cache {
-    my ($cache_location,$q) = @_;
+    my ($cache_location,$q,$timestamp) = @_;
     if (not defined $cache_location or not length $cache_location) {
         # serve the default image
         $cache_location = $config{libravatar_default_image};
+       if (not defined $timestamp or not $timestamp) {
+           $timestamp = (stat($cache_location))[9];
+       }
+    }
+    if (not defined $timestamp) {
+       # this probably means that the default image doesn't exist
+       print $q->header(status => 404);
+       print "404: Not found\n";
+       return;
+    }
+    my $etag = md5_hex($cache_location.$timestamp);
+    if (defined $q->http('if-none-match')
+       and $etag eq $q->http('if-none-match')) {
+       print $q->header(-status => 304);
+       print "304: Not modified\n";
+       return;
     }
     my $fh = IO::File->new($cache_location,'r') or
-        error($q,404, "Failed to open cached image $cache_location");
+       error($q,404, "Failed to open cached image $cache_location");
     my $m = File::LibMagic->new() or
-        error($q,500,'Unable to create File::LibMagic object');
+       error($q,500,'Unable to create File::LibMagic object');
     my $mime_string = $m->checktype_filename(abs_path($cache_location)) or
-        error($q,500,'Bad file; no mime known');
+       error($q,500,'Bad file; no mime known');
     print $q->header(-type => $mime_string,
-                     -expires => '+1d',
-                    );
+                    -expires => '+1d',
+                    -status => 200,
+                    -etag => $etag,
+                   );
     print <$fh>;
     close($fh);
 }