5. Operational Considerations (操作注意事项)
以下规则在此列出, 以确保所有 IMAP4rev1 实现能够正确互操作.
5.1. Mailbox Naming (邮箱命名)
邮箱名称是 7 位的. 客户端实现禁止 (MUST NOT) 尝试创建 8 位邮箱名称, 并且应该 (SHOULD) 将 LIST 或 LSUB 返回的任何 8 位邮箱名称解释为 UTF-8. 服务器实现应该 (SHOULD) 禁止创建 8 位邮箱名称, 并且不应该 (SHOULD NOT) 在 LIST 或 LSUB 中返回 8 位邮箱名称. 有关如何表示非 ASCII 邮箱名称的更多信息, 请参见第 5.1.3 节.
注意: 8 位邮箱名称在本协议的早期版本中未定义. 一些站点使用本地 8 位字符集来表示非 ASCII 邮箱名称. 这种用法不可互操作, 现在正式弃用.
不区分大小写的邮箱名称 INBOX 是一个特殊名称, 保留用于表示 "此服务器上此用户的主邮箱". 所有其他名称的解释由实现决定.
特别是, 本规范对非 INBOX 邮箱名称的大小写敏感性不采取立场. 一些服务器实现是完全大小写敏感的, 其他实现保留新创建名称的大小写但在其他方面不区分大小写, 还有一些实现将名称强制转换为特定大小写. 客户端实现必须 (MUST) 与这些中的任何一个交互. 如果服务器实现将非 INBOX 邮箱名称解释为不区分大小写, 则必须 (MUST) 按照第 5.1.3 节中的描述特别处理使用国际命名约定的名称.
创建新邮箱名称时有某些客户端注意事项:
-
任何作为 atom-specials 之一的字符 (参见正式语法) 都将要求邮箱名称表示为引号字符串或字面量.
-
CTL 和其他非图形字符难以在用户界面中表示, 最好避免.
-
尽管列表通配符字符 (
%和*) 在邮箱名称中有效, 但由于与通配符解释的冲突, 很难将此类邮箱名称与 LIST 和 LSUB 命令一起使用. -
通常, 保留一个字符 (由服务器实现确定) 来分隔层次结构级别.
-
两个字符
#和&按约定具有含义, 除非在该约定中使用, 否则应避免使用.
5.1.1. Mailbox Hierarchy Naming (邮箱层次命名)
如果希望导出层次邮箱名称, 邮箱名称必须 (MUST) 使用单个字符分隔层次结构级别, 采用从左到右的层次结构. 单个名称内的所有层次结构级别使用相同的层次分隔符字符.
示例:
INBOX.Work.Project1 (使用 . 作为分隔符)
INBOX/Personal/Family (使用 / 作为分隔符)
5.1.2. Mailbox Namespace Naming Convention (邮箱命名空间命名约定)
按照约定, 以 # 开头的任何邮箱名称的第一个层次元素标识名称其余部分的 "命名空间 (Namespace)". 这使得可以消除不同类型邮箱存储之间的歧义, 每个邮箱存储都有自己的命名空间.
示例:
提供 USENET 新闻组访问的实现可以 (MAY) 使用 #news 命名空间将 USENET 新闻组命名空间与其他邮箱的命名空间分开. 因此, comp.mail.misc 新闻组将具有邮箱名称 #news.comp.mail.misc, 而名称 comp.mail.misc 可以引用不同的对象 (例如, 用户的私人邮箱).
5.1.3. Mailbox International Naming Convention (邮箱国际命名约定)
按照约定, IMAP4rev1 中的国际邮箱名称使用 [UTF-7] 中描述的 UTF-7 编码的修改版本指定. 修改的 UTF-7 也可以在实现本协议早期版本的服务器中使用.
在修改的 UTF-7 中, 可打印的 US-ASCII 字符 (除了 &) 表示它们自己, 即八位字节值为 0x20-0x25 和 0x27-0x7e 的字符. 字符 & (0x26) 由两个八位字节序列 &- 表示.
所有其他字符 (八位字节值 0x00-0x1f 和 0x7f-0xff) 在修改的 BASE64 中表示, 与 [UTF-7] 进一步修改的是使用 , 而不是 /. 修改的 BASE64 禁止 (MUST NOT) 用于表示可以表示自身的任何可打印 US-ASCII 字符.
& 用于转换到修改的 BASE64, - 用于转换回 US-ASCII. 没有从 BASE64 到 US-ASCII 的隐式转换, 并且不允许空转换 (在 BASE64 中为 -&, 请注意在 US-ASCII 中 &- 表示 &). 但是, 所有名称都以 US-ASCII 开头, 并且必须 (MUST) 以 US-ASCII 结尾, 即, 以非 ASCII ISO-10646 字符结尾的名称必须 (MUST) 以 - 结尾.
这些修改的目的是纠正 UTF-7 的以下问题:
-
UTF-7 使用
+字符进行转换, 这与邮箱名称中+的常见用法冲突, 特别是 USENET 新闻组名称. -
UTF-7 的编码是 BASE64, 它使用
/字符, 这与/作为流行的层次分隔符的使用冲突. -
UTF-7 禁止未编码使用
\, 这与\作为流行的层次分隔符的使用冲突. -
UTF-7 禁止未编码使用
~, 这与某些服务器中~作为主目录指示符的使用冲突. -
UTF-7 允许多种替代形式来表示同一字符串, 特别是, 可打印的 US-ASCII 字符可以以编码形式表示.
尽管修改的 UTF-7 是一个约定, 但它对服务器处理带有嵌入 & 字符的任何邮箱名称提出了某些要求. 特别是, 服务器实现必须 (MUST) 保留修改的 UTF-7 名称的修改的 BASE64 部分的确切形式, 并将该文本视为区分大小写, 即使名称在其他方面不区分大小写或大小写折叠.
服务器实现应该 (SHOULD) 验证用作 CREATE 参数的带有嵌入 & 字符的任何邮箱名称是否: 采用正确的修改 UTF-7 语法, 没有多余的转换, 并且没有在修改的 BASE64 中编码可以表示自身的任何可打印 US-ASCII 字符. 但是, 客户端实现禁止 (MUST NOT) 依赖服务器执行此操作, 并且不应该 (SHOULD NOT) 尝试创建带有嵌入 & 字符的邮箱名称, 除非它符合修改的 UTF-7 语法.
导出不遵循修改 UTF-7 约定的邮件存储的服务器实现必须 (MUST) 将包含非 ASCII 字符或 & 字符的任何邮箱名称转换为修改的 UTF-7.
示例:
- 混合英语, 中文和日文文本的邮箱名称:
~peter/mail/&U,BTFw-/&ZeVnLIqe- - 无效的邮箱名称:
&Jjo!(因为它在!之前不包含转换到 US-ASCII) - 正确的形式:
&Jjo-! - 不允许的字符串:
&U,BTFw-&ZeVnLIqe-(因为它包含多余的转换) - 正确的形式:
&U,BTF2XlZyyKng-
5.2. Mailbox Size and Message Status Updates (邮箱大小和消息状态更新)
在任何时候, 服务器都可以发送客户端未请求的数据. 有时, 这种行为是必需的 (REQUIRED). 例如, 服务器以外的代理可以 (MAY) 将消息添加到邮箱 (例如, 新消息传递), 更改邮箱中消息的标志 (例如, 多个代理同时访问同一邮箱), 甚至从邮箱中删除消息. 如果在处理命令期间观察到邮箱大小更改, 服务器必须 (MUST) 自动发送邮箱大小更新. 服务器应该 (SHOULD) 自动发送消息标志更新, 而无需客户端明确请求此类更新.
关于服务器通知客户端删除消息存在特殊规则, 以防止同步错误, 有关更多详细信息, 请参阅 EXPUNGE 响应的描述. 特别是, 不允许 (NOT permitted) 发送会减少邮箱中消息数量的 EXISTS 响应, 只有 EXPUNGE 响应才能这样做.
无论客户端在记住服务器数据方面做出什么实现决策, 客户端实现都必须 (MUST) 记录邮箱大小更新. 它禁止 (MUST NOT) 假设初始邮箱选择后的任何命令都会返回邮箱的大小.
5.3. Response when no Command in Progress (没有命令进行时的响应)
允许服务器实现在没有命令进行时发送未标记响应 (EXPUNGE 除外). 发送此类响应的服务器实现必须 (MUST) 处理流量控制注意事项. 具体来说, 它们必须 (MUST) (1) 验证数据大小不超过底层传输的可用窗口大小, 或 (2) 使用非阻塞写入.
5.4. Autologout Timer (自动登出计时器)
如果服务器具有不活动自动登出计时器, 该计时器的持续时间必须 (MUST) 至少为 30 分钟. 在该间隔期间从客户端接收任何命令 (ANY command) 应该 (SHOULD) 足以重置自动登出计时器.
5.5. Multiple Commands in Progress (多个命令并行进行)
客户端可以 (MAY) 在不等待命令的完成结果响应的情况下发送另一个命令, 但需遵守歧义规则 (见下文) 和底层数据流的流量控制约束. 类似地, 服务器可以 (MAY) 在将当前命令处理完成之前开始处理另一个命令, 但需遵守歧义规则. 但是, 在启动任何后续命令之前, 必须 (MUST) 协商任何命令继续请求响应和命令继续.
例外情况是如果会导致歧义, 因为命令会影响其他命令的结果. 如果会导致歧义, 客户端禁止 (MUST NOT) 在不等待的情况下发送多个命令. 如果服务器检测到可能的歧义, 它必须 (MUST) 按照客户端给出的顺序执行命令以完成.
最明显的歧义示例是当命令会影响另一个命令的结果时, 例如, FETCH 消息的标志和 STORE 同一消息的标志.
不明显的歧义发生在允许未标记 EXPUNGE 响应的命令 (除 FETCH, STORE 和 SEARCH 之外的命令) 中, 因为未标记的 EXPUNGE 响应可以使后续命令中的序列号无效. 这对 FETCH, STORE 或 SEARCH 命令来说不是问题, 因为禁止服务器在这些命令中的任何一个进行时发送 EXPUNGE 响应. 因此, 如果客户端发送除 FETCH, STORE 或 SEARCH 之外的任何命令, 它必须 (MUST) 在发送带有消息序列号的命令之前等待完成结果响应.
注意: 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 是否包含消息序列号.
术语表 (本章重点术语):
- Mailbox (邮箱): 消息的容器
- INBOX: 保留的特殊邮箱名称, 表示用户的主邮箱
- Hierarchy Separator (层次分隔符): 用于分隔邮箱层次结构的字符
- Namespace (命名空间): 邮箱的逻辑分组
- Modified UTF-7 (修改的 UTF-7): 用于国际邮箱名称的编码方案
- EXPUNGE: 从邮箱中永久删除消息的操作
- Autologout Timer (自动登出计时器): 不活动超时后自动断开连接
- Command Pipelining (命令流水线): 在不等待响应的情况下发送多个命令