[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