4

IndyのMessagePartパーサーをスローするように見えるこの特定の種類のAmazonメッセージがあります。

メッセージは次のように構成されています(もちろん、大幅に要約されたバージョン)。

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はこれをコンテンツタイプとして持っています:

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

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

部品の痕跡はありませんtext/html

誰かがここで何が起こっているのか分かりますか?

(最新のIndyビルドを使用しています)

4

1 に答える 1

6

TIdMessage現在のIndy10SVNスナップショットを使用して、その電子メールデータをそのまま実行すると、正常に解析されます。予想どおり、、、、およびの3つのエントリMessagePartsが生成されます。multipart/alternativetext/plaintext/html

この同じテーマに関するEmbarcaderoフォーラムへの最近の投稿ではTIdIMAP4、重要な情報を省略しました。これは、失敗している電子メールを取得するために使用しています。無関係と思われる電子メールの部分には、Indy 10では修正されない既知の設計上の制限がある(ただし、Indy 11で必須としてすでにマークされている)Indyコードの一部にヒットするデータが含まれている必要があるため、これは重要です。しかし、これはに影響しTIdIMAP4ます。

内部的にTIdIMAP4.UIDRetreive()は、ダウンロードした生の電子メールをそのままにに渡しますTIdMessage.LoadFromStream()。内部のコアパーサーTIdMessageは、IMAPが実際には使用しないSMTPスタイルのドット透過性を使用して入力データがエスケープされることを想定しています。 TIdMessage現在、入力された電子メールデータのソースを知る方法がなく、その結果、エスケープされたデータのフォーマットを知ることができません。必要に応じてエスケープされたデータを解析およびデコードしTIdMessage、さらに解析するためにエスケープされていないデータを渡すのは、より高いレベルのプロトコルトランスポートの責任です。しかし、実際にはそうではありません。Indy 10では、ロジックの分離が適切に行われていません。 TIdMessageソースデータへの直接アクセスを使用します。これはで正常に機能しますが、では機能しTIdSMTPませTIdPOP3TIdIMAP4

ユニットには、この問題を必要とする状況(つまり、エスケープされていないデータをメソッドに渡す)でこの問題に対処するために特別に設計されたパブリックプロパティを持つIdMessageClient.pasという名前のヘルパークラスがあります。現在の回避策は、直接呼び出す代わりに、をインスタンス化し、そのプロパティにaを割り当て、そのプロパティをTrueに設定し、解析するソースと出力する宛先を渡すことです。これにより、Indyは、コアパーサーがエスケープ解除することを期待しているエスケープフォーマットを偽造することができます。TIdIOHandlerStreamMsgEscapeLinesTIdMessage.LoadFrom...()TIdMessage.LoadFromStream()TIdMessageClientTIdIOHandlerStreamMsgIOHandlerEscapeLinesTStreamTIdMessage

ただし、TIdIMAP4現在、この回避策はまだ利用されていません。これについて考えてみると、簡単に追加できるはずなので、調べてみます。TIdIMAP4.RetrieveNoDecodeToStream()それまでの間、またはを使用できますTIdIMAP4.UIDRetrieveNoDecodeToStream()。これは、宛先への書き込み時に間接的にデータをエスケープしTStream(修正が必要な別の既知の設計上の制限)、それをに渡してTStream通常TIdMessage.LoadFromStream()の解析を行うことができます。

更新: SMTPスタイルのドット透過性に依存しないようにするためのAppendMsg()およびInternalRetrieve()メソッドの更新をチェックインしました。TIdIMAP4これは数年前からインディのTODOリストに載っているので、最終的に対処するのは良いことです。

于 2012-12-10T06:02:30.907 に答える