plugins/libkolab

Aleksander Machniak machniak at kolabsys.com
Thu Jun 20 14:24:22 CEST 2013


 plugins/libkolab/lib/kolab_storage_folder.php |   57 +++++++++++++++++++-------
 1 file changed, 42 insertions(+), 15 deletions(-)

New commits:
commit 481cb9ffcf2443f95b77f99936e8edba5050b378
Author: Aleksander Machniak <machniak at kolabsys.com>
Date:   Thu Jun 20 14:22:25 2013 +0200

    Fix memory calculation when deciding if memory or file should be used
    for saved message. Handle saved message parts with file pointers
    for better performance (one temp file creation is skipped)

diff --git a/plugins/libkolab/lib/kolab_storage_folder.php b/plugins/libkolab/lib/kolab_storage_folder.php
index 702b621..9d7042f 100644
--- a/plugins/libkolab/lib/kolab_storage_folder.php
+++ b/plugins/libkolab/lib/kolab_storage_folder.php
@@ -688,13 +688,7 @@ class kolab_storage_folder
                 $object['_mailbox'] = $this->name;
             }
 
-            if (is_array($raw_msg)) {
-                $result = $this->imap->save_message($this->name, $raw_msg[0], $raw_msg[1], true, null, null, $binary);
-                @unlink($raw_msg[0]);
-            }
-            else {
-                $result = $this->imap->save_message($this->name, $raw_msg, null, false, null, null, $binary);
-            }
+            $result = $this->imap->save_message($this->name, $raw_msg, null, false, null, null, $binary);
 
             // delete old message
             if ($result && !empty($object['_msguid']) && !empty($object['_mailbox'])) {
@@ -861,6 +855,10 @@ class kolab_storage_folder
     /**
      * Creates source of the configuration object message
      *
+     * @param array  $object The array that holds the data of the object.
+     * @param string $type   The type of the kolab object.
+     * @param bool   $binary Enables use of binary encoding of attachment(s)
+     *
      * @return mixed Message as string or array with two elements
      *               (one for message file path, second for message headers)
      */
@@ -891,6 +889,7 @@ class kolab_storage_folder
         $mime     = new Mail_mime("\r\n");
         $rcmail   = rcube::get_instance();
         $headers  = array();
+        $files    = array();
         $part_id  = 1;
         $encoding = $binary ? 'binary' : 'base64';
 
@@ -914,8 +913,9 @@ class kolab_storage_folder
                 $memory += $attachment['size'];
             }
 
-            // 1.33 is for base64, we need at least 2x more memory than the message size
-            if ($memory * ($binary ? 1 : 1.33) * 2 > $mem_limit) {
+            // 1.33 is for base64, we need at least 4x more memory than the message size
+            if ($memory * ($binary ? 1 : 1.33) * 4 > $mem_limit) {
+                $marker   = '%%%~~~' . md5(microtime(true) . $memory) . '~~~%%%';
                 $is_file  = true;
                 $temp_dir = unslashify($rcmail->config->get('temp_dir'));
                 $mime->setParam('delay_file_io', true);
@@ -969,14 +969,42 @@ class kolab_storage_folder
                 $part_id++;
             }
             else if (!empty($att['path'])) {
-                $mime->addAttachment($att['path'], $att['mimetype'], $name, true, $encoding, 'attachment', '', '', '', null, null, '', RCUBE_CHARSET, $headers);
+                // To store binary files we can use faster method
+                // without writting full message content to a temporary file but
+                // directly to IMAP, see rcube_imap_generic::append().
+                if ($is_file && $binary) {
+                    $files[] = fopen($att['path'], 'r');
+                    $mime->addAttachment($marker, $att['mimetype'], $name, false, $encoding, 'attachment', '', '', '', null, null, '', RCUBE_CHARSET, $headers);
+                }
+                else {
+                    $mime->addAttachment($att['path'], $att['mimetype'], $name, true, $encoding, 'attachment', '', '', '', null, null, '', RCUBE_CHARSET, $headers);
+                }
                 $part_id++;
             }
 
             $object['_attachments'][$key]['id'] = $part_id;
         }
 
-        if ($is_file) {
+        if (!$is_file || !empty($files)) {
+            $message = $mime->getMessage();
+        }
+
+        // parse message and build message array with
+        // attachment file pointers in place of file markers
+        if (!empty($files)) {
+            $message = explode($marker, $message);
+            $tmp     = array();
+
+            foreach ($message as $msg_part) {
+                $tmp[] = $msg_part;
+                if ($file = array_shift($files)) {
+                    $tmp[] = $file;
+                }
+            }
+            $message = $tmp;
+        }
+        // write complete message body into temp file
+        else if ($is_file) {
             // use common temp dir
             $body_file = tempnam($temp_dir, 'rcmMsg');
 
@@ -988,11 +1016,10 @@ class kolab_storage_folder
                 return false;
             }
 
-            return array($body_file, $mime->txtHeaders());
-        }
-        else {
-            return $mime->getMessage();
+            $message = array(trim($mime->txtHeaders()) . "\r\n\r\n", fopen($body_file, 'r'));
         }
+
+        return $message;
     }
 
 





More information about the commits mailing list