From: Michael M Slusarz Date: Mon, 13 Jul 2009 23:39:27 +0000 (-0600) Subject: Use streams when sending compressed zip data X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=680965a10eac9b2c7a98568da16bea79747741b2;p=horde.git Use streams when sending compressed zip data --- diff --git a/imp/docs/CHANGES b/imp/docs/CHANGES index b2a207d10..ca648d2b2 100644 --- a/imp/docs/CHANGES +++ b/imp/docs/CHANGES @@ -2,6 +2,8 @@ v5.0-git -------- +[mms] When generating and sending compressed ZIP data, use server-side temp + streams to minimize memory usage. [mms] Decode bodypart data on server if possible (RFC 3516). [mms] Use PHP temporary streams when working with message body data to reduce memory usage (Request #3359). diff --git a/imp/folders.php b/imp/folders.php index a16b36297..b76e7f774 100644 --- a/imp/folders.php +++ b/imp/folders.php @@ -133,18 +133,24 @@ case 'download_folder_zip': if (!empty($folder_list)) { $mbox = $imp_folder->generateMbox($folder_list); if ($actionID == 'download_folder') { - $browser->downloadHeaders($folder_list[0] . '.mbox', null, false, strlen($mbox)); + $data = $mbox; + fseek($data, 0, SEEK_END); + $browser->downloadHeaders($folder_list[0] . '.mbox', null, false, ftell($data)); } else { $horde_compress = Horde_Compress::factory('zip'); try { - $mbox = $horde_compress->compress(array(array('data' => $mbox, 'name' => $folder_list[0] . '.mbox'))); + $data = $horde_compress->compress(array(array('data' => $mbox, 'name' => $folder_list[0] . '.mbox')), array('stream' => true)); + fclose($mbox); } catch (Horde_Exception $e) { + fclose($mbox); $notification->push($e, 'horde.error'); break; } - $browser->downloadHeaders($folder_list[0] . '.zip', 'application/zip', false, strlen($mbox)); + fseek($data, 0, SEEK_END); + $browser->downloadHeaders($folder_list[0] . '.zip', 'application/zip', false, ftell($data)); } - echo $mbox; + rewind($data); + fpassthru($data); exit; } break; diff --git a/imp/lib/Folder.php b/imp/lib/Folder.php index add8d707f..fdfca8241 100644 --- a/imp/lib/Folder.php +++ b/imp/lib/Folder.php @@ -476,11 +476,12 @@ class IMP_Folder * @param array $folder_list A list of folder names to generate a mbox * file for (UTF7-IMAP). * - * @return string An mbox format mailbox file. + * @return resource A stream resource containing the text of a mbox + * format mailbox file. */ public function generateMbox($folder_list) { - $body = ''; + $body = fopen('php://temp', 'r+'); if (empty($folder_list)) { return $body; @@ -488,7 +489,7 @@ class IMP_Folder foreach ($folder_list as $folder) { try { - $status = $GLOBALS['imp_imap']->status($folder, Horde_Imap_Client::STATUS_MESSAGES); + $status = $GLOBALS['imp_imap']->ob->status($folder, Horde_Imap_Client::STATUS_MESSAGES); } catch (Horde_Imap_Client_Exception $e) { continue; } @@ -497,7 +498,7 @@ class IMP_Folder * overhead. */ try { $res = $GLOBALS['imp_imap']->ob->fetch($folder, array( - Horde_Imap_Client::FETCH_FULLMSG => array('peek' => true), + Horde_Imap_Client::FETCH_FULLMSG => array('peek' => true, 'stream' => true), Horde_Imap_Client::FETCH_ENVELOPE => true, Horde_Imap_Client::FETCH_DATE => true, ), array('ids' => array($i), 'sequence' => true)); @@ -517,8 +518,11 @@ class IMP_Folder /* We need this long command since some MUAs (e.g. pine) * require a space in front of single digit days. */ $date = sprintf('%s %2s %s', $ptr['date']->format('D M'), $ptr['date']->format('j'), $ptr['date']->format('H:i:s Y')); - $body .= 'From ' . $from . ' ' . $date . "\r\n" . - $ptr['fullmsg'] . "\r\n"; + fwrite($body, 'From ' . $from . ' ' . $date . "\r\n"); + rewind($ptr['fullmsg']); + stream_copy_to_stream($ptr['fullmsg'], $body); + fclose($ptr['fullmsg']); + fwrite($body, "\r\n"); } } diff --git a/imp/lib/UI/Message.php b/imp/lib/UI/Message.php index d75560671..d6300a825 100644 --- a/imp/lib/UI/Message.php +++ b/imp/lib/UI/Message.php @@ -319,12 +319,12 @@ class IMP_UI_Message /* Set up the add address icon link if contact manager is * available. */ if (!is_null($addURL) && $link && $prefs->getValue('add_source')) { - $add_link = $registry->link('contacts/add', array('source' => $prefs->getValue('add_source'))); - if (is_a($add_link, 'PEAR_Error')) { + try { + $registry->link('contacts/add', array('source' => $prefs->getValue('add_source'))); $add_link = $registry->hasMethod('contacts/import') ? Horde_Util::addParameter($addURL, 'actionID', 'add_address') : null; - } + } catch (Horde_Exception $e) {} } foreach (Horde_Mime_Address::getAddressesFromObject($addrlist) as $ob) { diff --git a/imp/view.php b/imp/view.php index 60880e87e..2ce8b4f68 100644 --- a/imp/view.php +++ b/imp/view.php @@ -107,18 +107,20 @@ case 'download_all': if (!$name) { $name = sprintf(_("part %s"), $val); } - $tosave[] = array('data' => $mime->getContents(), 'name' => $name); + $tosave[] = array('data' => $mime->getContents(array('stream' => true)), 'name' => $name); } if (!empty($tosave)) { try { $horde_compress = Horde_Compress::factory('zip'); - $body = $horde_compress->compress($tosave); + $body = $horde_compress->compress($tosave, array('stream' => true)); } catch (Horde_Exception $e) { Horde::fatal($e); } - $browser->downloadHeaders($zipfile, 'application/zip', false, strlen($body)); - echo $body; + fseek($body, 0, SEEK_END); + $browser->downloadHeaders($zipfile, 'application/zip', false, ftell($body)); + rewind($body); + fpassthru($body); } exit; @@ -135,7 +137,7 @@ case 'download_render': if (Horde_Util::getFormData('zip')) { try { $horde_compress = Horde_Compress::factory('zip'); - $body = $horde_compress->compress(array(array('data' => $mime->getContents(), 'name' => $name))); + $body = $horde_compress->compress(array(array('data' => $mime->getContents(), 'name' => $name)), array('stream' => true)); } catch (Horde_Exception $e) { Horde::fatal($e); } @@ -159,11 +161,13 @@ case 'download_render': break; } - $browser->downloadHeaders($name, $type, false, strlen($body)); if (is_resource($body)) { + fseek($body, 0, SEEK_END); + $browser->downloadHeaders($name, $type, false, ftell($body)); rewind($body); fpassthru($body); } else { + $browser->downloadHeaders($name, $type, false, strlen($body)); echo $body; } exit;