Movatterモバイル変換


[0]ホーム

URL:


[RFC Home] [TEXT|PDF|HTML] [Tracker] [IPR] [Info page]

INFORMATIONAL
Network Working Group                                   A. Melnikov, Ed.Request for Comments: 4549                                    Isode Ltd.Category: Informational                                        June 2006Synchronization Operations for Disconnected IMAP4 ClientsStatus of This Memo   This memo provides information for the Internet community.  It does   not specify an Internet standard of any kind.  Distribution of this   memo is unlimited.Copyright Notice   Copyright (C) The Internet Society (2006).Abstract   This document attempts to address some of the issues involved in   building a disconnected IMAP4 client.  In particular, it deals with   the issues of what might be called the "driver" portion of the   synchronization tool: the portion of the code responsible for issuing   the correct set of IMAP4 commands to synchronize the disconnected   client in the way that is most likely to make the human who uses the   disconnected client happy.   This note describes different strategies that can be used by   disconnected clients and shows how to use IMAP protocol in order to   minimize the time of the synchronization process.   This note also lists IMAP extensions that a server should implement   in order to provide better synchronization facilities to disconnected   clients.Melnikov                     Informational                      [Page 1]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006Table of Contents1. Introduction ....................................................31.1. Conventions Used in This Document ..........................32. Design Principles ...............................................33. Overall Picture of Synchronization ..............................44. Mailbox Synchronization Steps and Strategies ....................74.1. Checking UID Validity ......................................74.2. Synchronizing Local Changes with the Server ................84.2.1. Uploading Messages to the Mailbox ...................84.2.2. Optimizing "move" and "copy" Operations .............94.2.3. Replaying Local Flag Changes .......................144.2.4. Processing Mailbox Compression (EXPUNGE) Requests ..154.2.5. Closing a Mailbox ..................................174.3. Details of "Normal" Synchronization of a Single Mailbox ...18           4.3.1. Discovering New Messages and Changes to Old                  Messages ...........................................184.3.2. Searching for "Interesting" Messages. ..............204.3.3. Populating Cache with "Interesting" Messages. ......214.3.4. User-Initiated Synchronization .....................224.4. Special Case: Descriptor-Only Synchronization .............224.5. Special Case: Fast New-Only Synchronization ...............234.6. Special Case: Blind FETCH .................................235. Implementation Considerations ..................................245.1. Error Recovery during Playback ............................265.2. Quality of Implementation Issues ..........................285.3. Optimizations .............................................286. IMAP Extensions That May Help ..................................306.1. CONDSTORE Extension .......................................307. Security Considerations ........................................338. References .....................................................338.1. Normative References ......................................338.2. Informative References ....................................349. Acknowledgements ...............................................34Melnikov                     Informational                      [Page 2]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 20061.  Introduction   Several recommendations presented in this document are generally   applicable to all types of IMAP clients.  However, this document   tries to concentrate on disconnected mail clients [IMAP-MODEL].  It   also suggests some IMAP extensions* that should be implemented by   IMAP servers in order to make the life of disconnected clients   easier.  In particular, the [UIDPLUS] extension was specifically   designed to streamline certain disconnected operations, like   expunging, uploading, and copying messages (see Sections4.2.1,   4.2.2.1, and 4.2.4).   Readers of this document are also strongly advised to readRFC 2683   [RFC2683].   * Note that the functionality provided by the base IMAP protocol     [IMAP4] is sufficient to perform basic synchronization.1.1.  Conventions Used in This Document   In examples, "C:" and "S:" indicate lines sent by the client and   server, respectively.  Long lines in examples are broken for   editorial clarity.   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this   document are to be interpreted as described inRFC 2119 [KEYWORDS].   Let's call an IMAP command idempotent if the result of executing the   command twice sequentially is the same as the result of executing the   command just once.2.  Design Principles   All mailbox state or content information stored on the disconnected   client should be viewed strictly as a cache of the state of the   server.  The "master" state remains on the server, just as it would   with an interactive IMAP4 client.  The one exception to this rule is   that information about the state of the disconnected client's cache   (the state includes flag changes while offline and during scheduled   message uploads) remains on the disconnected client: that is, the   IMAP4 server is not responsible for remembering the state of the   disconnected IMAP4 client.   We assume that a disconnected client is a client that, for whatever   reason, wants to minimize the length of time that it is "on the   phone" to the IMAP4 server.  Often this will be because the client is   using a dialup connection, possibly with very low bandwidth, butMelnikov                     Informational                      [Page 3]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006   sometimes it might just be that the human is in a hurry to catch an   airplane, or some other event beyond our control.  Whatever the   reason, we assume that we must make efficient use of the network   connection, both in the usual sense (not generating spurious traffic)   and in the sense that we would prefer not to have the connection   sitting idle while the client and/or the server is performing   strictly local computation or I/O.  Another, perhaps simpler way of   stating this is that we assume that network connections are   "expensive".   Practical experience with disconnected mail systems has shown that   there is no single synchronization strategy that is appropriate for   all cases.  Different humans have different preferences, and the same   human's preference will vary depending both on external circumstance   (how much of a hurry the human is in today) and on the value that the   human places on the messages being transferred.  The point here is   that there is no way that the synchronization program can guess   exactly what the human wants to do, so the human will have to provide   some guidance.   Taken together, the preceding two principles lead to the conclusion   that the synchronization program must make its decisions based on   some kind of guidance provided by the human, by selecting the   appropriate options in the user interface or through some sort of   configuration file.  Almost certainly, it should not pause for I/O   with the human in the middle of the synchronization process.  The   human will almost certainly have several different configurations for   the synchronization program, for different circumstances.   Since a disconnected client has no way of knowing what changes might   have occurred to the mailbox while it was disconnected, message   numbers are not useful to a disconnected client.  All disconnected   client operations should be performed using UIDs, so that the client   can be sure that it and the server are talking about the same   messages during the synchronization process.3.  Overall Picture of Synchronization   The basic strategy for synchronization is outlined below.  Note that   the real strategy may vary from one application to another or may   depend on a synchronization mode.   a) Process any "actions" that were pending on the client that were      not associated with any mailbox.  (In particular sending messages      composed offline with SMTP.  This is not part of IMAP      synchronization, but it is mentioned here for completeness.)Melnikov                     Informational                      [Page 4]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006   b) Fetch the current list of "interesting" mailboxes.  (The      disconnected client should allow the user to skip this step      completely.)   c) "Client-to-server synchronization": for each IMAP "action" that      was pending on the client, do the following:      1) If the action implies opening a new mailbox (any operation that         operates on messages), open the mailbox.  Check its UID         validity value (seeSection 4.1 for more details) returned in         the UIDVALIDITY response code.  If the UIDVALIDITY value         returned by the server differs, the client MUST empty the local         cache of the mailbox and remove any pending "actions" that         refer to UIDs in that mailbox (and consider them failed).  Note         that this doesn't affect actions performed on client-generated         fake UIDs (seeSection 5).      2) Perform the action.  If the action is to delete a mailbox         (DELETE), make sure that the mailbox is closed first (see alsoSection 3.4.12 of [RFC2683]).   d) "Server-to-client synchronization": for each mailbox that requires      synchronization, do the following:      1) Check the mailbox UIDVALIDITY (seeSection 4.1 for more         details) with SELECT/EXAMINE/STATUS.         If UIDVALIDITY value returned by the server differs, the client         MUST         * empty the local cache of that mailbox;         * remove any pending "actions" that refer to UIDs in that           mailbox and consider them failed; and         * skip step 2-II.      2) Fetch the current "descriptors";         I)  Discover new messages.         II) Discover changes to old messages.      3) Fetch the bodies of any "interesting" messages that the client         doesn't already have.   e) Close all open mailboxes not required for further operations (if      staying online) or disconnect all open connections (if going      offline).Melnikov                     Informational                      [Page 5]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006   Terms used:   "Actions" are queued requests that were made by the human to the   client's Mail User Agent (MUA) software while the client was   disconnected.   We define "descriptors" as a set of IMAP4 FETCH data items.   Conceptually, a message's descriptor is that set of information that   allows the synchronization program to decide what protocol actions   are necessary to bring the local cache to the desired state for this   message; since this decision is really up to the human, this   information probably includes at least a few header fields intended   for human consumption.  Exactly what will constitute a descriptor   depends on the client implementation.  At a minimum, the descriptor   contains the message's UID and FLAGS.  Other likely candidates are   theRFC822.SIZE,RFC822.HEADER, BODYSTRUCTURE, or ENVELOPE data   items.   Comments:   1) The list of actions should be ordered.  For example, if the human      deletes message A1 in mailbox A, then expunges mailbox A, and then      deletes message A2 in mailbox A, the human will expect that      message A1 is gone and that message A2 is still present but is now      deleted.      By processing all the actions before proceeding with      synchronization, we avoid having to compensate for the local MUA's      changes to the server's state.  That is, once we have processed      all the pending actions, the steps that the client must take to      synchronize itself will be the same no matter where the changes to      the server's state originated.   2) Steps a and b can be performed in parallel.  Alternatively, step a      can be performed after d.   3) On step b, the set of "interesting" mailboxes pretty much has to      be determined by the human.  What mailboxes belong to this set may      vary between different IMAP4 sessions with the same server,      client, and human.  An interesting mailbox can be a mailbox      returned by LSUB command (see Section 6.3.9 of [IMAP4]).  The      special mailbox "INBOX" SHOULD be in the default set of mailboxes      that the client considers interesting.  However, providing the      ability to ignore INBOX for a particular session or client may be      valuable for some mail filtering strategies.Melnikov                     Informational                      [Page 6]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006   4) On step d-2-II, the client also finds out about changes to the      flags of messages that the client already has in its local cache,      and about messages in the local cache that no longer exist on the      server (i.e., messages that have been expunged).   5) "Interesting" messages are those messages that the synchronization      program thinks the human wants to have cached locally, based on      the configuration and the data retrieved in step b.   6) A disconnected IMAP client is a special case of an IMAP client, so      it MUST be able to handle any "unexpected" unsolicited responses,      like EXISTS and EXPUNGE, at any time.  The disconnected client MAY      ignore EXPUNGE response during "client-to-server" synchronization      phase (step c).   The rest of this discussion will focus primarily on the   synchronization issues for a single mailbox.4.  Mailbox Synchronization Steps and Strategies4.1.  Checking UID Validity   The "UID validity" of a mailbox is a number returned in an   UIDVALIDITY response code in an OK untagged response at mailbox   selection time.  The UID validity value changes between sessions when   UIDs fail to persist between sessions.   Whenever the client selects a mailbox, the client must compare the   returned UID validity value with the value stored in the local cache.   If the UID validity values differ, the UIDs in the client's cache are   no longer valid.  The client MUST then empty the local cache of that   mailbox and remove any pending "actions" that refer to UIDs in that   mailbox.  The client MAY also issue a warning to the human.  The   client MUST NOT cancel any scheduled uploads (i.e., APPENDs) for the   mailbox.   Note that UIDVALIDITY is not only returned on a mailbox selection.   The COPYUID and APPENDUID response codes defined in the [UIDPLUS]   extension (see also 4.2.2) and the UIDVALIDITY STATUS response data   item also contain a UIDVALIDITY value for some other mailbox.  The   client SHOULD behave as described in the previous paragraph (but it   should act on the other mailbox's cache), no matter how it obtained   the UIDVALIDITY value.Melnikov                     Informational                      [Page 7]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 20064.2.  Synchronizing Local Changes with the Server4.2.1.  Uploading Messages to the Mailbox   Two of the most common examples of operations resulting in message   uploads are:   1) Saving a draft message   2) Copying a message between remote mailboxes on two different IMAP      servers or a local mailbox and a remote mailbox.   Message upload is performed with the APPEND command.  A message   scheduled to be uploaded has no UID associated with it, as all UIDs   are assigned by the server.  The APPEND command will effectively   associate a UID with the uploaded message that can be stored in the   local cache for future reference.  However, [IMAP4] doesn't describe   a simple mechanism to discover the message UID by just performing the   APPEND command.  In order to discover the UID, the client can do one   of the following:   1) Remove the uploaded message from cache.  Then, use the mechanism      described in 4.3 to fetch the information about the uploaded      message as if it had been uploaded by some other client.   2) Try to fetch header information as described in 4.2.2 in order to      find a message that corresponds to the uploaded message.  One      strategy for doing this is described in 4.2.2.   Case 1 describes a not particularly smart client.      C: A003 APPEND Drafts (\Seen $MDNSent) {310}      S: + Ready for literal data      C: Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)      C: From: Fred Foobar <foobar@blt.example.COM>      C: Subject: afternoon meeting      C: To: mooch@owatagu.siam.edu      C: Message-Id: <B27397-0100000@blt.example.COM>      C: MIME-Version: 1.0      C: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII      C:      C: Hello Joe, do you think we can meet at 3:30 tomorrow?      C:      S: A003 OK APPEND Completed   Fortunately, there is a simpler way to discover the message UID in   the presence of the [UIDPLUS] extension:Melnikov                     Informational                      [Page 8]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006      C: A003 APPEND Drafts (\Seen $MDNSent) {310}      S: + Ready for literal data      C: Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)      C: From: Fred Foobar <foobar@blt.example.COM>      C: Subject: afternoon meeting      C: To: mooch@owatagu.siam.edu      C: Message-Id: <B27397-0100000@blt.example.COM>      C: MIME-Version: 1.0      C: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII      C:      C: Hello Joe, do you think we can meet at 3:30 tomorrow?      C:      S: A003 OK [APPENDUID 1022843275 77712] APPEND completed   The UID of the appended message is the second parameter of APPENDUID   response code.4.2.2.  Optimizing "move" and "copy" Operations   Practical experience with IMAP and other mailbox access protocols   that support multiple mailboxes suggests that moving a message from   one mailbox to another is an extremely common operation.4.2.2.1.  Moving a Message between Two Mailboxes on the Same Server   In IMAP4, a "move" operation between two mailboxes on the same server   is really a combination of a COPY operation and a STORE +FLAGS   (\Deleted) operation.  This makes good protocol sense for IMAP, but   it leaves a simple-minded disconnected client in the silly position   of deleting and possibly expunging its cached copy of a message, then   fetching an identical copy via the network.   However, the presence of the UIDPLUS extension in the server can   help:      C: A001 UID COPY 567,414 "Interesting Messages"      S: A001 OK [COPYUID 1022843275 414,567 5:6] Completed   This tells the client that the message with UID 414 in the current   mailbox was successfully copied to the mailbox "Interesting Messages"   and was given the UID 5, and that the message with UID 567 was given   the UID 6.   In the absence of UIDPLUS extension support in the server, the   following trick can be used.  By including the Message-ID: header and   the INTERNALDATE data item as part of the descriptor, the client can   check the descriptor of a "new" message against messages that are   already in its cache and avoid fetching the extra copy.  Of course,Melnikov                     Informational                      [Page 9]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006   it's possible that the cost of checking to see if the message is   already in the local cache may exceed the cost of just fetching it,   so this technique should not be used blindly.  If the MUA implements   a "move" command, it makes special provisions to use this technique   when it knows that a copy/delete sequence is the result of a "move"   command.   Note that servers are not required (although they are strongly   encouraged with "SHOULD language") to preserve INTERNALDATE when   copying messages.   Also note that since it's theoretically possible for this algorithm   to find the wrong message (given sufficiently malignant Message-ID   headers), implementers should provide a way to disable this   optimization, both permanently and on a message-by-message basis.   Example 1: Copying a message in the absence of UIDPLUS extension.   At some point in time the client has fetched the source message and   some information was cached:      C: C021 UID FETCH <uids> (BODY.PEEK[] INTERNALDATE FLAGS)      ...      S: * 27 FETCH (UID 123 INTERNALDATE "31-May-2002 05:26:59 -0600"          FLAGS (\Draft $MDNSent) BODY[] {1036}      S: ...      S: Message-Id: <20040903110856.22a127cd@chardonnay>      S: ...      S: ...message body...      S: )      ...      S: C021 OK fetch completed   Later on, the client decides to copy the message:      C: C035 UID COPY 123 "Interesting Messages"      S: C035 OK Completed   As the server hasn't provided the COPYUID response code, the client   tries the optimization described above:      C: C036 SELECT "Interesting Messages"      ...      C: C037 UID SEARCH ON 31-May-2002 HEADER          "Message-Id" "20040903110856.22a127cd@chardonnay"      S: SEARCH 12368      S: C037 OK completedMelnikov                     Informational                     [Page 10]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006   Note that if the server has returned multiple UIDs in the SEARCH   response, the client MUST NOT use any of the returned UID.4.2.2.2.  Moving a Message from a Remote Mailbox to a Local   Moving a message from a remote mailbox to a local is done with FETCH   (that includes FLAGS and INTERNALDATE) followed by UID STORE <uid>   +FLAGS.SILENT (\Deleted):      C: A003 UID FETCH 123 (BODY.PEEK[] INTERNALDATE FLAGS)      S: * 27 FETCH (UID 123 INTERNALDATE "31-May-2002 05:26:59 -0600"          FLAGS (\Seen $MDNSent) BODY[]      S: ...message body...      S: )      S: A003 OK UID FETCH completed      C: A004 UID STORE <uid> +FLAGS.SILENT (\Deleted)      S: A004 STORE completed   Note that there is no reason to fetch the message during   synchronization if it's already in the client's cache.  Also, the   client SHOULD preserve delivery date in the local cache.4.2.2.3.  Moving a Message from a Local Mailbox to a Remote   Moving a message from a local mailbox to a remote is done with   APPEND:   C: A003 APPEND Drafts (\Seen $MDNSent) "31-May-2002 05:26:59 -0600"       {310}   S: + Ready for literal data   C: Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)   C: From: Fred Foobar <foobar@blt.example.COM>   C: Subject: afternoon meeting   C: To: mooch@owatagu.siam.edu   C: Message-Id: <B27397-0100000@blt.example.COM>   C: MIME-Version: 1.0   C: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII   C:   C: Hello Joe, do you think we can meet at 3:30 tomorrow?   C:   S: A003 OK [APPENDUID 1022843275 77712] completed   The client SHOULD specify the delivery date from the local cache in   the APPEND.   If the [LITERAL+] extension is available, the client can save a   round-trip*:Melnikov                     Informational                     [Page 11]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006   C: A003 APPEND Drafts (\Seen $MDNSent) "31-May-2002 05:26:59 -0600"       {310+}   C: Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)   C: From: Fred Foobar <foobar@blt.example.COM>   C: Subject: afternoon meeting   C: To: mooch@owatagu.siam.edu   C: Message-Id: <B27397-0100000@blt.example.COM>   C: MIME-Version: 1.0   C: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII   C:   C: Hello Joe, do you think we can meet at 3:30 tomorrow?   C:   S: A003 OK [APPENDUID 1022843275 77712] completed   * Note that there is a risk that the server will reject the message     due to its size.  If this happens, the client will waste bandwidth     transferring the whole message.  If the client wouldn't have used     the LITERAL+, this could have been avoided:   C: A003 APPEND Drafts (\Seen $MDNSent) "31-May-2004 05:26:59 -0600"       {16777215}   S: A003 NO Sorry, message is too big4.2.2.4.  Moving a Message between Two Mailboxes on Different Servers   Moving a message between two mailbox on two different servers is a   combination of the operations described in 4.2.2.2 followed by the   operations described in 4.2.2.3.4.2.2.5.  Uploading Multiple Messages to a Remote Mailbox with          MULTIAPPEND   When there is a need to upload multiple messages to a remote mailbox   (e.g., as per 4.2.2.3), the presence of certain IMAP extensions may   significantly improve performance.  One of them is [MULTIAPPEND].   For some mail stores, opening a mailbox for appending might be   expensive.  [MULTIAPPEND] tells the server to open the mailbox once   (instead of opening and closing it "n" times per "n" messages to be   uploaded) and to keep it open while a group of messages is being   uploaded to the server.   Also, if the server supports both [MULTIAPPEND] and [LITERAL+]   extensions, the entire upload is accomplished in a single   command/response round-trip.Melnikov                     Informational                     [Page 12]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006   Note: Client implementers should be aware that [MULTIAPPEND] performs   append of multiple messages atomically.  This means, for example, if   there is not enough space to save "n"-th message (or the message has   invalid structure and is rejected by the server) after successful   upload of "n-1" messages, the whole upload operation fails, and no   message will be saved in the mailbox.  Although this behavior might   be desirable in certain situations, it might not be what you want.   Otherwise, the client should use the regular APPEND command (Section4.2.2.3), possibly utilizing the [LITERAL+] extension.  See alsoSection 5.1 for discussions about error recovery.   Note: MULTIAPPEND can be used together with the UIDPLUS extension in   a way similar to what was described inSection 4.2.1.  [MULTIAPPEND]   extends the syntax of the APPENDUID response code to allow for   multiple message UIDs in the second parameter.   Example 2:   This example demonstrates the use of MULTIAPPEND together with   UIDPLUS (synchronization points where the client waits for   confirmations from the server are marked with "<--->"):   C: A003 APPEND Jan-2002 (\Seen $MDNSent) "31-May-2002 05:26:59 -0600"       {310}   <--->   S: + Ready for literal data   C: Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)   C: From: Fred Foobar <foobar@blt.example.COM>   C: Subject: afternoon meeting   C: To: mooch@owatagu.siam.edu   C: Message-Id: <B27397-0100000@blt.example.COM>   C: MIME-Version: 1.0   C: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII   C:   C: Hello Joe, do you think we can meet at 3:30 tomorrow?   C:  (\Seen) " 1-Jun-2002 22:43:04 -0800" {286}   <--->   S: + Ready for literal data   C: Date: Mon, 7 Feb 1994 22:43:04 -0800 (PST)   C: From: Joe Mooch <mooch@OWaTaGu.siam.EDU>   C: Subject: Re: afternoon meeting   C: To: foobar@blt.example.com   C: Message-Id: <a0434793874930@OWaTaGu.siam.EDU>   C: MIME-Version: 1.0   C: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII   C:   C: 3:30 is fine with me.   C:Melnikov                     Informational                     [Page 13]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006   S: A003 OK [APPENDUID 1022843275 77712,77713] completed   The upload takes 3 round-trips.   Example 3:   In this example, Example 2 was modified for the case when the server   supports MULTIAPPEND, LITERAL+, and UIDPLUS.  The upload takes only 1   round-trip.   C: A003 APPEND Jan-2002 (\Seen $MDNSent) "31-May-2002 05:26:59 -0600"       {310+}   C: Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)   C: From: Fred Foobar <foobar@blt.example.COM>   C: Subject: afternoon meeting   C: To: mooch@owatagu.siam.edu   C: Message-Id: <B27397-0100000@blt.example.COM>   C: MIME-Version: 1.0   C: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII   C:   C: Hello Joe, do you think we can meet at 3:30 tomorrow?   C:  (\Seen) " 1-Jun-2002 22:43:04 -0800" {286+}   C: Date: Mon, 7 Feb 1994 22:43:04 -0800 (PST)   C: From: Joe Mooch <mooch@OWaTaGu.siam.EDU>   C: Subject: Re: afternoon meeting   C: To: foobar@blt.example.com   C: Message-Id: <a0434793874930@OWaTaGu.siam.EDU>   C: MIME-Version: 1.0   C: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII   C:   C: 3:30 is fine with me.   C:   S: A003 OK [APPENDUID 1022843275 77712,77713] completed4.2.3.  Replaying Local Flag Changes   The disconnected client uses the STORE command to synchronize local   flag state with the server.  The disconnected client SHOULD use   +FLAGS.SILENT or -FLAGS.SILENT in order to set or unset flags   modified by the user while offline.  The FLAGS form MUST NOT be used,   as there is a risk that this will overwrite flags on the server that   have been changed by some other client.   Example 4:   For the message with UID 15, the disconnected client stores the   following flags \Seen and $Highest.  The flags were modified on the   server by some other client: \Seen, \Answered, and $Highest.  WhileMelnikov                     Informational                     [Page 14]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006   offline, the user requested that the $Highest flags be removed and   that the \Deleted flag be added.  The flag synchronization sequence   for the message should look like:      C: A001 UID STORE 15 +FLAGS.SILENT (\Deleted)      S: A001 STORE completed      C: A002 UID STORE 15 -FLAGS.SILENT ($Highest)      S: A002 STORE completed   If the disconnected client is able to store an additional binary   state information (or a piece of information that can take a value   from a predefined set of values) in the local cache of an IMAP   mailbox or in a local mailbox (e.g., message priority), and if the   server supports storing of arbitrary keywords, the client MUST use   keywords to store this state on the server.   Example 5:   Imagine a speculative mail client that can mark a message as one of   work-related ($Work), personal ($Personal), or spam ($Spam).  In   order to mark a message as personal, the client issues:      C: A001 UID STORE 15 +FLAGS.SILENT ($Personal)      S: A001 STORE completed      C: A002 UID STORE 15 -FLAGS.SILENT ($Work $Spam)      S: A002 STORE completed   In order to mark the message as not work, not personal and not spam,   the client issues:      C: A003 UID STORE 15 -FLAGS.SILENT ($Personal $Work $Spam)      S: A003 STORE completed4.2.4.  Processing Mailbox Compression (EXPUNGE) Requests   A naive disconnected client implementation that supports compressing   a mailbox while offline may decide to issue an EXPUNGE command to the   server in order to expunge messages marked \Deleted.  The problem   with this command during synchronization is that it permanently   erases all messages with the \Deleted flag set, i.e., even those   messages that were marked as \Deleted on the server while the user   was offline.  Doing this might result in an unpleasant surprise for   the user.   Fortunately the [UIDPLUS] extension can help in this case as well.   The extension introduces UID EXPUNGE command, that, unlike EXPUNGE,   takes a UID set parameter, that lists UIDs of all messages that can   be expunged.  When processing this command the server erases onlyMelnikov                     Informational                     [Page 15]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006   messages with \Deleted flag listed in the UID list.  Thus, messages   not listed in the UID set will not be expunged even if they have the   \Deleted flag set.   Example 6:   While the user was offline, 3 messages with UIDs 7, 27, and 65 were   marked \Deleted when the user requested to compress the open mailbox.   Another client marked a message \Deleted on the server (UID 34).   During synchronization, the disconnected client issues:      C: A001 UID EXPUNGE 7,27,65      S: * ... EXPUNGE      S: * ... EXPUNGE      S: * ... EXPUNGE      S: A001 UID EXPUNGE completed   If another client issues UID SEARCH DELETED command (to find all   messages with the \Deleted flag) before and after the UID EXPUNGE, it   will get:   Before:      C: B001 UID SEARCH DELETED      S: * SEARCH 65 34 27 7      S: B001 UID SEARCH completed   After:      C: B002 UID SEARCH DELETED      S: * SEARCH 34      S: B002 UID SEARCH completed   In the absence of the [UIDPLUS] extension, the following sequence of   commands can be used as an approximation.  Note: It's possible for   another client to mark additional messages as deleted while this   sequence is being performed.  In this case, these additional messages   will be expunged as well.   1) Find all messages marked \Deleted on the server.      C: A001 UID SEARCH DELETED      S: * SEARCH 65 34 27 7      S: A001 UID SEARCH completed   2) Find all messages that must not be erased (for the previous      example the list will consist of the message with UID 34).Melnikov                     Informational                     [Page 16]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006   3) Temporarily remove \Deleted flag on all messages found in step 2.      C: A002 UID STORE 34 -FLAGS.SILENT (\Deleted)      S: A002 UID STORE completed   4) Expunge the mailbox.      C: A003 EXPUNGE      S: * 20 EXPUNGE      S: * 7 EXPUNGE      S: * 1 EXPUNGE      S: A003 EXPUNGE completed      Here, the message with UID 7 has message number 1, with UID 27 has      message number 7, and with UID 65 has message number 20.   5) Restore \Deleted flag on all messages found when performing step      2.      C: A004 UID STORE 34 +FLAGS.SILENT (\Deleted)      S: A004 UID STORE completed4.2.5.  Closing a Mailbox   When the disconnected client has to close a mailbox, it should not   use the CLOSE command, because CLOSE does a silent EXPUNGE.  (Section4.2.4 explains why EXPUNGE should not be used by a disconnected   client.)  It is safe to use CLOSE only if the mailbox was opened with   EXAMINE.   If the mailbox was opened with SELECT, the client can use one of the   following commands to implicitly close the mailbox and prevent the   silent expunge:   1) UNSELECT - This is a command described in [UNSELECT] that works as      CLOSE, but doesn't cause the silent EXPUNGE.  This command is      supported by the server if it reports UNSELECT in its CAPABILITY      list.   2) SELECT <another_mailbox> - SELECT causes implicit CLOSE without      EXPUNGE.   3) If the client intends to issue LOGOUT after closing the mailbox,      it may just issue LOGOUT, because LOGOUT causes implicit CLOSE      without EXPUNGE as well.   4) SELECT <non_existing_mailbox> - If the client knows a mailbox that      doesn't exist or can't be selected, it MAY SELECT it.Melnikov                     Informational                     [Page 17]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006   If the client opened the mailbox with SELECT and just wants to avoid   implicit EXPUNGE without closing the mailbox, it may also use the   following:   5) EXAMINE <mailbox> - Reselect the same mailbox in read-only mode.4.3.  Details of "Normal" Synchronization of a Single Mailbox   The most common form of synchronization is where the human trusts the   integrity of the client's copy of the state of a particular mailbox   and simply wants to bring the client's cache up to date so that it   accurately reflects the mailbox's current state on the server.4.3.1.  Discovering New Messages and Changes to Old Messages   Let <lastseenuid> represent the highest UID that the client knows   about in this mailbox.  Since UIDs are allocated in strictly   ascending order, this is simply the UID of the last message in the   mailbox that the client knows about.  Let <lastseenuid+1> represent   <lastseenuid>'s UID plus one.  Let <descriptors> represent a list   consisting of all the FETCH data item items that the implementation   considers part of the descriptor; at a minimum this is just the FLAGS   data item, but it usually also includes BODYSTRUCTURE andRFC822.SIZE.  At this step, <descriptors> SHOULD NOT includeRFC822.   With no further information, the client can issue the following two   commands:      tag1 UID FETCH <lastseenuid+1>:* <descriptors>      tag2 UID FETCH 1:<lastseenuid> FLAGS   The first command will request some information about "new" messages   (i.e., messages received by the server since the last   synchronization).  It will also allow the client to build a message   number to UID map (only for new messages).  The second command allows   the client to      1) update cached flags for old messages;      2) find out which old messages got expunged; and      3) build a mapping between message numbers and UIDs (for old         messages).   The order here is significant.  We want the server to start returning   the list of new message descriptors as fast as it can, so that the   client can start issuing more FETCH commands, so we start out by   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 INTERNALDATERFC822.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 alsoSection 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 INTERNALDATERFC822.SIZE)      ...      C: A012 UID fetch <lastseenuid+101>:<lastseenuid+200>          (FLAGS BODYSTRUCTURE INTERNALDATERFC822.SIZE)      ...      ...      C: A0FF UID fetch <lastseenuid+901>:<uidnext>          (FLAGS BODYSTRUCTURE INTERNALDATERFC822.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 inSection 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 Sections4.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>:* (FLAGSRFC822.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      generated on the client.Melnikov                     Informational                     [Page 24]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006      1) APPEND Drafts (\Seen $MDNSent \Drafts) {<nnn>}         ...first version of the message follows...      2) APPEND Drafts (\Seen $MDNSent \Drafts) {<mmm>}         ...final version of the message follows...      3) STORE <old_uid> +FLAGS (\Deleted)      Step 1 corresponds to the first attempt to save the draft message,      step 2 corresponds to the second attempt to save the draft      message, and step 3 deletes the first version of the draft message      saved in step 1.      A naive disconnected client may send the command in step 3 without      replacing the fake client generated <old_uid> with the value      returned by the server in step 1.  A server will probably reject      this command, which will make the client believe that the      synchronization sequence has failed.   2)Section 5.1 discusses common implementation errors related to      error recovery during playback.   3) Don't assume that the disconnected client is the only client used      by the user.      Situation 2: Some clients may use the \Deleted flag as an      indicator that the message should not appear in the user's view.      Usage of the \Deleted flag for this purpose is not safe, as other      clients (e.g., online clients) might EXPUNGE the mailbox at any      time.   4) Beware of data dependencies between synchronization operations.      It might be very tempting for a client writer to perform some      optimizations on the playback log.  Such optimizations might      include removing redundant operations (for example, see      optimization 2 inSection 5.3), or their reordering.      It is not always safe to reorder or remove redundant operations      during synchronization because some operations may have      dependencies (as Situation 3 demonstrates).  So, if in doubt,      don't do this.      Situation 3: The user copies a message out of a mailbox and then      deletes the mailbox.Melnikov                     Informational                     [Page 25]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006         C: A001 SELECT Old-Mail         S: ...         C: A002 UID COPY 111 ToDo         S: A002 OK [COPYUID 1022843345 111 94] Copy completed         ...         C: A015 CLOSE         S: A015 OK Completed         C: A016 DELETE Old-Mail         S: A016 OK Mailbox deletion completed successfully      If the client performs DELETE (tag A016) first and COPY (tag A002)      second, then the COPY fails.  Also, the message that the user so      carefully copied into another mailbox has been lost.5.1.  Error Recovery during Playback   Error recovery during synchronization is one of the trickiest parts   to get right.  Below, we will discuss certain error conditions and   suggest possible choices for handling them.   1) Lost connection to the server.      The client MUST remember the current position in the playback      (replay) log and replay it starting from the interrupted operation      (the last command issued by the client, but not acknowledged by      the server) the next time it successfully connects to the same      server.  If the connection was lost while executing a non-      idempotent IMAP command (see the definition inSection 1), then      when the client is reconnected, it MUST make sure that the      interrupted command was indeed not executed.  If it wasn't      executed, the client must restart playback from the interrupted      command, otherwise from the following command.      Upon reconnect, care must be taken in order to properly reapply      logical operations that are represented by multiple IMAP commands,      e.g., UID EXPUNGE emulation when UID EXPUNGE is not supported by      the server (seeSection 4.2.4).      Once the client detects that the connection to the server was      lost, it MUST stop replaying its log.  There are existing      disconnected clients that, to the great annoyance of users, pop up      an error dialog for each and every playback operation that fails.   2) Copying/appending messages to a mailbox that doesn't exist.  (The      server advertises this condition by sending the TRYCREATE response      code in the tagged NO response to the APPEND or COPY command.)Melnikov                     Informational                     [Page 26]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006      The user should be advised about the situation and be given one of      the following choices:      a) Try to recreate a mailbox.      b) Copy/upload messages to another mailbox.      c) Skip copy/upload.      d) Abort replay.   3) Copying messages from a mailbox that doesn't exist, or renaming or      getting/changing ACLs [ACL] on a mailbox that doesn't exist:      a) Skip operation.      b) Abort replay.   4) Deleting mailboxes or deleting/expunging messages that no longer      exist.      This is actually is not an error and should be ignored by the      client.   5) Performing operations on messages that no longer exist.      a) Skip operation.      b) Abort replay.      In the case of changing flags on an expunged message, the client      should silently ignore the error.   Note 1: Several synchronization operations map to multiple IMAP   commands (for example, "move" described in 4.2.2).  The client must   guarantee atomicity of each such multistep operation.  For example,   when performing a "move" between two mailboxes on the same server, if   the server is unable to copy messages, the client MUST NOT attempt to   set the \Deleted flag on the messages being copied, let alone expunge   them.  However, the client MAY consider that move operation to have   succeeded even if the server was unable to set the \Deleted flag on   copied messages.   Note 2: Many synchronization operations have data dependencies.  A   failed operation must cause all dependent operations to fail as well.   The client should check this and MUST NOT try to perform all   dependent operations blindly (unless the user corrected the original   problem).  For example, a message may be scheduled to be appended to   a mailbox on the server and later on the appended message may be   copied to another mailbox.  If the APPEND operation fails, the client   must not attempt to COPY the failed message later on.  (See alsoSection 5, Situation 3).Melnikov                     Informational                     [Page 27]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 20065.2.  Quality of Implementation Issues   Below, some quality of implementation issues are listed for   disconnected clients.  They will help to write a disconnected client   that works correctly, performs synchronization as quickly as possible   (and thus can make the user happier as well as save her some money),   and minimizes the server load:   1) Don't lose information.      No matter how smart your client is in other areas, if it loses      information, users will get very upset.   2) Don't do work unless explicitly asked.  Be flexible.  Ask all      questions BEFORE starting synchronization, if possible.   3) Minimize traffic.      The client MUST NOT issue a command if the client already received      the required information from the server.      The client MUST make use of UIDPLUS extension if it is supported      by the server.      See also optimization 1 inSection 5.3.   4) Minimize the number of round-trips.      Round-trips kill performance, especially on links with high      latency.  Sections4.2.2.5 and5.2 give some advice on how to      minimize the number of round-trips.      See also optimization 1 inSection 5.3.5.3.  Optimizations   Some useful optimizations are described in this section.  A   disconnected client that supports the recommendations listed below   will give the user a more pleasant experience.   1) The initial OK or PREAUTH responses may contain the CAPABILITY      response code as described in Section 7.1 of [IMAP4].  This      response code gives the same information as returned by the      CAPABILITY command*.  A disconnected client that pays attention to      this response code can avoid sending CAPABILITY command and will      save a round-trip.Melnikov                     Informational                     [Page 28]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006      * Note: Some servers report in the CAPABILITY response code        extensions that are only relevant in unauthenticated state or in        all states.  Such servers usually send another CAPABILITY        response code upon successful authentication using LOGIN or        AUTHENTICATE command (that negotiates no security layer; see        Section 6.2.2 of [IMAP4]).  The CAPABILITY response code sent        upon successful LOGIN/AUTHENTICATE might be different from the        CAPABILITY response code in the initial OK response, as        extensions only relevant for unauthenticated state will not be        advertised, and some additional extensions available only in        authenticated and/or selected state will be.   Example 9:   S: * OK [CAPABILITY IMAP4REV1 LOGIN-REFERRALS STARTTLS       AUTH=DIGEST-MD5 AUTH=SRP] imap.example.com ready   C: 2 authenticate DIGEST-MD5   S: 2 OK [CAPABILITY IMAP4REV1 IDLE NAMESPACE MAILBOX-REFERRALS SCAN       SORT THREAD=REFERENCES THREAD=ORDEREDSUBJECT MULTIAPPEND]       User authenticated (no layer)   2) An advanced disconnected client may choose to optimize its replay      log.  For example, there might be some operations that are      redundant (the list is not complete):      a) an EXPUNGE followed by another EXPUNGE or CLOSE;      b) changing flags (other than the \Deleted flag) on a message that         gets immediately expunged;      c) opening and closing the same mailbox.   When optimizing, be careful about data dependencies between commands.   For example, if the client is wishing to optimize (see case b, above)      tag1 UID STORE <uid1> +FLAGS (\Deleted)      ...      tag2 UID STORE <uid1> +FLAGS (\Flagged)      ...      tag3 UID COPY <uid1> "Backup"      ...      tag4 UID EXPUNGE <uid1>   it can't remove the second UID STORE command because the message is   being copied before it gets expunged.   In general, it might be a good idea to keep mailboxes open during   synchronization (see case c above), if possible.  This can be more   easily achieved in conjunction with optimization 3 described below.Melnikov                     Informational                     [Page 29]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006   3) Perform some synchronization steps in parallel, if possible.      Several synchronization steps don't depend on each other and thus      can be performed in parallel.  Because the server machine is      usually more powerful than the client machine and can perform some      operations in parallel, this may speed up the total time of      synchronization.      In order to achieve such parallelization, the client will have to      open more than one connection to the same server.  Client writers      should not forget about non-trivial cost associated with      establishing a TCP connection and performing an authentication.      The disconnected client MUST NOT use one connection per mailbox.      In most cases, it is sufficient to have two connections.  The      disconnected client SHOULD avoid selecting the same mailbox in      more than one connection; seeSection 3.1.1 of [RFC2683] for more      details.      Any mailbox synchronization MUST start with checking the      UIDVALIDITY as described inSection 4.1 of this document.  The      client MAY use STATUS command to check UID Validity of a non-      selected mailbox.  This is preferable to opening many connections      to the same server to perform synchronization of multiple      mailboxes simultaneously.  As described in Section 5.3.10 of      [IMAP4], this SHOULD NOT be used on the selected mailbox.6.  IMAP Extensions That May Help   The following extensions can save traffic and/or the number of   round-trips:   1) The use of [UIDPLUS] is discussed in Sections4.1,4.2.1,4.2.2.1      and 4.2.4.   2) The use of the MULTIAPPEND and LITERAL+ extensions for uploading      messages is discussed inSection 4.2.2.5.   3) Use the CONDSTORE extension (seeSection 6.1) for quick flag      resynchronization.6.1.  CONDSTORE Extension   An advanced disconnected mail client should use the [CONDSTORE]   extension when it is supported by the server.  The client must cache   the value from HIGHESTMODSEQ OK response code received on mailbox   opening and update it whenever the server sends MODSEQ FETCH data   items.Melnikov                     Informational                     [Page 30]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006   If the client receives NOMODSEQ OK untagged response instead of   HIGHESTMODSEQ, it MUST remove the last known HIGHESTMODSEQ value from   its cache and follow the more general instructions inSection 3.   When the client opens the mailbox for synchronization, it first   compares UIDVALIDITY as described in step d-1 inSection 3.  If the   cached UIDVALIDITY value matches the one returned by the server, the   client MUST compare the cached value of HIGHESTMODSEQ with the one   returned by the server.  If the cached HIGHESTMODSEQ value also   matches the one returned by the server, then the client MUST NOT   fetch flags for cached messages, as they hasn't changed.  If the   value on the server is higher than the cached one, the client MAY use   "SEARCH MODSEQ <cached-value>" to find all messages with flags   changed since the last time the client was online and had the mailbox   opened.  Alternatively, the client MAY use "FETCH 1:* (FLAGS)   (CHANGEDSINCE <cached-value>)".  The latter operation combines   searching for changed messages and fetching new information.   In all cases, the client still needs to fetch information about new   messages (if requested by the user) as well as discover which   messages have been expunged.   Step d ("Server-to-client synchronization") inSection 4 in the   presence of the CONDSTORE extension is amended as follows:   d) "Server-to-client synchronization" - For each mailbox that      requires synchronization, do the following:      1a) Check the mailbox UIDVALIDITY (seesection 4.1 for more          details) with SELECT/EXAMINE/STATUS.          If the UIDVALIDITY value returned by the server differs, the          client MUST          * empty the local cache of that mailbox;          * "forget" the cached HIGHESTMODSEQ value for the mailbox;          * remove any pending "actions" that refer to UIDs in that            mailbox (note that this doesn't affect actions performed on            client-generated fake UIDs; seeSection 5); and          * skip steps 1b and 2-II;      1b) Check the mailbox HIGHESTMODSEQ.  If the cached value is the          same as the one returned by the server, skip fetching message          flags on step 2-II, i.e., the client only has to find out          which messages got expunged.Melnikov                     Informational                     [Page 31]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006      2) Fetch the current "descriptors".         I)  Discover new messages.         II) Discover changes to old messages and flags for new messages             using             "FETCH 1:* (FLAGS) (CHANGEDSINCE <cached-value>)" or             "SEARCH MODSEQ <cached-value>".             Discover expunged messages; for example, using             "UID SEARCH 1:<lastseenuid>".  (All messages not returned             in this command are expunged.)      3) Fetch the bodies of any "interesting" messages that the client         doesn't already have.         Example 10:         The UIDVALIDITY value is the same, but the HIGHESTMODSEQ value         has changed on the server while the client was offline.      C: A142 SELECT INBOX      S: * 172 EXISTS      S: * 1 RECENT      S: * OK [UNSEEN 12] Message 12 is first unseen      S: * OK [UIDVALIDITY 3857529045] UIDs valid      S: * OK [UIDNEXT 201] Predicted next UID      S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)      S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited      S: * OK [HIGHESTMODSEQ 20010715194045007]      S: A142 OK [READ-WRITE] SELECT completed   After that, either:      C: A143 UID FETCH 1:* (FLAGS) (CHANGEDSINCE 20010715194032001)      S: * 2 FETCH (UID 6 MODSEQ (20010715205008000) FLAGS (\Deleted))      S: * 5 FETCH (UID 9 MODSEQ (20010715195517000) FLAGS ($NoJunk          $AutoJunk $MDNSent))         ...      S: A143 OK FETCH completed   or:Melnikov                     Informational                     [Page 32]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006      C: A143 UID SEARCH MODSEQ 20010715194032001 UID 1:20      S: * SEARCH 6 9 11 12 18 19 20 23 (MODSEQ 20010917162500)      S: A143 OK Search complete      C: A144 UID SEARCH 1:20      S: * SEARCH 6 9 ...      S: A144 OK FETCH completed7.  Security Considerations   It is believed that this document does not raise any new security   concerns that are not already present in the base [IMAP4] protocol,   and these issues are discussed in [IMAP4].  Additional security   considerations may be found in different extensions mentioned in this   document; in particular, in [UIDPLUS], [LITERAL+], [CONDSTORE],   [MULTIAPPEND], and [UNSELECT].   Implementers are also reminded about the importance of thorough   testing.8.  References8.1.  Normative References   [KEYWORDS]    Bradner, S., "Key words for use in RFCs to Indicate                 Requirement Levels",BCP 14,RFC 2119, March 1997.   [IMAP4]       Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL -                 VERSION 4rev1",RFC 3501, March 2003.   [UIDPLUS]     Crispin, M., "Internet Message Access Protocol (IMAP) -                 UIDPLUS extension",RFC 4315, December 2005.   [LITERAL+]    Myers, J., "IMAP4 non-synchronizing literals",RFC2088, January 1997.   [CONDSTORE]   Melnikov, A. and S. Hole, "IMAP Extension for                 Conditional STORE Operation or Quick Flag Changes                 Resynchronization",RFC 4551, June 2006.   [MULTIAPPEND] Crispin, M., "Internet Message Access Protocol (IMAP) -                 MULTIAPPEND Extension",RFC 3502, March 2003.   [UNSELECT]    Melnikov, A., "Internet Message Access Protocol (IMAP)                 UNSELECT command",RFC 3691, February 2004.   [RFC2683]     Leiba, B., "IMAP4 Implementation Recommendations",RFC2683, September 1999.Melnikov                     Informational                     [Page 33]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 20068.2.  Informative References   [ACL]         Melnikov, A., "IMAP4 Access Control List (ACL)                 Extension",RFC 4314, December 2005.   [IMAP-MODEL]  Crispin, M., "Distributed Electronic Mail Models in                 IMAP4",RFC 1733, December 1994.9.  Acknowledgements   This document is based on version 01 of the text written by Rob   Austein in November 1994.   The editor appreciates comments posted by Mark Crispin to the IMAP   mailing list and the comments/corrections/ideas received from Grant   Baillie, Cyrus Daboo, John G. Myers, Chris Newman, and Timo Sirainen.   The editor would also like to thank the developers of Netscape   Messenger and Mozilla mail clients for providing examples of   disconnected mail clients that served as a base for many   recommendations in this document.Editor's Address   Alexey Melnikov   Isode Limited   5 Castle Business Village   36 Station Road   Hampton, Middlesex   TW12 2BX   United Kingdom   Phone: +44 77 53759732   EMail: alexey.melnikov@isode.comMelnikov                     Informational                     [Page 34]

