Indy为某些消息返回奇数内容类型.如何解决?

Dom*_*mus 4 delphi indy indy10

这种特殊的亚马逊消息似乎抛出了Indy的MessagePart解析器.

消息是结构化的(当然是强烈删节版本):

Content-Type: multipart/mixed;
       boundary="----=_Part_853547_18414509.1354745829993"

<some irrelevant header stuff>

------=_Part_853547_18414509.1354745829993
Content-Type: multipart/alternative;
       boundary="----=_Part_853548_20128671.1354745829993"

------=_Part_853548_20128671.1354745829993
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<the message in plain text>

------=_Part_853548_20128671.1354745829993
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<the message in HTML>

------=_Part_853548_20128671.1354745829993--

------=_Part_853547_18414509.1354745829993--
Run Code Online (Sandbox Code Playgroud)

现在,当我表演时

imap.UIDRetrieve(UID,Msg)
Run Code Online (Sandbox Code Playgroud)

然后

Msg.ContentType = "multipart/mixed"
Run Code Online (Sandbox Code Playgroud)

并且个人Msg.MessageParts将此作为内容类型:

Msg.MessageParts[0].ContentType = "multipart/alternative; boundary="----=_Part_853548_20128671.1354745829993""

Msg.MessageParts[1].ContentType = "text/plain"
Run Code Online (Sandbox Code Playgroud)

没有任何痕迹text/html.

有人会知道这里发生了什么吗?

(我正在使用最新的Indy版本)

Rem*_*eau 5

当我通过TIdMessage使用当前的Indy 10 SVN快照直接运行该电子邮件数据时,它解析得很好.三个MessageParts是生成的条目- multipart/alternative,text/plain以及text/html-如预期.

您最近发布的关于同一主题的Embarcadero论坛的帖子中,您遗漏了一条关键信息 - 您正在使用它TIdIMAP4来检索失败的电子邮件.这一点很重要,因为您认为不相关的电子邮件部分必须包含一些Indy代码的数据,这些代码具有已知的设计限制,不会在Indy 10中修复(但已经标记为Indy 11的要求)但哪个影响TIdIMAP4.

在内部,TIdIMAP4.UIDRetreive()将原始下载的电子邮件原样传递给TIdMessage.LoadFromStream().内部的核心解析器TIdMessage期望使用IMAP实际上不使用的SMTP样式的点透明度来转义输入数据. TIdMessage目前无法知道输入电子邮件数据的来源,因此无法知道转发数据的格式.更高级别的协议传输负责根据需要解析和解码转义数据,然后将未转义的数据传递TIdMessage给进一步解析.但现在情况并非如此.Indy 10中的逻辑分离并没有达到应有的程度. TIdMessage使用源数据,这在正常工作直接访问TIdSMTPTIdPOP3而不是在TIdIMAP4.

IdMessageClient.pas单元中,有一个名为helper的类TIdIOHandlerStreamMsg,它有一个公共EscapeLines属性,专门用于在需要它的情况下帮助解决这个问题(即将未转义的数据传递给TIdMessage.LoadFrom...()方法).TIdMessage.LoadFromStream()当前的解决方法不是直接调用,而是实例化a TIdMessageClient,为其属性分配,将TIdIOHandlerStreamMsgIOHandler属性设置EscapeLines为True,并将源传递TStream给解析和目标TIdMessage以输出到.这允许Indy伪造核心解析器期望无法转换的转义格式.

但是,TIdIMAP4目前尚未使用此解决方法.现在我想到这一点,它应该很容易添加,所以我会调查它.在此期间,您可以使用TIdIMAP4.RetrieveNoDecodeToStream()TIdIMAP4.UIDRetrieveNoDecodeToStream()在写入目标时间接转义数据TStream(另一个需要修复的已知设计限制),然后您可以将其TStream传递TIdMessage.LoadFromStream()给正常解析.

更新:我刚刚检查了更新AppendMsg()InternalRetrieve()方法,TIdIMAP4不再依赖于SMTP样式的点透明度.这已经在Indy的TODO列表上已经有好几年了,所以很高兴最终解决它.