Thunderbird:IMAP RFC 4551 Implementation

From MozillaWiki
Jump to navigation Jump to search

See RFC 4551 and bug 436151 for more details

This page describes my plan for implementing this RFC in the mailnews code.

Overview

This extension to the IMAP protocol is primarily intended for use by mobile devices but it will help Thunderbird users as well. It reduces the amount of data the client needs to sync every time a folder is selected. The server keeps track of modification sequence numbers for every change made to a folder. When a folder is selected, the server returns the highest modification sequence number for that folder. The client can then just do an incremental sync, based on the highest modification sequence number it is aware of. If those two numbers are the same, the client doesn't need to do any synchronization at all.

User Experience

This should all be transparent to the user. If their IMAP server supports this extension, selecting large folders should be quite a bit faster, especially over lower bandwidth connections.

We may need to provide a way for the user to turn off this feature, in case their server implementation has bugs in it. My fervent hope is that if this comes to pass, we can get by with a hidden pref.

How Syncing Works Today

When we open a folder, we list all the message UID's and flags in the folder, e.g.,

UID fetch 1:* (FLAGS)

The IMAP protocol code parses the responses and builds up the nsIImapFlagAndUidState object, which it then passes to nsImapMailFolder::UpdateImapMailboxInfo, via the nsIMailboxSpec argument. UpdateImapMailboxInfo then compares the uids and flags it knows about in the nsIMsgDatabase with the uids and flags the server knows about. It removes headers from the db that don't exist any more on the server, updates the flags of messages that it does know about, and tells the nsImapProtocol object about headers it doesn't know about, so the nsImapProtocol code can issue protocol to fetch those headers.

How Syncing Will Work with an RFC 4551 Supporting Server

First, we detect that the server supports RFC 4551, which it indicates by returning CONDSTORE as one of its capabilities. If so, we need to tell the server that we, the client, are interested in HIGHESTMODSEQ for particular imap folders, e.g.,:

SELECT INBOX (CONDSTORE)

As part of it's response, the server will say something like:

HIGHESTMODSEQ 150000000

The mod seq # is an unsigned 64 bit integer (as an aside, we don't typically deal with 64 bit unsigned ints, especially in our db code, so we might just persist this as a string).

If we knew about that mod seq #, then we know we don't need to do any synchronization. If our own highest mod seq # is lower, e.g., 140000000, then we just need to know about the things that have changed since our mod seq #, e.g.,

UID FETCH 1:* (FLAGS) (CHANGEDSINCE 140000000)

This will tell us about all the changes that happened since we last used the folder, i.e., messages added, messages deleted, and flags changed.