📄 rfc4549.txt
字号:
asking for the descriptors of all the messages we know the clientMelnikov Informational [Page 18]RFC 4549 Synch Ops for Disconnected IMAP4 Clients June 2006 cannot possibly have cached yet. The second command fetches the information we need to determine what changes may have occurred to messages that the client already has cached. Note that the former command should only be issued if the UIDNEXT value cached by the client differs from the one returned by the server. Once the client has issued these two commands, there's nothing more the client can do with this mailbox until the responses to the first command start arriving. A clever synchronization program might use this time to fetch its local cache state from disk or to start the process of synchronizing another mailbox. The following is an example of the first FETCH: C: A011 UID fetch 131:* (FLAGS BODYSTRUCTURE INTERNALDATE RFC822.SIZE) Note 1: The first FETCH may result in the server's sending a huge volume of data. A smart disconnected client should use message ranges (see also Section 3.2.1.2 of [RFC2683]), so that the user is able to execute a different operation between fetching information for a group of new messages. Example 7: Knowing the new UIDNEXT returned by the server on SELECT or EXAMINE (<uidnext>), the client can split the UID range <lastseenuid+1>:<uidnext> into groups, e.g., 100 messages. After that, the client can issue: C: A011 UID fetch <lastseenuid+1>:<lastseenuid+100> (FLAGS BODYSTRUCTURE INTERNALDATE RFC822.SIZE) ... C: A012 UID fetch <lastseenuid+101>:<lastseenuid+200> (FLAGS BODYSTRUCTURE INTERNALDATE RFC822.SIZE) ... ... C: A0FF UID fetch <lastseenuid+901>:<uidnext> (FLAGS BODYSTRUCTURE INTERNALDATE RFC822.SIZE) Note that unless a SEARCH command is issued, it is impossible to determine how many messages will fall into a subrange, as UIDs are not necessarily contiguous. Note 2: The client SHOULD ignore any unsolicited EXPUNGE responses received during the first FETCH command. EXPUNGE responses contain message numbers that are useless to a client that doesn't have the message-number-to-UID translation table.Melnikov Informational [Page 19]RFC 4549 Synch Ops for Disconnected IMAP4 Clients June 2006 The second FETCH command will result in zero or more untagged fetch responses. Each response will have a corresponding UID FETCH data item. All messages that didn't have a matching untagged FETCH response MUST be removed from the local cache. For example, if the <lastseenuid> had a value 15000 and the local cache contained 3 messages with the UIDs 12, 777, and 14999, respectively, then after receiving the following responses from the server, the client must remove the message with UID 14999 from its local cache. S: * 1 FETCH (UID 12 FLAGS (\Seen)) S: * 2 FETCH (UID 777 FLAGS (\Answered \Deleted)) Note 3: If the client is not interested in flag changes (i.e., the client only wants to know which old messages are still on the server), the second FETCH command can be substituted with: tag2 UID SEARCH UID 1:<lastseenuid> This command will generate less traffic. However, an implementor should be aware that in order to build the mapping table from message numbers to UIDs, the output of the SEARCH command MUST be sorted first, because there is no requirement for a server to return UIDs in SEARCH response in any particular order.4.3.2. Searching for "Interesting" Messages. This step is performed entirely on the client (from the information received in the step described in 4.3.1), entirely on the server, or on some combination of both. The decision on what is an "interesting" message is up to the client software and the human. One easy criterion that should probably be implemented in any client is whether the message is "too big" for automatic retrieval, where "too big" is a parameter defined in the client's configuration. Another commonly used criterion is the age of a message. For example, the client may choose to download only messages received in the last week (in this case, <date> would be today's date minus 7 days): tag3 UID SEARCH UID <uidset> SINCE <date> Keep in mind that a date search disregards time and time zone. The client can avoid doing this search if it specified INTERNALDATE in <descriptors> on the step described in 4.3.1. If the client did, it can perform the local search on its message cache.Melnikov Informational [Page 20]RFC 4549 Synch Ops for Disconnected IMAP4 Clients June 2006 At this step, the client also decides what kind of information about a particular message to fetch from the server. In particular, even for a message that is considered "too big", the client MAY choose to fetch some part(s) of it. For example, if the message is a multipart/mixed containing a text part and a MPEG attachment, there is no reason for the client not to fetch the text part. The decision of which part should or should not be fetched can be based on the information received in the BODYSTRUCTURE FETCH response data item (i.e., if BODYSTRUCTURE was included in <descriptors> on the step described in 4.3.1).4.3.3. Populating Cache with "Interesting" Messages. Once the client has found out which messages are "interesting", it can start issuing appropriate FETCH commands for "interesting" messages or parts thereof. Note that fetching a message into the disconnected client's local cache does NOT imply that the human has (or even will) read the message. Thus, the synchronization program for a disconnected client should always be careful to use the .PEEK variants of the FETCH data items that implicitly set the \Seen flag. Once the last descriptor has arrived and the last FETCH command has been issued, the client simply needs to process the incoming fetch items and use them to update the local message cache. In order to avoid deadlock problems, the client must give processing of received messages priority over issuing new FETCH commands during this synchronization process. This may necessitate temporary local queuing of FETCH requests that cannot be issued without causing a deadlock. In order to achieve the best use of the "expensive" network connection, the client will almost certainly need to pay careful attention to any flow-control information that it can obtain from the underlying transport connection (usually a TCP connection). Note: The requirement stated in the previous paragraph might result in an unpleasant user experience, if followed blindly. For example, the user might be unwilling to wait for the client to finish synchronization before starting to process the user's requests. A smart disconnected client should allow the user to perform requested operations in between IMAP commands that are part of the synchronization process. See also Note 1 in Section 4.3.1.Melnikov Informational [Page 21]RFC 4549 Synch Ops for Disconnected IMAP4 Clients June 2006 Example 8: After fetching a message BODYSTRUCTURE, the client discovers a complex MIME message. Then, it decides to fetch MIME headers of the nested MIME messages and some body parts. C: A011 UID fetch 11 (BODYSTRUCTURE) S: ... C: A012 UID fetch 11 (BODY[HEADER] BODY[1.MIME] BODY[1.1.MIME] BODY[1.2.MIME] BODY[2.MIME] BODY[3.MIME] BODY[4.MIME] BODY[5.MIME] BODY[6.MIME] BODY[7.MIME] BODY[8.MIME] BODY[9.MIME] BODY[10.MIME] BODY[11.MIME] BODY[12.MIME] BODY[13.MIME] BODY[14.MIME] BODY[15.MIME] BODY[16.MIME] BODY[17.MIME] BODY[18.MIME] BODY[19.MIME] BODY[20.MIME] BODY[21.MIME]) S: ... C: A013 UID fetch 11 (BODY[1.1] BODY[1.2]) S: ... C: A014 UID fetch 11 (BODY[3] BODY[4] BODY[5] BODY[6] BODY[7] BODY[8] BODY[9] BODY[10] BODY[11] BODY[13] BODY[14] BODY[15] BODY[16] BODY[21]) S: ...4.3.4. User-Initiated Synchronization After the client has finished the main synchronization process as described in Sections 4.3.1-4.3.3, the user may optionally request additional synchronization steps while the client is still online. This is not any different from the process described in Sections 4.3.2 and 4.3.3. Typical examples are: 1) fetch all messages selected in UI. 2) fetch all messages marked as \Flagged on the server.4.4. Special Case: Descriptor-Only Synchronization For some mailboxes, fetching the descriptors might be the entire synchronization step. Practical experience with IMAP has shown that a certain class of mailboxes (e.g., "archival" mailboxes) are used primarily for long-term storage of important messages that the human wants to have instantly available on demand but does not want cluttering up the disconnected client's cache at any other time. Messages in this kind of mailbox would be fetched exclusively by explicit actions queued by the local MUA. Thus, the only synchronization desirable on this kind of mailbox is fetching enough descriptor information for the user to be able to identify messages for subsequent download.Melnikov Informational [Page 22]RFC 4549 Synch Ops for Disconnected IMAP4 Clients June 2006 Special mailboxes that receive messages from a high volume, low priority mailing list might also be in this category, at least when the human is in a hurry.4.5. Special Case: Fast New-Only Synchronization In some cases, the human might be in such a hurry that he or she doesn't care about changes to old messages, just about new messages. In this case, the client can skip the UID FETCH command that obtains the flags and UIDs for old messages (1:<lastseenuid>).4.6. Special Case: Blind FETCH In some cases, the human may know (for whatever reason) that he or she always wants to fetch any new messages in a particular mailbox, unconditionally. In this case, the client can just fetch the messages themselves, rather than just the descriptors, by using a command like: tag1 UID FETCH <lastseenuid+1>:* (FLAGS BODY.PEEK[]) Note that this example ignores the fact that the messages can be arbitrary long. The disconnected client MUST always check for message size before downloading, unless explicitly told otherwise. A well-behaved client should instead use something like the following: 1) Issue "tag1 UID FETCH <lastseenuid+1>:* (FLAGS RFC822.SIZE)". 2) From the message sizes returned in step 1, construct UID set <required_messages>. 3) Issue "tag2 UID FETCH <required_messages> (BODY.PEEK[])". or 1) Issue "tag1 UID FETCH <lastseenuid+1>:* (FLAGS)". 2) Construct UID set <old_uids> from the responses of step 1. 3) Issue "tag2 SEARCH UID <old_uids> SMALLER <message_limit>". Construct UID set <required_messages> from the result of the SEARCH command. 4) Issue "tag3 UID FETCH <required_messages> (BODY.PEEK[])".Melnikov Informational [Page 23]RFC 4549 Synch Ops for Disconnected IMAP4 Clients June 2006 or 1) Issue "tag1 UID FETCH <lastseenuid+1>:* (FLAGS BODY.PEEK[]<0.<length>>)", where <length> should be replaced with the maximal message size the client is willing to download. Note: In response to such a command, the server will only return partial data if the message is longer than <length>. It will return the full message data for any message whose size is smaller than or equal to <length>. In the former case, the client will not be able to extract the full MIME structure of the message from the truncated data, so the client should include BODYSTRUCTURE in the UID FETCH command as well.5. Implementation Considerations Below are listed some common implementation pitfalls that should be considered when implementing a disconnected client. 1) Implementing fake UIDs on the client. A message scheduled to be uploaded has no UID, as UIDs are selected by the server. The client may implement fake UIDs internally in order to reference not-yet-uploaded messages in further operations. (For example, a message could be scheduled to be uploaded, but subsequently marked as deleted or copied to another mailbox). Here, the client MUST NOT under any circumstances send these fake UIDs to the server. Also, client implementers should be reminded that according to [IMAP4] a UID is a 32-bit unsigned integer excluding 0. So, both 4294967295 and 2147483648 are valid UIDs, and 0 and -1 are both invalid. Some disconnected mail clients have been known to send negative numbers (e.g., "-1") as message UIDs to servers during synchronization. Situation 1: The user starts composing a new message, edits it, saves it, continues to edit it, and saves it again. A disconnected client may record in its replay log (log of operations to be replayed on the server during synchronization) the sequence of operations as shown below. For the purpose of this situation, we assume that all draft messages are stored in the mailbox called Drafts on an IMAP server. We will also use the following conventions: <old_uid> is the UID of the intermediate version of the draft when it was saved for the first time. This is a fake UID generated on the client. <new_uid> is the UID of the final version of the draft. This is another fake UID
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -