1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963 |
- Network Working Group A. Melnikov, Ed.
- Request for Comments: 4549 Isode Ltd.
- Category: Informational June 2006
- Synchronization Operations for Disconnected IMAP4 Clients
- Status 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 2006
- Table of Contents
- 1. Introduction ....................................................3
- 1.1. Conventions Used in This Document ..........................3
- 2. Design Principles ...............................................3
- 3. Overall Picture of Synchronization ..............................4
- 4. Mailbox Synchronization Steps and Strategies ....................7
- 4.1. Checking UID Validity ......................................7
- 4.2. Synchronizing Local Changes with the Server ................8
- 4.2.1. Uploading Messages to the Mailbox ...................8
- 4.2.2. Optimizing "move" and "copy" Operations .............9
- 4.2.3. Replaying Local Flag Changes .......................14
- 4.2.4. Processing Mailbox Compression (EXPUNGE) Requests ..15
- 4.2.5. Closing a Mailbox ..................................17
- 4.3. Details of "Normal" Synchronization of a Single Mailbox ...18
- 4.3.1. Discovering New Messages and Changes to Old
- Messages ...........................................18
- 4.3.2. Searching for "Interesting" Messages. ..............20
- 4.3.3. Populating Cache with "Interesting" Messages. ......21
- 4.3.4. User-Initiated Synchronization .....................22
- 4.4. Special Case: Descriptor-Only Synchronization .............22
- 4.5. Special Case: Fast New-Only Synchronization ...............23
- 4.6. Special Case: Blind FETCH .................................23
- 5. Implementation Considerations ..................................24
- 5.1. Error Recovery during Playback ............................26
- 5.2. Quality of Implementation Issues ..........................28
- 5.3. Optimizations .............................................28
- 6. IMAP Extensions That May Help ..................................30
- 6.1. CONDSTORE Extension .......................................30
- 7. Security Considerations ........................................33
- 8. References .....................................................33
- 8.1. Normative References ......................................33
- 8.2. Informative References ....................................34
- 9. Acknowledgements ...............................................34
- Melnikov Informational [Page 2]
- RFC 4549 Synch Ops for Disconnected IMAP4 Clients June 2006
- 1. 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 Sections 4.2.1,
- 4.2.2.1, and 4.2.4).
- Readers of this document are also strongly advised to read RFC 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 in RFC 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, but
- Melnikov 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 (see Section 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 (see Section 5).
- 2) Perform the action. If the action is to delete a mailbox
- (DELETE), make sure that the mailbox is closed first (see also
- Section 3.4.12 of [RFC2683]).
- d) "Server-to-client synchronization": for each mailbox that requires
- synchronization, do the following:
- 1) Check the mailbox UIDVALIDITY (see Section 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
- the RFC822.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 Strategies
- 4.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 2006
- 4.2. Synchronizing Local Changes with the Server
- 4.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 completed
- Melnikov 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 big
- 4.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 (Section
- 4.2.2.3), possibly utilizing the [LITERAL+] extension. See also
- Section 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 in Section 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] completed
- 4.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. While
- Melnikov 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 completed
- 4.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 only
- Melnikov 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 completed
- 4.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. (Section
- 4.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 and
- RFC822.SIZE. At this step, <descriptors> SHOULD NOT include RFC822.
- 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 client
- Melnikov 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
- 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 in Section 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 in Section 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 (see Section 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 also
- Section 5, Situation 3).
- Melnikov Informational [Page 27]
- RFC 4549 Synch Ops for Disconnected IMAP4 Clients June 2006
- 5.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 in Section 5.3.
- 4) Minimize the number of round-trips.
- Round-trips kill performance, especially on links with high
- latency. Sections 4.2.2.5 and 5.2 give some advice on how to
- minimize the number of round-trips.
- See also optimization 1 in Section 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; see Section 3.1.1 of [RFC2683] for more
- details.
- Any mailbox synchronization MUST start with checking the
- UIDVALIDITY as described in Section 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 Sections 4.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 in Section 4.2.2.5.
- 3) Use the CONDSTORE extension (see Section 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 in Section 3.
- When the client opens the mailbox for synchronization, it first
- compares UIDVALIDITY as described in step d-1 in Section 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") in Section 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 (see section 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; see Section 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 completed
- 7. 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. References
- 8.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", RFC
- 2088, 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", RFC
- 2683, September 1999.
- Melnikov Informational [Page 33]
- RFC 4549 Synch Ops for Disconnected IMAP4 Clients June 2006
- 8.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.com
- Melnikov Informational [Page 34]
- RFC 4549 Synch Ops for Disconnected IMAP4 Clients June 2006
- Full Copyright Statement
- Copyright (C) The Internet Society (2006).
- This document is subject to the rights, licenses and restrictions
- contained in BCP 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 in BCP 78 and BCP 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 at
- http://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]
|