Network Working Group                                   A. Melnikov, Ed.
Request for Comments: 4549                                    Isode Ltd.
Category: Informational                                        June 2006
        
Network Working Group                                   A. Melnikov, Ed.
Request for Comments: 4549                                    Isode Ltd.
Category: Informational                                        June 2006
        

Synchronization Operations for Disconnected IMAP4 Clients

断开连接的IMAP4客户端的同步操作

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).

版权所有(C)互联网协会(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.

本文档试图解决构建断开连接的IMAP4客户端所涉及的一些问题。特别是,它处理的问题可能被称为同步工具的“驱动程序”部分:负责发出一组正确的IMAP4命令的代码部分,以最有可能让使用断开连接的客户机的人满意的方式同步断开连接的客户机。

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.

本说明描述了断开连接的客户端可以使用的不同策略,并说明了如何使用IMAP协议以最小化同步过程的时间。

This note also lists IMAP extensions that a server should implement in order to provide better synchronization facilities to disconnected clients.

本说明还列出了服务器应实现的IMAP扩展,以便为断开连接的客户端提供更好的同步功能。

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
        
   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
        
1. Introduction
1. 介绍

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).

本文档中提出的几个建议通常适用于所有类型的IMAP客户端。但是,本文档试图集中讨论断开连接的邮件客户端[IMAP-MODEL]。它还建议一些IMAP扩展*应该由IMAP服务器实现,以使断开连接的客户机的使用更加方便。特别是,[UIDPLUS]扩展专门设计用于简化某些断开连接的操作,如删除、上载和复制消息(请参见第4.2.1、4.2.2.1和4.2.4节)。

Readers of this document are also strongly advised to read RFC 2683 [RFC2683].

强烈建议本文件的读者阅读RFC 2683[RFC2683]。

* Note that the functionality provided by the base IMAP protocol [IMAP4] is sufficient to perform basic synchronization.

* 请注意,基本IMAP协议[IMAP4]提供的功能足以执行基本同步。

1.1. Conventions Used in This Document
1.1. 本文件中使用的公约

In examples, "C:" and "S:" indicate lines sent by the client and server, respectively. Long lines in examples are broken for editorial clarity.

在示例中,“C:”和“S:”分别表示客户端和服务器发送的行。为了编辑清晰起见,示例中的长行被打断。

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].

本文件中的关键词“必须”、“不得”、“必需”、“应”、“不应”、“应”、“不应”、“建议”、“可”和“可选”应按照RFC 2119[关键词]中所述进行解释。

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.

如果连续执行两次命令的结果与仅执行一次命令的结果相同,那么让我们调用IMAP命令幂等元。

2. Design Principles
2. 设计原则

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.

存储在断开连接的客户端上的所有邮箱状态或内容信息应严格视为服务器状态的缓存。与交互式IMAP4客户端一样,“主”状态仍保留在服务器上。此规则的一个例外是,有关断开连接的客户端缓存状态的信息(该状态包括脱机和定时消息上载期间的标志更改)保留在断开连接的客户端上:也就是说,IMAP4服务器不负责记住断开连接的IMAP4客户端的状态。

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

我们假设一个断开连接的客户机是一个客户机,无论出于何种原因,它都希望最小化它“在电话上”到IMAP4服务器的时间长度。这通常是因为客户端使用的是拨号连接,可能带宽很低,但是

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".

有时可能只是因为人类急于赶飞机,或者其他一些我们无法控制的事件。无论出于何种原因,我们假设必须有效利用网络连接,无论是在通常意义上(不产生虚假流量),还是在客户机和/或服务器严格执行本地计算或I/O时,我们不希望连接处于空闲状态。另一方面,也许更简单的说法是我们假设网络连接是“昂贵的”。

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.

综上所述,前两条原则得出的结论是,同步程序必须根据人类提供的某种指导,通过在用户界面中选择适当的选项或通过某种配置文件来做出决定。几乎可以肯定的是,它不应该在同步过程中间与I/O暂停。对于不同的情况,人类几乎肯定会有几种不同的同步程序配置。

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.

由于断开连接的客户端无法知道邮箱在断开连接时可能发生了哪些更改,因此邮件编号对断开连接的客户端没有用处。所有断开连接的客户端操作都应使用UID执行,以便客户端可以确保它和服务器在同步过程中谈论相同的消息。

3. Overall Picture of Synchronization
3. 同步的总体情况

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.)

a) 处理客户端上未与任何邮箱关联的任何挂起的“操作”。(特别是发送使用SMTP脱机编写的邮件。这不是IMAP同步的一部分,但为了完整性,这里提到了这一点。)

b) Fetch the current list of "interesting" mailboxes. (The disconnected client should allow the user to skip this step completely.)

b) 获取“感兴趣”邮箱的当前列表。(断开连接的客户端应允许用户完全跳过此步骤。)

c) "Client-to-server synchronization": for each IMAP "action" that was pending on the client, do the following:

c) “客户端到服务器同步”:对于客户端上挂起的每个IMAP“操作”,请执行以下操作:

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).

1) 如果该操作意味着打开新邮箱(对邮件进行的任何操作),请打开邮箱。检查UID有效性响应代码中返回的UID有效性值(有关更多详细信息,请参阅第4.1节)。如果服务器返回的UIDValm值不同,则客户端必须清空邮箱的本地缓存,并删除在邮箱中引用UID的任何未决的“动作”(并考虑它们失败)。请注意,这不会影响对客户端生成的伪UID执行的操作(请参阅第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]).

2) 执行操作。如果操作是删除邮箱(删除),请确保首先关闭邮箱(另请参见[RFC2683]第3.4.12节)。

d) "Server-to-client synchronization": for each mailbox that requires synchronization, do the following:

d) “服务器到客户端同步”:对于每个需要同步的邮箱,请执行以下操作:

1) Check the mailbox UIDVALIDITY (see Section 4.1 for more details) with SELECT/EXAMINE/STATUS.

1) 使用SELECT/Inspect/STATUS检查邮箱UID的有效性(有关更多详细信息,请参阅第4.1节)。

If UIDVALIDITY value returned by the server differs, the client MUST

如果服务器返回的UIDVality值不同,则客户端必须

* 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.

* 清空该邮箱的本地缓存;*删除在邮箱中引用UID的任何未决的“动作”,并考虑它们失败;和*跳过步骤2-II。

2) Fetch the current "descriptors";

2) 获取当前的“描述符”;

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.

3) 获取客户端还没有的任何“有趣”消息的主体。

e) Close all open mailboxes not required for further operations (if staying online) or disconnect all open connections (if going offline).

e) 关闭所有不需要进一步操作的打开邮箱(如果保持在线)或断开所有打开的连接(如果脱机)。

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.

“操作”是在客户端断开连接时,人工向客户端的邮件用户代理(MUA)软件发出的排队请求。

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.

我们将“描述符”定义为一组IMAP4获取数据项。从概念上讲,消息描述符是一组信息,允许同步程序决定将本地缓存带到该消息所需状态所需的协议操作;因为这个决定实际上是由人来决定的,所以这个信息可能至少包括几个供人使用的标题字段。描述符的具体构成取决于客户机实现。描述符至少包含消息的UID和标志。其他可能的候选项有RFC822.SIZE、RFC822.HEADER、BODYSTRUCTURE或信封数据项。

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.

1) 应该对操作列表进行排序。例如,如果人工删除邮箱A中的邮件A1,然后删除邮箱A,然后删除邮箱A中的邮件A2,则人工将认为邮件A1已消失,邮件A2仍然存在,但现在已删除。

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.

通过在继续同步之前处理所有操作,我们避免了必须补偿本地MUA对服务器状态的更改。也就是说,一旦我们处理了所有挂起的操作,客户端同步自身所必须采取的步骤将是相同的,无论服务器状态的更改起源于何处。

2) Steps a and b can be performed in parallel. Alternatively, step a can be performed after d.

2) 步骤a和b可以并行执行。或者,可以在d之后执行步骤a。

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.

3) 在步骤b中,“有趣的”邮箱集几乎必须由人来确定。在具有相同服务器、客户端和人员的不同IMAP4会话之间,属于此集合的邮箱可能有所不同。有趣的邮箱可以是LSUB命令返回的邮箱(请参见[IMAP4]第6.3.9节)。特殊邮箱“收件箱”应位于客户端认为感兴趣的默认邮箱集中。但是,为特定会话或客户端提供忽略收件箱的功能对于某些邮件过滤策略可能很有价值。

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).

4) 在步骤d-2-II中,客户机还可以发现客户机已在其本地缓存中的消息标志的更改,以及服务器上不再存在的本地缓存中的消息(即已删除的消息)。

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.

5) “有趣的”消息是那些同步程序认为人类希望根据配置和步骤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).

6) 断开连接的IMAP客户端是IMAP客户端的特例,因此它必须能够随时处理任何“意外”的未经请求的响应,如EXISTS和EXPUNGE。在“客户端到服务器”同步阶段(步骤c),断开连接的客户端可能会忽略删除响应。

The rest of this discussion will focus primarily on the synchronization issues for a single mailbox.

本讨论的其余部分将主要关注单个邮箱的同步问题。

4. Mailbox Synchronization Steps and Strategies
4. 邮箱同步步骤和策略
4.1. Checking UID Validity
4.1. 检查UID有效性

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.

邮箱的“UID有效性”是在邮箱选择时在OK Untaged响应中的UID有效性响应代码中返回的数字。当UID在会话之间无法持久化时,UID有效性值在会话之间更改。

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.

每当客户端选择邮箱时,客户端必须将返回的UID有效性值与本地缓存中存储的值进行比较。如果UID有效性值不同,则客户端缓存中的UID不再有效。然后,客户端必须清空该邮箱的本地缓存,并删除引用该邮箱中UID的任何挂起的“操作”。客户还可能向该人员发出警告。客户端不得取消邮箱的任何计划上载(即,附件)。

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.

请注意,UIDVality不仅在邮箱选择中返回。[UIDPLUS]扩展(另请参见4.2.2)中定义的COPYUID和APPENDUID响应代码以及UIDVALIDITY STATUS响应数据项也包含其他邮箱的UIDVALIDITY值。客户机的行为应如前一段所述(但它应作用于其他邮箱的缓存),无论它如何获得UIDVality值。

4.2. Synchronizing Local Changes with the Server
4.2. 将本地更改与服务器同步
4.2.1. Uploading Messages to the Mailbox
4.2.1. 正在将邮件上载到邮箱

Two of the most common examples of operations resulting in message uploads are:

导致消息上载的两个最常见的操作示例是:

1) Saving a draft message

1) 保存草稿邮件

2) Copying a message between remote mailboxes on two different IMAP servers or a local mailbox and a remote mailbox.

2) 在两个不同IMAP服务器上的远程邮箱或本地邮箱和远程邮箱之间复制邮件。

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:

使用APPEND命令执行消息上载。计划上载的邮件没有与之关联的UID,因为所有UID都是由服务器分配的。APPEND命令将有效地将UID与上载的消息相关联,该消息可以存储在本地缓存中以供将来参考。然而,[IMAP4]并没有描述一种通过执行APPEND命令来发现消息UID的简单机制。为了发现UID,客户端可以执行以下操作之一:

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.

1) 从缓存中删除上载的邮件。然后,使用4.3中描述的机制获取有关已上载消息的信息,就像它是由其他客户端上载的一样。

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.

2) 尝试获取4.2.2中所述的标题信息,以查找与上载消息相对应的消息。4.2.2中描述了一种执行此操作的策略。

Case 1 describes a not particularly smart client.

案例1描述了一个不是特别智能的客户端。

      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
        
      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:

幸运的是,有一种更简单的方法可以在[UIDPLUS]扩展中发现消息UID:

      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
        
      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.

附加消息的UID是APPENDUID响应代码的第二个参数。

4.2.2. Optimizing "move" and "copy" Operations
4.2.2. 优化“移动”和“复制”操作

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.

IMAP和其他支持多个邮箱的邮箱访问协议的实践经验表明,将邮件从一个邮箱移动到另一个邮箱是一种非常常见的操作。

4.2.2.1. Moving a Message between Two Mailboxes on the Same Server
4.2.2.1. 在同一服务器上的两个邮箱之间移动邮件

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.

在IMAP4中,同一服务器上两个邮箱之间的“移动”操作实际上是复制操作和存储+标志(\Deleted)操作的组合。这对于IMAP协议来说很有意义,但它让一个头脑简单的断开连接的客户端处于愚蠢的位置,删除并可能删除其缓存的消息副本,然后通过网络获取相同的副本。

However, the presence of the UIDPLUS extension in the server can help:

但是,服务器中存在UIDPLUS扩展可以帮助:

      C: A001 UID COPY 567,414 "Interesting Messages"
      S: A001 OK [COPYUID 1022843275 414,567 5:6] Completed
        
      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.

这会告诉客户端,当前邮箱中UID为414的邮件已成功复制到邮箱“有趣的邮件”并获得UID 5,UID为567的邮件获得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,

在服务器中缺少UIDPLUS扩展支持的情况下,可以使用以下技巧。通过将Message ID:header和INTERNALDATE数据项作为描述符的一部分,客户机可以根据缓存中已经存在的消息检查“新”消息的描述符,并避免获取额外副本。当然

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.

检查消息是否已在本地缓存中的成本可能超过仅获取消息的成本,因此不应盲目使用此技术。如果MUA执行“移动”命令,当它知道复制/删除序列是“移动”命令的结果时,它会特别规定使用此技术。

Note that servers are not required (although they are strongly encouraged with "SHOULD language") to preserve INTERNALDATE when copying messages.

请注意,复制消息时不需要服务器(尽管强烈建议使用“应语言”)来保留INTERNALDATE。

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.

还要注意的是,由于该算法在理论上有可能找到错误的消息(给定足够恶性的消息ID头),所以实现者应该提供一种方法来永久地和逐个消息地禁用该优化。

Example 1: Copying a message in the absence of UIDPLUS extension.

示例1:在没有UIDPLUS扩展的情况下复制消息。

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
        
      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
        
      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:

由于服务器未提供COPYUID响应代码,客户端将尝试上述优化:

      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
        
      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
        

Note that if the server has returned multiple UIDs in the SEARCH response, the client MUST NOT use any of the returned UID.

请注意,如果服务器在搜索响应中返回了多个UID,则客户端不得使用任何返回的UID。

4.2.2.2. Moving a Message from a Remote Mailbox to a Local
4.2.2.2. 将邮件从远程邮箱移动到本地邮箱

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):

将邮件从远程邮箱移动到本地邮箱是通过FETCH(包括标志和INTERNALDATE)完成的,后跟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
        
      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
4.2.2.3. 将邮件从本地邮箱移动到远程邮箱

Moving a message from a local mailbox to a remote is done with APPEND:

将邮件从本地邮箱移动到远程邮箱是通过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
        
   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.

客户机应该在APPEND中指定本地缓存的传递日期。

If the [LITERAL+] extension is available, the client can save a round-trip*:

如果[LITERAL+]扩展可用,则客户端可以保存往返*:

   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
        
   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:

* 请注意,由于邮件的大小,服务器有拒绝邮件的风险。如果发生这种情况,客户端将浪费带宽传输整个消息。如果客户端不使用LITERAL+,则可以避免:

   C: A003 APPEND Drafts (\Seen $MDNSent) "31-May-2004 05:26:59 -0600"
       {16777215}
   S: A003 NO Sorry, message is too big
        
   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
4.2.2.4. 在不同服务器上的两个邮箱之间移动邮件

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.2中描述的操作和4.2.2.3中描述的操作的组合。

4.2.2.5. Uploading Multiple Messages to a Remote Mailbox with MULTIAPPEND

4.2.2.5. 使用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].

当需要将多封邮件上载到远程邮箱时(例如,根据4.2.2.3),某些IMAP扩展的存在可能会显著提高性能。其中之一是[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.

对于某些邮件存储,打开邮箱进行附加可能会很昂贵。[MULTIAPPEND]告诉服务器打开邮箱一次(而不是每次上载“n”封邮件时打开和关闭邮箱“n”次),并在将一组邮件上载到服务器时保持邮箱打开。

Also, if the server supports both [MULTIAPPEND] and [LITERAL+] extensions, the entire upload is accomplished in a single command/response round-trip.

此外,如果服务器同时支持[MULTIAPPEND]和[LITERAL+]扩展,则整个上载将在单个命令/响应往返过程中完成。

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.

注意:客户机实现者应该知道,[MULTIAPPEND]以原子方式执行多条消息的追加。这意味着,例如,如果在成功上载“n-1”邮件后,没有足够的空间来保存“n”-th邮件(或者该邮件的结构无效且被服务器拒绝),则整个上载操作将失败,并且邮箱中不会保存任何邮件。虽然这种行为在某些情况下可能是可取的,但它可能不是您想要的。否则,客户端应该使用常规的APPEND命令(第4.2.2.3节),可能使用[LITERAL+]扩展名。有关错误恢复的讨论,请参见第5.1节。

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.

注:MULTIAPPEND可与UIDPLUS扩展一起使用,使用方式类似于第4.2.1节所述。[MULTIAPPEND]扩展了APPENDUID响应代码的语法,允许在第二个参数中使用多个消息UID。

Example 2:

例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 "<--->"):
        
   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:
        
   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:
        

S: A003 OK [APPENDUID 1022843275 77712,77713] completed

S:A003正常[附录UID 1022843275 7771277713]已完成

The upload takes 3 round-trips.

上传需要3次往返。

Example 3:

例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.

在本例中,针对服务器支持MULTIAPPEND、LITERAL+和UIDPLUS的情况修改了示例2。上传只需1次往返。

   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
        
   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
4.2.3. 重放本地标志更改

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.

断开连接的客户端使用STORE命令将本地标志状态与服务器同步。断开连接的客户端应使用+FLAGS.SILENT或-FLAGS.SILENT,以便在脱机时设置或取消设置用户修改的标志。不能使用FLAGS表单,因为这可能会覆盖服务器上已被其他客户端更改的标志。

Example 4:

例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

对于UID为15的消息,断开连接的客户端存储以下标志\Seen和$Highest。其他客户端在服务器上修改了标志:\Seen、\responsed和$Highest。虽然

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:

脱机时,用户请求删除$Highest标志并添加\ Deleted标志。消息的标志同步序列应如下所示:

      C: A001 UID STORE 15 +FLAGS.SILENT (\Deleted)
      S: A001 STORE completed
      C: A002 UID STORE 15 -FLAGS.SILENT ($Highest)
      S: A002 STORE completed
        
      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:

例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:

想象一下,一个投机性邮件客户端可以将邮件标记为工作相关($work)、个人($personal)或垃圾邮件($spam)之一。为了将邮件标记为个人邮件,客户端会发出:

      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
        
      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
        
      C: A003 UID STORE 15 -FLAGS.SILENT ($Personal $Work $Spam)
      S: A003 STORE completed
        
4.2.4. Processing Mailbox Compression (EXPUNGE) Requests
4.2.4. 处理邮箱压缩(删除)请求

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.

支持在脱机时压缩邮箱的原始断开连接的客户端实现可能会决定向服务器发出EXPUNGE命令,以便删除标记为\Deleted的邮件。同步过程中此命令的问题在于,它会永久删除设置了\Deleted标志的所有消息,即,即使是在用户脱机时在服务器上标记为\Deleted的消息。这样做可能会给用户带来不愉快的惊喜。

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

幸运的是,[UIDPLUS]扩展在这种情况下也有帮助。扩展引入了UID EXPUNGE命令,与EXPUNGE不同,该命令采用UID set参数,该参数列出了所有可以删除的消息的UID。处理此命令时,服务器仅擦除

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.

UID列表中列出了带有\Deleted标志的邮件。因此,即使设置了\Deleted标志,UID集中未列出的消息也不会被删除。

Example 6:

例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:

当用户脱机时,当用户请求压缩打开的邮箱时,3封UID为7、27和65的邮件被标记\删除。另一个客户端在服务器上标记了一条消息\已删除(UID 34)。在同步过程中,断开连接的客户端会出现以下问题:

      C: A001 UID EXPUNGE 7,27,65
      S: * ... EXPUNGE
      S: * ... EXPUNGE
      S: * ... EXPUNGE
      S: A001 UID EXPUNGE completed
        
      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:

如果另一个客户端在UID删除之前和之后发出UID SEARCH DELETED命令(查找带有\DELETED标志的所有邮件),它将获得:

Before:

之前:

      C: B001 UID SEARCH DELETED
      S: * SEARCH 65 34 27 7
      S: B001 UID SEARCH completed
        
      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
        
      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.

在没有[UIDPLUS]扩展的情况下,可以使用以下命令序列作为近似值。注意:在执行此序列时,其他客户端可以将其他消息标记为已删除。在这种情况下,这些附加消息也将被删除。

1) Find all messages marked \Deleted on the server.

1) 查找服务器上标记为\已删除的所有邮件。

      C: A001 UID SEARCH DELETED
      S: * SEARCH 65 34 27 7
      S: A001 UID SEARCH completed
        
      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).

2) 查找所有不能删除的消息(对于上一个示例,列表将包含UID为34的消息)。

3) Temporarily remove \Deleted flag on all messages found in step 2.

3) 在步骤2中找到的所有邮件上临时删除\删除标志。

      C: A002 UID STORE 34 -FLAGS.SILENT (\Deleted)
      S: A002 UID STORE completed
        
      C: A002 UID STORE 34 -FLAGS.SILENT (\Deleted)
      S: A002 UID STORE completed
        

4) Expunge the mailbox.

4) 删除邮箱。

      C: A003 EXPUNGE
      S: * 20 EXPUNGE
      S: * 7 EXPUNGE
      S: * 1 EXPUNGE
      S: A003 EXPUNGE completed
        
      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.

在这里,UID为7的消息的消息号为1,UID为27的消息号为7,UID为65的消息号为20。

5) Restore \Deleted flag on all messages found when performing step 2.

5) 执行步骤2时找到的所有邮件上的Restore\Deleted标志。

      C: A004 UID STORE 34 +FLAGS.SILENT (\Deleted)
      S: A004 UID STORE completed
        
      C: A004 UID STORE 34 +FLAGS.SILENT (\Deleted)
      S: A004 UID STORE completed
        
4.2.5. Closing a Mailbox
4.2.5. 关闭邮箱

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.

当断开连接的客户端必须关闭邮箱时,不应使用close命令,因为close执行静默删除。(第4.2.4节解释了为什么断开连接的客户端不应使用EXPUNGE。)只有在使用EXPEND打开邮箱时,才可以安全地使用CLOSE。

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:

如果使用SELECT打开邮箱,则客户端可以使用以下命令之一隐式关闭邮箱并防止静默删除:

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.

1) UNSELECT-这是一个在[UNSELECT]中描述的命令,其工作方式为关闭,但不会导致静默删除。如果服务器在其功能列表中报告取消选择,则该命令受服务器支持。

2) SELECT <another_mailbox> - SELECT causes implicit CLOSE without EXPUNGE.

2) 选择<other_mailbox>-选择导致隐式关闭而不删除。

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.

3) 如果客户端打算在关闭邮箱后发出注销,它可能只是发出注销,因为注销也会导致隐式关闭而不删除。

4) SELECT <non_existing_mailbox> - If the client knows a mailbox that doesn't exist or can't be selected, it MAY SELECT it.

4) 选择<non_existing_mailbox>-如果客户端知道某个邮箱不存在或无法选择,则可以选择该邮箱。

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:

如果客户端使用SELECT打开邮箱,并且只想避免在不关闭邮箱的情况下进行隐式删除,则它还可以使用以下选项:

5) EXAMINE <mailbox> - Reselect the same mailbox in read-only mode.

5) 检查<邮箱>-以只读模式重新选择同一邮箱。

4.3. Details of "Normal" Synchronization of a Single Mailbox
4.3. 单个邮箱“正常”同步的详细信息

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
4.3.1. 发现新邮件和对旧邮件的更改

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.

让<lastseenuid>表示客户端在此邮箱中知道的最高UID。由于UID是严格按升序分配的,因此这只是客户机知道的邮箱中最后一封邮件的UID。让<lastseenuid+1>表示<lastseenuid>的UID加1。让<descriptors>表示一个列表,该列表由实现认为是描述符一部分的所有获取数据项组成;至少这只是标志数据项,但它通常还包括BODYSTRUCTURE和RFC822.SIZE。在此步骤中,<descriptor>不应包括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
        
      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

第一个命令将请求有关“新”消息的一些信息(即,自上次同步以来服务器收到的消息)。它还允许客户端将消息编号构建为UID映射(仅适用于新消息)。第二个命令允许客户端

1) update cached flags for old messages;

1) 更新旧消息的缓存标志;

2) find out which old messages got expunged; and

2) 找出哪些旧邮件被删除;和

3) build a mapping between message numbers and UIDs (for old messages).

3) 构建消息编号和UID之间的映射(对于旧消息)。

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

这里的顺序很重要。我们希望服务器尽可能快地返回新消息描述符列表,这样客户机就可以开始发出更多的FETCH命令,因此我们首先要求客户机提供我们所知道的所有消息的描述符

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.

不可能已经缓存了。第二个命令获取确定客户端已经缓存的消息可能发生了哪些更改所需的信息。请注意,只有当客户端缓存的UIDNEXT值与服务器返回的UIDNEXT值不同时,才应发出前一个命令。一旦客户机发出这两个命令,在第一个命令的响应开始到达之前,客户机就不能再处理这个邮箱了。聪明的同步程序可能会利用这段时间从磁盘获取其本地缓存状态,或启动同步另一个邮箱的过程。

The following is an example of the first FETCH:

以下是第一次提取的示例:

C: A011 UID fetch 131:* (FLAGS BODYSTRUCTURE INTERNALDATE RFC822.SIZE)

C:A011 UID fetch 131:*(标志BODYSTRUCTURE INTERNALDATE RFC822.大小)

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.

注1:第一次获取可能会导致服务器发送大量数据。智能断开连接的客户端应使用消息范围(另请参见[RFC2683]第3.2.1.2节),以便用户能够在获取一组新消息的信息之间执行不同的操作。

Example 7:

例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:

知道服务器在选择或检查(<UIDNEXT>)时返回的新UIDNEXT后,客户端可以将UID范围<lastseenuid+1>:<UIDNEXT>拆分为多个组,例如100条消息。之后,客户可以发布:

      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)
        
      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.

请注意,除非发出搜索命令,否则无法确定有多少消息将落入子范围,因为UID不一定是连续的。

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.

注2:客户端应忽略在第一个FETCH命令期间收到的任何未经请求的删除响应。“删除”响应包含对没有消息号到UID转换表的客户端无效的消息号。

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.

第二个FETCH命令将导致零个或多个未标记的FETCH响应。每个响应将有一个对应的UID FETCH数据项。必须从本地缓存中删除所有没有匹配的未标记获取响应的消息。

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.

例如,如果<lastseenuid>的值为15000,且本地缓存分别包含3条UID为12、777和14999的消息,则在从服务器接收到以下响应后,客户端必须从其本地缓存中删除UID为14999的消息。

      S: * 1 FETCH (UID 12 FLAGS (\Seen))
      S: * 2 FETCH (UID 777 FLAGS (\Answered \Deleted))
        
      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:

注3:如果客户端对标志更改不感兴趣(即,客户端只想知道哪些旧消息仍在服务器上),则第二个FETCH命令可以替换为:

      tag2 UID SEARCH UID 1:<lastseenuid>
        
      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.

此命令将生成较少的通信量。但是,实现者应该知道,为了构建从消息编号到UID的映射表,必须首先对SEARCH命令的输出进行排序,因为服务器不需要在搜索响应中以任何特定顺序返回UID。

4.3.2. Searching for "Interesting" Messages.

4.3.2. 搜索“有趣”的消息。

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.

此步骤完全在客户机上执行(根据4.3.1所述步骤中接收到的信息),完全在服务器上执行,或在两者的某种组合上执行。关于什么是“有趣的”消息的决定取决于客户端软件和人员。在任何客户机中都应该实现一个简单的标准,即消息是否“太大”,无法自动检索,其中“太大”是客户机配置中定义的参数。

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):

另一个常用的标准是消息的时间。例如,客户端可能选择只下载上周收到的消息(在这种情况下,<date>将是今天的日期减去7天):

      tag3 UID SEARCH UID <uidset> SINCE <date>
        
      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.

请记住,日期搜索忽略时间和时区。如果客户机在4.3.1所述步骤的<descriptors>中指定INTERNALDATE,则可以避免执行此搜索。如果客户端这样做了,它可以在其消息缓存上执行本地搜索。

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).

在这一步中,客户机还决定从服务器获取关于特定消息的何种信息。特别是,即使对于被认为“太大”的消息,客户端也可以选择获取其中的某些部分。例如,如果消息是包含文本部分和MPEG附件的多部分/混合消息,则客户端没有理由不获取文本部分。可以根据BODYSTRUCTURE FETCH响应数据项中接收到的信息(即,如果BODYSTRUCTURE包含在4.3.1所述步骤的<descriptors>中)来决定应提取还是不应提取哪个零件。

4.3.3. Populating Cache with "Interesting" Messages.

4.3.3. 用“有趣的”消息填充缓存。

Once the client has found out which messages are "interesting", it can start issuing appropriate FETCH commands for "interesting" messages or parts thereof.

一旦客户机发现哪些消息是“有趣的”,它就可以开始为“有趣的”消息或其中的一部分发出适当的FETCH命令。

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.

请注意,将消息提取到断开连接的客户端的本地缓存并不意味着用户已经(甚至将)读取了消息。因此,断开连接的客户端的同步程序应始终小心使用隐式设置\Seen标志的FETCH数据项的.PEEK变体。

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.

一旦最后一个描述符到达并且发出了最后一个FETCH命令,客户端只需处理传入的FETCH项并使用它们来更新本地消息缓存。

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).

为了避免死锁问题,在同步过程中,客户端必须给予接收消息的处理优先级,而不是发出新的FETCH命令。这可能需要临时本地排队获取请求,如果不导致死锁,则无法发出这些请求。为了实现“昂贵”网络连接的最佳使用,客户机几乎肯定需要仔细注意它可以从底层传输连接(通常是TCP连接)获得的任何流控制信息。

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.

注:如果盲目遵循上一段中的要求,可能会导致不愉快的用户体验。例如,用户可能不愿意在开始处理用户的请求之前等待客户端完成同步。智能断开连接的客户端应允许用户在作为同步过程一部分的IMAP命令之间执行请求的操作。另见第4.3.1节注释1。

Example 8:

例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.

获取消息主体结构后,客户端会发现一条复杂的MIME消息。然后,它决定获取嵌套MIME消息的MIME头和一些正文部分。

   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: ...
        
   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
4.3.4. 用户启动的同步

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.

客户机完成第4.3.1-4.3.3节所述的主同步过程后,用户可以选择在客户机仍然在线的情况下请求额外的同步步骤。这与第4.3.2节和第4.3.3节中描述的过程没有任何不同。

Typical examples are:

典型的例子有:

1) fetch all messages selected in UI. 2) fetch all messages marked as \Flagged on the server.

1) 获取在UI中选择的所有消息。2) 获取服务器上标记为\标记的所有邮件。

4.4. Special Case: Descriptor-Only Synchronization
4.4. 特殊情况:仅描述符同步

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.

对于某些邮箱,获取描述符可能是整个同步步骤。IMAP的实践经验表明,特定类别的邮箱(例如“存档”邮箱)主要用于长期存储重要消息,这些消息是人们希望即时按需提供的,但不希望在任何其他时间弄乱断开连接的客户端缓存。此类邮箱中的邮件将仅通过本地MUA排队的显式操作获取。因此,这种邮箱上唯一需要的同步是获取足够的描述符信息,以便用户能够识别消息以供后续下载。

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
4.5. 特殊情况:仅快速新同步

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>).

在某些情况下,人类可能会非常匆忙,以至于他或她不关心对旧消息的更改,只关心新消息。在这种情况下,客户端可以跳过UID FETCH命令,该命令用于获取旧消息的标志和UID(1:<lastseenuid>)。

4.6. Special Case: Blind FETCH
4.6. 特殊情况:盲取

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[])
        
      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)".

1) 发出“tag1 UID获取<lastseenuid+1>:*(标志RFC822.SIZE)”。

2) From the message sizes returned in step 1, construct UID set <required_messages>.

2) 根据步骤1中返回的消息大小,构造UID set<required\u messages>。

3) Issue "tag2 UID FETCH <required_messages> (BODY.PEEK[])".

3) 发出“tag2 UID FETCH<required_messages>(BODY.PEEK[])”。

or

1) Issue "tag1 UID FETCH <lastseenuid+1>:* (FLAGS)".

1) 发出“tag1 UID FETCH<lastseenuid+1>:*(标志)”。

2) Construct UID set <old_uids> from the responses of step 1.

2) 根据步骤1的响应构造UID集<old_uids>。

3) Issue "tag2 SEARCH UID <old_uids> SMALLER <message_limit>". Construct UID set <required_messages> from the result of the SEARCH command.

3) 发出“tag2搜索UID<旧UID>更小<消息限制>”。根据搜索命令的结果构造UID set<required\u messages>。

4) Issue "tag3 UID FETCH <required_messages> (BODY.PEEK[])".

4) 发出“tag3 UID FETCH<required_messages>(BODY.PEEK[])”。

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.

1) 发出“tag1 UID FETCH<lastseenuid+1>:*(FLAGS BODY.PEEK[]<0.<length>>)”,其中<length>应替换为客户端愿意下载的最大消息大小。

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.

注意:响应此命令,如果消息长度超过<length>,服务器将只返回部分数据。它将返回大小小于或等于<length>的任何消息的完整消息数据。在前一种情况下,客户端将无法从截断的数据中提取消息的完整MIME结构,因此客户端还应该在UID FETCH命令中包含BODYSTRUCTURE。

5. Implementation Considerations
5. 实施考虑

Below are listed some common implementation pitfalls that should be considered when implementing a disconnected client.

下面列出了在实现断开连接的客户端时应考虑的一些常见实现陷阱。

1) Implementing fake UIDs on the client.

1) 在客户端上实现假UID。

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.

计划上载的邮件没有UID,因为服务器选择了UID。客户端可能在内部实现假UID,以便在进一步操作中引用尚未上载的消息。(例如,可以计划上载邮件,但随后将其标记为已删除或复制到其他邮箱)。在这里,客户端在任何情况下都不能向服务器发送这些假的UID。此外,应该提醒客户机实现者,根据[IMAP4],UID是一个32位无符号整数,不包括0。因此,4294967295和2147483648都是有效的UID,0和-1都是无效的。已知一些断开连接的邮件客户端在同步期间将负数(例如“-1”)作为消息UID发送到服务器。

Situation 1: The user starts composing a new message, edits it, saves it, continues to edit it, and saves it again.

情况1:用户开始编写新消息,编辑它,保存它,继续编辑它,然后再次保存它。

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.

断开连接的客户端可以在其重播日志(同步期间服务器上要重播的操作日志)中记录操作顺序,如下所示。在这种情况下,我们假设所有草稿邮件都存储在IMAP服务器上名为Drafts的邮箱中。我们还将使用以下约定:<old\u uid>是草稿第一次保存时的中间版本的uid。这是在客户端上生成的假UID<new_uid>是草稿最终版本的uid。这是在客户端上生成的另一个假UID。

1) APPEND Drafts (\Seen $MDNSent \Drafts) {<nnn>} ...first version of the message follows...

1) 追加草稿(\Seen$MDNSent\Drafts){<nnn>}…消息的第一个版本如下。。。

2) APPEND Drafts (\Seen $MDNSent \Drafts) {<mmm>} ...final version of the message follows...

2) 追加草稿(\Seen$MDNSent\Drafts){<mmm>}…消息的最终版本如下。。。

      3) STORE <old_uid> +FLAGS (\Deleted)
        
      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.

步骤1对应于第一次尝试保存草稿消息,步骤2对应于第二次尝试保存草稿消息,步骤3删除步骤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.

原始断开连接的客户端可以在步骤3中发送命令,而无需将生成的伪客户端<old\u uid>替换为服务器在步骤1中返回的值。服务器可能会拒绝此命令,这将使客户端认为同步序列已失败。

2) Section 5.1 discusses common implementation errors related to error recovery during playback.

2) 第5.1节讨论了回放期间与错误恢复相关的常见实现错误。

3) Don't assume that the disconnected client is the only client used by the user.

3) 不要假设断开连接的客户端是用户使用的唯一客户端。

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.

情况2:某些客户端可能使用\已删除标志作为指示,表明该消息不应出现在用户视图中。出于此目的使用\Deleted标志是不安全的,因为其他客户端(如在线客户端)可能随时删除邮箱。

4) Beware of data dependencies between synchronization operations.

4) 注意同步操作之间的数据依赖关系。

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.

对于客户端编写器来说,对回放日志执行一些优化可能非常诱人。此类优化可能包括删除冗余操作(例如,请参阅第5.3节中的优化2)或重新排序。

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.

在同步过程中重新排序或删除冗余操作并不总是安全的,因为某些操作可能具有依赖性(如情况3所示)。因此,如果有疑问,不要这样做。

Situation 3: The user copies a message out of a mailbox and then deletes the mailbox.

情形3:用户从邮箱复制邮件,然后删除邮箱。

         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
        
         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.

如果客户端先执行删除(标记A016),然后执行复制(标记A002),则复制失败。此外,用户如此小心地复制到另一个邮箱的邮件已丢失。

5.1. Error Recovery during Playback
5.1. 回放期间的错误恢复

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.

1) 与服务器的连接中断。

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.

客户端必须记住回放(replay)日志中的当前位置,并在下次成功连接到同一服务器时,从中断的操作(客户端发出的最后一个命令,但服务器未确认)开始对其进行回放。如果在执行非幂等IMAP命令时丢失了连接(请参见第1节中的定义),那么当客户端重新连接时,它必须确保中断的命令确实没有执行。如果没有执行,客户端必须从中断的命令重新启动播放,否则从以下命令重新启动播放。

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).

重新连接后,必须小心,以便正确地重新应用由多个IMAP命令表示的逻辑操作,例如,当服务器不支持UID EXPUNGE时的UID EXPUNGE仿真(请参阅第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.)

2) 正在将邮件复制/附加到不存在的邮箱。(服务器通过向APPEND或COPY命令发送标记无响应中的TRYCREATE响应代码来通告此条件。)

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.

a) 尝试重新创建邮箱。b) 将邮件复制/上载到其他邮箱。c) 跳过复制/上载。d) 中止重播。

3) Copying messages from a mailbox that doesn't exist, or renaming or getting/changing ACLs [ACL] on a mailbox that doesn't exist:

3) 从不存在的邮箱复制邮件,或重命名或获取/更改不存在的邮箱上的ACL[ACL]:

a) Skip operation. b) Abort replay.

a) 跳过操作。b) 中止重播。

4) Deleting mailboxes or deleting/expunging messages that no longer exist.

4) 删除邮箱或删除/删除不再存在的邮件。

This is actually is not an error and should be ignored by the client.

这实际上不是一个错误,客户端应该忽略它。

5) Performing operations on messages that no longer exist.

5) 对不再存在的消息执行操作。

a) Skip operation. b) Abort replay.

