From 103ddcde87f77da28fa2c1f7942763db1c65b34a Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Mon, 04 Oct 2010 14:09:26 -0400
Subject: [PATCH] - Minimize FETCH response for messages listing (when caching is disabled)

---
 program/include/rcube_imap.php         |   51 +++++++++++++++++++++++--
 program/include/rcube_message.php      |    1 
 program/include/rcube_imap_generic.php |   10 +---
 3 files changed, 50 insertions(+), 12 deletions(-)

diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index a888341..4e8998f 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -40,6 +40,7 @@
     public $delimiter = NULL;
     public $threading = false;
     public $fetch_add_headers = '';
+    public $get_all_headers = false;
 
     /**
      * Instance of rcube_imap_generic
@@ -77,6 +78,29 @@
     private $db_header_fields = array('idx', 'uid', 'subject', 'from', 'to', 'cc', 'date', 'size');
     private $options = array('auth_method' => 'check');
     private $host, $user, $pass, $port, $ssl;
+
+    /**
+     * All (additional) headers used (in any way) by Roundcube
+     * Not listed here: DATE, FROM, TO, SUBJECT, CONTENT-TYPE, LIST-POST
+     * (used for messages listing) are hardcoded in rcube_imap_generic::fetchHeaders()
+     *
+     * @var array
+     * @see rcube_imap::fetch_add_headers
+     */
+    private $all_headers = array(
+        'REPLY-TO',
+        'IN-REPLY-TO',
+        'CC',
+        'BCC',
+        'MESSAGE-ID',
+        'CONTENT-TRANSFER-ENCODING',
+        'REFERENCES',
+        'X-PRIORITY',
+        'X-DRAFT-INFO',
+        'MAIL-FOLLOWUP-TO',
+        'MAIL-REPLY-TO',
+        'RETURN-PATH',
+    );
 
 
     /**
@@ -1071,7 +1095,7 @@
     {
         // fetch reqested headers from server
         $a_header_index = $this->conn->fetchHeaders(
-            $mailbox, $msgs, false, false, $this->fetch_add_headers);
+            $mailbox, $msgs, false, false, $this->get_fetch_headers());
 
         if (empty($a_header_index))
             return 0;
@@ -1396,7 +1420,7 @@
             while (true) {
                 // do this in loop to save memory (1000 msgs ~= 10 MB)
                 if ($headers = $this->conn->fetchHeaders($mailbox,
-                    "$start:$end", false, false, $this->fetch_add_headers)
+                    "$start:$end", false, false, $this->get_fetch_headers())
                 ) {
                     foreach ($headers as $header) {
                         $this->add_message_cache($cache_key, $header->id, $header, NULL, true);
@@ -1458,7 +1482,7 @@
             $for_update = array_chunk($for_update, $chunk_size);
             foreach ($for_update as $uids) {
                 if ($headers = $this->conn->fetchHeaders($mailbox,
-                    $uids, false, false, $this->fetch_add_headers)
+                    $uids, false, false, $this->get_fetch_headers())
                 ) {
                     foreach ($headers as $header) {
                         $this->add_message_cache($cache_key, $header->id, $header, NULL, true);
@@ -1774,7 +1798,7 @@
             return $headers;
 
         $headers = $this->conn->fetchHeader(
-            $mailbox, $id, $is_uid, $bodystr, $this->fetch_add_headers);
+            $mailbox, $id, $is_uid, $bodystr, $this->get_fetch_headers());
 
         // write headers cache
         if ($headers) {
@@ -3062,6 +3086,23 @@
     }
 
 
+    /**
+     * Get message header names for rcube_imap_generic::fetchHeader(s)
+     *
+     * @return string Space-separated list of header names
+     */
+    private function get_fetch_headers()
+    {
+        $headers = explode(' ', $this->fetch_add_headers);
+        $headers = array_map('strtoupper', $headers);
+
+        if ($this->caching_enabled || $this->get_all_headers)
+            $headers = array_merge($headers, $this->all_headers);
+
+        return implode(' ', array_unique($headers));
+    }
+
+
     /* --------------------------------
      *   internal caching methods
      * --------------------------------*/
@@ -3348,7 +3389,7 @@
             // featch headers if unserialize failed
             if (empty($result[$uid]))
                 $result[$uid] = $this->conn->fetchHeader(
-                    preg_replace('/.msg$/', '', $key), $uid, true, false, $this->fetch_add_headers);
+                    preg_replace('/.msg$/', '', $key), $uid, true, false, $this->get_fetch_headers());
         }
 
         return $result;
diff --git a/program/include/rcube_imap_generic.php b/program/include/rcube_imap_generic.php
index 95e1180..f2a09ad 100644
--- a/program/include/rcube_imap_generic.php
+++ b/program/include/rcube_imap_generic.php
@@ -1059,7 +1059,7 @@
 	    $message_set = $this->compressMessageSet($message_set);
 
 	    if ($add)
-		    $add = ' '.strtoupper(trim($add));
+		    $add = ' '.trim($add);
 
 	    /* FETCH uid, size, flags and headers */
 	    $key  	  = 'FH12';
@@ -1067,12 +1067,8 @@
 	    $request .= "(UID RFC822.SIZE FLAGS INTERNALDATE ";
 	    if ($bodystr)
 		    $request .= "BODYSTRUCTURE ";
-	    $request .= "BODY.PEEK[HEADER.FIELDS ";
-	    $request .= "(DATE FROM TO SUBJECT REPLY-TO IN-REPLY-TO CC BCC ";
-	    $request .= "CONTENT-TRANSFER-ENCODING CONTENT-TYPE MESSAGE-ID ";
-	    $request .= "REFERENCES DISPOSITION-NOTIFICATION-TO X-PRIORITY ";
-	    $request .= "X-DRAFT-INFO LIST-POST MAIL-FOLLOWUP-TO MAIL-REPLY-TO ";
-        $request .= "RETURN-PATH".$add.")])";
+	    $request .= "BODY.PEEK[HEADER.FIELDS (DATE FROM TO SUBJECT CONTENT-TYPE ";
+	    $request .= "LIST-POST DISPOSITION-NOTIFICATION-TO".$add.")])";
 
 	    if (!$this->putLine($request)) {
 		    return false;
diff --git a/program/include/rcube_message.php b/program/include/rcube_message.php
index 6a6186d..19f36b3 100644
--- a/program/include/rcube_message.php
+++ b/program/include/rcube_message.php
@@ -74,6 +74,7 @@
     {
         $this->app = rcmail::get_instance();
         $this->imap = $this->app->imap;
+        $this->imap->get_all_headers = true;
 
         $this->uid = $uid;
         $this->headers = $this->imap->get_headers($uid, NULL, true, true);

--
Gitblit v1.9.1