Skip to main content

2. 协议概述 (Protocol Overview)

IMAP4rev2 协议假定存在可靠的数据流,例如 TCP 提供的数据流. 当使用 TCP 时,IMAP4rev2 服务器在端口 143 (明文端口) 或端口 993 (隐式 TLS 端口) 上监听.

2.2 命令和响应 (Commands and Responses)

IMAP4rev2 连接 (Connection) 由客户端/服务器网络连接的建立、来自服务器的初始问候以及客户端/服务器交互组成. 这些客户端/服务器交互由客户端命令 (Client Command)、服务器数据 (Server Data) 和服务器完成结果响应 (Server Completion Result Response) 组成.

客户端和服务器传输的所有交互都采用行的形式,即以 CRLF 结尾的字符串. IMAP4rev2 客户端或服务器的协议接收器读取的是一行或已知计数的八位字节序列后跟一行.

2.2.1 客户端协议发送器和服务器协议接收器 (Client Protocol Sender and Server Protocol Receiver)

客户端命令开始一个操作. 每个客户端命令都以一个标识符作为前缀,该标识符称为"标签" (Tag) (通常是一个短的字母数字字符串,例如 A0001、A0002 等). 客户端为每个命令生成不同的标签. 更正式地说:客户端应该 (SHOULD) 为每个命令生成唯一的标签,但服务器必须 (MUST) 接受标签重用.

客户端必须 (MUST) 严格遵循本规范中概述的语法. 发送缺少或多余空格或参数的命令是语法错误.

有两种情况下,来自客户端的行不代表完整的命令. 在一种情况下,命令参数用八位字节计数引用 (参见第 4.3 节中字面量 (Literal) 的描述),在另一种情况下,命令参数需要服务器反馈 (参见第 6.2.2 节中的 AUTHENTICATE 命令). 在任一情况下,如果服务器已准备好接收八位字节 (如果适用) 和命令的其余部分,则服务器发送命令继续请求响应 (Command Continuation Request Response). 此响应以标记 "+" 为前缀.

注意:相反,如果服务器在命令中检测到错误,它会发送带有与命令匹配的标签的 BAD 完成响应 (如下所述) 来拒绝命令并防止客户端发送更多命令.

也可能服务器为其他某个命令发送完成响应 (如果多个命令正在进行中) 或未标记的数据 (Untagged Data). 无论哪种情况,命令继续请求仍处于挂起状态,客户端对响应采取适当的操作并从服务器读取另一个响应. 在所有情况下,客户端必须 (MUST) 先发送完整的命令 (包括接收所有命令继续请求响应并为命令发送命令继续) 才能启动新命令.

IMAP4rev2 服务器的协议接收器从客户端读取命令行,解析命令及其参数,并传输服务器数据和服务器命令完成结果响应.

2.2.2 服务器协议发送器和客户端协议接收器 (Server Protocol Sender and Client Protocol Receiver)

服务器向客户端传输的数据和不表示命令完成的状态响应以标记 "*" 为前缀,称为未标记响应 (Untagged Responses).

服务器数据可以 (MAY) 作为客户端命令的结果发送,也可以 (MAY) 由服务器单方面发送. 由特定命令产生的服务器数据和单方面发送的服务器数据之间没有语法差异.

服务器完成结果响应指示操作的成功或失败. 它使用与开始操作的客户端命令相同的标签进行标记. 因此,如果有多个命令正在进行中,服务器完成响应中的标签标识该响应适用的命令. 有三种可能的服务器完成响应:OK (表示成功)、NO (表示失败) 或 BAD (表示协议错误,例如无法识别的命令或命令语法错误).

服务器发送给客户端的响应和数据不得 (MUST NOT) 使用未在正式语法 (Formal Syntax) 中描述的命令标签.

服务器完成结果响应可以包含可选的响应代码 (Response Code),它提供有关完成状态的其他信息. 响应代码由括号 ([...]) 括起来的数据组成. 不理解特定响应代码的客户端必须 (MUST) 能够接受该响应代码,而不会产生不良影响. 这意味着任何响应代码都可以安全地添加到任何完成响应,而不会对旧客户端造成问题.

IMAP4rev2 客户端的协议接收器从服务器读取响应并适当地处理它.


2.3 消息属性 (Message Attributes)

除了消息文本 (Message Texts) 之外,每条消息还具有几个属性 (Attributes),这些属性与消息相关联. 这些属性可以按消息序列号 (Message Sequence Number) 或唯一标识符 (Unique Identifier, UID) 检索.

2.3.1 消息号 (Message Numbers)

消息有两种形式的标识符:消息序列号和唯一标识符 (UID).

2.3.1.1 唯一标识符 (UID) 消息属性 (Unique Identifier (UID) Message Attribute)

唯一标识符 (Unique Identifier, UID) 是与消息关联的 32 位非零无符号整数值. UID 的主要目的是为消息提供在多个 IMAP 会话 (Sessions) 中保持持久性的标识符. 服务器必须 (MUST) 确保为邮箱中的每条消息分配唯一的 UID.

