RFC 5267

Contexts for IMAP4

πŸ“… published July 2008, from ietf

RFC 5267: Contexts for IMAP4 πŸŽ€

Title block, bestie: this one is from the Network Working Group (Request for Comments 5267). The authors are D. Cridland and C. King, both at Isode Limited. It's on the Standards Track and dated July 2008. The title block doesn't list anything it obsoletes or updates. πŸ¦‹

Status of This Memo ✨

Okay so this doc is an Internet standards track protocol for the Internet community, and it's basically asking for discussion and suggestions for improvements πŸ’Œ. For the current standardization state and status, check the "Internet Official Protocol Standards" (STD 1) list. And distribution is unlimited, so share away 🌸.

Abstract πŸ’–

IMAP4rev1 already has strong search tools in its core protocol, but it can't easily create live, updated results you can actually work with 😭. This memo adds that extension and shows how you can use it to get something like virtual mailboxes 🧚.

Table of Contents πŸ“š

1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
2.  Conventions Used in This Document  . . . . . . . . . . . . . .  3
3.  Extended Sort Syntax . . . . . . . . . . . . . . . . . . . . .  3
    3.1.  ESORT Extension  . . . . . . . . . . . . . . . . . . . . .  4
    3.2.  Ranges in Extended Sort Results  . . . . . . . . . . . . .  4
    3.3.  Extended SORT Example  . . . . . . . . . . . . . . . . . .  4
4.  Contexts . . . . . . . . . . . . . . . . . . . . . . . . . . .  5
    4.1.  Overview . . . . . . . . . . . . . . . . . . . . . . . . .  5
    4.2.  Context Hint . . . . . . . . . . . . . . . . . . . . . . .  5
    4.3.  Notifications of Changes . . . . . . . . . . . . . . . . .  6
      4.3.1.  Refusing to Update Contexts  . . . . . . . . . . . . .  7
      4.3.2.  Common Features of ADDTO and REMOVEFROM  . . . . . . .  8
      4.3.3.  ADDTO Return Data Item . . . . . . . . . . . . . . . .  8
      4.3.4.  REMOVEFROM Return Data Item  . . . . . . . . . . . . .  9
      4.3.5.  The CANCELUPDATE Command . . . . . . . . . . . . . . . 10
    4.4.  Partial Results  . . . . . . . . . . . . . . . . . . . . . 10
    4.5.  Caching Results  . . . . . . . . . . . . . . . . . . . . . 11
5.  Formal Syntax  . . . . . . . . . . . . . . . . . . . . . . . . 12
6.  Security Considerations  . . . . . . . . . . . . . . . . . . . 13
7.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 13
8.  Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 13
9.  References . . . . . . . . . . . . . . . . . . . . . . . . . . 14
    9.1.  Normative References . . . . . . . . . . . . . . . . . . . 14
    9.2.  Informative References . . . . . . . . . . . . . . . . . . 14
Appendix A.  Cookbook  . . . . . . . . . . . . . . . . . . . . . . 15
    A.1.  Virtual Mailboxes  . . . . . . . . . . . . . . . . . . . . 15
    A.2.  Trash Mailboxes  . . . . . . . . . . . . . . . . . . . . . 15
    A.3.  Immediate EXPUNGE Notifications  . . . . . . . . . . . . . 15
    A.4.  Monitoring Counts  . . . . . . . . . . . . . . . . . . . . 15
    A.5.  Resynchronizing Contexts . . . . . . . . . . . . . . . . . 16
Appendix B.  Server Implementation Notes . . . . . . . . . . . . . 16

1. Introduction ✨

Okay so the basic SEARCH command from [IMAP], plus the enhancements from [ESEARCH], is pretty compact 🀏. But that compactness only saves so much, and huge mailboxes can totally overwhelm the storage for results, even on high-end desktops πŸ’€.

The SORT command from [SORT] is genuinely useful πŸ™Œ. The catch is that it's annoying to use on changing mailboxes over low-bandwidth connections 😩.

This memo borrows ideas from [ACAP], like giving you a windowed view onto search or sort results and making updates that are efficient on bandwidth and round trips πŸ¦‹. It gets that from two extensions: "ESORT" and "CONTEXT" πŸ’….

2. Conventions Used in This Document πŸ’…

