因特网邮件访问协议,版本4rev1(IMAP4rev1)允许一个客户端访问和操作在一个服务器上的电子邮件。IMAP4rev1允许,以一种功能上等效于本地文件夹的方式,操作邮箱(远程邮件文件夹)。IMAP4rev1也提供这样一个功能,一个离线客户端与服务器异步(交互)。
IMAP4rev1包括以下操作:创建、删除、及重命名邮箱,检查新邮件,永久删除邮件,设置和清除标记,RFC2822及RFC2045解析,检索,及选择性的获取邮件属性,文本,及其中的一部分。IMAP4rev1中的邮件通过使用数字访问。这些数字或者是邮件序列号,或者是唯一标识符。
IMAP4rev1支持单个服务器。访问注册信息以支持多个IMAP4rev1服务器的机制在RFC2244中讨论。
IMAP4rev1不详述邮递邮件的方法;该职责由如RFC2821的某种邮件传输协议完成。
目录
IMAP4rev1协议规范
1. 如何阅读本文
1.1. 本文的结构
本文是基于一个IMAP4rev1客户端或者服务器的视点写的。第2章超出了本协议的范畴,对某些人而言,试图理解本协议的操作是不现实的。第3到第5章提供了IMAP4rev1操作的总体脉络和概念。
第6、7、9章分别描述了IMAP的命令、响应和语法。三者之间的联系如此紧密,甚至于我们几乎不可能独立地理解它们。特别的,不要试图单单从命令块推论命令语法,相反的,要参考正式语法。
1.2 本文用到的约定语
约定语用来描述基本的原理或者过程。本节将列出本文档的约定语。
例如,“C:”和“S:”分别表示由客户端和服务器发出的信息行。
“MUST”、“MUST NOT”、“REQUIRE”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“MAY”,及“OPTIONAL”这些基本的词,在本文中解释为[关键词]。
“can”(或者“may”)用来指出某种可能情况和条件,而不是该协议的任意一种功能。
“User”用来表示一个自然人,而“client”则用来表示用户运行的软件。
“Connection”表示从网络连接初始建立直至其结束的过程中,客户端、服务器间的整个、一连串的交互。
“Session”表示从选中一个邮箱(SELECT或者EXAMINE命令)直至选中结束(CLOSE命令,或者连接终止,另一个邮箱的SELECT或者EXAMINE命令)的过程中,客户端、服务器间的一连串交互。
没有特别说明时,字符串当作7位的US-ASCII处理。其它的字符集用“CHARSET”标识,与[MIME-IMT]中描述的、[CHARSET]中定义的是一样的。除了定义字符集,CHARSETs还有其它重要的语义,更多细节参考相关文档。
IMAP中有一些协议约定语。它们涉及到协议说明的某些方面,严格讲,这些方面不属于IMAP协议的部分,但是它们反映了被普遍认可的实践经验。协议的实现体需要考虑这些约定语,并避免冲突,不管实现这些约定语与否。例如,“&”不应该用作等级定义符――因为这与邮箱的网络命名约定冲突,而邮箱名称中“&”的其它使用则无碍。
1.3. 实现者需要特别注意的地方
强烈建议IMAP协议的实现者阅读与本文相关的[IMAP实现]的推荐文章,以利于理解这个协议的难点,及如何最好地创建一个有效沟通的产品。
IMAP4rev1设计成从[IMAP2]和未发布的IMAP2bis协议向上兼容。IMAP4rev1很好地兼容了RFC1730中描述的IMAP4协议;RFC1730中增加的、有异常的、被证实有问题的那些功能后来被删减了。在IMAP4rev1的发展历程中,早期的协议中某些方面遭到了废弃。[IMAP-OBSOLETE]中,描述了IMAP4rev1实现者使用早期的协议实现时,可能遇到的、废弃了的命令、响应及数据格式。
[IMAP-COMPAT]讨论了与IMAP2bis的其它兼容问题,与早期的协议的最一般性的差异。[IMAP-HISTORICAL]全面讨论了与[IMAP2]因罕见(被擅自主张者去除了)差异而产生的兼容问题;本文是历史关注的源头。
IMAP起初是为旧的[RFC-822]标准发展的,因此一些项目在它们的名称中把“RFC822”包含进来。除了RFC822.SIZE,还有更先进的取代;例如, RFC822.HEADER在新版中是BODY.PEEK[HEADER]。在所有案例中,“RFC822”应该解释为升级的[RFC-822]标准的参考。
2. 协议概述
2.1. 链路层
IMAP4rev1协议假定了类似TCP提供的可靠数据流。使用TCP时,IMAP4rev1服务器监听143端口。
2.2. 命令及响应
一次IMAP4rev1连接的组成有:一次客户端、服务器的网络连接的建立,服务器的初始欢迎,以及客户端、服务器的交互。这些客户端、服务器的交互由客户端命令、服务器数据和服务器的完成结果响应组成。
传送于客户端和服务器间的所有交互都是以行的形式,即,以一个CRLF为结束标志的字符串。一个IMAP4rev1客户端或者服务器的协议接收端要么是按行读取,要么是以一个已知的数值n,每次读取n个字节的串。
2.2.1. 客户端的协议发送和服务器端的协议接收
客户端命令引发操作。每个客户端命令以一个标识作为前缀(典型的有字母、数字构成的短字符串,如:A0001,A0002,等等)――它称为“标签”。客户端为每个命令生成不同的“标签”。
客户端必须严格遵守本说明中的语法大纲。发送缺损的命令,或者多余的空格、变量都属于语法错误。
客户端没有描述一个完整的命令,有两种情形。一种是,一个命令参数被以一个字节数引用(参看Data Formats下的String的原义描述);另一种是,命令参数要求服务器的反馈(参看AUTHENTICATE命令)。这再者中的任何一种情形下,服务器发送命令以不停地请求响应――如果为字节串(如果适当)和剩余命令准备就绪。响应用“+”作为前缀。
注意:而如果服务器发现命令的一个错误,它就发送一个带有匹配于命令(如下所描述的)的标签的BAD完整响应,以拒绝该命令,避免客户端再发送更多的命令。
服务器对一些其它的命令(如果多个命令相继发生)、或者非标签化的数据,请求发送完整的响应,这也是可能的。在两者中的任何一种情形下,连续的请求命令仍然是悬而不决的;客户端对响应采取相应的动作,并读取服务器的其它响应。所有情形下,客户端必须在初始化一个新的命令前发送一个完整命令(包括接收所有连续请求响应命令)
IMAP4rev1服务器端的协议接收端,从客户端读取命令行,解析该命令行及其参数,并传送服务器数据及一个服务器命令完成结果的响应。
2.2.2. 服务器端的协议发送和客户端的协议接收
那些没有标识命令完成的、被服务器传送至客户端的数据和状态响应,用“*”作为前缀,并称为非标签化的响应。
服务器数据可能被作为客户端命令的结果发送,或者可能被服务器单方面发送。源于特定命令的服务器数据,和单方面发送的服务器数据,二者之间没有语法上的差异。
服务器完成结果响应表示操作的成功或者失败。它具有与开始操作的客户端命令一样的标签。然而,如果有多于一个的命令在行进中,服务器完成响应的标签将标识该响应适用的命令。可能的服务器完成响应有三种:OK(表示成功),NO(表示失败),或者BAD(表示协议错误,如:未知命令,或者命令语法错误)。
服务器应当严格遵照本文档的语法大纲。任何带有协议语法错误,包括(但不限于)少了、多了空格或者参数,都应该被拒绝,并且服务器应当给客户端一个BAD服务器完成响应。
IMAP4rev1客户端的协议接收端从服务器读取一条响应行。它可以根据响应的第一个标记――可以是标签,一个“*”,或者一个“+”,做出动作作为响应。
客户端必须一直准备着接收任何服务器响应,包括非请求的服务器数据。服务器数据应当存储下来,以便客户端可以参照它存储的副本,而不是发送命令至服务器去请求数据。某些服务器数据则必须存储下来。
这个主题在服务器响应一节中有更细节的讨论。
2.3. 邮件属性
除了邮件文本,每个邮件都有一些与其相关的属性。这些属性可以被单独收回,或者与其它属性、或者邮件文本组合。
2.3.1. 邮件号
IMAP4rev1的邮件通过两个数值中的一个访问:唯一标识符,或者邮件序列号。
2.3.1.1. 唯一标识符(UID)的邮件属性
分配给每一个邮件的32位值,和唯一标识符的值(见下)形成一个64位的值,这个值永远不能指向这个邮箱中的其它任何邮件,或者它后面的同名邮箱。分配时,邮箱中的唯一标识符严格地按升序排列;每个邮件添加至邮箱时,它将被派予一个比它先加进来的邮件的唯一标识符更大的唯一标识符。与邮件序列号不同,唯一标识符可以是不连续的。
在其会话存活期,一个邮件的唯一标识符不能改变,也不应该在不同的会话间改变。唯一标识符在不同会话间的改变必须使用下面谈到的唯一标识符校验机制审查。永久唯一标识符要求客户端刷新其状态,以区别于与服务器的前面一个会话(例如:无连接,或者离线访问的客户端);这将在[IMAP-DISC]进一步地讨论。
与每个邮箱关联,有两个值维护着唯一标识符的指针:后续唯一标识符的值,和当前唯一标识符的值。
后续唯一标识符的值,是以后分配给这个邮箱中的新邮件的预留值。若非当前唯一标识符的值也改变了(见下),后续唯一标识符的值必须具有以下两个特点。第一,若非新的邮件被加进邮箱,后续唯一标识符的值不能改变;第二,一旦新的邮件被加进邮箱,后续唯一标识符必须改变,即使这些新的邮件随后被删除了。
注意:后续唯一标识符,是被用来提供这样一种手段,即客户端判断从上一次确认它的值后,是否有新的邮件被发送到邮箱。并不一定任何邮件都有唯一标识符。客户端只能推测,一旦它获得后续唯一标识符,此后到达的邮件的唯一标识符大于等于这个值。
当邮箱被选中时,唯一标识符的值将通过一个非标签化的OK响应的唯一标识符校验响应码发送。如果早先会话的唯一标识符不能永存于这个会话中,则唯一标识符的值必须大于早先会话的唯一标识符。
注意:理想情况下,唯一标识符可以一直永存。尽管本文档承认,不能永存的情况在特定服务器环境下是不可避免的,但我们极力鼓励避免这个问题的邮件存储实现技术。例如:
1)邮箱中的唯一标识符必须永远严格按升序排序。如果物理邮件存储被非IMAP代理刷新,则邮箱中的唯一标识符应当刷新,因为这种刷新(非IMAP代理刷新)导致旧的唯一标识符不再严格按升序排序了。
2)如果邮件存储没有唯一标识符的存储机制,那么它必须在每个会话刷新唯一标识符,并且每个会话必须具有一个唯一标识符校验值。
3)如果一个邮箱被删除,并且之后一个新的同名邮箱被创建,服务器必须保持区别于之前邮箱的唯一标识符的记录,或者分配给新邮箱一个新的唯一标识符校验码。在这里,一个好的唯一标识符校验码,是代表邮箱创建日期或者时间的32位数。使用一个常数,如1,是没问题的,但这只是在这样前提下――确保唯一标识符永远不再被使用,即使一个邮箱被删除(或者重命名),及一个新的同名邮箱不久被创建。
4)邮箱名、唯一标识符校验码、唯一标识符,三者的联合必须永远指向服务器上的一个固定邮件。特别的,实际日期、[RFC-2822]大小、邮戳、主体结构及邮件文本(RFC822、RFC822.HEADER、RFC822.TEXT、及所有BODY[…]获取数据项)必须永不改变。这并不包括邮件号、及可以通过一个STORE命令设置的属性(例如,FLAGS)。
2.3.1.2. 邮件序列号的邮件属性
邮箱中,从1到邮件总数的一个相对位置。这个位置必须是按升序排序了的唯一标识符。每当新的邮件被加进来,它就被分配一个比它加进来之前该邮箱中的邮件总数大1的邮件序列号。
在会话存活期,邮件序列号可以重新分配。例如,当一个邮件被从邮箱中永久删除,其后的所有邮件的邮件序列号就减小。邮箱的邮件总数也减小。类似的,一个新加进来的邮件将被分配一个邮件序列号――之前被删除了的其它邮件所持有的邮件序列号。
邮件序列号,不仅可以用于通过邮箱的相对位置访问邮件,还可以用于数学运算。例如,如果接收到一个非标签化的“11 EXISTS”,且之前接收了一个非标签化的“8 EXISTS”,那么,已经有邮件序列号为9、10、11的三个新邮件到达。另外一个例子,如果一个有523个邮件的邮箱中的邮件287的唯一标识符是12345,那么,实际上,该邮箱中,有286条邮件的唯一标识符小于12345,有236个邮件的唯一标识符大于12345.
2.3.2. 标记的邮件属性
与邮件相关联的一个0串或者已命名的符号串。向该串中新增时,设置一个标记,从该串中删除时,清除该标志。IMAP4rev1中有两种标记。两种标记的实例都可以是永久化的,或者会话化的。
系统标记是指在本文档中预告确定的。所有的系统标记以“/”开头。一些系统标记(/Deleted和/Seen)在其它地方的描述中有特殊的语义。目前定义的系统标记有:
/Seen
邮件已读
/Answered
邮件已回复
/Flagged
邮件标记为紧急或者特别注意。
/Deleted
邮件为删除状态。
/Draft
邮件未写完(标记为草稿状态)。
/Recent
邮件是新到达邮箱的。这个会话是关于这个邮件的第一个会话;如果这个会话是可读写的,后续会话将看不见这个邮件的/Recent设置符。客户端不能修改该标记。
一个会话,如果不能判断它是不是关于一个邮件的第一个会话,那么就应当考虑这个邮件是新的。
如果多个连接同时选中了同一个邮箱,哪个连接会看到带有/Recent设置符的、新到达的邮件,哪个连接会看到没有/Recent设置符的邮件,这还没有定义。
关键词是由服务器实现体定义的。关键词并不以“/”开头。服务器可以允许客户端定义新邮箱中的关键词(更多信息参看PERMANENTFLAGS响应码的描述)。
一个标记可以是永久的,或者会话化的(标记的生命周期为某个会话)。对于永久标记,客户端可以增加,或者从邮件标记集中永久删除;即,当前和后续会话将可以看见永久标记集中的任何变化。对会话标记的改变只在其会话内是可视的。
注意:/Recent系统标记是会话标记的一个特例。/Recent不能在一个STORE或者APPENT命令中作为一个变量,也不能被改变。
2.3.3. 实际日期的邮件属性
服务器上邮件的实际日期和时间。它是反映何时接收到邮件的日期和时间,而不是[RFC-2822]头部中的日期和时间。按照SMTP的定义,通过SMTP发送的邮件,其实际日期和时间反映的是这个邮件的最后发送日期和时间。通过IMAP4rev1的APPEND命令发送的邮件,其实际日期和时间反映的是APPEND命令描述中所指定的。其它情形下,实际日期和时间遵照实现体的定义。
2.3.4. [RFC-2822]大小的邮件属性
同于[RFC-2822]版中的表述,即邮件中的字节串的长度。
2.3.5. 信封结构的邮件属性
[RFC-2822]邮件头部的一个语法表示。注意,IMAP信封结构与SMTP的不同。
2.3.6. 主体结构的邮件属性
[MIME-IMB]邮件主体结构信息的解析表示。
2.4. 邮件文本
IMAP4rev1允许获取邮件的全部[RFC-2822]文本,也允许获取它的一部分。特别的,获取[RFC-2822]邮件头部、[RFC-2822]邮件主体、一个[MIME-IMB]主体部分、或者一个[MIME-IMB]头部,也是可以的。
3. 状态和流程图
一旦客户端和服务器间的连接建立完成,一个IMAP4rev1连接就会处于4种状态中的某一种。初始状态在服务器的欢迎中标识。大多数命令只在特定的状态中才是正确的。当连接处于不适当的状态时,客户端尝试一个不适当的命令引发协议错误,服务器将以一个BAD或者NO(取决于服务器的实现体)命令完成结果响应。
3.1. 未认证状态
在未认证状态下,大多数命令在得到许可前,客户端必须提供认证证书。若非连接已经是预认证了的,一个连接开始时,就进入了未认证状态。
3.2. 认证状态
在认证状态下,客户端是认证了的,它必须先于影响邮件的命令被许可前,选择一个邮箱以访问。当一个预认证连接开始,被认可的认证证书已经提供,选择一个邮箱发生错误后,或者一个成功的CLOSE命令后,就进入了认证状态。
3.3. 选中状态
在一个选中状态,一个邮箱被选中以访问。当一个邮箱被成功选中时,就进入了这个状态。
3.4. 注销状态
在注销状态下,连接正在被终止。一个客户端请求(通过LOGOUT命令),或者客户端、服务器的单方面动作,都会导致进入这个状态。
如果客户端请求注销状态,服务器必须在关闭连接前发送LOGOUT命令的一个非标签化BYE响应和一个标签化OK响应;客户端在关闭连接前,必须读取这个LOGOUT命令的标签化OK响应至。
在没有发送一个包含原因的、非标签化BYE响应的情况下,一个服务器不能单方面关闭连接。一个客户端不应单方面关闭连接,而应当发出一个LOGOUT命令。如果服务器发现客户端单方面关闭了连接,服务器可以忽略这个非标签化BYE响应,并简单地关闭它的连接。
+———————-+
|connection established|
+———————-+
||
//
+————————————–+
| server greeting |
+————————————–+
|| (1) || (2) || (3)
// || ||
+—————–+ || ||
|Not Authenticated| || ||
+—————–+ || ||
|| (7) || (4) || ||
|| // // ||
|| +—————-+ ||
|| | Authenticated |<=++ ||
|| +—————-+ || ||
|| || (7) || (5) || (6) ||
|| || // || ||
|| || +——–+ || ||
|| || |Selected|==++ ||
|| || +——–+ ||
|| || || (7) ||
// // // //
+————————————–+
| Logout |
+————————————–+
||
//
+——————————-+
|both sides close the connection|
+——————————-+
(1)未预认证的连接(OK欢迎)
(2)预认证的连接(PREAUTH欢迎)
(3)被拒绝的连接(BYE欢迎)
(4)成功LOGIN或者AUTHENTICATE命令
(5)成功的SELECT或者EXAMINE命令
(6)CLOSE命令,或者失败的SELECT、EXAMINE命令
(7)LOGOUT命令,服务器关闭,或者连接已关闭
4. 数据格式
IMAP4rev1使用文本型的命令和响应。IMAP4rev1中的数据可以是很多形式中的一种:原语、数字、字符串、圆括符列表、或者NIL。注意,一个特殊的数据项可能有几种形式;例如,使用“astring”语法定义的一个数据项可以是一个原语,或者一个字符串。
4.1. 原语
一个原语由一个以上普通字符组成。
4.2. 数字
一个数字由一个以上的数字字符组成,表示一个数值。
4.3. 字符串
一个字符串的两种形式:或者是原义字符串,或者是引用字符串。原义形式是普遍的字符串形式。处理原义字符串时,存在字符空间限制情况,为避免空间过载,就可以使用引用字符串。
一个原义字符串是一连串的0或者更多的字节数(包括CR和LF),左花括号形(“{”),字节数的长度,右花括号(“}”),和CRLF。如果是从服务器发送至客户端的原义字符串,CRLF是紧跟在字节数据后的。如果是从客户端发送至服务器的原义字符串,在发送字节数据(和其余命令)前,客户端必须等待接收一个连续请求命令(稍后讲述)。
一个引用字符串是一连串的0或者更多的7位字符,除CR和LF外,每个的后面都带有两个引用符(<”>)。
空字符串表示成“”(在两个双引号之间有0个字符的引用字符串),或者{0},其后跟着CRLF(一个原义的空字符串表示成{0})。
注意:即使字节数的长度为0,正在传送一个原义字符串的客户端也必须等待一个连续请求命令。
4.3.1. 字节及二进制字符串
通过使用[MIME-IMB]内容传输编码,就可以支持8位文本型的和二进制的邮件。IMAP4rev1实现体可以传送8位或者原义型的泛八进制字符,但只有当标识了[CHARSET]的时候才可以这样做。
虽然定义了一个二进制的主体编码,但是未编码的二进制字符串是不被接受的。一个“二进制字符串”是带有NUL字符的任意字符串。实现体必须在传送数据前,把二进制数据编码成文本形式,如BASE64。带有总数超量的CTL字符的字符串可能被认为是二进制。
4.4. 圆括符列表
表述为“圆括符列表”的数据结构;一连串的数据项,以空格为分隔,起始端和终止端带有圆括号。使用多级圆括符表示巢时,一个圆括符列表可以包含有其它的圆括符列表。
空列表表示成()――一个没有成员的圆括符列表。
4.5. NIL
“NIL”,这是个特殊的形式,它表示字符串或者圆括符列表的数据项不存在,它与空字符串“”或者空圆括符列表是有区别的。
注意:NIL永不使用于带有任何原语形式的数据项。例如,一个“NIL”的邮箱名是一个邮箱名为NIL的邮箱,而不是一个不存在的邮箱名。这是因为邮箱使用“astring”语法,它是原语型或者字符串型的。相对的,一个NIL地址名是一个不存在的个体名,因为地址名使用“nstring”语法,它是NIL或者一个字符串,而永远不会是一个原语。
5. 操作的考虑
这里列出了下面的规则,以确保所有的IMAP4rev1实现体恰当有效的沟通。
5.1. 邮箱命名
邮箱名是7位的。客户端实现体不能试图创建8位的邮箱名,应当把LIST或者LSUB返回的任意8位邮箱名解释为UTF-8。服务器实现体应当禁止8位邮箱名的创建,LIST或者LSUB不应当返回8位的邮箱名。关于如何表示非ASCII的邮箱名,更多信息请参看5.1.3一节。
注意:8位的邮箱名在本协议的早期版本中并未定义。一些站点使用一个本地的8位字符序列表示非ASCII邮箱名。这种用法是不能有效沟通的,现在而言也是不正规的。
不区分大小写的邮箱名INBOX是一个特殊的邮箱名,它被保留下来,表示“该服务器上该用户的主邮箱”。所有其它邮箱名的解释都是依赖于实现体的。
特别的,本文档未指定是否区分非INBOX邮箱名的大小写。一些服务器实现体全部区分大小写;一些服务器实现体保留新创建的邮箱名的大小写状态,而其它的则是不区分大小写的;还有一些服务器实现体则强制命名为特定形式。客户端实现体必须与其中的任何一种做好交互。如果一个服务器实现体把非INBOX邮箱名解释为不区分大小写的,则它必须特别使用5.1.3一节中所描述的国际命名约定。
创建一个新的邮箱名,有一些客户端的考虑:
1)原语类(参见正式语法一节)的任意一个字符要求邮箱名表述为一个引用字符串或者原义字符串。
2)CTL和其它生僻字符很难表述在用户界面,所以最好避免。
3)虽然通配符列表字符(“%”和“*”)在邮箱名中是正确的,但是因为与通配符的解释相冲突,所以很难把LIST和LSUB命令用于这样的邮箱名。
4)通常,保留一个字符(取决于服务器实现体)用于层级分隔。
5)“#”和“&”这两个字符有约定语上的意义,应当避免以其它意义使用它。
5.1.1. 邮箱层级命名
如果需要输出分层的邮箱名,邮箱名必须是从左到右的层级,并使用一个字符分隔不同层级。在一个邮箱名中,所有层级的分层使用同一个层级分隔字符表示。
5.1.2. 邮箱命名空间的约定
按照约定,任何邮箱名的第一个分层元素以“#”开头,它标识剩余名称的名称空间。这使得消除具有各自名称空间的、不同类型的邮箱存储间的含糊意义成为可能。
例如,提供访问USENET网络组的实现体可以使用“#news”名称空间把USENET网络组的名称空间与其它邮箱的网络组名称空间分割开来。Comp.mail.misc网络组可能有一个“#news.comp.mail.misc”的邮箱名,而邮箱名“comp.mail.misc”可以指向一个不同的对象(如,一个用户的本地邮箱)。
5.1.3. 邮箱的国际命名约定
按照约定,IMAP4rev1的国际邮箱名用“UTF-7”中所描述的UTF-7编码的修订版本描述。在执行本协议的一个早期版本的服务器上,修订版UTF-7同样是可以用的。
在修订版UTF-7中,除“&”外的US-ASCII打印字符都可以表示邮箱名;即八进制值为0×20-0×25和0×27-0×7e的字符。字符“&”(0×26)表示成两个八进制串“&-”。
所有其它字符(八进制值为0×00-0×1f和0×7f-0xff)表示成修订版BASE64,它具有“UTF-7”之后的一个修订――“,”替代“/”使用。修订版BASE64不能用来表示任何可以表示自身的US-ASCII打印字符。
“&”用来转换至修订版BASE64,“-”用来转换回US-ASCII。不存在从BASE64至US-ASCII的隐式转换,且无效转换(BASE64下的“-&”;注意,US-ASCII下的“&-”意为“&”)也是不允许的;就是说,一个以非ASCII ISO-10646字符结尾的邮箱名必须以一个“-”结尾。
这些修订是为了修正与UTF-7的以下错误:
1)UTF-7使用“+”字符实现转换;这跟邮箱名称中的“+”,特别是USENET网络组名称的一般用法相冲突。
2)UTF-7的编码是BASE64,它使用“/”字符;这跟“/”作为层级分隔符的普遍用法相冲突。
3)UTF-7禁止“/”的未编码使用;这跟“/”作为层级分隔符的普遍用法相冲突。
4)UTF-7禁止“~”的未编码合用;这跟一些服务器将“~”作为根目录标记的用法相冲突。
5)UTF-7允许选择多种形式表示同样的字符串;特别的,US-ASCII打印字符可以表示成编码后的形式。
虽然修订版UTF-7是一个约定,它在服务器建立了用一个嵌入的“&”字符处理任意邮箱名的一些请求。特别的,服务器实现体必须保留一个修订版UTF-7名称的修订版BASE64部分的准确形式,并把这些文本视为区分大小写的,即使邮箱名是不区分大小写的或者部分区分大小写、部分不区分大小写的。
服务器实现体应当用一个嵌入的“&”字符――用作CREATE的一个变量,检验任意邮箱名:正确修订版UTF-7语法中,不含有多余的转换符,也不含有可表示自身的任意US-ASCII打印字符的修订版BASE64编码。但是,客户端实现体不能依赖服务器做这个,也不应当试图用一个嵌入的“&”字符创建一个邮箱名,除非它用修订版UTF-7的语法编译。
不遵照修订版UTF-7约定、输出一个邮件存储的服务器实现体必须转换成修订版UTF-7的、含有非ASCII字符或者“&”字符的任意邮箱名。
例如,这是一个混合有英文、中文和日文文本的邮箱名:
~peter/mail/&U,BTFw-/&ZeVnLIqe-
例如,字符串“&Jjo!”不是一个正确的邮箱名,因为它的“!”前没有至US-ASCII的转换符。正确的形式是“&Jjo!-”。字符串“&U,BTFw-&ZeVnLIqe-”是不允许的,因为它含有多余的转换符。正确的形式是“&U,BTF2XlZyyKng-”。
5.2. 邮箱大小和邮件状态更新
任何时候,服务器可以发送客户端未请求的数据。有时,这种行为是有必要的。例如,代理而不是服务器,可能向邮箱中增加邮件(比如,新邮件发送),改变了邮箱中的邮件标记(比如,多个代理同时访问同一个邮箱),或者从邮箱中删除邮件。在处理一个命令的过程中,如果发现一个邮箱大小改变了,服务器必须自动发送邮箱大小的新信息。服务器应当自动发送邮件标记的新信息,而无需客户端明确请求这些新信息。
关于邮件的删除,客户端的服务器通告存在着特殊规则,以防止同步错误;更多细节参见EXPUNGE响应的描述。特别的,发送一个可能减小邮箱中邮件数量的EXISTS响应,这是不允许的;只有EXPUNGE响应可以这样做。
在记忆服务器数据方面,无论什么样的实现体,客户端实现体必须记忆邮箱大小的新信息。不能假定初始选中邮箱后的的任何命令都返回邮箱的大小。
5.3. 没有命令在行进中的响应
当没有命令在行进中时,不允许服务器实现体发送一个非标签化响应(EXPUNGE除外)。发送这些响应的服务器实现体必须处理流控制。特别的,它们必须:(1)确保数据大小不超过优先传输的可用窗体大小,或者(2)使用非阻塞式写入。
5.4. 自动注销计时器
如果服务器有一个静止的自动注销计时器,那么这个计时器的持续时间必须不少于30分钟。在这个间隔里,来自客户端的任何命令应当重设这个自动注销计时器。
5.5. 多个命令在行进中
受多义规则(见下)和优先数据流的流控制约束的影响,客户端可能不等到一个命令的完成结果响应就发送另外一个命令。类似的,受多义规则的影响,服务器可能在处理当前命令的实现前,就开始处理另外一个命令。不过,在任何后续命令初始化前,任何连续请求响应和连续命令必须协调。
因为一个命令可能影响到其它命令的结果,一个多义可能导致异常。客户端不应当未等待一个多义的返回结果就发送多个命令。如果服务器发现了一个可能存在的多义,它必须按照客户端给出的顺序完成命令的执行。
最常见的多义例子是,一个命令可能影响其它命令的结果,例如,一个邮件标记的FETCH和同一个邮件标记的STORE。
一个不常见的多义例子是,允许一个非标签化EXPUNGE响应的命令(除了FETCH,STORE,SEARCH),因为一个非标签化响应可以使一个后续命令的序列号无效。这个问题不会发生于FETCH,STORE,或者SEARCH命令,因为这些命令中的任何一个在行进中时,服务器禁止发送EXPUNGE响应。因此,如果客户端发送FETCH,STORE,或者SEARCH之外的任意命令,则必须在发送一个带有邮件序列号的命令前,就等待直至得到完成结果响应。
注意:UID FETCH,UID STORE,和UID SEARCH命令不同于FETCH,STORE,和SEARCH。如果客户端发送了一个UID命令,它必须在发送一个带有邮件序列号的命令前,就等待直至得到一个完成结果响应。
例如,下面的非等待式命令序列是无效的:
FETCH + NOOP + STORE
STORE + COPY + FETCH
COPY + COPY
CHECK + FETCH
下面是有效的非等待式命令序列的例子:
FETCH + STORE + SEARCH + CHECK
STORE + COPY + EXPUNGE
UID SEARCH + UID SEARCH非等待命令序列可能有效,可能无效,这取决于第二个UID SEARCH是否包含邮件序列号。
6. 客户端命令
本节描述IMAP4rev1命令。这些命令按照其被允许的状态组织。被多种状态允许的命令,只在其被允许的最小状态里列出(例如,在登录和选中状态都有效的命令,在登录状态中列出)。
命令参数,在下面的命令描述中标识为“参数:”,通过功能描述,而不是语法。命令参数的准确语法在正式语法一节中描述。
一些命令导致特定的服务器响应返回;它们在下面的命令描述中标识为“响应:”。响应一节中有这些响应的描述信息,正式语法一节中有这些响应的准确语法。将服务器数据作为任意命令的一个结果传送,这是有可能的。这样,不特别请求服务器数据的命令描述成“此命令无特定响应”,而不是“无”。
命令描述中的“结果:”指明一个命令可能的标签化状态响应,和这些状态响应的任何特定解释。
只有成功的、改变状态的文档化命令才会改变一个连接的状态。一个被拒绝命令(BAD响应)永远不会改变一个被选中邮箱的连接状态。一个失败命令(NO响应)一般不会改变被选中邮箱的连接状态;SELECT和EXAMINE命令例外。
6.1. 客户端命令-任意状态
以下命令在任何状态下都有效:CAPABILITY,NOOP,和LOGOUT。
6.1.1. CAPABILITY命令
参数:无
响应:请求非标签化响应:CAPABILITY
结果:OK-capability完成
BAD-未知命令,或者参数无效
CAPABILITY命令请求服务器支持的功能列表。在(标签化)OK响应之前,服务器必须发送一个非标签化的、带有“IMAP4rev1”作为其功能列表之一的CAPABILITY响应。
一个以“AUTH=”开头的capability名,表示服务器支持这种特定的认证机制。所有这些名称,在定义上,都是本文档的一部分。例如,一个实验性的“blurdybloop”认证者的认证capability可以是“AUTH=XBLURDYBLOOP”,而不是“XAUTH=BLURDYBLOOP”或者“XAUTH=XBLURDYBLOOP”。
其它的capability名参考本文档的扩展版、修订版、或者改正版。更多信息参见CAPABILITY响应的文档。除非有明确的客户端动作激活capability,否则,超出本文档IMAP4rev1基本集的capabilities是不可用的。
客户端和服务器必须实现STARTTLS,LOGINDISABLED,和AUTH=PALIN(“IMAP-TLS”中有描述)的capabilities。重要信息参看安全考虑一节。
关于站点形式或者实现体特定的capability信息参看题为“客户端命令-试验/扩展”一节。
例子:
C: abcd CAPABILITY
S: * CAPABILITY IMAP4rev1 STARTTLS AUTH=GSSAPI
LOGINDISABLED
S: abcd OK CAPABILITY completed
C: efgh STARTTLS
S: efgh OK STARTTLS completed
C: ijkl CAPABILITY
S: * CAPABILITY IMAP4rev1 AUTH=GSSAPI AUTH=PLAIN
S: ijkl OK CAPABILITY completed
6.1.2. NOOP命令
参数:无
响应:此命令无特定响应(见下)
结果:OK-noop完成
BAD-未知命令,或者参数无效
NOOP命令总是成功的。它什么也不做。
因为任何命令都可以返回一个状态更新作为非标签化数据,NOOP命令可以用作新邮件的周期性检测,或者在一个静止期间内的邮件状态刷新(实现这个,用这种方法是比较好的)。NOOP命令还可以用来重设服务器上任何静止的自动注销计时器。
例子:
C: a002 NOOP
S: a002 OK NOOP completed
…
C: a047 NOOP
S: * 22 EXPUNGE
S: * 23 EXISTS
S: * 3 RECENT
S: * 14 FETCH (FLAGS (/Seen /Deleted))
S: a047 OK NOOP completed
6.1.3. LOGOUT命令
参数:无
响应:要求非标签化的响应:BYE
结果:OK-logout完成
BAD-未知命令,或者无效参数
LOGOUT命令告知服务器,客户端准备关闭连接。服务器必须在(标签化)OK响应前,发送一个BYE非标签化响应,并随后关闭这个网络连接。
例子:
C: A023 LOGOUT
S: * BYE IMAP4rev1 Server logging out
S: A023 OK LOGOUT completed
(Server and client then close the connection)
6.2. 客户端命令-未认证状态
在未认证状态下,AUTHENTICATE或者LOGIN命令建立认证并进入认证状态。AUTHENTICATE命令为各种认证技术、隐藏保护和整数验证提供了一套常见的的机制;而LOGIN命令使用一个传统的用户名和简单文本密码对,没有建立隐藏保护或者整数验证的措施。
STARTTLS命令是建立会话隐藏保护和整数验证的一种可选形式,但是它不建立认证或者进入认证状态。
服务器实现体可能允许未建立认证就访问特定邮箱。这可以通过“ANONYMOUS”中描述的ANONYMOUS“SASL”认证者实现。以前的一个约定是使用用户ID“anonymous”的LOGIN命令;这种情况下,要求一个密码,尽管服务器可能选择接受任意密码。对匿名用户的约束依赖于实现体。
一旦被认证(包括匿名用户),就不可能再进入未认证状态。
除了一般命令(CAPABILITY,NOOP,和LOGOUT),未认证状态下以下命令也是正确的:STARTTLS,AUTHENTICATE和LOGIN。关于这些命令的重要信息请参看安全考虑一节。
6.2.1. STARTTLS命令
参数:无
响应:此命令无需特定响应
结果:OK-starttls完成,开始TLS对话
BAD-未知命令,或者无效参数
在来自服务器端的标签化OK响应末尾的CRLF之后,一个“TLS”对话就开始了。一旦一个客户端发出一个STARTTLS命令,它就不能再发送其它命令,直到服务器响应出现并且“TLS”对话结束。
服务器保持未认证状态,即使客户端证书在“TLS”对话期间是受支持的。这不排除像EXTERNAL(“SASL”中定义的)的认证机制使用“TLS”对话决定的用户标识。
一旦“TLS”开始,客户端必须丢弃关于服务器功能的缓存信息,且应当重新发出CAPABILITY命令。这对保护免受修改功能列表指向STARTTLS的中间者攻击是有必要的。服务器可以在STARTTLS后发出不同功能。
例子:
C: a001 CAPABILITY
S: * CAPABILITY IMAP4rev1 STARTTLS LOGINDISABLED
S: a001 OK CAPABILITY completed
C: a002 STARTTLS
S: a002 OK Begin TLS negotiation now
C: a003 CAPABILITY
S: * CAPABILITY IMAP4rev1 AUTH=PLAIN
S: a003 OK CAPABILITY completed
C: a004 LOGIN joe password
S: a004 OK LOGIN completed
6.2.2. AUTHENTICATE命令
参数:认证机制名
响应:可请求的连续数据
结果:OK-authenticate完成,当前为认证状态
NO-authenticate失败:不支持的认证机制,被拒绝的证书
BAD-未知命令,或者无效参数,认证对话被取消
AUTHENTICATE命令向服务器指出一个[SASL]认证机制。如果服务器支持被请求的认证机制,则它执行一个认证协议对话来认证并确认客户端。它也可以为后续协议交互构建一个OPTIONAL安全层。如果被请求的认证机制不被支持,则服务器通过发送一个标签化NO响应来拒绝AUTHENTICATE命令。
AUTHENTICATE命令不支持[SASL]的可选“初始响应”特性。[SASL]5.1一节,说明了如何处理使用一个初始响应的认证机制。
[SASL]的这个协议的片面描述的服务名称是“imap”。
认证协议对话由认证机制特定的、一系列服务器邀请和客户端响应组成。一个服务器邀请由一个以“+”开头,后跟一个BASE64编码的字符串的命令连续请求响应组成。如果客户端希望取消一个认证对话,它就发出由一个“*”组成的一个行。如果服务器接收到这样一个响应,它必须通过发送一个标签化的BAD响应来拒绝AUTHENTICATE命令。
如果一个安全层是通过[SASL]认证对话构建的,那么,紧跟在结束客户端的认证对话的CRLF、及服务器的标签化OK响应的CRLF之后,它就起效了。
客户端和服务器实现体必须自己执行AUTHENTICATE命令时,并不要求它实现[IMAP-TLS]中描述的简单机制以外的任何认证机制。同时,不要求一个认证机制被支持于任意安全层。
注意:一个服务器实现体必须执行一个不允许任何简单文本型密码机制的配置,除非STARTTLS命令已经启动,或者提供了保护会话免受密码窥探的其它机制。在没有保护机制避免密码窥探的情况下使用简单文本型密码机制,服务器站点不应当使用这样的配置。客户端和服务器实现体应当执行不使用简单文本型密码的其它[SASL]机制,像[SASL]中描述的GSSAPI机制和(或者)[DIGEST-MD5]机制。
服务器和客户端可以支持多个认证机制。服务器应当在其CAPABILITY命令的响应中列出其支持的认证机制,以便客户端知道使用何种认证机制。
在一个成功的AUTHENTICATE命令的标签化OK响应里,服务器可以包含进一个CAPABILITY响应码,以便自动发送功能。如果一个客户端认出这些自动的功能,它就无需发送一个CAPABILITY命令。只有在一个安全层没有被AUTHENTICATE命令构建的时候,才能这样做,因为作为一个AUTHENTICATE命令的一部分的标签化OK响应,是不受加密或者整数验证的保护的。在这种情况下,[SASL]要求客户端重新发出一个CAPABILITY命令。
如果一个AUTHENTICATE命令以一个NO响应宣告失败,客户端可以通过发出另外一个AUTHENTICATE命令尝试另外一个认证机制。它也可以通过使用LOGIN命令尝试认证(更多细节参看6.2.3一节)。就是说,客户端可以按降序请求认证类别,LOGIN命令则是最后的选择。
在认证对话期间,从客户端传送至服务器的授权标识被服务器解释为正处于优先级的用户名,即正请求的用户。
例子:
S: * OK IMAP4rev1 Server
C: A001 AUTHENTICATE GSSAPI
S: +
C: YIIB+wYJKoZIhvcSAQICAQBuggHqMIIB5qADAgEFoQMCAQ6iBwMFACAAAACjggEmYYIBIjCCAR6gAwIBBaESGxB1Lndhc2hpbmd0b24uZWR1oi0wK6ADAgEDoSQwIhsEaW1hcBsac2hpdmFtcy5jYWMud2FzaGluZ3Rvbi5lZHWjgdMwgdCgAwIBAaEDAgEDooHDBIHAcS1GSa5b+fXnPZNmXB9SjL8Ollj2SKyb+3S0iXMljen/jNkpJXAleKTz6BQPzj8duz8EtoOuNfKgweViyn/9B9bccy1uuAE2HI0yC/PHXNNU9ZrBziJ8Lm0tTNc98kUpjXnHZhsMcz5Mx2GR6dGknbI0iaGcRerMUsWOuBmKKKRmVMMdR9T3EZdpqsBd7jZCNMWotjhivd5zovQlFqQ2Wjc2+y46vKP/iXxWIuQJuDiisyXF0Y8+5GTpALpHDc1/pIGmMIGjoAMCAQGigZsEgZg2on5mSuxoDHEA1w9bcW9nFdFxDKpdrQhVGVRDIzcCMCTzvUboqb5KjY1NJKJsfjRQiBYBdENKfzK+g5DlV8nrw81uOcP8NOQCLR5XkoMHC0Dr/80ziQzbNqhxO6652Npft0LQwJvenwDI13YxpwOdMXzkWZN/XrEqOWp6GCgXTBvCyLWLlWnbaUkZdEYbKHBPjd8t/1×5Yg==
S: + YGgGCSqGSIb3EgECAgIAb1kwV6ADAgEFoQMCAQ+iSzBJoAMCAQGiQgRAtHTEuOP2BXb9sBYFR4SJlDZxmg39IxmRBOhXRKdDA0uHTCOT9Bq3OsUTXUlk0CsFLoa8j+gvGDlgHuqzWHPSQg==
C:
S: + YDMGCSqGSIb3EgECAgIBAAD/////6jcyG4GE3KkTzBeBiVHeceP2CWY0SR0fAQAgAAQEBAQ=
C: YDMGCSqGSIb3EgECAgIBAAD/////3LQBHXTpFfZgrejpLlLImPwkhbfa2QteAQAgAG1yYwE=
S: A001 OK GSSAPI authentication successful
注意:服务器邀请和客户端响应中的换行是为了编辑上的清楚,而不是实际认证符。
6.2.3. LOGIN 命令
参数:用户名
密码
响应:此命令无特定响应
结果:OK-login完成,当前是认证状态
NO-login失败:用户名或者密码被拒绝
BAD-未知命令,或者无效参数
LOGIN命令向服务器确认客户端,并带有确认该用户的简单文本型密码。
在一个成功的LOGIN命令的标签化OK响应里,服务器可以包含进一个CAPABILITY响应码,以便(实现)自动发送功能。如果一个客户认出了这些自动的功能,则它无需发送一个CAPABILITY命令。
例子:
C: a001 LOGIN SMITH SESAME
S: a001 OK LOGIN completed
注意:在一个不安全网络(比如因特网)上使用LOGIN命令有安全风险,因为任何网络传输的监控者都可以获取简单文本型密码。LOGIN命令不应当使用,除非作为最后一种方法,同时,建议客户端实现体采取措施使LOGIN命令的任何自动使用无效。
除非STARTTLS命令已经构建,或者已经提供了保护会话免受密码窥探的机制,否则,一个服务器实现体必须实现一个机制,在这个机制里宣告LOGINDISABLED功能并且不允许LOGIN命令。服务器站点不应当使用没有这样一个免受密码窥探(功能)的保护机制、而允许LOGIN命令的配置。如果LOGINDISABLED功能被宣告,则一个客户端实现体不能发送一个LOGIN命令。
6.3. 客户端命令-认证状态
在认证状态下,把邮箱作为原语实体来操作的命令是允许的。在这些命令中,SELECT及EXMINE命令将会选中一个邮箱以访问及进入选中状态。
除了常见的命令(CAPABILITY,NOOP,和LOGOUT),以下命令在认证状态下也是正确的:SELECT,EXAMINE,CREATE,DELETE,RENAME,SUBSCRIBE,UNSUBSCRIBE,LIST,LSUB,STATUS,和APPEND。
6.3.1. SEELCT命令
参数:邮箱名
响应:要求非标签化的响应:FLAGS,EXISTS,RECENT
要求OK非标签化响应:UNSEEN,PERMANENTFLAGS,UIDNEXT,UIDVALIDITY
结果:OK-select完成,当前是选中状态
NO-select失败,当前是认证状态:不存在这个邮箱,不能访问邮箱
BAD-未知命令,或者参数无效
SELECT命令选中一个邮箱,以便这个邮箱中的邮件可以被访问。在返回一个OK给客户端前,服务器必须发送以下非标签化数据给客户端。要注意的是,这个协议的早期版本只要求FLAGS,EXISTS,和RECENT非标签化数据;因此,客户端实现体应当把丢失数据作为个别情况讨论。
FLAGS
邮箱中被定义的标记。更多细节参看FLAGS响应的描述。
EXISTS
邮箱中邮件的数量。更多细节参看EXISTS响应的描述。
RECENT
带有/Recent标记符的邮件的数量。更多细节参看RECENT响应的描述。
OK [UNSEEN ]
邮箱中第一封不可视邮件的邮件序列号。如果没有这个,客户端就不能对这个油箱中的第一封邮件做任何相关推测,如果想找到它,就需要发出一个SEARCH命令。
OK [PERMANENTFLAGS ()]
客户端可以永久修改的邮件标记的列表。如果没有这个,客户端应当推测所有的标记都是可以永久修改的。
OK [UIDNEXT ]
下一个唯一标识符的值。更多信息参考2.3.1.1一节。如果没有这个,客户端不能对下一个唯一标识符做任何相关推测。
OK [UIDVALIDITY ]
当前唯一标识符的值。更多信息参考2.3.1.1一节。如果没有这个,服务器就不支持唯一标识符。
在一个连接中,一次只能选中一个邮箱;同时访问多个邮箱要求多个连接。在尝试新的选择前,SELECT命令自动释放对任何当前选中邮箱的选中。因此,如果一个邮箱被选中,一个失败的SELECT命令正尝试,则没有邮箱被选中。
如果客户端被允许修改邮箱,则服务器应当把“[READ-WRITE]”响应码作为标签化OK响应的文本的前缀。
如果客户端没有修改邮箱的权限,但是有读取权限,则邮箱以只读方面选中,且服务器必须用“[READ-ONLY]”响应码作为标签化OK响应的文本前缀,以SELECT。通过SELECT方式的只读访问,与通过EXAMINE方式的只读访问,二者的区别在于,特定的只读邮箱可能允许基于用户(而不是全局)的永久状态的改变。在一个基于服务器的.newsrc文件中做了标记的网络论坛邮件就是这种可以被修改的、带有只读邮箱的、基于用户的永久状态的一个例子。
例子:
C: A142 SELECT INBOX
S: * 172 EXISTS
S: * 1 RECENT
S: * OK [UNSEEN 12] Message 12 is first unseen
S: * OK [UIDVALIDITY 3867529045] UID valid
S: * OK [UIDNEXT 4392] Predicted next UID
S: * FLAGS (/Answered /Flagged /Deleted /Seen /Draft)
S: * OK [PERMANENTFLAGS (/Deleted /Seen /*)] Limited
S: A142 OK [READ-WRITE] SELECT completed
6.3.2. EXAMINE命令
参数:邮箱名
响应:要求非标签化响应:FLAGS,EXISTS,RECENT
要求OK非标签化响应:UNSEEN,PERMANENTFLAGS,UIDNEXT,UIDVALIDITY
结果:OK-examine完成,当前是选中状态
NO-examine失败,当前是认证状态:没有这个邮箱,不能访问邮箱
BAD-未知命令,或者无效参数
EXAMINE命令与SELECT相同,并返回同样的输出;不过,只读方式时选中的邮箱是一样的。邮箱的永久状态下,没有变动,包括有基于用户的状态的权限;特别的,EXAMINE不能使邮件丢失/Recent标记。
EXAMINE命令的标签化OK响应文本必须以“[READ-ONLY]”开头。
例子:
C: A932 EXAMINE blurdybloop
S: * 17 EXISTS
S: * 2 RECENT
S: * OK [UNSEEN 8] Message 8 is first unseen
S: * OK [UIDVALIDITY 3857529045] UIDs valid
S: * OK [UIDNEXT 4392] Predicted next UID
S: * FLAGS (/Answered /Flagged /Deleted /Seen /Draft)
S: * OK [PERMANENTFLAGS ()] No permanent flags permitted
S: A932 OK [READ-ONLY] EXAMINE completed
6.3.3. CREATE命令
参数:邮箱名
响应:此命令无需特定响应
结果:OK-create完成
NO-create失败:不能创建这个名称的邮箱
BAD-未知命令,或者无效参数
CREATE命令用给定名称创建一个邮箱。只有当这个名称的新邮箱被创建完成时,才返回一个OK响应。试图创建INBOX,或者一个与已在邮箱名同名的邮箱,引发一个错误。创建过程中的任何错误都将返回一个标签化NO响应。
如果邮箱名以服务器的层级分隔符作为尾缀(就像通过LIST命令从服务器返回的),这就告诉客户端准备在这个名称的层级下创建邮箱名。不要求这个通知的的服务器实现体必须忽略这个通知。任何情况下,这个被创建邮箱的名称(应当)没有多余的层级分隔符。
如果邮箱名的其它地方出现服务器的层级分隔符,服务器应当创建CREATE命令成功完成所需要的每一个层级。即,在一个以“/”作为层级分隔符的服务器上创建“foo/bar/zap”的尝试,如果foo/和foo/bar不存在,则应当创建它们。
如果一个被创建的邮箱,它的名称与已经被删除的邮箱名相同,那么,它的唯一标识符必须大于邮箱中先前引用中用到的任何一个唯一标识符,除非新的引用有一个不同的唯一标识符值。更多细节参看UID命令的描述。
例子:
C: A003 CREATE owatagusiam/
S: A003 OK CREATE completed
C: A004 CREATE owatagusiam/blurdybloop
S: A004 OK CREATE completed
注意:这个例子的解释依赖于,从LIST“/”是否返回为层级分隔符。如果“/”是层级分隔符,带有一个名为“blurdybloop”成员的一个新层级“owatagusiam”被创建。否则,处在同一层级的两个邮箱被创建。
6.3.4. DELETE命令
参数:邮箱名
响应:此命令无需特定响应
结果:OK-delete完成
NO-delete失败:不能删除这个名称的邮箱
BAD-未知命令,或者无效参数
DELETE命令永久删除给定名称的邮箱。若邮箱被删除,则返回一个标签化的OK响应。尝试删除INBOX,或者一个不存在的邮箱,是错误的。
DELETE命令不能删除子级。例如,如果一个邮箱有一个子级“foo.bar”(假设“.”是层级定义符),删除“foo”不能删除“foo.bar”。尝试删除一个带有子级、并且有/Noselect属性的邮箱名,是错误的(更多细节参看LIST响应的描述)。
删除一个带有子级、并且没有/Noselect属性的邮箱名,是允许的。这种情况下,这个邮箱中的所有邮件被删除,且这个邮箱名将取得/Noselect邮箱名属性。
删除了的邮箱使用的最高唯一标识符的值必须保留,这样一个新创建的同名邮箱就不会再使用先前引用的标识符,除非这个新的引用有一个不同的唯一标识符值。更多细节参看UID命令的描述。
例子:
C: A682 LIST “” *
S: * LIST () “/” blurdybloop
S: * LIST (/Noselect) “/” foo
S: * LIST () “/” foo/bar
S: A682 OK LIST completed
C: A683 DELETE blurdybloop
S: A683 OK DELETE completed
C: A684 DELTE foo
S: A684 NO Name “foo” has inferior hierarchical names
C: A685 DELETE foo/bar
S: A685 OK DELETE Completed
C: A686 LIST “” *
S: * LIST (/Noselect) “/” foo
S: A686 OK LIST completed
C: A687 DELETE foo
S: A687 OK DELETE Completed
C: A82 LIST “” *
S: * LIST () “.” Blurdybloop
S: * LIST () “.” Foo
S: * LIST () “.” Foo.bar
S: A82 OK LIST completed
C: A83 DELETE blurdybloop
S: A83 OK DELETE completed
C: A84 DELETE foo
S: A84 OK DELETE Completed
C: A85 LIST “” *
S: * LIST () “.” foo.bar
S: A85 OK LIST completed
C: A86 LIST “” %
S: * LIST (/Noselect) “.” foo
S: A86 OK LIST completed
6.3.5. RENAME命令
参数:已经存在的邮箱名
新的邮箱名
响应:此命令无需特定响应
结果:OK-rename完成
NO-rename失败:不能重命名邮箱为这个名称,不能以这个名称重命名至邮箱
BAD-未知命令,或者无效参数
RENAME命令改变一个邮箱的名称。当且仅当邮箱被重命名完成时,才返回一个标签化的OK响应。尝试把一个不存在的邮箱名重命名至一个已经存在的邮箱名,是错误的。重命名中的任何错误都将返回一个标签化的NO响应。
如果名称有子级名,(当重命名这个名称时)则子级名必须也被重命名。例如,重命名“foo”为“zap”,将重命名“foo/bar”(假设“/”是层级定义符)为“zap/bar”。
如果服务器层级分隔符出现在名称中,那么服务器应当创建RENAME命令成功完成所需要的每一个父级名。即,尝试在一个以“/”为层级分隔符的服务器上重命名“foo/bar/zap”为baz/rag/zowie,如果baz/和baz/rag/不存在,则应当创建它们。
旧邮箱使用的最高唯一标识符的值必须保留,这样一个新创建的同名邮箱就不会再使用先前引用的标识符,除非这个新的引用有一个不同的唯一标识符值。更多细节参看UID命令的描述。
重命名INBOX是允许的,并且有特殊的行为。它移动INBOX中的所有邮件至一个给定名称的新邮箱中,INBOX则为空。如果服务器实现体支持INBOX的子级名,则这些不受INBOX重命名的影响。
例子:
C: A682 LIST “” *
S: * LIST () “/” blurdybloop
S: * LIST (/Noselect) “/” foo
S: * LIST () “/” foo/bar
S: A682 OK LIST completed
C: A683 RENAME blurdybloop sarasoop
S: A683 OK RENAME completed
C: A684 RENAME foo zowie
S: A684 OK RENAME Completed
C: A685 LIST “” *
S: * LIST () “/” sarasoop
S: * LIST (/Noselect) “/” zowie
S: * LIST () “/” zowie/bar
S: A685 OK LIST completed
C: Z432 LIST “” *
S: * LIST () “.” INBOX
S: * LIST () “.” INBOX.bar
S: Z432 OK LIST completed
C: Z433 RENAME INBOX old-mail
S: Z433 OK RENAME completed
C: Z434 LIST “” *
S: * LIST () “.” INBOX
S: * LIST () “.” INBOX.bar
S: * LIST () “.” old-mail
S: Z434 OK LIST completed
6.3.6. SUBSCRIBE命令
参数:邮箱
响应:此命令无需特定
结果:OK-subscribe完成
NO-subscribe失败:不能订阅这个邮箱名
BAD-未知命令,或者无效参数
SUBSCRIBE命令增加指定邮箱名至服务器的活动邮箱序列或者订阅邮箱序列中,通过LSUB命令返回。当且仅当订阅成功时,该命令返回一个标签化的OK响应。
服务器可以向SUBSCRIBE证实邮箱参数以确保它的存在。但是,它不能单方面从订阅列表中删除一个存在的邮箱名,即使该邮箱名不存在了。
注意:这个需求是出于,一个服务器可以选择,在一个邮箱名众所周知的邮箱的内容过期后,常规地删除该邮箱(比如,“system-alerts”),以便在新的内容匹配时重新创建它。
例子:
C: A002 SUBSCRIBE #news.comp.mail.mime
S: A002 OK SUBSCRIBE completed
6.3.7. UNSUBSCRIBE命令
参数:邮箱名
响应:此命令无需特定响应
结果:OK-unsubscribe完成
NO-unsubscribe失败:不能取消订阅该邮箱名
BAD-未知命令,无效参数
UNSUBSCRIBE从服务器的活动邮箱序列或者订阅邮箱序列中删除特定邮箱名,通过LSUB命令返回。当且仅当取消订阅成功时,该命令返回一个标签化的OK响应。
例子:
C: A002 UNSUBSCRIBE #news.comp.mail.mime
S: A002 OK UNSUBSCRIBE completed
6.3.8. LIST命令
参数:引用名,带可能的通配符的邮箱名
响应:非标签化的响应:LIST
结果:OK-list完成
NO-list失败:不能列出该引用或者名称
BAD-未知命令,或者无效参数
LIS命令返回客户端可用的所有名称的完整序列的一个名称子序列。返回0,或者更多的非标签化LIST答复,包含名称属性,层级定义符,和名称;更多细节参看LIST答复的描述。
LIST命令应当迅速返回其数据,没有过度的延时。例如,它不应当节外生枝地计算/Marked或者/Unmarked状态,或者进行其它处理;如果每一个名称需要1秒钟的处理,那么列出1200个名称则需要20分钟!
一个空的(“”空串)引用名参数表明邮箱名是通过SELECT解释的。返回的邮箱名必须与受支持的邮箱名模式匹配。一个非空的引用名参数是一个邮箱名,或者邮箱的一个层级,它指定了被解释的邮箱名的上下文。
一个空的(“”空串)邮箱名参数是为返回层级定义符和引用中所给定名称的根结点名的一个特殊请求。如果引用不是根结点,或者是一个空串,返回作为根结点的值可能是空串。在所有情况下,都返回一个层级定义符(或者NIL-如果没有层级)。这允许客户端取得层级定义符(或者证实邮箱名是在同一级的),即使当前没有那个名称的邮箱存在。
引用和邮箱名参数被解释成一个规范形式,它表示成一个清晰的从左到右层级。返回的邮箱名将会在解释形式中。
注意:引用参数的解释是基于实现体定义的。它取决于服务器实现体是否有一个“当前工作目录”,及开头的、可替代当前工作目录的“折断符”的概念,
例如,在一个输出UNIX或者NT文件系统的服务器上,引用参数包含当前工作目录,且邮箱名可能包含被解释成在当前工作目录中的名称。
如果一个服务器没有折断符的概念,则规范形式应是带邮箱名的引用名。注意,如果服务器实现了名称空间的约定(5.1.2一节),则“#”必须被作为折断符对待。
如果服务器参数不是一个邮箱层级(即,它是一个/NoInferiors名称),且/或引用参数不以层级定义符结束,则引用参数的解释是基于实现体的。例如,一个“foo/bar”的引用和“rag/baz”的邮箱名可以解释成“foo/bar/rag/baz”,“foo/barrage/baz”,或者“foo/rag/baz”。客户端不应当使用这样的一个引用参数,除非有用户的明确请求。一个分层的浏览器不能对服务器的引用解释作任何的假设,除非引用是一个邮箱层级并且以层级定义符结束。
包含于被解释形式的、引用参数的任何部分应当以被解释形式为前缀。它应当与引用名称参数有相同的形式。这个规则允许客户端决定返回的邮箱名是否是在引用参数的上下文中,或者邮箱参数的一些相关信息是否可以代替引用参数。没有这个上下文,可能客户端得知道服务器名称语义,包括什么字符串是可以代替一个名称上下文的折断符。
例如,这里是在一个基于UNIX的服务器上,引用和邮箱名可能被如何解释的一些例子:
引用邮箱名解释
~smith/Mail/ foo.* ~smith/Mail/foo.*
archive/ % archive/%
#news. comp.mail.* #news.comp.mail.*
~smith/Mail/ /usr/doc/foo /usr/doc/foo
archive/ ~fred/Mail/* ~fred/Mail/*
开头的三个例子演示了引用参数的上下文中的解释。注意,“~simth/Mail”不应当改成类似“/u2/users/smith/Mail”,否则客户端就不可能断定这个解释是在引用的上下文中。
字符“*”是一个通配符,它匹配其所在位置的0个或者更多的字符。字符“%”类似于“*”,但是它不匹配一个层级定义符。如果“%”通配符是一个邮箱名参数的最后一个字符,匹配的层级也会返回。如果这些层级不是可选择的邮箱,则它们带着/Noselect邮箱属性返回(更多细节参看LIST响应的描述)。
允许服务器实现体通过禁止特定的字符或者名称,以免在特定情形下匹配一个通配符,这样就隐藏源于通配符的、不同的可访问邮箱。例如,一个基于UNIX的服务器可以限制“*”的解释,以便一个初始的“/”字符不匹配。
如果对该用户而言INBOX是受该服务器支持的,并且大写字符串“INBOX”匹配带有如上所述通配符的、被解释的参数和邮箱名参数,那么,特殊名称INBOX包含于LIST的输出。删去INBOX的质疑是,SELECT INBOX是否会返回失败;这无关于用户的真实INBOX是否位于这个服务器或者其它服务器。
例子:
C: A101 LIST “” “”
S: * LIST (/Noselect) “/” “”
S: A101 OK LIST Completed
C: A102 LIST #news.comp.mail.misc “”
S: * LIST (/Noselect) “.” #news.
S: A102 OK LIST Completed
C: A103 LIST /usr/staff/jones “”
S: * LIST (/Noselect) “/” /
S: A103 OK LIST Completed
C: A202 LIST ~/Mail/ %
S: * LIST (/Noselect) “/” ~/Mail/foo
S: * LIST () “/” /Mail/meetings
S: A202 OK LIST completed
6.3.9. LSUB命令
参数:引用名,带有可能的通配符的邮箱名
响应:非标签化的响应:LSUB
结果:OK-lsub完成
NO-lsub失败:不能列出那个引用或者名称
BAD-未知命令,或者无效参数
LSUB命令返回的是,用户已经声明为活动的、或者订阅了的名称序列的一个名称子集。0个或者更多的非标签化LSUB答复被返回。LSUB的参数同于LIST的形式。
返回的非标签化LSUB响应可能包含从一个非标签化LIST响应的不同邮箱标记。如果出现这个,那么在非标签化LIST中的标记会被认为是更可信的。
当使用带有%通配符的LSUB时,一种特殊的情形就出现了。试想一下,如果“foo/bar”(带有一个“/”层级定义符)是已订阅的,而“foo”不是。在LSUB响应中,LSUB的一个“%”通配符必须返回foo,而不是foo/bar,并且它必须标记为带/Noselect属性的。
服务器不能单方面从订阅列表中移除一个已经存在的邮箱名,即使那个名称的邮箱已经不存在了。
例子:
C: A002 LSUB “#news.” “comp.mail.*”
S: * LSUB () “.” #news.comp.mail.mime
S: * LSUB () “.” #news.comp.mail.misc
S: A002 OK LSUB completed
C: A003 LSUB “#news.” “comp.%”
S: * LSUB (/NoSelect) “.” #news.comp.mail
S: A003 OK LSUB completed
6.3.10. STATUS命令
参数:邮箱名,状态数据项名
响应:非标签化响应:STATUS
结果:OK-status完成
NO-status失败:没有那个名称的status
BAD-未知命令,或者无效参数
STATUS命令请求指定邮箱的状态。它不改变当前被选中的邮箱,也不影响被请求的邮箱中的任何邮件的状态(特别的,STATUS不能使邮件失去/Recent标记)。
STATUS提供了这样一个选择:在没有取消选择第一次IMAP4rev1连接中的当前邮箱的情况下,就打第二次IMAP4rev1连接,并在一个邮箱上进行一个EXAMINE命令以请求那个邮箱的状态。
与LIST命令不同,STATUS命令不一定是快速响应的。在特定条件下,它可能是很慢的。在某些实现体中,服务器被希望以只读方式内部打开邮箱获取特定的状态信息。STATUS命令不接受通配符,这一点也与LIST命令不同。
注意:STATUS命令用于访问邮箱的状态,而不是当前选中的邮箱。因为STATUS命令可以使邮箱被内部打开,且这个信息是可以通过在选中邮箱上的其它手段获取的,所以STATUS命令不应当用于当前选中邮箱。
STATUS命令不能用于“检查选中邮箱中的新邮件”操作(关于检查新邮件的恰当方法的更多信息,参看第7章,7.3.1和7.3.2)。
因为STATUS命令不一定是快速响应的,所以客户端不应当预计能够发出一连串的STATUS命令并获得相应的执行。
当前定义了的、可以请求的状态数据项有:
MESSAGES
邮箱中邮件数量。
RECENT
带有/Recent标记位的邮件数量。
UIDNEXT
邮箱的下一个唯一标识符的值。更多信息参看2.3.1.1一节。
UIDVALIDITY
邮箱的唯一标识符检验码。更多信息参看2.3.1.1一节。
UNSEEN
不带有/Seen标记位的邮件数量。
例子:
C: A042 STATUS blurdybloop (UIDNEXT MESSAGES)
S: * STATUS blurdybloop (MESSAGES 231 UIDNEXT 44292)
S: A042 OK STATUS completed
6.3.11. APPEND命令
参数:邮箱名,OPTIONAL位的组合列表,OPTIONAL日期/时间串,邮件原义
响应:此命令无特定响应
结果:OK-append完成
NO-append错误:不能添加到该邮箱,标记、或者日期/时间、或者邮件文本有错误
BAD-未知命令,或者无效参数
APPEND命令将原义参数像一个新邮件一样添加到指定的目标邮箱末尾。这个参数应当是一个[RFC-2822]邮件的格式。邮件中允许8位字符串。一个不能正确保存8位数据的服务器执行体必须能够用一个[MIME-IMB]内容转换编码,进行8位APPEND数据与7位(APPEND数据)之间的可逆转换。
注意:可能有例外,比如,草稿邮件――其中被请求的[RFC-2822]头在APPEND的邮件原义参数中被省略了。这样做的整个关联必须被理解并小心权衡。
如果一个组合列表被声明,则标记位应当在结果邮件中被设置;否则,结果邮件的标记列表默认设置为空。两种情况下,Recent标记都要设置。
如果声明了一个日期-时间,实际日期应当在结果邮件中被设置;否则,结果邮件的实际日期默认设置为当前日期和时间。
如果插入操作因为某种原因不能成功,邮箱必须恢复至APPEND尝试前的状态;不允许局部的插入操作。
如果目标邮箱不存在,服务器必须返回一个错误,且不能自动创建邮箱。除非确定目标邮箱不能被创建,否则,服务器必须发送响应码“[TRYCREATE]”作为标签化NO响应的文本的前缀。这给客户端一个暗示,即它可以尝试一个CREATE命令,并且,如果CREATE成功,还可以重试APPEND。
如果邮箱当前被选中,正常的新邮件动作应当发生。特别地,服务器应当通过一个非标签化的EXISTS响应迅速通知客户端。如果服务器不这样做,客户端可以在一个或者多个APPEND命令之后发出一个NOOP命令(或者,NOOP命令失败,发出一个CHECK命令)。
例子:
C: A003 APPEND saved-messages (/Seen) {310}
S: + Ready for literal data
C: Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)
C: From: Fred Foobar
C: Subject: afternoon meeting
C: To:
C: Message-Id:
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
注意:APPEND命令不用于邮件发送,因为它不支持转换[SMTP]信封信息的机制。
6.4. 客户端命令-被选中状态
在被选中状态,操作一个邮箱中邮件的命令是被允许的。
除了全局命令(CAPABILITY, NOOP, 及LOGOUT),及认证状态命令(SELECT, EXAMINE, CREATE, DELETE, RENAME, SUBSCRIBE, UNSUBSCRIBE, LIST, LSUB, STATUS, 及APPEND),在被选中状态时以下命令也是有效的:CHECK, CLOSE, EXPUNGE, SEARCH, FETCH, STORE, COPY, 及UID。
6.4.1. CHECK命令
参数:无
响应:此命令无需特定响应
结果:OK-check完成
BAD-未知命令,或者无效参数
CHECK命令请求当前被选中邮箱的一个检查站。一个检查站指向每个取决于实现体的、与邮箱相关联的(例如,以邮箱在硬盘中的状态,决定它在服务器上的内存中的状态)、并不是作为每个命令的一部分进行常规执行的内部事务。一个检查站可以完成实时的非瞬时数量。如果一个服务器实现体没有这些内部事务的考虑,CHECK等效于NOOP。
一个EXISTS非标签化响应作为CHECK的一个结果发生,这是不一定的。NOOP,而不是CHECK,应当用于新邮件的投票。
例子:
C: FXXZ CHECK
S: FXXZ OK CHECK Completed
6.4.2. CLOSE命令
参数:无
响应:此命令无需特定响应
结果:OK-close完成,当前是认证状态
BAD-未知命令,或者无效参数
CLOSE命令从当前被选中邮箱中永久删除带有/Deleted标记位的所有邮件,并从被选中状态返回至认证状态。没有非标签化EXPUNGE响应被发送。
如果邮箱通过EXAMINE命令被选中,或者用别的方法以只读方式选中,则没有邮件会被删除,也不会报错。
甚至,一个邮箱被选中,没有预先发送一个CLOSE命令,一个SELECT, EXAMINE, 或者LOGOUT命令就可以被发出。SELECT, EXAMINE, 及LOGOUT命令没有进行删除,就暗暗关闭了当前被选中的邮箱。然而,当很多邮件被删除时,一个CLOSE-LOGOUT或者CLOSE-SELECT序列比一个EXPUNGE-LOGOUT或者EXPUNGE-SELECT快得多,因为没有非标签化EXPUNGE响应(客户端可以适当忽略)被发送。
6.4.3. EXPUNGE命令
参数:无
响应:非标签化响应:EXPUNGE
结果:OK-expunge完成
NO-expunge失败:不能删除(例如,没有权限)
BAD-未知命令,或者无效参数
EXPUNGE命令从当前被选中邮箱中永久删除带有/Delted标记位的所有邮件。在返回一个OK到客户端前,每个被删除的的邮件会引发一个非标签化的EXPUNGE响应被发送。
例子:
C: A202 EXPUNGE
S: * 3 EXPUNGE
S: * 3 EXPUNGE
S: * 5 EXPUNGE
S: * 8 EXPUNGE
S: A202 OK EXPUNGE complted
注意:在这个例子中,邮件3,4,7,及11带/Deleted标记位。进一步的解释参看EXPUNGE响应的描述。
6.4.4. SEARCH命令
参数:OPTIONAL [CHARSET]声明,检索准则(一个或者多个)
响应:REQUIRED非标签化响应:SEARCH
结果:OK-search完成
NO-search错误:不能检索该[CHARSET]或者准则
BAD-未知命令,或者无效参数
SEARCH命令检索邮箱以获取符合给定准则的邮件。检索准则由一个或者多个检索关键词组成。来自服务器的非标签化SEARCH响应由符合检索准则的邮件相应的邮件序列号列表组成。
当多个关键词被声明时,结果是匹配这些关键词的所有邮件的交集(并起效)。例如,准则 DELETED FROM “SMITH” SINCE 1-Feb-1994 指向来自Smith的、自从1994年2月1日开始存放于邮箱中的所有被删除的邮件。一个检索关键词也可以是一个或者多个检索关键词的一个组合列表(例如,使用OR和NOT关键词)。
服务器实现体可能拒绝接受带有终端内容媒体类型的[MIM-IMB]主体部分,而接受TEXT和SEARCH匹配集相应的MESSAGE。
OPTIONAL [CHARSET]声明由其后紧跟着一个注册了的[CHARSET]的字“CHARSET”组成。它表示,出现在检索准则中的字符串的[CHARSET]。在以[CHARSET]而不是US-ASCII比较文本之前,[MIME-IMB]内容转换编码,及在[RFC-2822]/[MIME-IMB]头部的[MIME-HDRS]字符串,必须被解码。US-ASCII必须受支持;其它的[CHARSET]s可能受支持。
如果服务器不支持声明了的[CHARSET],它必须返回一个标签化的NO响应(而不是一个BAD)。该响应应当包含BADCHARSET响应码,该响应码可能列出受服务器支持的[CHARSET]s。
在字符串形式的所有检索关键词里,如果该字符串是该范围的一个子串,则邮件符合该关键词。匹配是不区分大小写的。
已定义的检索关键词如下。参数的准确语法定义参看正式语法一节。
带有已声明的邮件序列号集相应的邮件序列号的邮件。
ALL
邮件中所有邮件;ANDing的默认初始关键词。
ANSWERED
带有/Answered标记位的邮件。
BCC
在信封结构的BCC域包含有指定字符串的邮件。
BEFORE
实际日期(忽视时间和时区)早于指定日期的邮件。
BODY
在邮件的主体域包含有指定字符串的邮件。
CC
在信封结构的CC域包含有指定字符串的邮件。
DELETED
带有/Deleted标记位的邮件。
DRAFT
带有/Draft标记位的邮件。
FLAGGED
带有/Flagged标记位的邮件。
FROM
在信封结构的FROM域包含有指定字符串的邮件。
HEADER
带有一个含指定field-name([RFC-2822]中定义)的头部、且在该头部(它跟在colon之后)的文本中包含指定字符串的邮件。如果将要检索的字符串(参数中的string)长度为零,那么,它将匹配带有一个含指定field-name、内容可有可无的头部行的所有邮件。
KEYWORD
带有指定关键词标记位的邮件。
LARGER
带有一个[RFC-2822](定义)的、大于指定字节数的大小的邮件。
NEW
带有/Recent标记位,但不带有/Seen标记的邮件。它在功能上等效于“(RECENT UNSEEN)”。
NOT
不符合指定检索关键词的邮件。
OLD
不带有/Recent标记位的邮件。它在功能上等效于“NOT RECENT”(与“NOT NEW”相反)。
ON
实际日期(忽视时间和时区)在指定日期的邮件。
OR
符合任意一个检索关键词的邮件。
RECENT
带有/Recent标记位的邮件。
SEEN
带有/Seen标记位的邮件。
SENTBEFORE
[RFC-2822]Date: header(忽视时间和时区)早于指定日期的邮件。
SENTON
[RFC-2822]Date: header (忽视时间和时区)在指定日期的邮件。
SENTSINCE
[RFC-2822]Date: header (忽视时间和时区)在指定日期或者晚于指定日期的邮件。
SINCE
实际日期(忽视时间和时区)在指定日期或者晚于指定日期的邮件。
SMALLER
带有一个[RFC-2822]的、小于指定字节数大小的邮件。
SUBJECT
在信封结构的SUBJECT域含有指定字符串的邮件。
TEXT
在邮件的头部或者主体含有指定字符串的邮件。
TO
在信封结构的TO域含有指定字符串的邮件。
UID
带有指定唯一标识符集相应的唯一标识符的邮件。序列集顺序排列是允许的。
UNANSWERED
不带有/Answered标记位的邮件。
UNDELETED
不带有/Deleted标记位的邮件。
UNDRAFT
不带有/Draft标记位的邮件。
UNFLAGGED
不带有/Flagged标记位的邮件。
UNKEYWORD
不带有指定关键词标记位的邮件。
UNSEEN
不带有/Seen标记位的邮件。
例子:
C: A282 SEARCH FLAGGED SINCE 1-Feb-1994 NOT FROM “Smith”
S: * SEARCH 2 84 882
S: A282 OK SEARCH completed
C: A283 SEARCH TEXT “string not in mailbox”
S: * SEARCH
S: A283 OK SEARCH completed
C: A284 SEARCH CHARSET UTF-8 TEXT {6}
C: XXXXXX
S: * SEARCH 43
S: A284 OK SEARCH completed
注意:因为本文档限制于7位ASCII文本,所以不可能显示真的UTF-8。“XXXXXX”可能是实际处理中的8位数据的6个字节。
6.4.5. FETCH命令
参数:序列集,邮件数据项名称或者宏
响应:非标签化响应:FETCH
结果:OK-fetch完成
NO-fetch错误:不能获取该数据
BAD-未知命令,或者无效参数
FETCH命令获取邮箱中的一个邮件的相关数据。被获取的数据项可以是一个原语,或者一个组合列表。
在正式语法中基于msg-att-static规则确认的大部分数据项,是静态的,并且不能因为任意特定邮件而改变。在正式语法中msg-att-static规则确认的其它数据项,可以改变,或者作为一个STORE命令的一个结果,或者因为外部事件。
例如,如果一个客户端接收到它已经知道的、一个邮件的一个信封,它可以安全地忽略新传送的信封。
有三种宏,它们指明数据项的普遍使用集,并能代替数据项使用。一个宏必须被自身所用,并且不能与其它宏或者数据项连接。
ALL
等效于:(FLAGS INTERNALDATE RFC822.SIZE ENVELOPE)
FAST
等效于:(FLAGS INTERNALDATE RFC822.SIZE)
FULL
等效于:(FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY)
现在已经定义的、可以被获取的数据项有:
BODY
BODYSTRUCTURE的不可扩展形式。
特定主体块的文本。块声明是一个零的集合,或者根据时间分隔开的更多块声明。一个块声明或者是一个块号,或者是以下的一个:HEADER,HEADER.FIELDS,HEADER.FIELDS.NOT,MIME,及TEXT。一个空的块声明指向整个邮件,包括头部。
每个邮件有至少一个块号。Non-[MIME-IMB]邮件,及不带内嵌邮件的non-multipart[MIME-IMB]邮件,只有一个块1。
邮件簇被分配连续的块号,如果它们出现在邮件中。如果一个特定块的类型是邮件或者邮件簇,则这个块后面必须跟着它在块簇中的块号的时间。
一个类型为MEEAGE/RFC822类型的块也有块号,指向MESSAGE块域的块集。
HEADER,HEADER.FIELDS,HEADER.FIELDS.NOT,及TEXT块声明可能是单个块声明,也可能是以一个或者多个数字型的块声明为前缀――其前提是该数字型的块声明指向一个MESSAGE/RFC822类型的块。MIME块声明必须以一个或者多个数字型的块声明为前缀。
HEADER,HEADER.FIELDS,及HEADER.FIELDS.NOT块声明指向邮件的[RFC-2822]头部,或者一个内嵌[MIME-IMT] MESSAGE/RFC822邮件。HEADER.FIELDS和HEADER.FIELDS.NOT其后跟着field-name([RFC-2822]中有定义)名称的一个列表,并返回头部的一个子集。HEADER.FIELDS返回的子集只包括那些带有与列表中的名称之一相符的一个field-name的头部域;类似地,HEADER.FIELDS.NOT返回的子集只包含带有一个不匹配域名称的头部域。域匹配是不区分大小写的,除非用别的方法强制。子集化并不把[RFC-2822]定义的、头部和主体之间的空行排除在外;空行包含在所有头部获得中,除非一个邮件没有主体也没有空行。
MIME块声明指向该块的[MIME-IMB]头部。
TEXT块声明指向邮件的文本主体,不包括[RFC-2822]头部。
这是一个带有它的一些块声明的复杂邮件的一个例子:
HEADER ([RFC-2822] header of the message)
TEXT ([RFC-2822] text body of the message) MULTIPART/MIXID
1 TEXT/PLAIN
2 APPLICATION/OCTET-STREAM
3 MESSAGE/RFC2822
3.HEADER ([RFC-2822] header of the message)
3.TEXT ([RFC-2822] text body of the message) MULTIPART/MIXED
3.1 TEXT/PLAIN
3.2 APPLICATION/OCTET-STREAM
4 MULTIPART/MIXED
4.1 IMAGE/GIF
4.1.MIME ([MIME-IMB] header for the IMAGE/GIF)
4.2 MESSAGE/RFC822
4.2.HEADER ([RFC-2822] header of the message)
4.2.TEXT ([RFC-2822] text body of the message) MULTIPART/MIXID
4.2.1 TEXT/PLAIN
4.2.2 MULTIPART/ALTERNATIVE
4.2.2.1 TEXT/PLAIN
4.2.2.2 TEXT/RICHTEXT
获取指定文本的一个子串是可能的。这是通过添加一个开的角符(“〈”),请求的第一个字节位置,一个时间,请求的字节的最大数,及一个闭的角符(“〉”)到块声明,来实现的。如果起始字节超出了文本的末尾,则返回一个空的字符串。
试图读取超出文本末尾内容的任何局部获取都会被适当截断。从第0字节开始的一个局部获取都返回局部获取,即使这种截断发生。
注意:这意味着一个1500字节的邮件的BODY[]<0.2048>将返回带有一个大小1500的原义的BODY[]<0>,而不是BODY[]。
注意:一个HEADER.FIELDS或者HEADER.FIELDS.NOT块声明的一个子串获取,在子集化头部之后计算。
/Seen标记是隐含标记;如果这导致标记改变,它们应当作为FETCH响应的一部分被包含进来。
BODY[
BODYSTRUCTURE
邮件的[MIME-IMB]主体结构。它的计算是由服务器把[MIME-IMB]头部域解释为[RFC-2822]头部和[MIME-IMB]头部。
ENVELOPE
邮件的信封结构。它的计算是由服务器把[RFC-2822]头部解释为组件块,默认为所需要的多个域。
FLASG
为该邮件设置的标记。
INTERNALDATE
邮件的实际日期。
RFC822
功能上等效于BODY[],不同的是,其结果的非标签化FETCH数据(返回RFC822)的语法。
RFC822.HEADER
功能上等效于BODY.PEEK[HEADER],不同的是,其结果的非标签化FETCH数据(返回RFC822.HEADER)的语法。
RFC822.SIZE
邮件的[RFC-2822]大小。
RFC822.TEXT
功能上等效于BODY[TEXT],不同的是,其结果的非标签化FETCH数据(返回RFC822.TEXT)的语法。
UID
邮件的唯一标识符。
例子:
C: A654 FETCH 2:4 (FLAGS BODY[HEADER.FIELDS (DATE FROM)])
S: * 2 FETCH ….
S: * 3 FETCH ….
S: * 4 FETCH ….
S: A654 OK FETCH completed
6.4.6. STORE命令
参数:序列集,邮件数据项名称,邮件数据项值
响应:非标签化响应:FETCH
结果:OK-store完成
NO-store错误:不能保存该数据
BAD-未知命令,或者无效参数
STORE命令修改邮箱中邮件相关的数据。正常地,STORE将返回数据更新后的值和一个非标签化FETCH响应。数据项名称中的“.SILENT”后缀保护该非标签化FETCH,且服务器应当假定客户端已经自行决定了该更新后的值,或者客户端不关心该更新后的值。
注意:不管是否使用了“.SILENT”后缀,如果发现一个邮件的标记有源于外部资源的改变,服务器应当发送一个非标签化FETCH响应。目的是使标记的状态在没有竞争的情况下确定。
现在已经定义了的、可以保存的数据项有:
FLAGS
用参数替代邮件(不是/Recent)的标记。返回标记集的新值,就像那些标记集的FETCH结果一样。
FLAGS.SILENT
等效于FLAGS,但是不会返回一个新值。
+FLAGS
增加参数至邮件的标记集中。返回标记集的新值,就像那些标记集的FETCH结果一样。
-FLAGS
从邮件的标记集中删除参数。返回标记集的新值,就像那些标记集的FETCH结果一样。
-FLAGS.SILENT
等效于-FLAGS,但是不会返回一个新值。
例子:
C: A003 STORE 2:4 +FLAGS (/Deleted)
S: * 2 FETCH (FLAGS (/Deleted /Seen))
S: * 3 FETCH (FLAGS (/Deleted))
S: * 4 FETCH (FLAGS (/Deleted /Flagged /Seen))
S: A003 OK STORE completed
6.4.7. COPY命令
参数:序列集,邮箱名
响应:此命令无需特定响应
结果:OK-copy完成
NO-copy错误:不能复制那些邮件,或者复制到那个名称
BAD-未知命令,或者无效参数
COPY命令复制指定邮件到特定目标邮箱的末尾。在拷贝件中,邮件的标记和实际日期应当被保存,且Recent标记应当被设置。
如果目标邮箱不存在,服务器应当返回一个错误。它不应当自动创建邮箱。除非确实不能创建目标邮箱,否则服务器必须发送响应码“[TRYCRETAE]”作为标签化NO响应的文本前缀。这暗示客户端,它可以尝试一个CREATE命令,并且如果CREATE成功,它可以重试COPY。
如果COPY命令因为某种原因不能成功,服务器实现体必须恢复目标邮箱状态到COPY尝试之前的状态。
例子:
C: A003 COPY 2:4 MEETING
S: A003 OK COPY completed
6.4.8. UID命令
参数:命令名,命令参数集
响应:非标签化响应:FETCH,SEARCH
结果:OK-UID命令完成
NO-UID命令错误
BAD-未知命令,或者无效参数
UID命令有两种形式。在第一种形式中,它的参数是一个带有相应的一些适当参数的COPY,FETCH,或者STORE命令。不过,参数序列中的数字是唯一标识符,而不是邮件序列号。序列集是许可的,但是有可能唯一标识符不是连续的。
一个不存在的唯一标识符将被忽略,而不会产生任何错误信息。一个UID FETCH命令可能只返回一个OK,没有任何数据;一个UID COPY或者UID STORE可能只返回一个OK,没有任何操作。
在第二种形式中,UID命令的参数是一个带有SEARCH命令参数的SEARCH命令。这些参数的解释同于它们仅仅跟着SEARCH;但是,一个UID SEARCH命令的一个SEARCH响应返回的数字是唯一标识符,而不是邮件序列号。例如,命令UID SEARCH 1:100 UID 443:557返回的是,邮件序列的数字队列1:100,及UID队列443:557,这两个序列集的交集相应的唯一标识符。
注意:在上面的例子中,出现了UID队列443:557。一个不存在的唯一标识符会被忽略,而不会产生任何错误信息,同样的解释也适用于此。因此,即使UID443或者557不存在,这个队列也是有效的,且可以包含一个存在的UID495。
还要注意,一个UID队列559:*永远包括邮箱中最末邮件的UID,即使559大于已分配的任何UID值。这是因为一个队列的内容独立于队列末点的顺序。因此,以*作为一个末点的任意UID队列表示至少一个邮件(该邮件的UID是最大的),除非这个邮箱是空的。
一个非标签化FETCH响应中的“*”后的数字永远是一个邮件序列号,而不是一个唯一标识符,甚至对于一个UID命令响应也是如此。然而,服务器实现体必须隐式地包括UID邮件数据项作为一个UID命令引发的任意FETCH的响应部分,不管一个UID是否被指定为一个到FETCH的邮件数据项。
注意:包括一个UID邮件数据项作为一个FETCH的响应部分,这个规则主要适用于UID FETCH和UID STORE命令,包括一个不含UID作为一个邮件数据项的UID FETCH命令。尽管其它UID命令不太可能引发一个非标签化的FETCH,但是这个规则也适用于这些命令。
例子:
C: A999 UID FETCH 4827313:4828442 FLAGS
S: * 23 FETCH (FLAGS (/Seen) UID 4827313)
S: * 24 FETCH (FLAGS (/Seen) UID 4827943)
S: * 25 FETCH (FLAGS (/Seen) UID 4828442)
S: A999 OK UID FETCH completed
6.5. 客户端命令-试验/扩展
6.5.1. X命令
参数:已定义的实现体
响应:已定义的实现体
结果:OK-命令完成
NO-失败
BAD-未知命令,或者无效参数
任何以一个X为前缀的命令都是一个试验命令。不属于本文档、本文档的标准修正版或者一个IESG认证的试验标准的一部分的命令,必须用X作为前缀。
任何增加的、一个试验命令引发的非标签化响应也必须以一个X作为前缀。服务器实现体不能发送任何这样的非标签化响应,除非客户端通过发出关联的试验命令来请求它。
例子:
C: a441 CAPABILITY
S: * CAPABILITY IMAP4rev1 XPIG-LATIN
S: a441 OK CAPABILITY completed
C: A442 XPIG-LATIN
S: * CAPABILITY IMAP4rev1 XPIG-LATIN
S: a441 OK CAPABILITY completed
C: A442 XPIG-LATIN
S: * XPIG-LATIN ow-nay eaking-spay ig-gay atin-lay
S: A442 OK XPIG-LATIN ompleted-cay
7.服务器响应
服务器响应有三种形式:状态响应,服务器数据,及命令连续请求。一个服务器响应中的信息,在下面的响应描述中定义的“内容:”,通过功能,而不是语法来描述。服务器响应的精确语法在正式语法一节中有描述。
客户端必须一直准备着接收任何响应。
状态响应可以是标签化或者非标签化的。标签化的状态响应表示一个客户端命令的完成结果(OK,NO,或者BAD状态),并且有一个与该命令匹配的标签。
某些状态响应,及所有的服务器数据,是非标签化的。一个非标签化的响应用一个“*”记号而不是一个标签来表示。非标签化的状态响应表示服务器欢迎,或者那些不表示一个命令完成的服务器状态(例如,一个紧急系统关机警告)。因为历史原因,非标签化服务器数据响应也被称为“主动提供的数据”,虽然严格地讲,只有单方面服务器数据是真正的“主动提供的数据”。
某些服务器数据,当客户端接收到它们的时候,必须被记录下来;它被记到那些数据的描述里。这些数据承载着影响到所有后来的命令和响应的解释的紧急信息(例如,创建或者销毁邮件相关的更新)。
其它的服务器数据应当记录以便以后参考;如果客户端不需要记录这些数据,或者没有明显的意图要记录这些数据(例如,没有其它SEARCH命令在行进中时的一个SEARCH响应),那么就应当忽略这些数据。
当IMAP连接在选中状态时,单方面的、非标签化的服务器数据的一个例子就发生了。在选中状态,服务器确认邮箱的新邮件,这作为命令执行的一部分。通常,这是任何一个命令的执行的一部分;因此,一个NOOP命令就可以确认新邮件。如果发现新邮件,服务器发送非标签化的、反映邮箱的新大小的EXISTS和RECENT响应。经常有不同的连接至相同邮箱的服务器实现体,如果另外的代理改变任意邮件标记的状态或者删除任意邮件,它也应当发送适当的、单方面的、非标签化FETCH和EXPUNGE响应。
命令的连续请求响应使用标记“+”取代一个标签。这些响应由服务器发送,以确信一个不完整的客户端命令和命令的剩余部分的准备就绪。
7.1. 服务器响应-状态响应
状态响应是OK,NO,BAD,PREAUTH和BYE。OK,NO,和BAD可以是标签化或者非标签化的。PREAUTH和BYE永远是非标签化的。
服务器响应可能包含一个可选的“响应码”。一个响应码由一个原语形式的四方形内的数据组成,可能后面跟着一个空格和参数。响应码为客户端软件包含其它信息或者状态码,而不只是OK/NO/BAD的情况,它定义于,当出现一个已经定义的、客户端基于该额外信息可采用的动作时。
目前已定义的响应码有:
ALERT
可读文本,包含一个警告,这个警告必须以一种唤起用户对该邮件的注意的式样展现给用户。
BADCHARSET
后面随意地跟着字符集的一个组合列表。给定的字符集不被这个实现体支持时,一个SEARCH就失败了。如果字符集的选择列表给定了,那么这就列出被这个实现体支持的字符集。
CAPABILITY
后面跟着功能的一个列表。这将会出现在初始的OK或者PREAUTH响应,以传送一个初始的功能列表。这使得没必要让一个客户端发送一个单独的CAPABILITY命令,如果它认出了这个响应。
PARSE
可读文本,描绘解析邮箱中的一个邮件的[RFC-2822]头部或者[MIME-IMB]头部时的一个错误。
PERMANENTFLAGS
后面跟着标记的一个组合列表,指明客户端可以永久修改的已知标记。在FLAGS非标签化响应中,但不在PERMANENTFLAGS列表中的任何标记,不能被永久性地设置。如果客户端试图存储一个不在PREMANENTFLAGS列表中的标记,服务器或者忽略该修改,或者只存储当前会话的剩余部分的状态修改。PERMANENTFLAGS列表也可以包括特殊的标记/*,它表明可以通过尝试存储邮箱中的那些标记,来创建新的关键词。
READ-ONLY
邮箱以只读方式选中,或者当被选中时它的连接已经从读写方式改变为只读方式了。
READ-WRITE
邮箱以读写方式选中,或者当被选中时它的连接已经从只读方式改变为读写方式了。
TRYCREATE
一个APPEND或者COPY尝试失败,因为目标邮箱不存在(与其它一些原因相反)。这是对客户端的一个提示,如果邮箱先通过CREATE命令被创建,这个操作就能够成功。
UIDNEXT
后面跟着一个十进制的数字,指明下一个唯一标识符的值。更多信息参考2.3.1.1一节。
UIDVALIDITY
后面跟着一个十进制的数字,指明唯一标识符的值。更多信息参考2.3.1.1一节。
UNSEEN
后面跟着一个二进制的数字,指明不带有/Seen标记位的第一个邮件的号数。
定义于特定的客户端或者服务器实现体的扩展响应码应当以一个“X”作为前缀,直到它们被加到这个协议的一个版本中来。客户端实现体应当忽略其不认识的响应码。
7.1.1. OK 响应
内容:OPTIONAL响应码,可读文本
OK响应指明来自服务器的一个信息邮件。其标签化时,它指明关联命令的成功完成。可读文本可能作为一个信息邮件展现给用户。其非标签化形式指明一个纯信息的邮件;信息的各类可能通过一个响应码来指明。
其非标签化形式也用于连接启动时的三个可能欢迎中的一个。它指明该连接是未认证的,且需要一个LOGIN命令。
例子:
S: * OK IMAP4rev1 server ready
C: A001 LOGIN fred blurdybloop
S: * OK [ALERT] System shutdown in 10 minutes
S: A001 OK LOGIN Completed
7.1.2. NO响应
内容:OPTIONAL响应码,可读文本
NO响应指明来自服务器的一个错误。其标签化时,它报告客户端命令的一个协议级的错误;标签指明导致该错误的命令。其非标签化形式指明关联命令不能抉择的一个协议级错误;它也指明一个内部服务器失败。可读文本描述了这种情况。
例子:
C: … very long command line…
S: * BAD Command line too long
C: …empty line …
S: * BAD Empty command line
C: A443 EXPUNGE
S: * BAD Disk crash, attempting salvage to a new disk!
S: * OK Salvage successful, no data lost
S: A443 OK Expunge completed
7.1.3. BAD响应
内容:OPTIONAL响应码,可读文本
BAD响应指明来自服务器的一个错误。其标签化时,它报告客户端命令的一个协议级的错误;标签指明导致该错误的命令。其非标签化形式指明关联命令不能抉择的一个协议级错误;它也指明一个内部服务器失败。可读文本描述了这种情况。
例子:
C: …very long command line…
S: * BAD Command line too long
C: …empty line…
S: * BAD Empty command line
C: A443 EXPUNGE
S: * BAD Disk crash, attempting salvage to a new disk!
S: * OK Salvage successful, no data lost
S: A443 OK Expunge completed
7.1.4. PREAUTH响应
内容:OPTIONAL响应码,可读文本
PREAUTH响应永远是非标签化的,且是连接启动时三种可能欢迎中的一种。它指明连接已经通过外部手段认证了;因而不需要LOGIN命令。
例子:
S: * PREAUTH IMAP4rev1 server logged in as Smith
7.1.5. BYE响应
内容:OPTIONAL响应码,可读文本
BYE响应永远是非标签化的,且指明该服务器准备关闭连接。可读文本可能被客户端用一个状态报告呈现给用户。BYE响应在以下4种情形下的一种发送:
1)作为一个正常注销队列的一部分。服务器将在发送标签化的OK响应至LOGOUT命令后,关闭连接。
2)作为一个突然关机的公告。服务器突然关掉连接。
3)作为一个静止状态的自动注销的一个公告。服务器突然关掉连接。
4)作为连接开始时的三种可能欢迎的一个,表明服务器不愿接收来自该客户端的连接。服务器突然关掉连接。
作为一个正常的注销序列(第一种情况)的一部分发生的一个BYE,及因为一个失败(其它的情况)发生的一个BYE,两者的区别是,在失败的情况下连接突然关掉。在所有情况下,客户端都应当继续读取来自服务器的响应数据,直到连接关闭;这将确保任何未决的、非标签化的,或者完成了的响应被读取及处理。
例子:
S: * BYE Autologout; idle for too long
7.2. 服务器响应-服务器和邮箱状态
这些响应永远是非标签化的。这是服务器和邮箱的状态数据如何被从服务器传送至客户端(的所在)。这些响应的一个特点是,很多因为来自一个命令而有相同的名字。
7.2.1. CAPABILITY响应
内容:capability列表
CAPABILITY响应作为一个CAPABILITY命令的一个结果发生。capability列表包含一个用空格分隔的、服务器支持的功能列表。功能列表必须包含原语“IMAP4rev1”。
另外,客户端和服务器实现体必须实现STARTTLS,LOGINDISABLED,及AUTH=PLAIN(描述于[IMAP-TLS])功能。重要信息参看安全考虑一节。
以“AUTH=”开头的一个功能名表明服务器支持这种特别的认证机制。
LOGINDISABLED功能表明LOGIN命令是不可用的,并且,即使用户名和密码是正确的,服务器也将会以一个标签化的NO响应作为使用LOGIN命令的任何尝试的响应。如果服务器宣告LOGINDISABLED功能,那么一个IMAP客户端就不能发送LOGIN命令。
其它的功能名表明服务器支持IMAP4rev1协议的一个扩展,修订版,或者改善版。服务器响应必须遵守本文档,直至客户端发送一个使用关联功能的命令。
功能名必须以“X”开头,或者是标准的,或者是标准的IMAP4rev1扩展,修订版,或者在IANA注册的改善版。一个服务器不能提供未注册的,或者非标准的功能名,除非这些名称以“X”为前缀。
客户端不应当请求“IMAP4rev1”以外的任何功能名,而且必须忽略任何未知的功能名。
通过在初始PREAUTH时使用一个CAPABILITY响应码,或者使用OK响应,通过发送标签化的OK响应中的一个更新的CAPABILITY响应作为一个成功认证的一部分,服务器就可以自动地发送功能。如果客户端识别出了这些自动的功能,它就没必要发送一个单独的CAPABILITY命令。
例子:
S: * CAPABILITY IMAP4rev1 STARTTLS AUTH=GSSAPI XPIG-LATIN
7.2.2. LIST响应
内容:名称属性,层级分隔符,名称
LIST响应作为一个LIST命令的一个结果发生。它返回符合LIST描述的一个单独的名称。一个单独的LIST命令可能会有多个LIST响应。
有四个名称属性被定义:
/Noinferiors
该名称下不可能存在任何子层;现在没有子层,以后也不能创建。
/Marked
邮箱已经被服务器标记为“受关注的”;上次被选中后,这个邮箱大概有新的邮件加进来。
/Unmarked
自从被选中后,这个邮箱就没有加进新的邮件。
如果对服务器来说判断邮箱是否是“受关注的”、或者其名称是否是一个/Noselect名称并不切实可行,则服务器不应当发送/Marked或者/Unmarked。
层级分隔符是用来分隔一个邮箱名称的层级的一个字符。一个客户端可以用它来创建子邮箱,及检索名称层级的更高级或者更低级。一个顶层节点的所有孩子必须使用相同的分隔符。一个NIL层级分隔符意味着不存在层级;即名称都在一层。
名称展现为明确的从左至右的层级,并且,用作LIST和LSUB命令的一个参考时必须是正确的。除非/Noselect被指明,否则,用作命令(如SELECT,接受邮箱名)的参数时,名称必须是正确的。
例子:
S: * LIST (/Noselect) “/” ~/Mail/foo
7.2.3. LSUB响应
内容:名称属性,层级分隔符,名称
LSUB响应作为一个LSUB命令的一个结果发生。它返回符合LSUB描述的一个单独的名称。一个单独的LSUB命令可以有多个LSUB响应。LIST响应的数据形式是一样的。
例子:
S: * LSUB () “.” #news.comp.mail.misc
7.2.4. STATUS响应
内容:名称,状态组合列表
STATUS响应作为一个STATUS命令的一个结果发生。它返回符合STATUS描述和请求的邮箱状态信息的邮箱名。
例子:
S: * STATUS blurdybloop (MESSAGES 231 UIDNEXT 44292)
7.2.5. SEARCH响应
内容:0个或者更多个数字
SEARCH响应作为一个SEARCH或者UID SEARCH命令的一个结果发生。这些数字指向那些符合检索标准的邮件。对SEARCH,这些是邮件序列号;对UID SEARCH,这些是唯一标识符。每个数字被一个空格分开。
例子:
S: * SEARCH 2 3 6
7.2.6. FLAGS响应
内容:标记组合列表
FLAGS响应作为一个SELECT或者EXAMINE命令的一个结果发生。标记组合列表确定适用于该邮箱的标记(至少,系统定义的标记)。系统标记以外的标记也可以存在,这取决于服务器实现体。
来自FLAGS响应的更新必须被客户端记录。
例子:
S: * FLAGS (/Answered /Flagged /Deleted /Seen /Draft)
7.3. 服务器响应-邮箱大小
这些响应永远是非标签化的。这是邮箱大小的改变怎样被从服务器传送至客户端的(的所在)。后面直接跟着“*”符号的是表示一个邮件数量的数字。
7.3.1. EXISTS响应
内容:无
EXISTS响应报告邮箱中的邮箱数量。这个响应作为一个SELECT或者EXAMINE命令,及邮箱大小是否改变的一个结果发生(例如,新邮件)。
来自EXISTS响应的更新必须被客户端记录。
例子:
S: * 23 EXISTS
7.3.2. RECENT响应
内容:无
RECENT响应报告带有/Recent标记位的邮件的数量。这个响应作为一个SELECT或者EXAMINE命令,及邮箱大小是否改变的一个结果发生(例如,新邮件)。
注意:新近邮件的邮件序列号不一定是邮箱中的最高n个邮件的一个连续队列(该邮箱中,n是被RECENT响应报告的数值)。 例子:多个客户端打开了同一个邮箱(第一个被通报的会话将视其为新近的,其它的会话将视其为非新近的,及当邮箱被一个非IMAP代理重新排序时)。
辨别新近邮件的唯一可靠方法是察看邮件标记,看哪个带有/Recent标记位,或者做一个SEARCH RECENT。
来自RECENT响应的更新必须被客户端记录。
例子:
S: * 5 RECENT
7.4. 服务器响应-邮件状态
这些响应永远是非标签化的。这是邮件数据如何被从服务器传送至客户端(的所在)。它经常被作为带有相同名称(参数)的一个命令的一个结果。后面直接跟着“*”符号的,是表示一个邮件序列号的一个数字。
7.4.1. EXPUNGE响应
内容:无
EXPUNGE响应报告指定邮件序号已经被从邮件中永久删除了。邮箱中每一个后续的邮件的邮件序列号都马上减1,且这个减小反映在后来的响应中的邮件序列号(包括其它非标签化的EXPUNGE响应)。
EXPUNGE响应也减小邮箱中的邮件数量;没必要发送一个带有新值的EXISTS响应。
作为即时减少规则的一个结果,出现在成功的EXPUNGE响应的一个集合中的邮件序列号,取决于邮件是按由小到大的顺序删除,还是按由大到小的顺序删除。例如,假如一个有9个邮件的邮箱中的最后5个邮件被删除,一个“由小到大”的服务器将会发送5个非标签化EXPUNGE响应至邮件序列号5,而一个“由大到小”的服务器将会发送成功的非标签化EXPUNGE响应至邮件序列号9,8,7,6,及5。
当没有命令在行进中时,或者正在响应一个FETCH,STORE,或者SEARCH命令时,不能发送一个EXPUNGE。为避免客户端和服务器之间的邮件序列号的同步造成丢失,这是有必要的。一个命令不是“在行进中”的,直到已经接收到完成命令;特别的,在命令连续的竞争中,一个命令不是“在行进中”的。
注意:UID FETCH,UID STORE,及UID SEARCH是不同于FETCH,STORE,及SEARCH的命令。一个EXPUNGE响应可以在一个UID命令期间发送。
来自EXPUNGE响应的更新必须被客户端记录。
例子:
S: * 44 EXPUNGE
7.4.2. FETCH响应
内容:邮件数据
FETCH响应返回客户端的一个邮件的相关数据。这些数据是名称项及其值的数据对,这些对分别被放在一个圆括号中。这个响应作为一个FETCH或者STORE命令的结果发生,也可以因为单方面的服务器决定发生(例如,标记更新)。
目前的数据项有:
BODY
BODYSTRUCTURE的一种形式,不带额外数据。
BODY[
表示指定块的主体内容的一个字符串。它应当被客户端通过内容转换编码,主体类型,及子类型来解释。
如果原始字节被指定,则该字符串是整个主体内容的一个子字符串,它从那个原始字节开始。这意味着,BODY[]<0>可能是被切断的,而BODY[]是不切断的。
注意:这个原始字节的方法不能被一个服务器在一个FETCH响应中使用,除非客户端通过一个BODY[
如果一个[CHARSET]标识符是这个块的主体参数组合列表的一部分,则8位文本数据是允许的。注意,头部(部分指HEADER或者MIME,或者一个MESSAGE/RFC822部分的头部),必须是7位的;8位字符在头部中是不允许的。还要注意,头部和主体间的[RFC-2822]分隔用空行并不见效于头部行的子集;该空行永远被作为头部数据的一部分被包含进来,除非邮件没有主体和空行。
非文本数据,如二进制数据,在传至客户端之前,必须转换编码为文本形式,如BASE64。客户端必须对转换编码的字符串解码,以得到原始的二进制数据。
BODYSTRUCTURE
描述一个邮件的[MIME-IMB]主体结构的一个组合列表。它是由服务器通过解析[MIME-IMB]头部域,必要情况下还包括各种默认域,计算出的。
例如,一个48行,2279字节的一个简单文本邮件有一个主体结构:(“TEXT” “PLAIN” (“CHARSET” “US-ASCII”) NIL NIL “7BIT” 2279 48)。多个部分被表示为组合巢。一个或者多个巢状主体结构的一个序列,代替了作为组合列表的第一元素的一个主体类型。组合列表的第二个元素是多个子表(混合的,相减的,平行的,二择一的,等等)。
例如,由一个文本和一个BASE64编码的文本附件组成的一个两部分邮件,可以有一个主体结构:((“TEXT” “PLAIN” (“CHARSET” “US-ASCII”) NIL NIL “7BIT” 1152 23)(“TEXT” “PLAIN” (“CHARSET” “US-ASCII” “NAME” “cc.diff”)”” “Compiler diff” “BASE64” 4554 73) “MIXED”)
扩展数据遵从多个子表。扩展数据不会与BODY获取返回,但是可以与一个BODYSTRUCTURE获取返回。扩展数据,如果出现,必须是按被定义的顺序。一个多域主体扩展数据有以下顺序:
主体参数组合列表
属性/值对的一个组合列表 [例如,”(foo” “bar” “baz” “rag”)其中“bar”是“foo”的值,“rag”是“baz”的值] ,如[MIME-IMB]所定义的。
主体部署
一个组合列表,由一个部署类型的字符串组成,其后跟着部署属性/值对的一个组合列表,如[DISPOSITION]所定义的。
主体语言
给出了主体语言值的一个字符串或者组合列表,如[LANGUAGE-TAGS]所定义的。
主体定位
给出了主体内容的URI的一个字符串列表,如[LOCATION]所定义的。
在该协议的这个版本中,还没有定义后来的扩展数据的任何一个。这些扩展数据可以包括0或者更多的NIL,字符串,数字,或者这些数据的潜在巢状组合列表。执行一个BODYSTRUCTURE获取的客户端实现体必须有所准备地接收这些扩展数据。服务器实现体不能发送这些扩展数据,直到它已经被该协议的一个修订版所定义。
一个非多域主体部分的基本域有以下顺序:
主体类型
给出了内容媒体类型的一个字符串,如[MIME-IMB]所定义的。
主体子类型
给出了内容的子类型的一个字符串,如[MIME-IMB]所定义的。
主体参数组合列表
属性/值对的一个组合列表[例如,(“foo” “bar” “baz” “rag”)其中,”bar”是”foo”的值,”rag’是”baz”的值],如[MIME-IMB]所定义的。
主体号
给出了内容号的一个字符串,如[MIME-IMB]所定义的。
主体描述
给出了内容描述的一个字符串,如[MIME-IMB]所定义的。
主体编码
给出了内容转换编码的一个字符串,如[MIME-IMB]所定义的。
主体大小
给出了主体的字节大小的一个数字。注意,这个大小是其转换编码中的大小,而不是任何解码结果后的大小。
MESSAGE类型和子类型的一个主体类型包括,基本域后紧跟的信封结构,主体结构,及压缩邮件的文本行大小。
TEXT类型的一个主体类型包括,基本域后紧跟的、文本行中的主体大小。注意,这个大小是其内容转换编码中的大小,而不是任何解码结果后的大小。
扩展数据跟着基本域和以上指定类型的域列表。扩展数据不会与BODY获取返回,但是可以与BODYSTRUCTURE获取返回。扩展数据,如果出现,必须按定义的顺序。
一个非多域主体部分的扩展数据有以下的顺序:
主体MD5
给出了主体MD5值的一个字符串,如[MD5]所定义的。
主体部署
一个组合列表,它与针对一个多域主体部分的主体部署有同样的内容和功能。
主体语言
给出了主体语言值的一个字符串或者组合列表,如[LANUAGE-TAGS]所定义的。
主体定位
给出了主体内容URI的一个字符串列表,如[LOCATION]所定义的。
该协议的这个版本还没有定义任何下列扩展数据,它们可能如上面所描述的,属于多域扩展数据。
ENVELOPE
描述了一个邮件的信封结构的一个组合列表。这是由服务器通过解析[RFC-2822]头部为组件部分来算出的,默认为所需要的多种域。
信封结构的域有以下顺序:日期,主题,寄信方,收信方,回复至,送至,抄送,秘密抄送,转送至,及邮件号。日期,主题,转送至,及邮件号是字符串。寄信方,收信方,回复至,送至,抄送,及秘密抄送域是地址结构的组合列表。
一个地址结构是描述一个电子邮件地址的一个组合列表。一个地址结构的域有以下的顺序:个人名称,[SMTP]域列表(路由),邮件名,及主机名。
[RFC-2822]聚合语法由主机名为NIL的一种特殊的地址结构形式指明。如果邮箱名域也是NIL,那么这是聚合的一个末尾(RFC822语法中的分号)。如果邮箱名域是非NIL的,那么这是聚合的一个开始,且邮箱名域中有聚合名称。
如果日期,主题,转送至,及邮件号头部行不出现在[RFC-2822]头部中,那么信封的相关成员为NIL;如果这些头部行出现了但是为空,那么信封的相关成员是空字符串。
注意:在“出现了但是为空“的情况下,一些服务器可能返回一个NIL信封成员。客户端应当将NIL和空字符串看成是一样的。
注意:[RFC-2822]要求所有邮件有一个正确的日期头部。因此,信封中的日期成员不能为NIL或者空字符串。
注意:[RFC-2822]要求,转送至和邮件号头部,如果出现了,就要有非空的内容。因此,信封中的转送至和邮件号成员不能是空字符串。
如果寄信方,收信方,抄送,及秘密抄送头部行出现在[RFC-2822]头部中,或者出现了但为空,则信封的相关成员为NIL。
如果发送方或者转送至的行出现在[RFC-2822]头部,或者出现了但为空,则服务器将信封的相关成员设置为与寄信方一样的值(不要求客户端获知这一点)。
注意:[RFC-2822]要求,所有的邮件都有一个正确的寄信方头部。因此,信封中的寄信方,发送方,及回复至等成员不能为NIL。
FLAGS
为该邮件设置的标记的一个组合列表。
INTERNALDATE
表示邮件的实际日期的一个字符串。
RFC822
等效于BODY[]。
RFC822.HEADER
等效于BODY[HEADER]。注意,它不会引起/Seen被设置,因为RFC822.HEADER响应数据是作为RFC822.HEADER的一个FETCH的一个结果发生的。BODY[HEADER]响应数据是作为BODY[HEADER] (引起/Seen的设置)或者BODY.PEEK[HEADER](不会引起/Seen的设置)的一个FETCH的一个结果发生的。
RFC822.SIZE
表示邮件的[RFC-2822]大小的一个数字。
RFC822.TEXT
等效于BODY[TEXT]。
UID
表示邮件的唯一标识符的一个数字。
例子:
S: * 23 FETCH (FLAGS (/Seen) RFC822.SIZE 44827)
7.5. 服务器响应-命令连续请求
命令连续请求响应由一个“+”符号而不是一个标签指明。这种响应形式指明服务器准备好接收来自客户端的一个连续命令。该响应的剩余部分是一行文本。
该响应被用于AUTHENTICATE命令以传送服务器数据至客户端,及请求其它客户端数据。该响应也使用于任意命令的一个参数是一个文本的情况。
不允许客户端发送文本字节,除非服务器指明希望这样。这允许服务器在一个逐行(处理)的规则下处理命令及拒绝错误。命令的剩余部分,包括终止一个命令的CRLF,跟在文本字节后。如果有任何其它命令参数,则一个空格和那些参数跟在文本字节后。
例子:C: A001 LOGIN {11}
S: + Ready for additional command text
C: FRED FOOBAR {7}
S: + Ready for additional command text
C: fat man
S: A001 OK LOGIN completed
C: A044 BLURDYBLOOP {102856}
S: A044 BAD No such command as “BLURDYBLOOP”
8. IMAP4rev1连接例子
以下是一个IMAP4rev1连接的一个抄本。在该例中,为了编辑上的清楚,就折断了长行。
S: * OK IMAP4rev1 Service Ready
C: a001 login mrc secret
S: a001 OK LOGIN completed
C: a002 select inbox
S: * 18 EXISTS
S: * FLAGS (/Answered /Flagged /Deleted /Seen /Draft)
S: * 2 RECENT
S: * OK [UNSEEN 17] Message 17 is the first unseen message
S: * OK [UIDVALIDITY 3857529045] UIDs valid
S: a002 OK [READ-WRITE] SELECT completed
C: a003 fetch 12 full
S: * 12 FETCH (FLAGS (/Seen) INTERNALDATE ”17-Jul-1996 02:44:25 -0700″
.SIZE 4286 ENVELOPE (“Wed, 17 Jul 1996 02:23:25 -0700 (PDT)”
“IMAP4rev1 WG mtg summary and minutes”
((“Terry Gray” NIL ”gray” ”cac.washington.edu”))
((“Terry Gray” NIL ”gray” ”cac.washington.edu”))
((“Terry Gray” NIL ”gray” ”cac.washington.edu”))
((NIL NIL ”imap” ”cac.washington.edu”))
((NIL NIL ”minutes” ”CNRI.Reston.VA.US”)
(“John Klensin” NIL ”KLENSIN” ”MIT.EDU”)) NIL NIL
“<>”)
BODY (“TEXT” ”PLAIN” (“CHARSET” ”US-ASCII”) NIL NIL ”7BIT” 3028
92))
S: a003 OK FETCH completed
C: a004 fetch 12 body[header]
S: * 12 FETCH (BODY[HEADER] {342}
S: Date: Wed, 17 Jul 1996 02:23:25 -0700 (PDT)
S: From: Terry Gray <>
S: Subject: IMAP4rev1 WG mtg summary and minutes
S: To:
S: cc: , John Klensin <>
S: Message-Id:
S: MIME-Version: 1.0
S: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII
S:
S: )
S: a004 OK FETCH completed
C: a005 store 12 +flags /deleted
S: * 12 FETCH (FLAGS (/Seen /Deleted))
S: a005 OK +FLAGS completed
C: a006 logout
S: * BYE IMAP4rev1 server terminating connection
S: a006 OK LOGOUT completed
9. 正式语法
以下语法规范中使用[ABNF]中指定的Augmented Backus-Naur Form(ABNF)符号。
当现出二择一的、或者可选的规则,其中一个晚期规则与一个早期规则交迭时,早期规则必须优先。例如,解析为一个标记的“/Seen”是/Seen标记名,而不是一个标记扩展,虽然“/Seen”可以被解析为一个标记扩展。以下是这个规则的实例的一些,但不是全部:
注意:[ABNF]规则必须严格遵守;特别的:
(1)除非另外指明,否则所有字母都是不区分大小写的。使用大写或者小写字母定义符号字符只是为了编辑上的清楚而已。实现体必须以一种不区分大小写的方式接收这些字符串。
(2)任何情况下,SP正确地指向一个空间。不允许替代TAB,插入其它空格,或者将SP看作等效的LWSP。
(3)ASCII字符NUL,%x00,任何时候都不能使用。
(为避免引起不必要的曲解,也是因为译者认为这一部分对所有的协议实现者来说都是非常极为重要的部分,所以下面列出的语法及其注释部分全部原文贴出,不对注释进行翻译,不便之处,见谅)
address = ”(“ addr-name SP addr-adl SP addr-mailbox SP
addr-host ”)”
addr-adl = nstring
; Holds route from [] route-addr if
; non-NIL
addr-host = nstring
; NIL indicates [] group syntax.
; Otherwise, holds [] domain name
addr-mailbox = nstring
; NIL indicates end of [] group; if
; non-NIL and addr-host is NIL, holds
; [] group name.
; Otherwise, holds [] local-part
; after removing [] quoting
addr-name = nstring
; If non-NIL, holds phrase from []
; mailbox after removing [] quoting
append = ”APPEND” SP mailbox [SP flag-list] [SP date-time] SP
literal
astring = 1*ASTRING-CHAR / string
ASTRING-CHAR = ATOM-CHAR / resp-specials
atom = 1*ATOM-CHAR
atom-specials = ”(“ / ”)” / ”{“ / SP / CTL / list-wildcards /
quoted-specials / resp-specials
authenticate = ”AUTHENTICATE” SP auth-type *(CRLF base64)
auth-type = atom
; Defined by [SASL]
base64 = *(4base64-char) [base64-terminal]
base64-char = ALPHA / DIGIT / ”+” / ”/”
; Case-sensitive
base64-terminal = (2base64-char ”==”) / (3base64-char ”=”)
body = ”(“ (body-type-1part / body-type-mpart) ”)”
body-extension = nstring / number /
“(“ body-extension *(SP body-extension) ”)”
; Future expansion. Client implementations
; MUST accept body-extension fields. Server
; implementations MUST NOT generate
; body-extension fields except as defined by
; future standard or standards-track
; revisions of this specification.
body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang
[SP body-fld-loc *(SP body-extension)]]]
; MUST NOT be returned on non-extensible
; ”BODY” fetch
body-ext-mpart = body-fld-param [SP body-fld-dsp [SP body-fld-lang
[SP body-fld-loc *(SP body-extension)]]]
; MUST NOT be returned on non-extensible
; ”BODY” fetch
body-fields = body-fld-param SP body-fld-id SP body-fld-desc SP
body-fld-enc SP body-fld-octets
body-fld-desc = nstring
body-fld-dsp = ”(“ string SP body-fld-param ”)” / nil
body-fld-enc = (DQUOTE (“7BIT” / ”8BIT” / ”BINARY” / ”BASE64″/
“QUOTED-PRINTABLE”) DQUOTE) / string
body-fld-id = nstring
body-fld-lang = nstring / ”(“ string *(SP string) ”)”
body-fld-loc = nstring
body-fld-lines = number
body-fld-md5 = nstring
body-fld-octets = number
body-fld-param = ”(“ string SP string *(SP string SP string) ”)” / nil
body-type-1part = (body-type-basic / body-type-msg / body-type-text)
[SP body-ext-1part]
body-type-basic = media-basic SP body-fields
; MESSAGE subtype MUST NOT be ””
body-type-mpart = 1*body SP media-subtype
[SP body-ext-mpart]
body-type-msg = media-message SP body-fields SP envelope
SP body SP body-fld-lines
body-type-text = media-text SP body-fields SP body-fld-lines
capability = (“AUTH=” auth-type) / atom
; New capabilities MUST begin with ”X” or be
; registered with IANA as standard or
; standards-track
capability-data = ”CAPABILITY” *(SP capability) SP ”IMAP4rev1″
*(SP capability)
; Servers MUST implement the STARTTLS, AUTH=PLAIN,
; and LOGINDISABLED capabilities
; Servers which offer compatibility MUST
; list ”IMAP4″ as the first capability.
CHAR8 = %x01-ff
; any OCTET except NUL, %x00
command = tag SP (command-any / command-auth / command-nonauth /
command-select) CRLF
; Modal based on state
command-any = ”CAPABILITY” / ”LOGOUT” / ”NOOP” / x-command
; Valid in all states
command-auth = append / create / delete / examine / list / lsub /
rename / select / status / subscribe / unsubscribe
; Valid only in Authenticated or Selected state
command-nonauth = login / authenticate / ”STARTTLS”
; Valid only when in Not Authenticated state
command-select = ”CHECK” / ”CLOSE” / ”EXPUNGE” / copy / fetch / store /
uid / search
; Valid only when in Selected state
continue-req = ”+” SP (resp-text / base64) CRLF
copy = ”COPY” SP sequence-set SP mailbox
create = ”CREATE” SP mailbox
; Use of INBOX gives a NO error
date = date-text / DQUOTE date-text DQUOTE
date-day = 1*2DIGIT
; Day of month
date-day-fixed = (SP DIGIT) / 2DIGIT
; Fixed-format version of date-day
date-month = ”Jan” / ”Feb” / ”Mar” / ”Apr” / ”May” / ”Jun” /
“Jul” / ”Aug” / ”Sep” / ”Oct” / ”Nov” / ”Dec”
date-text = date-day ”-” date-month ”-” date-year
date-year = 4DIGIT
date-time = DQUOTE date-day-fixed ”-” date-month ”-” date-year
SP time SP zone DQUOTE
delete = ”DELETE” SP mailbox
; Use of INBOX gives a NO error
digit-nz = %x31-39
; 1-9
envelope = ”(“ env-date SP env-subject SP env-from SP
env-sender SP env-reply-to SP env-to SP env-cc SP
env-bcc SP env-in-reply-to SP env-message-id ”)”
env-bcc = ”(“ 1*address ”)” / nil
env-cc = ”(“ 1*address ”)” / nil
env-date = nstring
env-from = ”(“ 1*address ”)” / nil
env-in-reply-to = nstring
env-message-id = nstring
env-reply-to = ”(“ 1*address ”)” / nil
env-sender = ”(“ 1*address ”)” / nil
env-subject = nstring
env-to = ”(“ 1*address ”)” / nil
examine = ”EXAMINE” SP mailbox
fetch = ”FETCH” SP sequence-set SP (“ALL” / ”FULL” / ”FAST” /
fetch-att / ”(“ fetch-att *(SP fetch-att) ”)”)
fetch-att = ”ENVELOPE” / ”FLAGS” / ”INTERNALDATE” /
““ [".HEADER" / ".SIZE" / ".TEXT"] /
“BODY” ["STRUCTURE"] / ”UID” /
“BODY” section ["<" number "." nz-number ">"] /
“BODY.PEEK” section ["<" number "." nz-number ">"]
flag = ”/Answered” / ”/Flagged” / ”/Deleted” /
“/Seen” / ”/Draft” / flag-keyword / flag-extension
; Does not include ”/Recent”
flag-extension = ”/” atom
; Future expansion. Client implementations
; MUST accept flag-extension flags. Server
; implementations MUST NOT generate
; flag-extension flags except as defined by
; future standard or standards-track
; revisions of this specification.
flag-fetch = flag / ”/Recent”
flag-keyword = atom
flag-list = ”(“ [flag *(SP flag)] ”)”
flag-perm = flag / ”/*”
greeting = ”*” SP (resp-cond-auth / resp-cond-bye) CRLF
header-fld-name = astring
header-list = ”(“ header-fld-name *(SP header-fld-name) ”)”
list = ”LIST” SP mailbox SP list-mailbox
list-mailbox = 1*list-char / string
list-char = ATOM-CHAR / list-wildcards / resp-specials
list-wildcards = ”%” / ”*”
literal = ”{“ number ”}” CRLF *CHAR8
; Number represents the number of CHAR8s
login = ”LOGIN” SP userid SP password
lsub = ”LSUB” SP mailbox SP list-mailbox
mailbox = ”INBOX” / astring
; INBOX is case-insensitive. All case variants of
; INBOX (e.g., ”iNbOx”) MUST be interpreted as INBOX
; not as an astring. An astring which consists of
; the case-insensitive sequence ”I” ”N” ”B” ”O” ”X”
; is considered to be INBOX and not an astring.
; Refer to section 5.1 for further
; semantic details of mailbox names.
mailbox-data = ”FLAGS” SP flag-list / ”LIST” SP mailbox-list /
“LSUB” SP mailbox-list / ”SEARCH” *(SP nz-number) /
“STATUS” SP mailbox SP ”(“ [status-att-list] ”)” /
number SP ”EXISTS” / number SP ”RECENT”
mailbox-list = ”(“ [mbx-list-flags] ”)” SP
(DQUOTE QUOTED-CHAR DQUOTE / nil) SP mailbox
mbx-list-flags = *(mbx-list-oflag SP) mbx-list-sflag
*(SP mbx-list-oflag) /
mbx-list-oflag *(SP mbx-list-oflag)
mbx-list-oflag = ”/Noinferiors” / flag-extension
; Other flags; multiple possible per LIST response
mbx-list-sflag = ”/Noselect” / ”/Marked” / ”/Unmarked”
; Selectability flags; only one per LIST response
media-basic = ((DQUOTE (“APPLICATION” / ”AUDIO” / ”IMAGE” /
“MESSAGE” / ”VIDEO”) DQUOTE) / string) SP
media-subtype
; Defined in [MIME-IMT]
media-message = DQUOTE ”MESSAGE” DQUOTE SP DQUOTE ”“ DQUOTE
; Defined in [MIME-IMT]
media-subtype = string
; Defined in [MIME-IMT]
media-text = DQUOTE ”TEXT” DQUOTE SP media-subtype
; Defined in [MIME-IMT]
message-data = nz-number SP (“EXPUNGE” / (“FETCH” SP msg-att))
msg-att = ”(“ (msg-att-dynamic / msg-att-static)
*(SP (msg-att-dynamic / msg-att-static)) ”)”
msg-att-dynamic = ”FLAGS” SP ”(“ [flag-fetch *(SP flag-fetch)] ”)”
; MAY change for a message
msg-att-static = ”ENVELOPE” SP envelope / ”INTERNALDATE” SP date-time /
““ [".HEADER" / ".TEXT"] SP nstring /
“.SIZE” SP number /
“BODY” ["STRUCTURE"] SP body /
“BODY” section ["<" number ">"] SP nstring /
“UID” SP uniqueid
; MUST NOT change for a message
nil = ”NIL”
nstring = string / nil
number = 1*DIGIT
; Unsigned 32-bit integer
; (0 <= n < 4,294,967,296)
nz-number = digit-nz *DIGIT
; Non-zero unsigned 32-bit integer
; (0 < n < 4,294,967,296)
password = astring
quoted = DQUOTE *QUOTED-CHAR DQUOTE
QUOTED-CHAR =
/
“/” quoted-specials
quoted-specials = DQUOTE / ”/”
rename = ”RENAME” SP mailbox SP mailbox
; Use of INBOX as a destination gives a NO error
response = *(continue-req / response-data) response-done
response-data = ”*” SP (resp-cond-state / resp-cond-bye /
mailbox-data / message-data / capability-data) CRLF
response-done = response-tagged / response-fatal
response-fatal = ”*” SP resp-cond-bye CRLF
; Server closes connection immediately
response-tagged = tag SP resp-cond-state CRLF
resp-cond-auth = (“OK” / ”PREAUTH”) SP resp-text
; Authentication condition
resp-cond-bye = ”BYE” SP resp-text
resp-cond-state = (“OK” / ”NO” / ”BAD”) SP resp-text
; Status condition
resp-specials = ”]”
resp-text = ["[" resp-text-code "]“ SP] text
resp-text-code = ”ALERT” /
“BADCHARSET” [SP "(" astring *(SP astring) ")" ] /
capability-data / ”PARSE” /
“PERMANENTFLAGS” SP ”(”
[flag-perm *(SP flag-perm)] ”)” /
“READ-ONLY” / ”READ-WRITE” / ”TRYCREATE” /
“UIDNEXT” SP nz-number / ”UIDVALIDITY” SP nz-number /
“UNSEEN” SP nz-number /
atom [SP 1*
]
search = ”SEARCH” [SP "CHARSET" SP astring] 1*(SP search-key)
; CHARSET argument to MUST be registered with IANA
search-key = ”ALL” / ”ANSWERED” / ”BCC” SP astring /
“BEFORE” SP date / ”BODY” SP astring /
“CC” SP astring / ”DELETED” / ”FLAGGED” /
“FROM” SP astring / ”KEYWORD” SP flag-keyword /
“NEW” / ”OLD” / ”ON” SP date / ”RECENT” / ”SEEN” /
“SINCE” SP date / ”SUBJECT” SP astring /
“TEXT” SP astring / ”TO” SP astring /
“UNANSWERED” / ”UNDELETED” / ”UNFLAGGED” /
“UNKEYWORD” SP flag-keyword / ”UNSEEN” /
; Above this line were in [IMAP2]
“DRAFT” / ”HEADER” SP header-fld-name SP astring /
“LARGER” SP number / ”NOT” SP search-key /
“OR” SP search-key SP search-key /
“SENTBEFORE” SP date / ”SENTON” SP date /
“SENTSINCE” SP date / ”SMALLER” SP number /
“UID” SP sequence-set / ”UNDRAFT” / sequence-set /
“(“ search-key *(SP search-key) ”)”
section = ”[" [section-spec] ”]”
section-msgtext = ”HEADER” / ”HEADER.FIELDS” [".NOT"] SP header-list /
“TEXT”
; top-level or MESSAGE/RFC822 part
section-part = nz-number *(“.” nz-number)
; body part nesting
section-spec = section-msgtext / (section-part ["." section-text])
section-text = section-msgtext / ”MIME”
; text other than actual body part (headers, etc.)
select = ”SELECT” SP mailbox
seq-number = nz-number / ”*”
; message sequence number (COPY, FETCH, STORE
; commands) or unique identifier (UID COPY,
; UID FETCH, UID STORE commands).
; * represents the largest number in use. In
; the case of message sequence numbers, it is
; the number of messages in a non-empty mailbox.
; In the case of unique identifiers, it is the
; unique identifier of the last message in the
; mailbox or, if the mailbox is empty, the
; mailbox’s current UIDNEXT value.
; The server should respond with a tagged BAD
; response to a command that uses a message
; sequence number greater than the number of
; messages in the selected mailbox. This
; includes ”*” if the selected mailbox is empty.
seq-range = seq-number ”:” seq-number
; two seq-number values and all values between
; these two regardless of order.
; Example: 2:4 and 4:2 are equivalent and indicate
; values 2, 3, and 4.
; Example: a unique identifier sequence range of
; 3291:* includes the UID of the last message in
; the mailbox, even if that value is less than 3291.
sequence-set = (seq-number / seq-range) *(“,” sequence-set)
; set of seq-number values, regardless of order.
; Servers MAY coalesce overlaps and/or execute the
; sequence in any order.
; Example: a message sequence number set of
; 2,4:7,9,12:* for a mailbox with 15 messages is
; equivalent to 2,4,5,6,7,9,12,13,14,15
; Example: a message sequence number set of *:4,5:7
; for a mailbox with 10 messages is equivalent to
; 10,9,8,7,6,5,4,5,6,7 and MAY be reordered and
; overlap coalesced to be 4,5,6,7,8,9,10.
status = ”STATUS” SP mailbox SP
“(“ status-att *(SP status-att) ”)”
status-att = ”MESSAGES” / ”RECENT” / ”UIDNEXT” / ”UIDVALIDITY” /
“UNSEEN”
status-att-list = status-att SP number *(SP status-att SP number)
store = ”STORE” SP sequence-set SP store-att-flags
store-att-flags = (["+" / "-"] ”FLAGS” [".SILENT"]) SP
(flag-list / (flag *(SP flag)))
string = quoted / literal
subscribe = ”SUBSCRIBE” SP mailbox
text = 1*TEXT-CHAR
time = 2DIGIT ”:” 2DIGIT ”:” 2DIGIT
; Hours minutes seconds
uid = ”UID” SP (copy / fetch / search / store)
; Unique identifiers used instead of message
; sequence numbers
uniqueid = nz-number
; Strictly ascending
unsubscribe = ”UNSUBSCRIBE” SP mailbox
userid = astring
x-command = ”X” atom
zone = (“+” / ”-”) 4DIGIT
; Signed four-digit value of hhmm representing
; hours and minutes east of Greenwich (that is,
; the amount that the given time differs from
; Universal Time). Subtracting the timezone
; from the given time will give the UT form.
; The Universal Time zone is ”+0000″.
10. 作者的说明
该文档是早期文档的一个修订版或者改写版,且接替了下列文档的协议规范:RFC2060,RFC1730,未发布的IMAP2bis.TXT文档,RFC1176,及RFC1064。
11. 安全考虑
IMAP4rev1协议事务,包括电子邮件数据,直接在网络上发送,除非有防窃听的保护。这是通过使用STARTTLS,AUTHENTICATE命令中通过了的秘密保护,或者一些其它的保护机制来完成的。
11.1. STARTTLS安全考虑
该文档中的STARTTLS命令和LOGINDISABLED功能的规范替代[IMAP-TLS]中的。[IMAP-TLS]保持PLAIN [SASL]认证的标准。
IMAP客户端和服务器实现体必须实现TLS_RSA_WITH_RC4_128_MD5 [TLS]密码体,并且应当实现TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA [TLS]密码体。这是重要的,因为这样才能保证任意两个兼容的实现体能够注册到一块。所有其它密码体都是OPTIONAL。注意,这个变更源于[IMAP-TLS]的2.1一节。
在[TLS]对话期间,客户端必须确认服务器主机名和出现在服务器证书邮件中的服务器标识,以免受中间人攻击。如果匹配失败,客户端应当请求用户的明确确认,或者终止连接,并指明该服务器标识是可疑的。匹配按照以下规则进行:
客户端必须把用来打开连接的服务器主机名和服务器证书中表示的服务器名相比较。客户端不能使用来源于一个不安全的远程资源的服务器主机名的任意形式(例如,不安全的DNS查找)。不执行CNAME规范。
匹配是不区分大小写的。
一个“*”通配符可以被用来表示证书中的左边任意多个字符。例如,*.example.com可以匹配a.example.com, foo.example.com, 等等,但是不能匹配example.com。
如果证书包含多个名(例如,多于一个的DNS名称域),那么这些域的任意一个的(成功)匹配就被认为是可接收的。
客户端和服务器必须确认STARTTLS命令和后续的[TLS]对话的结果,以了解是否完成了可接收的认证或者秘密。
11.2. 其它安全考虑
由无效信任书引起的,一个AUTHENTICATE命令的一个服务器错误邮件不应当详述为什么信任书无效。
使用LOGIN直接发送密码。这可以通过使用一个[SASL]机制的、不支持简单文本密码的AUTHENTICATE命令,通过经STARTTLS早期对话加密,或者其它保护机制避免。
一个服务器实现体必须实现一个配置,认证时,要求:
(1)STARTTLS命令已经通过。
或者
(2)其它保护会话防密码窃听的机制已经提供。
或者
(3)以下措施已采用:
(a)LOGINDISABLED功能被通报,且使用简单文本密码的[SASL]机制(如,PLAIN)没在功能列表中通报。
且
(b)AUTHENTICATE命令返回一个错误,即使密码是正确的。
(c)AUTHENTICATE命令返回使用简单文本密码的所有[SASL]机制的一个错误,即使密码是正确的。
针对一个失败的LOGIN命令的一个服务器错误邮件不应当指明该用户名,对于该密码,是无效的。
一个服务器应当有适当的机制限制或者延期失败的AUTHENTICATE/LOGIN尝试。
其它安全考虑在AUTHENTICATE及LOGIN命令的那一节中有讨论。
12. IANA考虑
IMAP4功能通过出版一个标准本或者IESG核准的试验RFC注册。该注册本现在位于:
该规范修订了之前[IMAP-TLS]定义了的STARTTLS及LOGINDISABLED扩展,因此该注册将更新。
附录
A. 标准参考
下列文档包含了有助于适当理解本文档的定义或者规范:
[ABNF] Crocker, D. and P. Overell, ”Augmented BNF for
Syntax Specifications: ABNF”, ,
November 1997.
[ANONYMOUS] Newman, C., ”Anonymous SASL Mechanism”, RFC
2245, November 1997.
[CHARSET] Freed, N. and J. Postel, ”IANA Character Set
Registration Procedures”, , October
2000.
[DIGEST-MD5] Leach, P. and C. Newman, ”Using Digest
Authentication as a SASL Mechanism”, ,
May 2000.
[DISPOSITION] Troost, R., Dorner, S. and K. Moore,
“Communicating Presentation Information in
Internet Messages: The Content-Disposition
Header”, , August 1997.
[IMAP-TLS] Newman, C., ”Using TLS with IMAP, POP3 and
ACAP”, , June 1999.
[KEYWORDS] Bradner, S., ”Key words for use in RFCs to
Indicate Requirement Levels”, BCP 14, ,
March 1997.
[LANGUAGE-TAGS] Alvestrand, H., ”Tags for the Identification of
Languages”, BCP 47, , January 2001.
[LOCATION] Palme, J., Hopmann, A. and N. Shelness, ”MIME
Encapsulation of Aggregate Documents, such as
HTML (MHTML)”, , March 1999.
[MD5] Myers, J. and M. Rose, ”The Content-MD5 Header
Field”, , October 1995.
[MIME-HDRS] Moore, K., ”MIME (Multipurpose Internet Mail
Extensions) Part Three: Message Header
Extensions for Non-ASCII Text”, ,
November 1996.
[MIME-IMB] Freed, N. and N. Borenstein, ”MIME
(Multipurpose Internet Mail Extensions) Part
One: Format of Internet Message Bodies”, RFC
2045, November 1996.
[MIME-IMT] Freed, N. and N. Borenstein, ”MIME
(Multipurpose Internet Mail Extensions) Part
Two: Media Types”, , November 1996.
[] Resnick, P., ”Internet Message Format”, RFC
2822, April 2001.
[SASL] Myers, J., ”Simple Authentication and Security
Layer (SASL)”, , October 1997.
[TLS] Dierks, T. and C. Allen, ”The TLS Protocol
Version 1.0″, , January 1999.
[UTF-7] Goldsmith, D. and M. Davis, ”UTF-7: A Mail-Safe
Transformation Format of Unicode”, ,
May 1997.
The following documents describe quality-of-implementation issues
that should be carefully considered when implementing this protocol:
[IMAP-IMPLEMENTATION] Leiba, B., ”IMAP Implementation
Recommendations”, , September 1999.
[IMAP-MULTIACCESS] Gahrns, M., ”IMAP4 Multi-Accessed Mailbox
Practice”, , July 1997.
A.1 Informative References
The following documents describe related protocols:
[IMAP-DISC] Austein, R., ”Synchronization Operations for
Disconnected IMAP4 Clients”, Work in Progress.
[IMAP-MODEL] Crispin, M., ”Distributed Electronic Mail
Models in IMAP4″, , December 1994.
[ACAP] Newman, C. and J. Myers, ”ACAP – Application
Configuration Access Protocol”, ,
November 1997.
[SMTP] Klensin, J., ”Simple Mail Transfer Protocol”,
STD 10, , April 2001.
The following documents are historical or describe historical aspects
of this protocol:
[IMAP-COMPAT] Crispin, M., ”IMAP4 Compatibility with
IMAP2bis”, , December 1996.
[IMAP-HISTORICAL] Crispin, M., ”IMAP4 Compatibility with IMAP2
and IMAP2bis”, , December 1994.
[IMAP-OBSOLETE] Crispin, M., ”Internet Message Access Protocol
- Obsolete Syntax”, , December 1996.
[IMAP2] Crispin, M., ”Interactive Mail Access Protocol
- Version 2″, , August 1990.
[] Crocker, D., ”Standard for the Format of ARPA
Internet Text Messages”, STD 11, ,
August 1982.
[] Postel, J., ”Simple Mail Transfer Protocol”,
STD 10, , August 1982.
B. 修改于
1) Clarify description of unique identifiers and their semantics.
2) Fix the SELECT description to clarify that UIDVALIDITY is required
in the SELECT and EXAMINE responses.
3) Added an example of a failing search.
4) Correct store-att-flags: ”#flag” should be ”1#flag”.
5) Made search and section rules clearer.
6) Correct the STORE example.
7) Correct ”BASE645″ misspelling.
8) Remove extraneous close parenthesis in example of two-part message
with text and BASE64 attachment.
9) Remove obsolete ”MAILBOX” response from mailbox-data.
10) A spurious ”<” in the rule for mailbox-data was removed.
11) Add CRLF to continue-req.
12) Specifically exclude ”]” from the atom in resp-text-code.
13) Clarify that clients and servers should adhere strictly to the
protocol syntax.
14) Emphasize in 5.2 that EXISTS can not be used to shrink a mailbox.
15) Add NEWNAME to resp-text-code.
16) Clarify that the empty string, not NIL, is used as arguments to
LIST.
17) Clarify that NIL can be returned as a hierarchy delimiter for the
empty string mailbox name argument if the mailbox namespace is flat.
18) Clarify that addr-mailbox and addr-name have quoting
removed.
19) Update UTF-7 reference.
20) Fix example in 6.3.11.
21) Clarify that non-existent UIDs are ignored.
22) Update DISPOSITION reference.
23) Expand state diagram.
24) Clarify that partial fetch responses are only returned in
response to a partial fetch command.
25) Add UIDNEXT response code. Correct UIDVALIDITY definition
reference.
26) Further clarification of ”can” vs. ”MAY”.
27) Reference .
28) Clarify that superfluous shifts are not permitted in modified
UTF-7.
29) Clarify that there are no implicit shifts in modified UTF-7.
30) Clarify that ”INBOX” in a mailbox name is always INBOX, even if
it is given as a string.
31) Add missing open parenthesis in media-basic grammar rule.
32) Correct attribute syntax in mailbox-data.
33) Add UIDNEXT to EXAMINE responses.
34) Clarify UNSEEN, PERMANENTFLAGS, UIDVALIDITY, and UIDNEXT
responses in SELECT and EXAMINE. They are required now, but weren’t
in older versions.
35) Update references with RFCnumbers.
36) Flush text-mime2.
37) Clarify that modified UTF-7 names must be case-sensitive and that
violating the convention should be avoided.
38) Correct UID FETCH example.
39) Clarify UID FETCH, UID STORE, and UID SEARCH vs. untagged EXPUNGE
responses.
40) Clarify the use of the word ”convention”.
41) Clarify that a command is not ”in progress” until it has been
fully received (specifically, that a command is not ”in progress”
during command continuation negotiation).
42) Clarify envelope defaulting.
43) Clarify that SP means one and only one space character.
44) Forbid silly states in LIST response.
45) Clarify that the ENVELOPE, INTERNALDATE, *, BODY*, and UID
for a message is static.
46) Add BADCHARSET response code.
47) Update formal syntax to [ABNF] conventions.
48) Clarify trailing hierarchy delimiter in CREATE semantics.
49) Clarify that the ”blank line” is the [] delimiting blank
line.
50) Clarify that RENAME should also create hierarchy as needed for
the command to complete.
51) Fix body-ext-mpart to not require language if disposition
present.
52) Clarify the .HEADER response.
53) Correct missing space after charset astring in search.
54) Correct missing quote for BADCHARSET in resp-text-code.
55) Clarify that ALL, FAST, and FULL preclude any other data items
appearing.
56) Clarify semantics of reference argument in LIST.
57) Clarify that a null string for SEARCH HEADER X-FOO means any
message with a header line with a field-name of X-FOO regardless of
the text of the header.
58) Specifically reserve 8-bit mailbox names for future use as UTF-8.
59) It is not an error for the client to store a flag that is not in
the PERMANENTFLAGS list; however, the server will either ignore the
change or make the change in the 会话 only.
60) Correct/clarify the text regarding superfluous shifts.
61) Correct typographic errors in the ”Changes” section.
62) Clarify that STATUS must not be used to check for new messages in
the selected mailbox
63) Clarify LSUB behavior with ”%” wildcard.
64) Change AUTHORIZATION to AUTHENTICATE in section 7.5.
65) Clarify description of multipart body type.
66) Clarify that STORE FLAGS does not affect /Recent.
67) Change ”west” to ”east” in description of timezone.
68) Clarify that commands which break command pipelining must wait
for a completion result response.
69) Clarify that EXAMINE does not affect /Recent.
70) Make description of MIME structure consistent.
71) Clarify that date searches disregard the time and timezone of the
INTERNALDATE or Date: header. In other words, ”ON 13-APR-2000″ means
messages with an INTERNALDATE text which starts with ”13-APR-2000″,
even if timezone differential from the local timezone is sufficient
to move that INTERNALDATE into the previous or next day.
72) Clarify that the header fetches don’t add a blank line if one
isn’t in the [] message.
73) Clarify (in discussion of UIDs) that messages are immutable.
74) Add an example of CHARSET searching.
75) Clarify in SEARCH that keywords are a type of flag.
76) Clarify the mandatory nature of the SELECT data responses.
77) Add optional CAPABILITY response code in the initial OK or
PREAUTH.
78) Add note that server can send an untagged CAPABILITY command as
part of the responses to AUTHENTICATE and LOGIN.
79) Remove statement about it being unnecessary to issue a CAPABILITY
command more than once in a connection. That statement is no longer
true.
80) Clarify that untagged EXPUNGE decrements the number of messages
in the mailbox.
81) Fix definition of ”body” (concatenation has tighter binding than
alternation).
82) Add a new ”Special Notes to Implementors” section with reference
to [IMAP-IMPLEMENTATION].
83) Clarify that an untagged CAPABILITY response to an AUTHENTICATE
command should only be done if a security layer was not negotiated.
84) Change the definition of atom to exclude ”]”. Update astring to
include ”]” for compatibility with the past. Remove resp-text-atom.
85) Remove NEWNAME. It can’t work because mailbox names can be
literals and can include ”]”. Functionality can be addressed via
referrals.
86) Move modified UTF-7 rationale in order to have more logical
paragraph flow.
87) Clarify UID uniqueness guarantees with the use of MUST.
88) Note that clients should read response data until the connection
is closed instead of immediately closing on a BYE.
89) Change references to .
90) Clarify that should be followed instead of .
91) Change recommendation of optional automatic capabilities in LOGIN
and AUTHENTICATE to use the CAPABILITY response code in the tagged
OK. This is more interoperable than an unsolicited untagged
CAPABILITY response.
92) STARTTLS and AUTH=PLAIN are mandatory to implement; add
recommendations for other [SASL] mechanisms.
93) Clarify that a ”connection” (as opposed to ”server” or ”command”)
is in one of the four states.
94) Clarify that a failed or rejected command does not change state.
95) Split references between normative and informative.
96) Discuss authentication failure issues in security section.
97) Clarify that a data item is not necessarily of only one data
type.
98) Clarify that sequence ranges are independent of order.
99) Change an example to clarify that superfluous shifts in
Modified-UTF7 can not be fixed just by omitting the shift. The
entire string must be recalculated.
100) Change Envelope Structure definition since [] uses
“envelope” to refer to the [SMTP] envelope and not the envelope data
that appears in the [] header.
101) Expand on .HEADER response data vs. BODY[HEADER].
102) Clarify Logout state semantics, change ASCII art.
103) Security changes to comply with IESG requirements.
104) Add definition for body URI.
105) Break sequence range definition into three rules, with rewritten
descriptions for each.
106) Move STARTTLS and LOGINDISABLED here from [IMAP-TLS].
107) Add IANA Considerations section.
108) Clarify valid client assumptions for new message UIDs vs.
UIDNEXT.
109) Clarify that changes to permanentflags affect concurrent
会话s as well as subsequent 会话s.
110) Clarify that authenticated state can be entered by the CLOSE
command.
111) Emphasize that SELECT and EXAMINE are the exceptions to the rule
that a failing command does not change state.
112) Clarify that newly-appended messages have the Recent flag set.
113) Clarify that newly-copied messages SHOULD have the Recent flag
set.
114) Clarify that UID commands always return the UID in FETCH
responses.
C.关键词索引
+FLAGS
(store command data item)
+FLAGS.SILENT (store command data item)
-FLAGS (store command data item)
-FLAGS.SILENT (store command data item)
ALERT (response code)
ALL (fetch item)
ALL (search key)
ANSWERED (search key)
APPEND (command)
AUTHENTICATE (command)
BAD (response)
BADCHARSET (response code)
BCC (search key)
BEFORE (search key)
BODY (fetch item)
BODY (fetch result)
BODY (search key)
BODY.PEEK[]<> (fetch item)
BODYSTRUCTURE (fetch item)
BODYSTRUCTURE (fetch result)
BODY[]<> (fetch result)
BODY[]<> (fetch item)
BYE (response)
Body Structure (message attribute)
CAPABILITY (command)
CAPABILITY (response code)
CAPABILITY (response)
CC (search key)
CHECK (command)
CLOSE (command)
COPY (command)
CREATE (command)
DELETE (command)
DELETED (search key)
DRAFT (search key)
ENVELOPE (fetch item)
ENVELOPE (fetch result)
EXAMINE (command)
EXISTS (response)
EXPUNGE (command)
EXPUNGE (response)
Envelope Structure (message attribute)
FAST (fetch item)
FETCH (command)
FETCH (response)
FLAGGED (search key)
FLAGS (fetch item)
FLAGS (fetch result)
FLAGS (response)
FLAGS (store command data item)
FLAGS.SILENT (store command data item)
FROM (search key)
FULL (fetch item)
Flags (message attribute)
HEADER (part specifier)
HEADER (search key)
HEADER.FIELDS (part specifier)
HEADER.FIELDS.NOT (part specifier)
INTERNALDATE (fetch item)
INTERNALDATE (fetch result)
Internal Date (message attribute)
KEYWORD (search key)
Keyword (type of flag)
LARGER (search key)
LIST (command)
LIST (response)
LOGIN (command)
LOGOUT (command)
LSUB (command)
LSUB (response)
MAY (specification requirement term)
MESSAGES (status item)
MIME (part specifier)
MUST (specification requirement term)
MUST NOT (specification requirement term)
Message Sequence Number (message attribute)
NEW (search key)
NO (response)
NOOP (command)
NOT (search key)
OK (response)
OLD (search key)
ON (search key)
OPTIONAL (specification requirement term)
OR (search key)
PARSE (response code)
PERMANENTFLAGS (response code)
PREAUTH (response)
Permanent Flag (class of flag)
READ-ONLY (response code)
READ-WRITE (response code)
RECENT (response)
RECENT (search key)
RECENT (status item)
RENAME (command)
REQUIRED (specification requirement term)
(fetch item)
(fetch result)
.HEADER (fetch item)
.HEADER (fetch result)
.SIZE (fetch item)
.SIZE (fetch result)
.TEXT (fetch item)
.TEXT (fetch result)
SEARCH (command)
SEARCH (response)
SEEN (search key)
SELECT (command)
SENTBEFORE (search key)
SENTON (search key)
SENTSINCE (search key)
SHOULD (specification requirement term)
SHOULD NOT (specification requirement term)
SINCE (search key)
SMALLER (search key)
STARTTLS (command)
STATUS (command)
STATUS (response)
STORE (command)
SUBJECT (search key)
SUBSCRIBE (command)
会话 Flag (class of flag)
System Flag (type of flag)
TEXT (part specifier)
TEXT (search key)
TO (search key)
TRYCREATE (response code)
UID (command)
UID (fetch item)
UID (fetch result)
UID (search key)
UIDNEXT (response code)
UIDNEXT (status item)
UIDVALIDITY (response code)
UIDVALIDITY (status item)
UNANSWERED (search key)
UNDELETED (search key)
UNDRAFT (search key)
UNFLAGGED (search key)
UNKEYWORD (search key)
UNSEEN (response code)
UNSEEN (search key)
UNSEEN (status item)
UNSUBSCRIBE (command)
Unique Identifier (UID) (message attribute)
X (command)
[] Size (message attribute)
/Answered (system flag)
/Deleted (system flag)
/Draft (system flag)
/Flagged (system flag)
/Marked (mailbox name attribute)
/Noinferiors (mailbox name attribute)
/Noselect (mailbox name attribute)
/Recent (system flag)
/Seen (system flag)
/Unmarked (mailbox name attribute)