The slightly out of date documentation for Indy 10 does not explain what belongs in the AExpectedResponses parameter for the SendCmd function in the TIdImap4 class. But even after looking through the source code for TIdImap4 to see how SendCmd is used internally and searching on google, I'm not getting a consistent picture of when to include items from the responses and/or results section of the IMAP RFCs and/or leave that parameter blank. Can anyone explain a little bit how this parameter is used and what should be in it?
Or, perhaps, it would help to use a concrete example:
I am implementing UID MOVE for servers that support that RFC... so so far I have:
IMAP.SendCmd('UID MOVE '+uidList.CommaText +' '+destFolder,[],true);
And from reading the RFC (6851), there are some hints about the expected responses ("nothing specific") and result (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
but there's also a note later on that there may be untagged "unrelated" responses in relation to this command before the 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.
And the RFC gives an example of such:
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
It seems fairly but not exactly the same as what I'm really seeing connecting to gmail, which is basically, the same with no untagged OK, and the addition of an untagged EXISTS command (which I believe is included to support the UIDPLUS extension support):
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>
so here I'm seeing untagged responses of "EXPUNGE" and "EXISTS" and apparently "OK" could be sent as well, before the resulting "OK".
So I'm a little fuzzy on whether what actually belongs in AExpectedResponses is [EXPUNGE, EXISTS, OK], nothing [], the results [OK, NO, BAD] or something else entirely. Thank you.
When parsing the lines of a response, any line that does not begin with a word in the AExpectedResponses
list is not treated as part of the response itself (unless the line begins with the same tag as the command, of course, since that terminates the response). The line is stored in the TIdReplyIMAP4(LastCmdResult).Extra
property instead of the LastCmdResult.Text
property, if stored at all.
In your UID MOVE
example response:
If you include 'OK'
in the AExpectedResponses
list then the * OK [COPYUID 432432 42:69 1202:1229]
line (if received) will be saved in the LastCmdResult.Text
property, otherwise it will be saved in the TIdReplyIMAP4(LastCmdResult).Extra
property instead.
If you include 'EXPUNGE'
in the AExpectedResponses
list then the * <msgid> EXPUNGE
lines (if received) will be saved in the LastCmdResult.Text
property, otherwise they will be saved in the TIdReplyIMAP4(LastCmdResult).Extra
property instead.
If you include 'EXISTS'
in the AExpectedResponses
list then the * <msgid> EXISTS
lines (if received) will be saved in the LastCmdResult.Text
property, otherwise they will be saved in the TIdReplyIMAP4(LastCmdResult).Extra
property instead.
Basically, whatever you specify in AExpectedResponses
will be saved in TIdReplyIMAP4.Text
, and anything else will be either discarded or saved in TIdReplyIMAP4.Extra
instead.
Or at least that is a simplified explanation. TIdIMAP4
is a very complex component, mainly because IMAP is actually an asynchronous protocol, but TIdIMAP4
is a synchronous component, so its response parser employs several rules to handle cases when unexpected unsolicited responses arrive when not expected, and it doesn't want to just discard them. So you kind of have to pay attention to the Extra
property (which TIdIMAP4
doesn't really do internally, though it probably should). Maybe in Indy 11, TIdIMAP4
will be redesigned to separate response handling to a separate thread or an event-based model, but that is not likely to happen in Indy 10.