In examples, "C:" marks lines sent by the client messaging user agent, and "S:" marks lines from the IMAP4rev1 ([IMAP]) server πŸŽ€. "//" starts an inline comment that isn't part of the protocol exchange πŸ’¬. Line breaks get added pretty freely so things are easier to read 🌸. The examples are meant to be read in order, since state carries over from one example to the next 🧚.

Although the examples show a server that supports [ESEARCH], that's not a strict requirement of this spec 🫢.

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 [KEYWORDS] πŸ”₯.

Other capitalized words are usually names of IMAP extensions or commands. They're uppercased just for clarity, and they're case-insensitive 🌈.

3. Extended Sort Syntax πŸ“

Servers that implement the extended SORT give you a whole suite of extensions to the SORT and UID SORT commands from [SORT] ✨. It lets you use return options, the same ones used with SEARCH and specified in [IMAP-ABNF], with SORT in a similar way πŸ‘‘.

The SORT and UID SORT commands get extended with an optional list of return options. Those options come right after a RETURN atom, immediately after the command πŸ’–. If that list is missing, the server returns results the way [SORT] describes πŸ™ˆ.

The extended SORT command always returns results in the requested sort order. Otherwise it behaves just like the extended SEARCH command from [IMAP-ABNF], as extended by [ESEARCH] πŸ’œ. Specifically, the extended SORT command returns its results in an ESEARCH response πŸ”₯.

3.1. ESORT Extension πŸ¦‹

Servers that advertise the capability "ESORT" support the return options from [ESEARCH] in the SORT command ✨. Those return options are adapted like this:

  • MIN: returns the message number or UID of the lowest sorted message that satisfies the search criteria πŸ’….
  • MAX: returns the message number or UID of the highest sorted message that satisfies the search criteria 🌸.
  • ALL: returns all message numbers or UIDs that match the search criteria, in the requested sort order, using a sequence-set πŸŽ€. Note the use of ranges described below in Section 3.2 πŸ‘€.
  • COUNT: works the same as in [ESEARCH] 🧚.

3.2. Ranges in Extended Sort Results 🌈

Any ranges the server gives, including ones inside the sequence-set of an ESEARCH response that comes from an extended SORT or UID SORT command, MUST be ordered in increasing numerical order after expansion, following the usual [IMAP] rules πŸ”₯.

So basically 10:12 is the same as 12:10, and also the same as 10,11,12 🀯. To avoid confusion, servers SHOULD only present ranges when the first seq-number is lower than the second πŸ’–. That means either 10:12 or 10,11,12 is fine, but 12:10 SHOULD be avoided πŸ™…β€β™€οΈ.

3.3. Extended SORT Example πŸ’…

If the list of return options is there but empty, the server gives you the ALL return data item in an ESEARCH response ✨. That's functionally the same as an unextended UID SORT command, but it can use a smaller representation 🫢:

      C: E01 UID SORT RETURN () (REVERSE DATE) UTF-8 UNDELETED
         UNKEYWORD $Junk
      S: * ESEARCH (TAG "E01") UID ALL 23765,23764,23763,23761,[...]
      S: E01 OK Sort completed

Notice that the first three results are not shown as the range 23765:23763, as Section 3.2 requires πŸ™ˆ.

4. Contexts 🧚

4.1. Overview πŸ¦‹

The Contexts extension is present in any IMAP4rev1 server whose advertised capabilities include the string CONTEXT=SEARCH and/or CONTEXT=SORT πŸ’œ.

For CONTEXT=SEARCH, the server supports the extended SEARCH command syntax from [IMAP-ABNF] and accepts three extra return options πŸŽ€.

Servers that advertise CONTEXT=SORT also advertise the SORT capability, as described in [SORT]. They support the extended SORT command syntax from Section 3, and they accept three extra return options for that extended SORT 🌸.

These extra return options let you get notifications of changes to the results of SEARCH or SORT commands. They also give you access to partial results πŸ”₯.

A server that advertises the CONTEXT=SEARCH extension orders all SEARCH results, whether they come from a UID SEARCH or a SEARCH command, in mailbox order. That means by message number and UID πŸ‘‘. So the UID SEARCH, SEARCH, UID SORT, or SORT command you used (together these are called the searching command) always has an order, the requested order. For UID SEARCH and SEARCH commands, that order is the mailbox order πŸ’–.

None of the return specifiers interact with each other, or with any return specifiers defined in [ESEARCH] or Section 3.1 πŸ™ˆ. Still, implementations that support CONTEXT are believed to also support ESEARCH and ESORT πŸ’….

