MailKit 的 IMessageSummary.Envelope.InReplyTo 字段始终为空

MailKit's IMessageSummary.Envelope.InReplyTo field is always null

我正在尝试使用 IMAP 协议和 MailKit 库实现邮件客户端。

无论我如何配置 IMapClinet,字段 IMessageSummary.Envelope.InReplyTo 始终为空。

我正在使用如下所示的 Fetch 方法:

client.Inbox.Fetch(startIndex, -1, MessageSummaryItems.Full | MessageSummaryItems.UniqueId | MessageSummaryItems.References | MessageSummaryItems.All | MessageSummaryItems.Headers);

有趣的是 In-Reply-To 的 header 存在并且包含 References header 上也存在的值(它们具有相同的值),但提到的字段始终为空。

我是不是遗漏了什么,或者我是否需要在访问其字段之前以某种方式评估 Envelop 属性?

编辑

这是@jstedfast 建议的要检查的协议日志:

Connected to imap://127.0.0.1:143/
S: * OK IMAP4rev1 SmarterMail
C: A00000000 CAPABILITY
S: * CAPABILITY IMAP4rev1 AUTH=CRAM-MD5 AUTH=PLAIN UIDPLUS QUOTA XLIST CHILDREN ENABLE IDLE
S: A00000000 OK CAPABILITY completed
C: A00000001 AUTHENTICATE CRAM-MD5
S: + PDE5MTIwMTU2NjMugwNDIzQFJvamFuUEM+
C: cm9qYW5Acm9qYW5wYy5sb2NhbCAyNGRiYMTNjNzk5YTkyYjBhZjkxYTU3ZQ==
S: A00000001 OK CRAM authentication successful
C: A00000002 CAPABILITY
S: * CAPABILITY IMAP4rev1 AUTH=CRAM-MD5 AUTH=PLAIN UIDPLUS QUOTA XLIST CHILDREN ENABLE IDLE
S: A00000002 OK CAPABILITY completed
C: A00000003 LIST "" ""
S: * LIST (\Noselect) "/" ""
S: A00000003 OK LIST completed
C: A00000004 LIST "" "INBOX"
S: * LIST (\HasNoChildren \Inbox) "/" "Inbox"
S: A00000004 OK LIST completed
C: A00000005 XLIST "" "*"
S: * XLIST (\HasNoChildren \Trash) "/" "Deleted Items"
S: * XLIST (\HasNoChildren) "/" "Drafts"
S: * XLIST (\HasNoChildren \Inbox) "/" "Inbox"
S: * XLIST (\HasNoChildren \Spam) "/" "Junk E-Mail"
S: * XLIST (\HasNoChildren \Sent) "/" "Sent Items"
S: A00000005 OK XLIST completed
C: A00000006 SELECT Inbox
S: * 1 EXISTS
S: * 0 RECENT
S: * OK [UNSEEN 1] Message 1 is first unseen
S: * OK [UIDVALIDITY 1] UIDs valid
S: * OK [UIDNEXT 35] Predicted next UID
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft \Recent)
S: * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \Recent)] Folder flags
S: A00000006 OK [READ-WRITE] SELECT completed
C: A00000007 FETCH 1:* (UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY BODY.PEEK[HEADER])
S: * 1 FETCH (UID 34 FLAGS () INTERNALDATE "7-Apr-2020 18:36:29 +0200" RFC822.SIZE 1536 ENVELOPE ("Tue, 07 Apr 2020 16:36:22 GMT" "Re: Hi dear friend" (({15}
S: test@mypc.local NIL "test" "mypc.local")) (({15}
S: test@mypc.local NIL "test" "mypc.local")) ((NIL NIL "test" "mypc.local")) ((NIL NIL "someone" "mypc.local")) NIL NIL NIL "<e938d94ca6ac4be085192f00cdc7fdd6@mypc.local>") BODY (("text" "plain" ("charset" "utf-8") NIL NIL "quoted-printable" 242 11) ("text" "html" ("charset" "utf-8") NIL NIL "quoted-printable" 482 8) "alternative") BODY[HEADER] {468}
S: From: "test@mypc.local" <test@mypc.local>
S: To: <my@mypc.local>
S: Subject: Re: Hi dear friend
S: Date: Tue, 07 Apr 2020 16:36:22 GMT
S: Reply-To: test@mypc.local
S: Message-ID: <e938d94ca6ac4be085192f00cdc7fdd6@mypc.local>
S: MIME-Version: 1.0
S: Content-Type: multipart/alternative; 
S:  boundary=de8794cbb22d4f6ea5a415917f9287ee
S: In-Reply-To: <specified-message-id>
S: References: <specified-message-id>
S: Disposition-Notification-To: test@mypc.local
S: X-SmarterMail-TotalSpamWeight: 0 (Authenticated)
S: 
S: )
S: A00000007 OK FETCH completed