与消息序列号不同,消息的 UID 严格递增 (但不一定是连续的),即使在会话期间也是如此. 服务器必须 (MUST) 确保,如果将新消息添加到邮箱,则新消息的 UID 大于邮箱中任何现有消息的 UID.

UID 的唯一性和严格递增特性的一个例外是 UID 有效性值 (UIDVALIDITY Value). UIDVALIDITY 值与邮箱关联,并随邮箱一起返回 (例如,在 SELECT 和 EXAMINE 响应中). UIDVALIDITY 值用于检测邮箱中的 UID 是否已被重置.

UIDVALIDITY 值必须 (MUST) 大于零. UIDVALIDITY 值的主要目的是在无法保持 UID 持久性的情况下提供保证. 例如,在以下情况下,服务器必须 (MUST) 在将来的会话中使用不同的 UIDVALIDITY 值:

  1. 一个邮箱必须 (MUST) 分配一个新的 UIDVALIDITY 值,如果现有 UID 对应的消息在邮箱中不再有效. 例如,如果邮箱被删除和重新创建.

  2. 为了清楚起见:如果删除了一个旧的邮箱且创建了具有相同名称的新邮箱,新邮箱必须 (MUST) 具有与旧邮箱不同的 UIDVALIDITY 值.

  3. 不得 (MUST NOT) 将邮箱从一个 IMAP 服务器移动到另一个 IMAP 服务器而不更改其 UIDVALIDITY 值,除非两个 IMAP 服务器提供对公共邮箱存储库的访问权限. 特殊情况:服务器可以 (MAY) 使用不同的 UIDVALIDITY 值将邮箱重新分配给不同的用户,同时保留相同的名称. 例如,如果 "user1" 的邮箱被删除,然后具有相同名称的邮箱稍后分配给 "user2",则服务器必须 (MUST) 将新的 UIDVALIDITY 值分配给邮箱的新实例.

  4. 邮箱名称、UIDVALIDITY 和 UID 的组合必须 (MUST) 永远引用该服务器上的单个不可变 (或已删除) 消息. 特别是,内部日期 (Internal Date)、RFC822.SIZE、信封 (Envelope)、正文结构 (Body Structure) 和消息文本 (所有 BODY[...] 获取数据项) 绝不能 (MUST) 更改. 这不包括消息序列号,也不包括可以通过 STORE 命令设置的属性 (例如 FLAGS). 当消息被删除时,其 UID 不得 (MUST NOT) 在相同的 UIDVALIDITY 值下重用.

2.3.1.2 消息序列号消息属性 (Message Sequence Number Message Attribute)

消息序列号 (Message Sequence Number) 是从 1 到邮箱中消息数的相对位置. 此位置必须 (MUST) 按升序唯一标识符排序. 当添加每条新消息时,它被分配的消息序列号比添加该新消息之前邮箱中的消息数大 1.

消息序列号可以在会话期间重新分配. 例如,当消息从邮箱中永久删除 (expunged) 时,所有后续消息的消息序列号都会递减. 邮箱中的消息数也会递减. 同样,新消息可以被分配一个在删除之前由其他消息持有的消息序列号.

除了通过邮箱中的相对位置访问消息外,消息序列号还可以用于数学计算. 例如,如果收到未标记的 "11 EXISTS",并且之前收到了未标记的 "8 EXISTS",则有三条新消息到达,消息序列号为 9、10 和 11. 作为另一个例子,如果 523 条消息邮箱中的消息 287 的 UID 为 12345,则恰好有 286 条消息的 UID 较小,236 条消息的 UID 较大.

2.3.2 标志消息属性 (Flags Message Attribute)

消息具有与之关联的零个或多个命名标记 (Named Tokens) 的列表,称为"标志" (Flags). 通过将标志添加到此列表来设置标志,通过删除标志来清除标志. IMAP4rev2 中有两种类型的标志:系统标志 (System Flags) 和关键字 (Keywords). 任一类型的标志都可以是永久的或仅会话的.

系统标志是在本规范中预定义并以 "" 开头的标志名称. 某些系统标志 (\Deleted 和 \Seen) 具有本文档其他地方描述的特殊语义. 当前定义的系统标志有:

  • \Seen - 消息已被阅读
  • \Answered - 消息已被回复
  • \Flagged - 消息被"标记"为紧急/特别关注
  • \Deleted - 消息被"标记为删除",以便稍后通过 EXPUNGE 删除
  • \Draft - 消息尚未完成撰写 (标记为草稿)
  • \Recent - 此标志在 IMAP4rev1 中使用,现已弃用

关键字 (Keyword) 由服务器实现定义. 关键字不以 "" 开头. 服务器可以 (MAY) 允许客户端在邮箱中定义新关键字 (有关更多信息,请参见 PERMANENTFLAGS 响应代码的描述). 一些以 "$" 开头的关键字也在本规范中定义.