4.2. Context Hint πŸ’–

The CONTEXT return option SHOULD be used by a client to signal that later use of the search criteria is likely ✨. Servers MAY ignore this return option, or use it as a hint to keep a full result cache or index 🧚.

A client might want a count of matching messages before it asks for the actual results 🫢. Here, the client is telling the server it plans to fetch the results later πŸ¦‹:

    C: A01 SEARCH RETURN (CONTEXT COUNT) UNDELETED
       UNKEYWORD $Junk
    S: * ESEARCH (TAG "A01") COUNT 23765
    S: A01 OK Search completed.

Part 1 of 4 is done, bestie πŸŽ€ Part 2 picks up with Section 4.3, Notifications of Changes, and the ADDTO and REMOVEFROM stuff πŸ”₯

4.3. Notifications of Changes πŸ””

okay so, if a client uses the UPDATE search return option, the server starts sending unsolicited notifications whenever the results change. Those updates are what the unmodified searching command would have returned, and they arrive in ADDTO and REMOVEFROM data items inside ESEARCH responses. it's giving live updates πŸ’–

These ESEARCH responses carry the search correlator (the tag) of the searching command, so clients MUST NOT reuse tags, same rule as Section 2.2.1 of [IMAP]. 🚫 If you try to use UPDATE with a tag that's already attached to an earlier searching command that also used UPDATE, the server SHALL result in rejecting the searching command with a BAD response. so don't do that, bestie πŸ’€

Both ADDTO and REMOVEFROM data items SHOULD reach clients in a timely manner, as and when the results change. That could be new messages landing in the mailbox, metadata like flags changing, or messages getting expunged. ✨

This usually happens at the same moment as the FETCH, EXISTS, or EXPUNGE responses that carry the source of the change. πŸŽ€

Updates stop when the mailbox is no longer selected, or when the client issues the CANCELUPDATE command (defined in Section 4.3.5), whichever comes first. ⏰

Unlike [ACAP], a client doesn't need to create a context with CONTEXT before it can use UPDATE. Also, not using UPDATE with a CONTEXT doesn't change the results of later searching commands, because there is no snapshot facility. πŸ“Έ no snapshots here, sis.

UPDATE doesn't interact with any other return options. So RETURN (UPDATE MIN), for example, doesn't notify you about the minimum UID or sequence number. It notifies you about all changes to the set of matching messages instead. 🧠 That also means a client using UPDATE and PARTIAL on the same search program could get notifications about messages it doesn't actually care about right now. main character energy for the server, not so much for the client 😭

Last thing: as the errata to [IMAP] specifies, any message sequence numbers used in the search program are evaluated when the command is received. So if the messages those numbers refer to change later, no notifications will be emitted. πŸ™ˆ

This time, the client wants notifications of updates and asks for a count:

C: B01 UID SEARCH RETURN (UPDATE COUNT) DELETED
   KEYWORD $Junk
S: * ESEARCH (TAG "B01") COUNT 74
S: B01 OK Search completed, will notify.
// Note that the following is rejected, and has no effect:
C: B01 SORT RETURN (UPDATE) FLAGGED
S: B01 BAD Tag reuse

4.3.1. Refusing to Update Contexts πŸ™…β€β™€οΈ

In some cases the server MAY refuse to provide updates, for example when an internal limit on the number of update contexts has been reached. When that happens, an untagged NO is generated while the command is being processed, with a response-code of NOUPDATE. The response-code takes the tag of the search command whose UPDATE request the server is refusing to honour as its argument. πŸ₯Ί

Any other return options that were specified SHALL still be honoured. πŸ’…

Servers MUST provide at least one updating context per client, and SHOULD provide more. See Appendix B for strategies on reducing the impact of additional updating contexts. Sorted contexts cost more to implement than unsorted ones, so refusing updates for a SORT command does not mean SEARCH contexts will also be refused. 🧩

This time, the client wants notifications of updates and asks for a count:

C: B02 UID SORT RETURN (UPDATE COUNT) UTF-8
   KEYWORD $Junk
S: * ESEARCH (TAG "B02") COUNT 74
S: * NO [NOUPDATE "B02"] Too many contexts
S: B02 OK Search completed, will not notify.

How the client handles this could be to retry with a UID SEARCH command, or to cancel an existing context. See Section 4.3.5. πŸ”„

4.3.2. Common Features of ADDTO and REMOVEFROM ✨