a) 跳过操作。b) 中止重播。

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.

注1:多个同步操作映射到多个IMAP命令(例如,4.2.2中描述的“移动”)。客户机必须保证每个这样的多步骤操作的原子性。例如,在同一服务器上的两个邮箱之间执行“移动”时,如果服务器无法复制邮件,则客户端不得尝试在要复制的邮件上设置\Deleted标志,更不用说删除它们了。但是,即使服务器无法在复制的消息上设置\删除的标志,客户端也可以认为移动操作已经成功。

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).

注2:许多同步操作都有数据依赖关系。失败的操作必须导致所有相关操作也失败。客户机应该检查这一点,不能盲目地执行所有相关操作(除非用户纠正了原始问题)。例如,可以将消息调度为附加到服务器上的邮箱,并且稍后可以将附加的消息复制到另一个邮箱。如果追加操作失败,客户端以后不得尝试复制失败的消息。(另见第5节情况3)。

5.2. Quality of Implementation Issues
5.2. 执行质量问题

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.

1) 不要丢失信息。

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.

2) 除非明确要求,否则不要做工作。要灵活。如果可能,在开始同步之前询问所有问题。

3) Minimize traffic.

3) 尽量减少交通。

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.

如果服务器支持UIDPLUS扩展,则客户端必须使用它。

See also optimization 1 in Section 5.3.

另见第5.3节中的优化1。

4) Minimize the number of round-trips.

4) 尽量减少往返次数。

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.

往返会降低性能,尤其是在延迟时间较长的链路上。第4.2.2.5节和第5.2节就如何尽量减少往返次数给出了一些建议。

See also optimization 1 in Section 5.3.

另见第5.3节中的优化1。

5.3. Optimizations
5.3. 优化

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.

1) 初始确认或预授权响应可能包含[IMAP4]第7.1节所述的能力响应代码。此响应代码提供的信息与CAPABILITY命令*返回的信息相同。注意此响应代码的断开连接的客户端可以避免发送能力命令,并将节省往返时间。

* 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.

* 注意:某些服务器在功能响应代码扩展中报告,这些扩展仅在未经验证的状态或所有状态下相关。此类服务器通常在使用登录或身份验证命令成功进行身份验证后发送另一个功能响应代码(不协商安全层;参见[IMAP4]第6.2.2节)。成功登录/身份验证时发送的功能响应代码可能与初始OK响应中的功能响应代码不同,因为仅与未经身份验证状态相关的扩展将不会被通告,并且一些仅在已验证和/或选定状态下可用的附加扩展将被通告。

Example 9:

例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)
        
   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):

2) 高级断开连接的客户端可以选择优化其重播日志。例如,可能存在一些冗余操作(列表不完整):

      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.
        
      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)

优化时,请注意命令之间的数据依赖关系。例如,如果客户希望优化(见上文案例b)

      tag1 UID STORE <uid1> +FLAGS (\Deleted)
      ...
      tag2 UID STORE <uid1> +FLAGS (\Flagged)
      ...
      tag3 UID COPY <uid1> "Backup"
      ...
      tag4 UID EXPUNGE <uid1>
        
      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.

它无法删除第二个UID STORE命令,因为在删除消息之前正在复制该消息。

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.

通常,如果可能的话,在同步过程中保持邮箱打开可能是一个好主意(请参见上面的案例c)。这可以结合下面描述的优化3更容易地实现。

3) Perform some synchronization steps in parallel, if possible.

3) 如果可能,并行执行一些同步步骤。

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.

为了实现这种并行化,客户端必须打开到同一服务器的多个连接。客户端编写者不应该忘记与建立TCP连接和执行身份验证相关的非平凡成本。断开连接的客户端不能对每个邮箱使用一个连接。在大多数情况下,有两个连接就足够了。断开连接的客户端应避免在多个连接中选择同一邮箱;详见[RFC2683]第3.1.1节。

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.

任何邮箱同步都必须从检查本文档第4.1节中所述的UID有效性开始。客户端可以使用STATUS命令检查未选择邮箱的UID有效性。这比打开同一服务器的多个连接以同时执行多个邮箱的同步更可取。如[IMAP4]第5.3.10节所述,这不应用于所选邮箱。

6. IMAP Extensions That May Help
6. 可能有帮助的IMAP扩展

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.

1) 第4.1、4.2.1、4.2.2.1和4.2.4节讨论了[UIDPLUS]的使用。

2) The use of the MULTIAPPEND and LITERAL+ extensions for uploading messages is discussed in Section 4.2.2.5.

2) 第4.2.2.5节讨论了如何使用MULTIAPPEND和LITERAL+扩展上传消息。

3) Use the CONDSTORE extension (see Section 6.1) for quick flag resynchronization.

3) 使用CONDSTORE扩展(参见第6.1节)进行快速标志重新同步。

6.1. CONDSTORE Extension
6.1. 调味品分店

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.

当服务器支持[CONDSTORE]扩展时,高级断开连接的邮件客户端应使用该扩展。客户端必须缓存邮箱打开时收到的HIGHESTMODSEQ OK响应代码中的值,并在服务器发送MODSEQ FETCH数据项时更新该值。

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.

如果客户端接收到NOMODSEQ OK Untaged响应而不是HIGHESTMODSEQ,则必须从其缓存中删除最后一个已知的HIGHESTMODSEQ值,并遵循第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.

当客户端打开邮箱进行同步时,它首先比较UID的有效性,如第3节中步骤d-1所述。如果缓存的UIDVality值与服务器返回的值匹配,则客户端必须将缓存的HIGHESTMODSEQ值与服务器返回的值进行比较。如果缓存的HIGHESTMODSEQ值也与服务器返回的值匹配,则客户端不能获取缓存消息的标志,因为它们没有更改。如果服务器上的值高于缓存的值,则客户端可以使用“SEARCH MODSEQ<cached value>”查找自上次客户端联机并打开邮箱以来标志已更改的所有邮件。或者,客户端可以使用“fetch1:*(标志)(CHANGEDSINCE<cached value>)”。后一种操作结合了搜索更改的消息和获取新信息。

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:

第4节中的步骤d(“服务器到客户端同步”)在CONDSTORE扩展存在的情况下修改如下:

d) "Server-to-client synchronization" - For each mailbox that requires synchronization, do the following:

d) “服务器到客户端同步”-对于每个需要同步的邮箱,请执行以下操作:

1a) Check the mailbox UIDVALIDITY (see section 4.1 for more details) with SELECT/EXAMINE/STATUS.

1a)使用选择/检查/状态检查邮箱UID的有效性(有关更多详细信息,请参阅第4.1节)。

If the UIDVALIDITY value returned by the server differs, the client MUST

如果服务器返回的UIDVality值不同,则客户端必须

