当前位置 : 主页 > 编程语言 > delphi >

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

来源:互联网 收集:自由互联 发布时间:2021-06-23
这种特殊的亚马逊消息似乎抛出了Indy的MessagePart解析器. 消息是结构化的(当然是强烈删节版本): Content-Type: multipart/mixed; boundary="----=_Part_853547_18414509.1354745829993"some irrelevant header stuff--
这种特殊的亚马逊消息似乎抛出了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--

现在,当我表演时

imap.UIDRetrieve(UID,Msg)

然后

Msg.ContentType = "multipart/mixed"

并且单个Msg.MessageParts将此作为content-type:

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

Msg.MessageParts[1].ContentType = "text/plain"

没有文字/ html部分的痕迹.

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

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

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

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

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

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

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

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

网友评论