diff --git a/database/database.mysql b/database/database.mysql
index 672edd03b54dbc7a4af86d5cc5db4702a9ab39e0..3aaa2f1134967a208d734a535989519cba81132e 100644
--- a/database/database.mysql
+++ b/database/database.mysql
@@ -105,6 +105,7 @@ CREATE TABLE cache (
   cid varchar(255) NOT NULL default '',
   data mediumtext,
   expire int(11) NOT NULL default '0',
+  created int(11) NOT NULL default '0',
   PRIMARY KEY  (cid)
 ) TYPE=MyISAM;
 
diff --git a/database/database.pgsql b/database/database.pgsql
index 780af623326775e955c602e262ef9ee736e43d7d..84eda045f796e90efea42b5b769f780bcae8f832 100644
--- a/database/database.pgsql
+++ b/database/database.pgsql
@@ -102,6 +102,7 @@ CREATE TABLE cache (
   cid varchar(255) NOT NULL default '',
   data text default '',
   expire integer NOT NULL default '0',
+  created integer NOT NULL default '0',
   PRIMARY KEY  (cid)
 );
 
diff --git a/includes/common.inc b/includes/common.inc
index a7e5164d23378cdca5e3d1661486b1467f5452d7..9fd254497de4ca71ee8de98d9433acec78bdfb41 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -462,16 +462,17 @@ function format_size($size) {
 }
 
 function cache_get($key) {
-  $cache = db_fetch_object(db_query("SELECT data FROM cache WHERE cid = '%s'", $key));
-  return $cache->data ? $cache->data : 0;
+  $cache = db_fetch_object(db_query("SELECT data, created FROM cache WHERE cid = '%s'", $key));
+  $created = $cache->created;
+  return $cache->data ? $cache : 0;
 }
 
 function cache_set($cid, $data, $expire = 0) {
   if (db_fetch_object(db_query("SELECT cid FROM cache WHERE cid = '%s'", $cid))) {
-    db_query("UPDATE cache SET data = '%s' WHERE cid = '%s'", $data, $cid);
+    db_query("UPDATE cache SET data = '%s', created = %d, expire = %d WHERE cid = '%s'", $data, time(), $expire, $cid);
   }
   else {
-    db_query("INSERT INTO cache (cid, data, expire) VALUES('%s', '%s', '%s')", $cid, $data, $expire);
+    db_query("INSERT INTO cache (cid, data, created, expire) VALUES('%s', '%s', %d, %d)", $cid, $data, time(), $expire);
   }
 }
 
@@ -515,7 +516,7 @@ function page_get_cache() {
     }
   }
 
-  return $cache ? $cache : 0;
+  return $cache;
 }
 
 function format_interval($timestamp) {
@@ -764,8 +765,18 @@ function page_header() {
   }
 
   if (variable_get("cache", 0)) {
-    if ($data = page_get_cache()) {
-      print $data;
+    if ($cache = page_get_cache()) {
+      $date = gmdate("D, d M Y H:i:s", $cache->created) ." GMT";
+      header("Last-Modified: $date");
+      header("ETag: \"$date\"");
+      if ($headers = getallheaders()) {
+        // NOTE: the above is an Apache-ism so for the time being we don't send 304 headers to IIS servers.
+        if ($headers["If-Modified-Since"] == $date && $headers["If-None-Match"] == "\"$date\"") {
+          header("HTTP/1.0 304 Not Modified");
+          exit();
+        }
+      }
+      print $cache->data;
       exit();
     }
   }
diff --git a/modules/forum.module b/modules/forum.module
index cfe9dc4cd6e8de3516405bf06c9c09234bfb58c9..7825f7eeb6bd40c4df76bdbefbe9c5562683878d 100644
--- a/modules/forum.module
+++ b/modules/forum.module
@@ -104,7 +104,7 @@ function forum_block($op = "list", $delta = 0) {
       }
 
       $blocks["subject"] = t("Forum topics");
-      $blocks["content"] = $content;
+      $blocks["content"] = $content->data;
     }
   }
 
