Index: trunk/BookmarkApp.pm
===================================================================
--- trunk/BookmarkApp.pm	(revision 56)
+++ trunk/BookmarkApp.pm	(revision 57)
@@ -7,5 +7,5 @@
 
 use Encode;
-use HTTP::Date qw{time2isoz time2iso};
+use HTTP::Date qw{time2isoz time2iso time2str str2time};
 use JSON;
 use Bookmarks;
@@ -135,4 +135,6 @@
 
     # list all the bookmarks 
+    my $mtime = $self->_bookmarks->get_last_modified_time;
+
     my $format = $q->param('format') || 'html';
 
@@ -239,4 +241,5 @@
             -type    => 'text/html',
             -charset => 'UTF-8',
+            -Last_Modified => time2str($mtime),
         );
 
@@ -335,4 +338,16 @@
     my $bookmark = $self->_bookmarks->get_bookmark({ id => $id });
     if ($bookmark) {
+        # check If-Modified-Since header to return cache response
+        if ($self->query->env->{HTTP_IF_MODIFIED_SINCE}) {
+            my $cache_time = str2time($self->query->env->{HTTP_IF_MODIFIED_SINCE});
+            if ($bookmark->mtime <= $cache_time) {
+                $self->header_type('redirect');
+                $self->header_props(
+                    -status => 304,
+                );
+                return;
+            }
+        }
+        
         if ($format eq 'json') {
             $self->header_props(
@@ -349,4 +364,5 @@
                 -type    => 'text/html',
                 -charset => 'UTF-8',
+                -Last_Modified => time2str($bookmark->mtime),
             );
             return $self->tt_process(
Index: trunk/Bookmarks.pm
===================================================================
--- trunk/Bookmarks.pm	(revision 56)
+++ trunk/Bookmarks.pm	(revision 57)
@@ -169,4 +169,12 @@
     $sth->execute(@bind);
     return @{ $sth->fetchall_arrayref({}) };
+}
+
+sub get_last_modified_time {
+    my $self = shift;
+    my $sth = $self->dbh->prepare('select mtime from bookmarks order by mtime desc limit 1');
+    $sth->execute;
+    my ($mtime) = $sth->fetchrow_array;
+    return $mtime;
 }
 
