Поле IMessageSummary.Envelope.InReplyTo в MailKit всегда пустое - PullRequest
1 голос
/ 07 апреля 2020

Я пытаюсь реализовать почтовый клиент, используя протокол IMAP и библиотеку MailKit.

Независимо от того, как я настраиваю IMapCl inet, поле IMessageSummary.Envelope.InReplyTo всегда равно нулю.

Я использую метод Fetch, как показано ниже:

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

И что интересно, заголовок для In-Reply-To присутствует и содержит значение, которое также присутствует в заголовке References (они имеют одинаковое значение), но все же упомянутое поле всегда пусто.

Я что-то упустил или мне нужно как-то оценить свойство 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.

Новый вопрос : В случае, если In-Reply-To отсутствует на ENVELOPE, правильно ли вручную проверять заголовки, чтобы найти значение, или это безопаснее использовать поле References, которое предоставляется объектом IMessageSummary?

1 Ответ

1 голос
/ 07 апреля 2020

MailKit анализирует значение ENVELOPE, возвращаемое сервером IMAP. Если вы посмотрите на Протокол протокола , предоставляют ли ответы сервера IMAP ненулевое значение In-Reply-To в ответе ENVELOPE?

Значение 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 вторую от последней строки.

Редактировать:

Хорошо, теперь, когда вы вставили журнал, мы можем посмотреть, что мы получили с сервера. Вот соответствующий бит:

... 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 = "Вт, 07 апреля 2020 16:36:22 GMT"

env-subject = "Re: Привет, дорогой друг"

env-from = (("test@mypc.local" NIL "тест" "myp c .local"))

env-sender = (("test@mypc.local" NIL "тест") "myp c .local"))

env-reply-to = ((NIL NIL "test" "myp c .local"))

env-to = ((NIL NIL "кто-то" "myp c .local"))

env-cc = NIL

env-bcc = NIL

env-in-reply-to = NIL

env-message-id = ""

Итак, проблема в том, что IMAP-сервер сообщает MailKit, что значение In-Reply-To равно NIL (он же null).

Исходя из необработанных заголовков, которые вы возвращаете для этого сообщения, ясно, что сервер SmarterMail IMAP содержит ошибки по крайней мере 2 способами:

  1. Значение env-in-reply-to отправляется как NIL когда оно должно быть явно "<specified-message-id>"
  2. env-sender отправляется как дубликат env-from, но должно быть NIL в вашем случае на основе заголовков, потому что он сопоставляется с Sender: он ader, которого нет в вашем примере сообщения.

Вопрос к вам: буквально "<specified-message-id>" находится в заголовках? Интересно, может быть, SmarterMail отправляет NIL, потому что это технически недопустимый синтаксис и, возможно, SmarterMail не может его проанализировать?

Просто мысль.

Относительно " Новый вопрос "в вашем посте:

Да, вы можете запросить заголовок In-Reply-To и вручную его проанализировать - это прекрасно. Фактически, способ MessageSummaryItems.References работает так: он запрашивает HEADER.FIELDS (REFERENCES) и затем анализирует необработанный заголовок. Поскольку вы также отправляете MessageSummaryItems.Headers, MailKit знает, что бессмысленно снова запрашивать References, так как это будет частью ответа Headers.

Я бы, наверное, не рекомендуется запрашивать полный набор MessageSummaryItems.Headers (если только у вас нет особой c необходимости извлекать их все), поскольку вам не нужно много дополнительных данных. Опять же, когда речь идет о сломанном сервере IMAP, возможно, лучше попросить Headers, чем Envelope.

Идея Envelope состоит в том, что это более или менее все, что вам нужно клиенту знать о том, чтобы отобразить список сообщений для пользователя.

Причина, по которой MailKit имеет MessageSummaryItems.References (а не какой-либо другой отдельный заголовок), заключается в том, что для выполнения требуется заголовок References правильная нарезка резьбы с использованием методов MailKit.MessageThreader.Thread(). Он также будет использовать значение Envelope.InReplyTo, но это не обязательно, я не думаю, потому что технически, References означает , предполагается, что должен иметь тот же токен msg-id, что и один его значений.

Заголовок References представляет собой цепочку значений заголовка Message-Id, возвращающуюся к root "диалога" (это немного сложнее, чем это, поскольку клиентам разрешено обрезать некоторые из них). msg-id значения, как только список становится слишком длинным, но это общая идея).

...