The result update set in the return data item is specified as UIDs or message numbers, depending on how UPDATE was specified. If UPDATE was in a SEARCH or SORT command, the results are message numbers. In a UID SEARCH or UID SORT command, they're UIDs. πŸ”’

The client MUST process ADDTO and REMOVEFROM return data items in the order they appear, including ones inside a single ESEARCH response. Servers MUST generate ADDTO and REMOVEFROM responses so that the results stay in the requested order. Order is everything here, babe πŸ‘‘

As with any response other than EXPUNGE, ESEARCH responses carrying ADDTO and/or REMOVEFROM return data items MAY be sent at any time. Servers MAY send them when no command is in progress, during the processing of any command, or while the client is using the IDLE facility described in [IDLE]. Implementors are recommended to read [NOTIFY] as a way for clients to signal that they're willing to process responses at any time. They are also recommended to pay close attention to Section 5.3 of [IMAP]. πŸ“¬

It's expected that typical server implementations will emit ADDTO when they would normally emit the causal FETCH or EXISTS. Similarly, they'll emit REMOVEFROM when they would normally emit the causal FETCH or EXPUNGE. πŸ¦‹

4.3.3. ADDTO Return Data Item 🌸

The ADDTO return data item carries, as its payload, a list of pairs. Each pair is a context position plus a set of result updates, in the requested order, to be inserted at that context position. When the searching command is a SEARCH or UID SEARCH command, the context position MAY be zero. Each pair is processed in the order it appears. 🧁

Heads up: an ADDTO containing message sequence numbers that were added because messages were delivered or appended MUST be sent after the EXISTS notification itself. That way those sequence numbers are valid when the client sees them. 🫢

If the context position is non-zero, the result update is inserted at the given context position. That means the first result in the set takes up the new context position after insertion, and whatever result was already sitting there gets shifted to a later context position. πŸŽ€

When the context position is zero, the client MAY insert the message numbers or UIDs into the result list so that the list stays in mailbox order. In that case, servers are RECOMMENDED to order the result update into mailbox order, which gives the shortest representation in set-syntax. πŸ“

[...]
S: * 23762 FETCH (FLAGS (\Deleted \Seen))
S: * 23763 FETCH (FLAGS ($Junk \Seen))
S: * ESEARCH (TAG "B01") UID ADDTO (0 32768:32769)

This example assumes that messages 23762 and 23763, with UIDs 32768 and 32769 respectively, previously had neither \Deleted nor $Junk set. Also notice that only the ADDTO is included, not the COUNT, even though it has changed. 🀏

If the searching command "C01" first generated a result list of 2734:2735, then the following three responses are equivalent and all yield a result list of 2731:2735:

[...]
S: * ESEARCH (TAG "C01") UID ADDTO (1 2733 1 2732 1 2731)
S: * ESEARCH (TAG "C01") UID ADDTO (1 2733) ADDTO (1 2731:2732)
S: * ESEARCH (TAG "C01") UID ADDTO (1 2731:2733)

The last one is the preferred representation. πŸ†

4.3.4. REMOVEFROM Return Data Item πŸ—‘οΈ

The REMOVEFROM return data item carries, as its payload, a list of pairs. Each pair is a context position plus a set of result updates, in the requested order, to be removed starting from that context position. When the searching command is a SEARCH or UID SEARCH command, the context position MAY be zero. Each pair is processed in the order it appears. πŸ”

If the context position is non-zero, the results are removed at the given context position. The first result in the set occupies the given context position before removal, and any result that was already there gets shifted to an earlier context position. 🌊

When the context position is zero, the client removes the message numbers or UIDs from the result list wherever they occur. Servers are RECOMMENDED to order the result list in mailbox order, so the client gets the best benefit from set-syntax. πŸ’œ

Note that a REMOVEFROM containing message sequence numbers that were removed because those messages were expunged MUST be sent before the expunge notification itself. That keeps those sequence numbers valid. 🫠

In this example, a message in the result list gets expunged. The REMOVEFROM happens without any command in progress; see Section 4.3.2. Notice that EXPUNGE responses don't behave this way. 🧹

[...]
S: * ESEARCH (TAG "B01") UID REMOVEFROM (0 32768)
C: B03 NOOP
S: * 23762 EXPUNGE
S: B03 OK Nothing done.

4.3.5. The CANCELUPDATE Command πŸ›‘

