From 21601b4deb74555cfde23d3d7c9e255d5f98f5d2 Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Fri, 06 Sep 2013 12:21:09 -0400
Subject: [PATCH] Make cached message size limit configurable - messages_cache_threshold (#1489317)

---
 CHANGELOG                                  |    1 +
 program/lib/Roundcube/rcube_imap.php       |    5 +++--
 program/lib/Roundcube/rcube_imap_cache.php |   29 +++++++++++++++++++++--------
 config/defaults.inc.php                    |    5 +++++
 4 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index dc14364..c7b3626 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG Roundcube Webmail
 ===========================
 
+- Make cached message size limit configurable - messages_cache_threshold (#1489317)
 - Make identities matching case insensitive (#1485480)
 - Fix issue where too big message data was stored in cache causing sql errors (#1489316)
 - Log also failed logins to userlogins log
diff --git a/config/defaults.inc.php b/config/defaults.inc.php
index 2a51b08..bdcbbd3 100644
--- a/config/defaults.inc.php
+++ b/config/defaults.inc.php
@@ -164,6 +164,11 @@
 // Lifetime of messages cache. Possible units: s, m, h, d, w
 $config['messages_cache_ttl'] = '10d';
 
+// Maximum cached message size in kilobytes.
+// Note: On MySQL this should be less than (max_allowed_packet - 30%)
+$config['messages_cache_threshold'] = 50;
+
+
 // ----------------------------------
 // SMTP
 // ----------------------------------
diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
index 689a626..aa07423 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -3785,9 +3785,10 @@
         if ($this->messages_caching && !$this->mcache) {
             $rcube = rcube::get_instance();
             if (($dbh = $rcube->get_dbh()) && ($userid = $rcube->get_user_id())) {
-                $ttl = $rcube->config->get('messages_cache_ttl', '10d');
+                $ttl       = $rcube->config->get('messages_cache_ttl', '10d');
+                $threshold = $rcube->config->get('messages_cache_threshold', 50);
                 $this->mcache = new rcube_imap_cache(
-                    $dbh, $this, $userid, $this->options['skip_deleted'], $ttl);
+                    $dbh, $this, $userid, $this->options['skip_deleted'], $ttl, $threshold);
             }
         }
 
diff --git a/program/lib/Roundcube/rcube_imap_cache.php b/program/lib/Roundcube/rcube_imap_cache.php
index 33e45c3..d72bfe0 100644
--- a/program/lib/Roundcube/rcube_imap_cache.php
+++ b/program/lib/Roundcube/rcube_imap_cache.php
@@ -56,6 +56,13 @@
     private $ttl;
 
     /**
+     * Maximum cached message size
+     *
+     * @var int
+     */
+    private $threshold;
+
+    /**
      * Internal (in-memory) cache
      *
      * @var array
@@ -96,9 +103,9 @@
      * @param int        $userid       User identifier
      * @param bool       $skip_deleted skip_deleted flag
      * @param string     $ttl          Expiration time of memcache/apc items
-     *
+     * @param int        $threshold    Maximum cached message size
      */
-    function __construct($db, $imap, $userid, $skip_deleted, $ttl=0)
+    function __construct($db, $imap, $userid, $skip_deleted, $ttl=0, $threshold=0)
     {
         // convert ttl string to seconds
         $ttl = get_offset_sec($ttl);
@@ -109,6 +116,7 @@
         $this->userid       = $userid;
         $this->skip_deleted = $skip_deleted;
         $this->ttl          = $ttl;
+        $this->threshold    = $threshold;
     }
 
 
@@ -1174,11 +1182,16 @@
      *
      * @param rcube_message_header|rcube_message_part
      */
-    private function message_object_prepare(&$msg)
+    private function message_object_prepare(&$msg, &$size = 0)
     {
-        // Remove body too big (>25kB)
-        if ($msg->body && strlen($msg->body) > 25 * 1024) {
-            unset($msg->body);
+        // Remove body too big
+        if ($msg->body && ($length = strlen($msg->body))) {
+            $size += $length;
+
+            if ($size > $this->threshold * 1024) {
+                $size -= $length;
+                unset($msg->body);
+            }
         }
 
         // Fix mimetype which might be broken by some code when message is displayed
@@ -1192,13 +1205,13 @@
 
         if (is_array($msg->structure->parts)) {
             foreach ($msg->structure->parts as $part) {
-                $this->message_object_prepare($part);
+                $this->message_object_prepare($part, $size);
             }
         }
 
         if (is_array($msg->parts)) {
             foreach ($msg->parts as $part) {
-                $this->message_object_prepare($part);
+                $this->message_object_prepare($part, $size);
             }
         }
     }

--
Gitblit v1.9.1