似乎 In-Reply-To 仅与 References 一起出现在邮件的 header 中。

新问题:在[=20=上没有In-Reply-To的情况下,手动检查[=是正确的方法吗? 45=]s 来查找值,还是使用 IMessageSummary object?

提供的 References 字段更安全?

MailKit 解析 IMAP 服务器返回的 ENVELOPE 值。如果您查看 Protocol Log,IMAP 服务器响应是否在 ENVELOPE 响应中提供 non-null In-Reply-To 值?

ENVELOPE 值具有以下语法:

envelope        = "(" env-date SP env-subject SP env-from SP
                  env-sender SP env-reply-to SP env-to SP env-cc SP
                  env-bcc SP env-in-reply-to SP env-message-id ")"

env-bcc         = "(" 1*address ")" / nil

env-cc          = "(" 1*address ")" / nil

env-date        = nstring

env-from        = "(" 1*address ")" / nil

env-in-reply-to = nstring

env-message-id  = nstring

env-reply-to    = "(" 1*address ")" / nil

env-sender      = "(" 1*address ")" / nil

env-subject     = nstring

env-to          = "(" 1*address ")" / nil

TL;DR,您将在 ENVELOPE 括号列表值中查找 second-to-last 字符串。

编辑:

好的,现在您已经粘贴了日志,我们可以看看从服务器返回的内容。这是相关的位:

... ENVELOPE ("Tue, 07 Apr 2020 16:36:22 GMT" "Re: Hi dear friend" (({15}
S: test@mypc.local NIL "test" "mypc.local")) (({15}
S: test@mypc.local NIL "test" "mypc.local")) ((NIL NIL "test" "mypc.local")) ((NIL NIL "someone" "mypc.local")) NIL NIL NIL "<e938d94ca6ac4be085192f00cdc7fdd6@mypc.local>")

env-date = "Tue, 07 Apr 2020 16:36:22 GMT"

env-subject = "Re: Hi dear friend"

env-from = (("test@mypc.local" 无 "test" "mypc.local"))

env-sender = (("test@mypc.local" 无 "test" "mypc.local"))

env-reply-to = ((无无"test" "mypc.local"))

env-to = ((无无"someone" "mypc.local"))

env-cc = 零

env-bcc = 零

env-in-reply-to = 无

env-message-id = ""

所以问题是 IMAP 服务器告诉 MailKit In-Reply-To 值是 NIL(又名 null)。

根据您收到此邮件的原始 headers,很明显 SmarterMail IMAP 服务器至少在两个方面存在问题:

  1. env-in-reply-to 值作为 NIL 发送,而它显然应该是 "<specified-message-id>"
  2. env-sender 作为 env-from 的副本发送,但根据headers,因为它映射到 Sender: header,您的示例消息不存在。

问你一个问题:"<specified-message-id>" 字面意思是 header 中的内容?我想知道 SmarterMail 是否正在发送 NIL,因为那是 技术上 无效的语法,也许 SmarterMail 无法解析它?

只是一个想法。

关于您 post 中的 "New Question":

是的,您可以请求 In-Reply-To header 并手动解析它 - 这完全没问题。事实上,MessageSummaryItems.References 的工作方式是它请求 HEADER.FIELDS (REFERENCES),然后解析原始的 header。由于您 发送 MessageSummaryItems.Headers,MailKit 知道再次请求 References 毫无意义,因为它将成为 Headers 响应的一部分.

我可能会建议不要请求完整的 MessageSummaryItems.Headers 集(除非您有特定需要将它们全部获取),因为它有很多您不需要的额外数据。再一次,在处理损坏的 IMAP 服务器时,也许请求 Headers 比请求 Envelope 更好。

Envelope 的想法是 more-or-less 您需要客户端了解的所有内容,以便向用户显示 message-list。

MailKit 具有 MessageSummaryItems.References(而不是任何其他个体 header)的原因是因为需要 References header 才能使用MailKit.MessageThreader.Thread() 方法。它也会使用 Envelope.InReplyTo 值,但我认为这不是必需的,因为从技术上讲,References 应该 与其值之一相同的 msg-id 标记。

References header 是 Message-Id header 值的链回到 "conversation" 的根(它比那更复杂一点因为一旦列表变得太长,客户可以 trim 一些 msg-id 值,但这是一般的想法)。