When a client no longer wants updates, it may issue the CANCELUPDATE command. That stops the server from sending any updates to the contexts named in the arguments. The command takes one or more tags of the commands that were used to request updates as its arguments. πŸ™…

The server MAY free any resources associated with a disabled context. Even so, the client is free to issue further searching commands with the same criteria and requested order, including PARTIAL requests. πŸ”“

C: B04 CANCELUPDATE "B01"
S: B04 OK No further updates.

4.4. Partial Results 🍰

The PARTIAL search return option makes the server provide, in an ESEARCH response, a subset of the results. That subset is denoted by the sequence range given as its mandatory argument. The first result is 1, so the first 500 results come from a return option of "PARTIAL 1:500", and the second 500 come from "PARTIAL 501:1000". This intentionally mirrors message sequence numbers. πŸͺž

A single command MUST NOT contain more than one PARTIAL or ALL search return option. In other words, you can have one PARTIAL, one ALL, or neither PARTIAL nor ALL, and that's it. 🚦

For SEARCH results, the entire result list MUST be ordered in mailbox order, meaning UID or message sequence number order. πŸ“š

When a PARTIAL search return option points at results that don't exist, because its range starts or ends higher than the current number of results, the server returns just the results that are actually in the set. The result is a PARTIAL return data item whose payload is the original range plus a set of results that may be shorter than the range. πŸ«₯

Clients don't need to request PARTIAL results in any particular order. Since mailboxes can change, clients will often want to combine PARTIAL with UPDATE, especially if they plan to walk a large set of results. Those two return options don't interact, though. The UPDATE still provides notifications for all matching results. πŸšΆβ€β™€οΈπŸ’¨

// Recall from A01 that there are 23764 results.
C: A02 UID SEARCH RETURN (PARTIAL 23500:24000) UNDELETED
   UNKEYWORD $Junk
C: A03 UID SEARCH RETURN (PARTIAL 1:500) UNDELETED
   UNKEYWORD $Junk
C: A04 UID SEARCH RETURN (PARTIAL 24000:24500) UNDELETED
   UNKEYWORD $Junk
S: * ESEARCH (TAG "A02") UID PARTIAL (23500:24000 ...)
// 264 results in set syntax elided,
// this spans the end of the results.
S: A02 OK Completed.
S: * ESEARCH (TAG "A03") UID PARTIAL (1:500 ...)
// 500 results in set syntax elided.
S: A03 OK Completed.
S: * ESEARCH (TAG "A04") UID PARTIAL (24000:24500 NIL)
// No results are present, this is beyond the end of the results.
S: A04 OK Completed.

4.5. Caching Results ✨

okay so servers are allowed to cache results from a SEARCH or SORT, even if CONTEXT didn't ask for it πŸ’… The point is to make later searches faster, like picking up a PARTIAL search right where the last one stopped πŸ¦‹ Server implementations MAY cache results from a SEARCH or SORT, whether or not hinted to by CONTEXT, in order to make subsequent searches more efficient, perhaps by recommencing a subsequent PARTIAL search where a previous search left off.

BUT (and this is the big rule 🚨) servers MUST act exactly the same whether they're caching or not. Nobody gets to be sneaky about it. So any cache has to be kept up to date as the mailbox changes 🫢 Another option is to just toss the results whenever anything changes in the mailbox 🧹


5. Formal Syntax πŸŽ€

okay this part is the whole grammar, all collected in one place bestie πŸ€“ It's ABNF, which is defined in [ABNF], and it pulls in definitions from [IMAP], [IMAP-ABNF], and [SORT].

capability          =/ "CONTEXT=SEARCH" / "CONTEXT=SORT" / "ESORT"
    ;; <capability> from [IMAP]

command-select      =/ "CANCELUPDATE" 1*(SP quoted)
    ;; <command-select> from [IMAP]

context-position      = number
    ;; Context position may be 0 for SEARCH result additions.
    ;; <number> from [IMAP]

modifier-context    = "CONTEXT"

modifier-partial    = "PARTIAL" SP partial-range

partial-range       = nz-number ":" nz-number
    ;; A range 500:400 is the same as 400:500.
    ;; This is similar to <seq-range> from [IMAP],
    ;; but cannot contain "*".

modifier-update     = "UPDATE"

search-return-opt   =/ modifier-context / modifier-partial /
                       modifier-update
    ;; All conform to <search-return-opt>, from [IMAP-ABNF]

