From 21601b4deb74555cfde23d3d7c9e255d5f98f5d2 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Fri, 6 Sep 2013 18:21:09 +0200 Subject: Make cached message size limit configurable - messages_cache_threshold (#1489317) --- CHANGELOG | 1 + config/defaults.inc.php | 5 +++++ program/lib/Roundcube/rcube_imap.php | 5 +++-- program/lib/Roundcube/rcube_imap_cache.php | 29 +++++++++++++++++++++-------- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index dc143645f..c7b362694 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 2a51b0805..bdcbbd333 100644 --- a/config/defaults.inc.php +++ b/config/defaults.inc.php @@ -164,6 +164,11 @@ $config['imap_cache_ttl'] = '10d'; // 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 689a6266d..aa074233f 100644 --- a/program/lib/Roundcube/rcube_imap.php +++ b/program/lib/Roundcube/rcube_imap.php @@ -3785,9 +3785,10 @@ class rcube_imap extends rcube_storage 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 33e45c365..d72bfe0ab 100644 --- a/program/lib/Roundcube/rcube_imap_cache.php +++ b/program/lib/Roundcube/rcube_imap_cache.php @@ -55,6 +55,13 @@ class rcube_imap_cache */ private $ttl; + /** + * Maximum cached message size + * + * @var int + */ + private $threshold; + /** * Internal (in-memory) cache * @@ -96,9 +103,9 @@ class rcube_imap_cache * @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 @@ class rcube_imap_cache $this->userid = $userid; $this->skip_deleted = $skip_deleted; $this->ttl = $ttl; + $this->threshold = $threshold; } @@ -1174,11 +1182,16 @@ class rcube_imap_cache * * @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 @@ class rcube_imap_cache 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); } } } -- cgit v1.2.3