* 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;

* 清空该邮箱的本地缓存;*“忘记”邮箱的缓存HIGHESTMODSEQ值;*删除该邮箱中引用UID的任何挂起的“操作”(请注意,这不会影响对客户端生成的伪UID执行的操作;请参阅第5节);和*跳过步骤1b和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.

1b)检查邮箱高度ModSeq。如果缓存的值与服务器返回的值相同,则跳过步骤2-II上的获取消息标志,即客户端只需找出哪些消息被删除。

2) Fetch the current "descriptors".

2) 获取当前的“描述符”。

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>".

二) 使用“FETCH 1:*(flags)(CHANGEDSINCE<cached value>)”或“SEARCH MODSEQ<cached value>”,发现对旧消息和新消息标志的更改。

Discover expunged messages; for example, using "UID SEARCH 1:<lastseenuid>". (All messages not returned in this command are expunged.)

发现已删除的邮件;例如,使用“UID搜索1:<lastseenuid>”。(此命令中未返回的所有消息都将被删除。)

3) Fetch the bodies of any "interesting" messages that the client doesn't already have.

3) 获取客户端还没有的任何“有趣”消息的主体。

Example 10:

例10:

The UIDVALIDITY value is the same, but the HIGHESTMODSEQ value has changed on the server while the client was offline.

UIDVALIDITY值相同,但客户端脱机时服务器上的HIGHESTMODSEQ值已更改。

      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
        
      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
        
      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:

或:

      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
        
      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
7. 安全考虑

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].

据信,本文件不会提出任何新的安全问题,而这些问题在基本[IMAP4]协议中尚未出现,这些问题将在[IMAP4]中讨论。在本文件中提到的不同扩展中可以找到其他安全注意事项;特别是在[UIDPLUS]、[LITERAL+]、[CONDSTORE]、[MULTIAPPEND]和[UNSELECT]中。

Implementers are also reminded about the importance of thorough testing.

还提醒实施者彻底测试的重要性。

8. References
8. 工具书类
8.1. Normative References
8.1. 规范性引用文件

[KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

[关键词]Bradner,S.,“RFC中用于表示需求水平的关键词”,BCP 14,RFC 2119,1997年3月。

[IMAP4] Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1", RFC 3501, March 2003.

[IMAP4]Crispin,M.,“互联网消息访问协议-版本4rev1”,RFC 35012003年3月。

[UIDPLUS] Crispin, M., "Internet Message Access Protocol (IMAP) - UIDPLUS extension", RFC 4315, December 2005.

[UIDPLUS]Crispin,M.,“互联网消息访问协议(IMAP)-UIDPLUS扩展”,RFC 4315,2005年12月。

[LITERAL+] Myers, J., "IMAP4 non-synchronizing literals", RFC 2088, January 1997.

[LITERAL+]Myers,J.,“IMAP4非同步文字”,RFC2088,1997年1月。

[CONDSTORE] Melnikov, A. and S. Hole, "IMAP Extension for Conditional STORE Operation or Quick Flag Changes Resynchronization", RFC 4551, June 2006.

[CONDSTORE]Melnikov,A.和S.Hole,“条件存储操作或快速标志更改再同步的IMAP扩展”,RFC 45512006年6月。

[MULTIAPPEND] Crispin, M., "Internet Message Access Protocol (IMAP) - MULTIAPPEND Extension", RFC 3502, March 2003.

[MULTIAPPEND]Crispin,M.,“互联网消息访问协议(IMAP)-多附加扩展”,RFC 35022003年3月。

[UNSELECT] Melnikov, A., "Internet Message Access Protocol (IMAP) UNSELECT command", RFC 3691, February 2004.

[UNSELECT]Melnikov,A.,“互联网消息访问协议(IMAP)UNSELECT命令”,RFC 3691,2004年2月。

[RFC2683] Leiba, B., "IMAP4 Implementation Recommendations", RFC 2683, September 1999.

[RFC2683]Leiba,B.,“IMAP4实施建议”,RFC 2683,1999年9月。

8.2. Informative References
8.2. 资料性引用

[ACL] Melnikov, A., "IMAP4 Access Control List (ACL) Extension", RFC 4314, December 2005.

[ACL]Melnikov,A.,“IMAP4访问控制列表(ACL)扩展”,RFC 4314,2005年12月。

[IMAP-MODEL] Crispin, M., "Distributed Electronic Mail Models in IMAP4", RFC 1733, December 1994.

[IMAP-MODEL]Crispin,M.,“IMAP4中的分布式电子邮件模型”,RFC 1733,1994年12月。

9. Acknowledgements
9. 致谢

This document is based on version 01 of the text written by Rob Austein in November 1994.

本文件基于Rob Austein于1994年11月编写的文本01版。

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.

编辑感谢Mark Crispin在IMAP邮件列表中发表的评论以及Grant Baillie、Cyrus Daboo、John G.Myers、Chris Newman和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.

编辑还要感谢Netscape Messenger和Mozilla邮件客户端的开发人员提供了断开连接的邮件客户端的示例,这些示例是本文中许多建议的基础。

Editor's Address

编辑地址

Alexey Melnikov Isode Limited 5 Castle Business Village 36 Station Road Hampton, Middlesex TW12 2BX United Kingdom

英国米德尔塞克斯郡汉普顿车站路36号城堡商业村5号Alexey Melnikov Isode Limited TW12 2BX

   Phone: +44 77 53759732
   EMail: alexey.melnikov@isode.com
        
   Phone: +44 77 53759732
   EMail: alexey.melnikov@isode.com
        

Full Copyright Statement

完整版权声明

Copyright (C) The Internet Society (2006).

版权所有(C)互联网协会(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.

本文件受BCP 78中包含的权利、许可和限制的约束,除其中规定外,作者保留其所有权利。

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.

IETF对可能声称与本文件所述技术的实施或使用有关的任何知识产权或其他权利的有效性或范围,或此类权利下的任何许可可能或可能不可用的程度,不采取任何立场;它也不表示它已作出任何独立努力来确定任何此类权利。有关RFC文件中权利的程序信息,请参见BCP 78和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.

向IETF秘书处披露的知识产权副本和任何许可证保证,或本规范实施者或用户试图获得使用此类专有权利的一般许可证或许可的结果,可从IETF在线知识产权存储库获取,网址为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.

IETF邀请任何相关方提请其注意任何版权、专利或专利申请,或其他可能涵盖实施本标准所需技术的专有权利。请将信息发送至IETF的IETF-ipr@ietf.org.

Acknowledgement

确认

Funding for the RFC Editor function is provided by the IETF Administrative Support Activity (IASA).

RFC编辑器功能的资金由IETF行政支持活动(IASA)提供。