resp-text-code      =/ "NOUPDATE" SP quoted
    ;; <resp-text-code> from [IMAP]

ret-data-addto      = "ADDTO"
                       SP "(" context-position SP sequence-set
                       *(SP context-position SP sequence-set)
                       ")"
    ;; <sequence-set> from [IMAP]

ret-data-partial    = "PARTIAL"
                      SP "(" partial-range SP partial-results ")"
    ;; <partial-range> is the requested range.

partial-results     = sequence-set / "NIL"
    ;; <sequence-set> from [IMAP]
    ;; NIL indicates no results correspond to the requested range.

ret-data-removefrom = "REMOVEFROM"
                       SP "(" context-position SP sequence-set
                       *(SP context-position SP sequence-set)
                       ")"
    ;; <sequence-set> from [IMAP]

search-return-data  =/ ret-data-partial / ret-data-addto /
                       ret-data-removefrom
    ;; All conform to <search-return-data>, from [IMAP-ABNF]

sort                =/ extended-sort
    ;; <sort> from [SORT]

extended-sort       = ["UID" SP] "SORT" search-return-opts
                      SP sort-criteria SP search-criteria
    ;; <search-return-opts> from [IMAP-ABNF]
    ;; <sort-criteria> and <search-criteria> from [SORT]

6. Security Considerations πŸ”

okay this section is serious, so listen up πŸ™ˆ This document adds new IMAP4 capabilities, and that means it does not change the underlying security considerations of [IMAP]. The authors and reviewers believe that no new security issues are introduced with these additional IMAP4 capabilities.

BUT, the one real risk is this: making a huge pile of contexts could be a denial-of-service avenue for authorized users 😭 Implementors may cut that down by limiting how many contexts can be made, using the protocol features in Section 4.3.1 πŸ’œ They can also shrink how much each context costs, using the implementation strategies in Appendix B. And they can log context creation and usage, so admins have something to act on πŸ“‹


7. IANA Considerations πŸ¦‹

IMAP4 capabilities get registered by publishing a Standards Track or IESG-approved Experimental RFC, so that's the rule for getting one in 🌸

This document defines the ESORT, CONTEXT=SEARCH, and CONTEXT=SORT IMAP capabilities. IANA has added them to the registry accordingly ✨


8. Acknowledgements 🫢

Much of the design here can be found in ACAP, so shoutout to that 🌈 Valuable comments came in, both the "yes this is good" kind and the "I disagree" kind, from Alexey Melnikov, Arnt Gulbrandsen, Cyrus Daboo, Filip Navara, Mark Crispin, Peter Coates, Philip Van Hoof, Randall Gellens, Timo Sirainen, Zoltan Ordogh, and others. Lots of those comments really shaped the design or the wording. The authors thank everyone involved, including the people who aren't named here πŸ’–


9. References πŸ“š

