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

时间:2016-06-27 23:23:37

标签: indy indy10

Indy 10的略微过时的文档没有解释TIdImap4类中SendCmd函数的AExpectedResponses参数中的内容。但即使在查看TIdImap4的源代码以了解如何在内部使用SendCmd并在Google上进行搜索之后,我也无法获得有关何时在IMAP RFC的响应和/或结果部分中包含项目的一致信息和/或将该参数留空。任何人都可以解释一下这个参数是如何使用的以及它应该包含在哪里?

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

我正在为支持该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]或其他完全属性有点模糊。谢谢。

1 个答案:

答案 0 :(得分:1)

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

UID MOVE示例回复中:

如果您在'OK'列表中加入AExpectedResponses,则* OK [COPYUID 432432 42:69 1202:1229]行(如果收到)将保存在LastCmdResult.Text媒体资源中,否则会保存在而是TIdReplyIMAP4(LastCmdResult).Extra财产。

如果您在'EXPUNGE'列表中加入AExpectedResponses,则* <msgid> EXPUNGE行(如果收到)将保存在LastCmdResult.Text媒体资源中,否则会保存在而是TIdReplyIMAP4(LastCmdResult).Extra财产。

如果您在'EXISTS'列表中加入AExpectedResponses,则* <msgid> EXISTS行(如果收到)将保存在LastCmdResult.Text媒体资源中,否则会保存在而是TIdReplyIMAP4(LastCmdResult).Extra财产。

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

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