RFC 4549        Synch Ops for Disconnected IMAP4 Clients       June 2006Full Copyright Statement   Copyright (C) The Internet Society (2006).   This document is subject to the rights, licenses and restrictions   contained inBCP 78, and except as set forth therein, the authors   retain all their rights.   This document and the information contained herein are provided on an   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.Intellectual Property   The IETF takes no position regarding the validity or scope of any   Intellectual Property Rights or other rights that might be claimed to   pertain to the implementation or use of the technology described in   this document or the extent to which any license under such rights   might or might not be available; nor does it represent that it has   made any independent effort to identify any such rights.  Information   on the procedures with respect to rights in RFC documents can be   found inBCP 78 andBCP 79.   Copies of IPR disclosures made to the IETF Secretariat and any   assurances of licenses to be made available, or the result of an   attempt made to obtain a general license or permission for the use of   such proprietary rights by implementers or users of this   specification can be obtained from the IETF on-line IPR repository athttp://www.ietf.org/ipr.   The IETF invites any interested party to bring to its attention any   copyrights, patents or patent applications, or other proprietary   rights that may cover technology that may be required to implement   this standard.  Please address the information to the IETF at   ietf-ipr@ietf.org.Acknowledgement   Funding for the RFC Editor function is provided by the IETF   Administrative Support Activity (IASA).Melnikov                     Informational                     [Page 35]

[8]ページ先頭

©2009-2025 Movatter.jp