本文档定义了几个最初未在 [RFC3501] 中定义但被客户端实现发现有用的关键字. 服务器实现应该 (SHOULD) 支持这些关键字 (在 SEARCH 中允许,并在 APPEND、COPY 和 MOVE 命令中允许和保留):

$Forwarded
消息已通过嵌入或附加到新消息的方式转发到另一个电子邮件地址. 当电子邮件客户端成功将消息转发到另一个电子邮件地址时,它会设置此关键字. 此关键字的典型用法是为已转发的消息显示不同 (或附加) 的图标. 一旦设置,该标志不应该 (SHOULD NOT) 被清除.

$MDNSent
已为此消息生成并发送消息处理通知 (Message Disposition Notification) [RFC8098]. 有关如何使用此关键字以及对客户端和服务器的要求的更多详细信息,请参见 [RFC3503].

$Junk
用户 (或代表用户的投递代理) 可以选择将消息标记为肯定包含垃圾邮件 ($Junk,另请参见相关关键字 $NotJunk). $Junk 关键字可用于标记、分组或隐藏不需要的消息 (此类消息稍后可能会被移动或删除). 有关更多信息,请参见 [IMAP-KEYWORDS-REG].

$NotJunk
用户 (或代表用户的投递代理) 可以选择将消息标记为肯定不包含垃圾邮件 ($NotJunk,另请参见相关关键字 $Junk). $NotJunk 关键字可用于标记、分组或显示用户想要查看的消息. 有关更多信息,请参见 [IMAP-KEYWORDS-REG].

$Phishing
$Phishing 关键字可以由投递代理用来将消息标记为极有可能是钓鱼电子邮件. 投递代理确定为钓鱼电子邮件的消息也应被视为垃圾邮件,并应用适当的垃圾邮件过滤,包括设置 $Junk 标志并将消息放置在 \Junk 特殊用途邮箱中 (参见第 7.3.1 节,如果可用).

如果同时设置了 $Phishing 标志和 $Junk 标志,用户代理应该 (SHOULD) 向用户显示附加警告消息. 此外,当用户单击消息中的任何超链接时,用户代理可能会显示警告,例如"此消息可能试图窃取您的个人信息".

在用户代理显示警告之前要求同时设置 $Phishing 和 $Junk 是为了与理解 $Junk 标志但不理解 $Phishing 标志的现有客户端更好地向后兼容. 这是为了当未扩展的客户端删除 $Junk 标志时,扩展的客户端也将显示正确的状态. 有关更多信息,请参见 [IMAP-KEYWORDS-REG].

$Junk 和 $NotJunk 是互斥的. 如果为一条消息设置了多个这些标志,客户端必须 (MUST) 将其视为未设置任何一个,并且应该 (SHOULD) 在 IMAP 服务器上取消设置这两个标志.

其他已注册的关键字可以在"IMAP 和 JMAP 关键字"注册表 [IMAP-KEYWORDS-REG] 中找到. 新关键字应该 (SHOULD) 使用 [RFC5788] 中指定的程序在此注册表中注册.

标志可以基于每个标志是永久的或仅会话的. 永久标志 (Permanent Flags) 是客户端可以从消息标志中永久添加或删除的标志,即并发和后续会话将看到永久标志的任何更改. 对会话标志 (Session Flags) 的更改仅在该会话中有效.

2.3.3 内部日期消息属性 (Internal Date Message Attribute)

内部日期 (Internal Date) 消息属性是服务器上消息的内部日期和时间. 这不是 [RFC5322] 标头中的日期和时间,而是反映消息何时被接收的日期和时间. 对于通过 [SMTP] 传递的消息,这是 [SMTP] 定义的消息最终传递的日期和时间. 对于由 IMAP4rev2 COPY 或 APPEND 命令创建的消息,这是那些命令指定的日期和时间.

2.3.4 RFC822.SIZE 消息属性 (RFC822.SIZE Message Attribute)

RFC822.SIZE 是消息以 [RFC5322] 格式表示时的八位字节数. 此大小应该 (SHOULD) 与 "FETCH BODY[]" 命令的结果匹配. 如果消息在内部以其他格式存储,服务器会计算大小并经常存储它以供以后使用,以避免需要重新计算.

2.3.5 信封结构消息属性 (Envelope Structure Message Attribute)

信封结构 (Envelope Structure) 是消息的 [RFC5322] 标头的解析表示. 请注意,IMAP 信封结构与 [SMTP] 信封不同.

2.3.6 正文结构消息属性 (Body Structure Message Attribute)

正文结构 (Body Structure) 是消息的 [MIME-IMB] 正文结构信息的解析表示.

2.4 消息文本 (Message Texts)

除了能够获取消息的完整 [RFC5322] 文本之外,IMAP4rev2 还允许获取完整消息文本的部分内容. 具体来说,可以获取 [RFC5322] 消息标头 (Message Header)、[RFC5322] 消息正文 (Message Body)、[MIME-IMB] 正文部分 (Body Part) 或 [MIME-IMB] 标头.