tidimap4.SendCmd 的 AExpectedResponses 参数属于什么?

What belongs in AExpectedResponses parameter to tidimap4.SendCmd?

Indy 10 的稍微过时的文档没有解释 TIdImap4 class 中 SendCmd 函数的 AExpectedResponses 参数中的内容。但是,即使在查看了 TIdImap4 的源代码以了解内部如何使用 SendCmd 并在 google 上进行搜索之后,我也没有得到关于何时包含响应 and/or 结果部分中的项目的一致图片IMAP RFC and/or 将该参数留空。谁能解释一下这个参数是如何使用的,里面应该有什么?

或者,也许,使用一个具体的例子会有所帮助:

我正在为支持该 RFC 的服务器实施 UID MOVE...到目前为止我有:

IMAP.SendCmd('UID MOVE '+uidList.CommaText +' '+destFolder,[],true);

并且通过阅读 RFC (6851),有一些关于预期响应(“没有特定内容”)和结果(OK、NO、BAD)的提示。

3.1.  MOVE Command
   Arguments: sequence set
              mailbox name
   Responses: no specific responses for this command
   Result: OK - move completed
           NO - move error: can't move those messages or to that name
           BAD - command unknown or arguments invalid

但稍后还有一条说明,在 OK 之前可能存在与此命令相关的未标记的“不相关”响应:

Note that the server may send unrelated EXPUNGE responses as well, if
any happen to have been expunged at the same time; this is normal
IMAP operation.

RFC 给出了一个这样的例子:

   C: a UID MOVE 42:69 foo
   S: * OK [COPYUID 432432 42:69 1202:1229]
   S: * 22 EXPUNGE
   S: (more expunges)
   S: a OK Done

这看起来与我实际看到的连接到 gmail 的情况相当但不完全相同,基本上是一样的,没有未标记的 OK,并且添加了未标记的 EXISTS 命令(我相信它包含在支持 UIDPLUS 扩展支持):

Sent 6/25/2016 4:08:04 PM: C246 UID MOVE 179,180,181,183,184,198,199 [Gmail]/Trash<EOL>
Recv 6/25/2016 4:08:04 PM: * 48 EXPUNGE<EOL>
Recv 6/25/2016 4:08:04 PM: * 48 EXPUNGE<EOL>
Recv 6/25/2016 4:08:04 PM: * 48 EXPUNGE<EOL>
Recv 6/25/2016 4:08:04 PM: * 49 EXPUNGE<EOL>
Recv 6/25/2016 4:08:04 PM: * 49 EXPUNGE<EOL>
Recv 6/25/2016 4:08:04 PM: * 54 EXPUNGE<EOL>
Recv 6/25/2016 4:08:04 PM: * 54 EXPUNGE<EOL>
Recv 6/25/2016 4:08:04 PM: * 53 EXISTS<EOL>
Recv 6/25/2016 4:08:04 PM: C246 OK [COPYUID 2 179:181,183:184,198:199 80,79,78,77,76,75,74] (Success)<EOL>

所以在这里我看到“EXPUNGE”和“EXISTS”的未标记响应,显然“OK”也可以在结果“OK”之前发送。

所以我有点不清楚 AExpectedResponses 中实际属于什么 [EXPUNGE, EXISTS, OK],什么都没有 [],结果 [OK,NO,BAD] 还是完全是其他东西。谢谢。

解析响应行时,任何不以 AExpectedResponses 列表中的单词开头的行都不会被视为响应本身的一部分(除非该行以与命令,当然,因为那会终止响应)。该行存储在 TIdReplyIMAP4(LastCmdResult).Extra 属性 中,而不是 LastCmdResult.Text 属性,如果有的话。

在您的 UID MOVE 示例响应中:

如果您在 AExpectedResponses 列表中包含 'OK',则 * OK [COPYUID 432432 42:69 1202:1229] 行(如果收到)将保存在 LastCmdResult.Text 属性 中,否则它将保存在 TIdReplyIMAP4(LastCmdResult).Extra 属性 中。

如果您在 AExpectedResponses 列表中包含 'EXPUNGE',则 * <msgid> EXPUNGE 行(如果收到)将保存在 LastCmdResult.Text 属性 中,否则它们将保存在 TIdReplyIMAP4(LastCmdResult).Extra 属性 中。

如果您在 AExpectedResponses 列表中包含 'EXISTS',则 * <msgid> EXISTS 行(如果收到)将保存在 LastCmdResult.Text 属性 中,否则它们将保存在 TIdReplyIMAP4(LastCmdResult).Extra 属性 中。

基本上,您在 AExpectedResponses 中指定的任何内容都将保存在 TIdReplyIMAP4.Text 中,其他任何内容都将被丢弃或保存在 TIdReplyIMAP4.Extra 中。

或者至少这是一个简化的解释。 TIdIMAP4 是一个非常复杂的组件,主要是因为 IMAP 实际上是一个异步协议,而 TIdIMAP4 是一个同步组件,所以它的响应解析器使用几个规则来处理意外的未经请求的响应在不期望的情况下到达的情况,它不想只是丢弃它们。所以你必须注意 Extra 属性(TIdIMAP4 在内部并没有真正做到,尽管它可能应该这样做)。也许在 Indy 11 中,TIdIMAP4 将被重新设计以将响应处理分离到单独的线程或基于事件的模型,但这不太可能在 Indy 10 中发生。