[dev] Reading messages with Horde_Mime_Part::parseMessage()

Michael M Slusarz slusarz at horde.org
Tue Mar 22 05:27:13 UTC 2011


Quoting Gunnar Wrobel <wrobel at horde.org>:

> Hi Micheal,
>
> when working on the final elements of the Kolab_Storage API this  
> weekend I used Horde_Mime_Part::parseMessage() to read in complete  
> messages from the IMAP backend. I replaced one part of these  
> messages with alterPart() and tried writing the messages back via  
> toString(). The resulting message did however duplicate the message  
> to some extend. When reading multi-part messages with parseMessage()  
> the base part ($message->getPart('0')) contains the complete message  
> text including all subparts. This leads to the duplication when  
> using $message->toString() afterwards.
>
> My expectation was that this would hold true:
>
> $message = Horde_Mime_Part::parseMessage($message_text);
> $message->toString() == $message_text;

This is essentially true.  But this is not what you are doing.  You  
are building the message data and then altering it.  Horde_Mime_Part  
has not really been tested to do this.

The problem you have encountered deals with the need to preserve the  
EXACT text of the original message.  When we parse the original  
message, Horde_Mime_Part is keeping around the exact original text of  
each part.  This is necessary for PGP/SMIME signed parts which require  
the *exact* text of the original message (including the unparsed  
subparts) in order to work correctly.  Unlike a message living on an  
IMAP server, this message text may not exist in an accessible location  
to access at a later time.  So this full text must be stored in the  
container parts (e.g. the base (0) multipart) to ensure it can be  
accessed later.

However, altering a subpart does not change this original text in the  
parent part so that is why you are seeing the strange results from  
toString() (e.g. the repetition).

The solution that I can come up with is to allow Horde_Mime_Part to  
support callback functions for setContents().  This callback would  
allow the contents to be dynamically determined when getContents() is  
called.  For MIME messages living on an IMAP server, this callback  
would download the message data from the server.  For parsed messages,  
this callback would contain the string offsets within the file/data.   
For string data, this would simply hold the string in memory.  This  
callback would allow access to the canonical data.

I really hate to make such a big change to the Mime library this close  
to the release of H4.  But as Gunnar has discovered, the Mime library  
is very broken when it comes to altering the existing data, so this is  
something that really needs to be fixed immediately.

michael

___________________________________
Michael Slusarz [slusarz at horde.org]




More information about the dev mailing list