Some more places to use streams
authorMichael M Slusarz <slusarz@curecanti.org>
Tue, 30 Jun 2009 17:28:14 +0000 (11:28 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Tue, 30 Jun 2009 19:10:36 +0000 (13:10 -0600)
imp/lib/Compose.php
imp/lib/Contents.php
imp/lib/Spam.php
imp/view.php

index 150eba2..57edd4a 100644 (file)
@@ -1470,7 +1470,7 @@ class IMP_Compose
                 $part->setCharset(NLS::getCharset());
                 $part->setType('message/rfc822');
                 $part->setName(_("Forwarded Message"));
-                $part->setContents($contents->fullMessageText());
+                $part->setContents($contents->fullMessageText(array('stream' => true)));
 
                 try {
                     $this->addMIMEPartAttachment($part);
@@ -1835,12 +1835,15 @@ class IMP_Compose
 
         switch ($this->_cache[$id]['filetype']) {
         case 'vfs':
+            // TODO: Use streams
             $vfs = VFS::singleton($GLOBALS['conf']['vfs']['type'], Horde::getDriverConfig('vfs', $GLOBALS['conf']['vfs']['type']));
             $part->setContents($vfs->read(self::VFS_ATTACH_PATH, $this->_cache[$id]['filename']));
             break;
 
         case 'file':
-            $part->setContents(file_get_contents($this->_cache[$id]['filename']));
+            $fp = fopen($this->_cache[$id]['filename'], 'r');
+            $part->setContents($fp);
+            fclose($fp);
         }
 
         return $part;
index 36aac8f..104cd84 100644 (file)
@@ -232,23 +232,34 @@ class IMP_Contents
     /**
      * Returns the full message text.
      *
-     * @return string  The full message text.
+     * @param array $options  Additional options:
+     * <pre>
+     * 'stream' - (boolean) If true, return a stream for bodytext.
+     *            DEFAULT: No
+     * </pre>
+     *
+     * @return mixed  The full message text, or an array with a text entry
+     *                (header text) and a stream resource (body text) if
+     *                'stream' is true.
      */
-    public function fullMessageText()
+    public function fullMessageText($options = array())
     {
         if (is_null($this->_mailbox)) {
             return $this->_message->toString();
         }
 
         try {
-            // TODO - use streams
             $res = $GLOBALS['imp_imap']->ob->fetch($this->_mailbox, array(
-                Horde_Imap_Client::FETCH_HEADERTEXT => array(array('peek' => true)),
-                Horde_Imap_Client::FETCH_BODYTEXT => array(array('peek' => true))
+                Horde_Imap_Client::FETCH_HEADERTEXT => array(array('peek' => true, 'stream' => !empty($options['stream']))),
+                Horde_Imap_Client::FETCH_BODYTEXT => array(array('peek' => true, 'stream' => !empty($options['stream'])))
             ), array('ids' => array($this->_index)));
-            return $res[$this->_index]['headertext'][0] . $res[$this->_index]['bodytext'][0];
+            return empty($options['stream'])
+                ? $res[$this->_index]['headertext'][0] . $res[$this->_index]['bodytext'][0]
+                : array($res[$this->_index]['headertext'][0], $res[$this->_index]['bodytext'][0]);
         } catch (Horde_Imap_Client_Exception $e) {
-            return '';
+            return empty($options['stream'])
+                ? ''
+                : array();
         }
     }
 
@@ -314,14 +325,8 @@ class IMP_Contents
             !is_null($part) &&
             empty($options['nocontents']) &&
             !is_null($this->_mailbox) &&
-            !$part->getContents()) {
-            $contents = $this->getBodyPart($id, array('length' => empty($options['length']) ? null : $options['length'], 'stream' => true));
-            if (($part->getPrimaryType() == 'text') &&
-                (Horde_String::upper($part->getCharset()) == 'US-ASCII') &&
-                Horde_Mime::is8bit($contents)) {
-                $contents = Horde_String::convertCharset($contents, 'US-ASCII');
-            }
-            $part->setContents($contents);
+            !$part->getContentsAsStream()) {
+            $part->setContents($this->getBodyPart($id, array('length' => empty($options['length']) ? null : $options['length'], 'stream' => true)));
 
             if (empty($options['nodecode'])) {
                 $part->transferDecodeContents();
index bb864b0..c9e6283 100644 (file)
@@ -52,7 +52,7 @@ class IMP_Spam
                 /* If a (not)spam reporting program has been provided, use
                  * it. */
                 if (!empty($GLOBALS['conf'][$action]['program'])) {
-                    $raw_msg = $imp_contents->fullMessageText();
+                    $raw_msg = $imp_contents->fullMessageText(true);
 
                     /* Use a pipe to write the message contents. This should
                      * be secure. */
@@ -72,7 +72,9 @@ class IMP_Spam
                         Horde::logMessage('Cannot open process ' . $prog, __FILE__, __LINE__, PEAR_LOG_ERR);
                         return 0;
                     }
-                    fwrite($pipes[0], $raw_msg);
+                    fwrite($pipes[0], $raw_msg[0]);
+                    rewind($raw_msg[1]);
+                    stream_copy_to_stream($raw_msg[1], $pipes[0]);
                     fclose($pipes[0]);
                     $stderr = '';
                     while (!feof($pipes[2])) {
index 05c034e..a7950ff 100644 (file)
@@ -37,6 +37,14 @@ function _sanitizeName($name)
     return Horde_String::convertCharset(trim(preg_replace('/[^\pL\pN-+_. ]/u', '_', $name), ' _'), 'UTF-8');
 }
 
+function _fullMessageTextLength($ob)
+{
+    fseek($ob[1], 0, SEEK_END);
+    $len = strlen($ob[0]) + ftell($ob[1]);
+    rewind($ob[1]);
+    return $len;
+}
+
 /* Don't compress if we are already sending in compressed format. */
 if ((isset($_GET['actionID']) && ($_GET['actionID'] == 'download_all')) ||
     !empty($_GET['zip'])) {
@@ -162,9 +170,10 @@ case 'view_attach':
     exit;
 
 case 'view_source':
-    $msg = $contents->fullMessageText();
-    $browser->downloadHeaders('Message Source', 'text/plain', true, strlen($msg));
-    echo $msg;
+    $msg = $contents->fullMessageText(array('stream' => true));
+    $browser->downloadHeaders('Message Source', 'text/plain', true, _fullMessageTextLength($msg));
+    echo $msg[0];
+    fpassthru($msg[1]);
     exit;
 
 case 'save_message':
@@ -182,8 +191,10 @@ case 'save_message':
 
     $date = new DateTime($mime_headers->getValue('date'));
 
-    $body = 'From ' . $from . ' ' . $date->format('D M d H:i:s Y') . "\r\n" . $contents->fullMessageText();
-    $browser->downloadHeaders($name . '.eml', 'message/rfc822', false, strlen($body));
-    echo $body;
+    $hdr = 'From ' . $from . ' ' . $date->format('D M d H:i:s Y') . "\r\n";
+    $msg = $contents->fullMessageText(array('stream' => true));
+    $browser->downloadHeaders($name . '.eml', 'message/rfc822', false, strlen($hdr) + _fullMessageTextLength($msg));
+    echo $hdr . $msg[0];
+    fpassthru($msg[1]);
     exit;
 }