9.1. Normative References

  • [ABNF] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, January 2008.
  • [ESEARCH] Melnikov, A. and D. Cridland, "IMAP4 Extension to SEARCH Command for Controlling What Kind of Information Is Returned", RFC 4731, November 2006.
  • [IMAP] Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1", RFC 3501, March 2003.
  • [IMAP-ABNF] Melnikov, A. and C. Daboo, "Collected Extensions to IMAP4 ABNF", RFC 4466, April 2006.
  • [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [SORT] Crispin, M. and K. Murchison, "Internet Message Access Protocol - SORT and THREAD Extensions", RFC 5256, June 2008.

9.2. Informative References

  • [ACAP] Newman, C. and J. Myers, "ACAP -- Application Configuration Access Protocol", RFC 2244, November 1997.
  • [IDLE] Leiba, B., "IMAP4 IDLE command", RFC 2177, June 1997.
  • [NOTIFY] Melnikov, A., Gulbrandsen, A., and C. King, "The IMAP NOTIFY Extension", Work in Progress, March 2008.

Appendix A. Cookbook πŸ“

A.1. Virtual Mailboxes 🧚

you can totally build something that acts like a virtual mailbox with these tools πŸ’… It just gets handled on the client side. First the client SELECTs the real "backing" mailbox. Then, whenever it wants, it can switch to a filtered view by sending RETURN (COUNT UPDATE CONTEXT), and it uses RETURN (PARTIAL x:y) as the user scrolls. Those results get fed into a FETCH to fill up the summary views.

A super useful view is UID SORT (DATE) RETURN (...) UTF-8 UNSEEN UNDELETED. It sorts the mailbox by INTERNALDATE and only shows messages that are unread and not yet deleted πŸ“¬

A.2. Trash Mailboxes πŸ—‘οΈ

certain contexts are perfect for client devs who want a trash-mailbox vibe without eating up a lot of bandwidth 🫧 The simple criteria UNDELETED only matches messages that aren't deleted, and the matching DELETED search key can power a per-mailbox trash-like virtual mailbox πŸ₯€

A.3. Immediate EXPUNGE Notifications ⚑

SEARCH RETURN (UPDATE) ALL makes a context that tells you right away about expunged messages. It won't touch message sequence numbers until the normal EXPUNGE message can go out, so you keep the perks of sequence numbering πŸ”’ This could be handy for clients who want to show that behavior πŸ™Œ

A.4. Monitoring Counts πŸ“Š

a client doesn't need to keep any result cache at all πŸ™…β€β™€οΈ It can just keep a simple count of messages that match the search criteria. This would normally use SEARCH instead of UID SEARCH, because its representation is smaller. This is useful for things like keeping an eye on flagged but unanswered messages with SEARCH RETURN (UPDATE COUNT) FLAGGED UNANSWERED 🚩

A.5. Resynchronizing Contexts πŸ”„

making a context and getting access to it can all happen in one round-trip, so it's quick πŸƒβ€β™€οΈ You can skip resyncing if nothing has changed, but in most cases it's simpler to just resync by recreating the context πŸ’«


Appendix B. Server Implementation Notes πŸ› οΈ

okay this one's for the server devs πŸ€“ A server might cache results, but it's not mandated or required πŸ™Œ That's especially true when the client uses SEARCH or UID SEARCH. For example, UPDATE processing can be done efficiently by comparing the old flag state (if there is one) with the new one. PARTIAL can be done by re-running the search until you reach the window you need. That's all because there's no snapshot facility, so there's nothing frozen to lean on 🧊

For a new message, the server can just test it against all the current UPDATE context search programs. For any that match, it sends the ADDTO return data πŸ“¨

Same vibe for a flag change on an existing message. The server checks whether the message matched with its old flags and whether it matches with the new ones. If those results differ, it sends ADDTO or REMOVEFROM return data to match πŸ”

For PARTIAL requests, the server can run a full search, throw away results until it hits the lower bound, and stop once it has enough results 🎯

With some extra state, you can restart PARTIAL searches and skip that initial discard phase βœ‚οΈ

For the best performance, though, caching the full search results is needed. That speeds up responses, but it costs memory 🧠 One reasonable strategy is to balance that trade-off at run-time: throw away search results after a suitable timeout, and regenerate them when they're needed ⏳

This means you need state for storing the search program for any UPDATE contexts. You can also optionally store both the search program and the (updated) results for other contexts as needed πŸ“¦

Also note that without a server-side results cache, it may be impossible to know whether an expunged message used to match, unless the original message is still around. So some implementations may be forced into using a results cache in lots of situations 😡

And UPDATE contexts created with SORT or UID SORT will almost certainly need some form of results caching πŸ’€


Authors' Addresses 🏑

Dave Cridland
Isode Limited
5 Castle Business Village
36, Station Road
Hampton, Middlesex  TW12 2BX
GB

EMail: dave.cridland@isode.com


Curtis King
Isode Limited
5 Castle Business Village
36, Station Road
Hampton, Middlesex  TW12 2BX
GB

EMail: cking@mumbo.ca

Copyright (C) The IETF Trust (2008).

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, THE IETF TRUST 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 ✨

okay so this part is about who owns what πŸ’… The IETF doesn't take a side on whether any patents or other IP rights someone claims actually count, or how far they reach. It also doesn't say it went looking for any of them πŸ™ˆ If you want the rules for rights in RFC documents, check out BCP 78 and BCP 79.

Copies of IPR disclosures sent to the IETF Secretariat live in the IETF online IPR repository at http://www.ietf.org/ipr. That's also where you'll find any licensing assurances, plus the results of anyone trying to get a general license or permission for implementers or users. Lowkey the best place to check if you're building something 🧚

And if you know of any copyrights, patents, patent applications, or other proprietary rights that might cover technology needed to implement this standard, the IETF wants to hear about it 🫢 Send it to ietf-ipr@ietf.org. Main character energy for good citizenship, periodt πŸŽ€

πŸ“¦ where this page comes from