@@ -310,7 +310,7 @@ function forum_get_forums($tid = 0) {
     $tid = 0;
   }
 
-  $forums = unserialize(cache_get("forum:$tid"));
+  $forums = cache_get("forum:$tid");
 
   if (!$forums) {
     $forums = array();
@@ -333,6 +333,7 @@ function forum_get_forums($tid = 0) {
   }
 
   if ($user->uid && $forums) {
+    $forums = unserialize($forums);
     foreach (_forum_topics_read($user->uid) as $tid => $old) {
       if ($forums[$tid]) {
         $forums[$tid]->old_topics = $old;
diff --git a/modules/forum/forum.module b/modules/forum/forum.module
index cfe9dc4cd6e8de3516405bf06c9c09234bfb58c9..7825f7eeb6bd40c4df76bdbefbe9c5562683878d 100644
--- a/modules/forum/forum.module
+++ b/modules/forum/forum.module
@@ -104,7 +104,7 @@ function forum_block($op = "list", $delta = 0) {
       }
 
       $blocks["subject"] = t("Forum topics");
-      $blocks["content"] = $content;
+      $blocks["content"] = $content->data;
     }
   }
 
@@ -310,7 +310,7 @@ function forum_get_forums($tid = 0) {
     $tid = 0;
   }
 
-  $forums = unserialize(cache_get("forum:$tid"));
+  $forums = cache_get("forum:$tid");
 
   if (!$forums) {
     $forums = array();
@@ -333,6 +333,7 @@ function forum_get_forums($tid = 0) {
   }
 
   if ($user->uid && $forums) {
+    $forums = unserialize($forums);
     foreach (_forum_topics_read($user->uid) as $tid => $old) {
       if ($forums[$tid]) {
         $forums[$tid]->old_topics = $old;
diff --git a/modules/locale.module b/modules/locale.module
index a726fc6c3593743eb1af49960bdb4df62371096c..8dfccad476f1713e7f033a26bdf0215999bd28a6 100644
--- a/modules/locale.module
+++ b/modules/locale.module
@@ -282,7 +282,10 @@ function locale($string) {
   static $locale_t;
 
   if (!isset($locale_t)) {
-    $locale_t = unserialize(cache_get("locale:$locale"));
+    $cache = cache_get("locale:$locale");
+    if ($cache) {
+      $locale_t = unserialize($cache->data);
+    }
   }
 
   if ($locale_t[$string] != "") {
diff --git a/modules/locale/locale.module b/modules/locale/locale.module
index a726fc6c3593743eb1af49960bdb4df62371096c..8dfccad476f1713e7f033a26bdf0215999bd28a6 100644
--- a/modules/locale/locale.module
+++ b/modules/locale/locale.module
@@ -282,7 +282,10 @@ function locale($string) {
   static $locale_t;
 
   if (!isset($locale_t)) {
-    $locale_t = unserialize(cache_get("locale:$locale"));
+    $cache = cache_get("locale:$locale");
+    if ($cache) {
+      $locale_t = unserialize($cache->data);
+    }
   }
 
   if ($locale_t[$string] != "") {
diff --git a/update.php b/update.php
index 03761877a3b38dfcd8c8851af0e26bd674652315..6089074042a6456ff2b1fa863ab97b463e025c02 100644
--- a/update.php
+++ b/update.php
@@ -57,7 +57,8 @@
   "2002-10-17" => "update_42",
   "2002-10-26" => "update_43",
   "2002-11-08" => "update_44",
-  "2002-11-20" => "update_45"
+  "2002-11-20" => "update_45",
+  "2002-12-10" => "update_46"
 );
 
 // Update functions
@@ -636,6 +637,10 @@ function update_45() {
   update_sql("ALTER TABLE page ADD description varchar(128) NOT NULL default ''");
 }
 
+function update_46() {
+  update_sql("ALTER TABLE cache ADD created int(11) NOT NULL default '0'");
+}
+
 function update_upgrade3() {
   update_sql("INSERT INTO system VALUES ('archive.module','archive','module','',1)");
   update_sql("INSERT INTO system VALUES ('block.module','block','module','',1)");