跳到主要内容

2. 消息词法分析

2.1. 一般描述

在最基本层面上, 消息是一系列字符. 符合本规范的消息由取值范围为 1 到 127 的字符组成, 并解释为 US-ASCII 字符. 为方便起见, 本文档有时把这个范围内的字符简称为 "US-ASCII characters".

注意: 本规范规定消息由 US-ASCII 范围 1 到 127 的字符组成. 还有其他文档, 尤其是 MIME 文档系列 (RFC 2045, RFC 2046, RFC 2047, RFC 2049, RFC 4288, RFC 4289), 扩展了本规范, 允许使用该范围之外的值. 这些机制的讨论不在本规范范围内.

消息被划分为若干字符行. 一行是一串由回车和换行两个字符分隔的字符; 也就是 carriage return (CR) 字符 (ASCII 值 13) 后面立即跟随 line feed (LF) 字符 (ASCII 值 10). 本文档通常把这个 carriage-return/line-feed 对写作 "CRLF".

消息由头部字段组成 (统称为 "消息的头部字段段"), 后面可以可选地跟随正文. 头部字段段是一系列字符行, 具有本规范定义的特殊语法. 正文只是跟随头部字段段的一串字符, 并通过一个空行与头部字段段分隔 (即 CRLF 之前没有任何内容的行).

注意: 通常说法和本规范早期版本使用 "header" 一词既指整个头部字段段, 也指单个头部字段. 为避免歧义, 本文档不单独使用 "header" 或 "headers", 而是始终使用 "header field" 指单个字段, 使用 "header section" 指整个集合.

消息结构示意

Message
├── Header Section
│ ├── From: [email protected] CRLF
│ ├── To: [email protected] CRLF
│ ├── Subject: Hello CRLF
│ └── Date: ... CRLF
├── Empty Line
│ └── CRLF
└── Body
├── This is the message body. CRLF
└── Second line. CRLF

2.1.1. 行长度限制

本规范对一行中的字符数设置了两个限制. 每行字符必须不超过 998 个字符, 并且应当不超过 78 个字符, 不包括 CRLF.

998 字符硬限制 的存在源于许多发送, 接收或存储 IMF 消息的实现限制, 这些实现无法处理一行超过 998 个字符的情况. 为了健壮性, 接收实现最好能够处理一行中任意多的字符. 但是, 有太多实现 (遵循 RFC 5321 的传输要求) 不接受每行含 CR 和 LF 在内超过 1000 个字符的消息, 因此实现不要创建这类消息很重要.

更保守的 78 字符建议 是为了适应许多显示这些消息的用户界面实现, 这些实现可能会截断每行超过 78 个字符的显示, 或以灾难性方式换行显示, 即使这类实现不符合本规范意图 (如果它们实际造成信息丢失, 也不符合 RFC 5321 的意图). 再次说明, 虽然这个限制施加在消息上, 但显示消息的实现为了健壮性, 有责任处理一行中任意多的字符 (当然至少要达到 998 字符限制).

行长度限制摘要:

限制类型长度 (不包括 CRLF)要求原因
硬限制998 个字符MUST许多实现无法处理更长的行
建议限制78 个字符SHOULD适应用户界面中的显示截断
Line Length Examples:

Compliant with recommendation (within 78 characters):
Subject: This is a short subject line

Compliant but exceeds recommendation (78-998 characters):
Subject: This is a very long subject line that exceeds the recommended 78 character limit but is still within the required 998 character maximum limit

Non-compliant (exceeds 998 characters):
Subject: [Content exceeding 998 characters...]

2.2. 头部字段

头部字段是以字段名开头的行, 后跟冒号 (":"), 再后跟字段主体, 并以 CRLF 结束. 字段名必须由可打印 US-ASCII 字符组成 (即取值在 33 到 126 之间且包括端点的字符), 但冒号除外. 字段主体可以由可打印 US-ASCII 字符以及空格 (SP, ASCII 值 32) 和水平制表符 (HTAB, ASCII 值 9) 组成; 这些字符合称为空白字符 (WSP). 字段主体禁止包含 CR 和 LF, 除非它们用于第 2.2.3 节所述的 "folding" 和 "unfolding". 所有字段主体都必须符合本规范第 3 节和第 4 节描述的语法.

头部字段格式:

Field-Name: Field-BodyCRLF
↑ ↑ ↑ ↑
| | | +--- Line terminator
| | +---------- Field content
| +----------------- Colon delimiter
+------------------------- Field name

示例:

From: [email protected]
Subject: Meeting Tomorrow
Date: Mon, 20 Dec 2025 10:00:00 +0800

2.2.1. 非结构化头部字段主体

本规范中的一些字段主体被简单定义为 "unstructured"; 第 3.2.5 节规定其为任意可打印 US-ASCII 字符加空白字符, 没有进一步限制. 这些称为非结构化字段主体. 从语义上看, 非结构化字段主体只应当作为单行字符处理, 不再进行进一步处理 (第 2.2.3 节所述的 "folding" 和 "unfolding" 除外).

非结构化字段示例:

Subject: This is any text I want to write
Comments: Here's a free-form comment

特征:

  • 自由形式内容, 可以使用任意可打印 ASCII 字符.
  • 不要求特定语法结构.
  • 只需要处理折叠和展开.

2.2.2. 结构化头部字段主体

本规范中的一些字段主体具有比上述非结构化字段主体更严格的语法. 这些称为 "structured" 字段主体. 结构化字段主体是本规范第 3 节和第 4 节所述特定词法 token 的序列. 按照语法, 这些 token 中的许多可以以注释 (第 3.2.2 节所述) 和空白字符引入或结束, 而这些空白字符受第 2.2.3 节所述 "folding" 和 "unfolding" 的约束. 结构化字段主体的语义分析与其语法一起给出.

结构化字段示例:

From: Alice Smith <[email protected]>
To: [email protected], [email protected]
Date: Mon, 20 Dec 2025 10:00:00 +0800

特征:

  • 必须遵循严格语法规则.
  • 包含特定词法 token, 例如电子邮件地址和 date-time.
  • 可以包含注释和空白字符.
  • 需要按照语法进行解析.

比较:

类型语法严格度处理方式典型示例
非结构化宽松, 自由文本作为整体字符串Subject, Comments
结构化严格, 具有特定语法按词法 token 解析From, To, Date

2.2.3. 长头部字段

每个头部字段在逻辑上都是一行字符, 由字段名, 冒号和字段主体组成. 但是, 为了方便, 并为了处理每行 998/78 字符限制, 头部字段的字段主体部分可以拆分成多行表示; 这称为 "folding". 一般规则是: 凡是本规范允许折叠空白 (不只是 WSP 字符) 的位置, 都可以在任何 WSP 之前插入 CRLF.

折叠示例:

原始头部字段:

Subject: This is a test

可以表示为 (折叠后):

Subject: This
is a test

注意: 虽然结构化字段主体定义允许在任何允许折叠空白的位置折叠 (甚至允许在词法 token 内部折叠), 但折叠应当限制在较高层级的语法分隔处放置 CRLF. 例如, 如果字段主体定义为逗号分隔值, 推荐在分隔结构化项的逗号之后折叠, 而不是在项内部折叠, 即使其他位置也允许折叠.

折叠规则:

  1. 插入点: 在任意 WSP (空格或制表符) 前插入 CRLF.
  2. 续行: 下一行必须以 WSP 开头.
  3. 推荐位置: 位于高层级语法分隔处, 例如逗号之后.

多地址折叠示例:

Recommended folding (after commas):
To: [email protected],
[email protected],
[email protected]

Not recommended but legal:
To: [email protected], bob@
example.com, [email protected]

Unfolding 是把这种折叠的多行表示移回其单行表示的反向过程. 展开只需删除任何后面立即跟随 WSP 的 CRLF. 每个头部字段都应当以其展开形式进行后续语法和语义评估. 展开后的头部字段没有长度限制, 因而可能无限长.

展开过程:

Before folding (logical):
Subject: This is a very long subject line

After folding (transmission):
Subject: This is a
very long subject line

After unfolding (parsing):
Subject: This is a very long subject line

展开算法:

1. Identify: Find CRLF + WSP pattern
2. Remove: Delete CRLF, keep WSP
3. Result: Continuous single-line string

2.3. 正文

消息正文只是若干 US-ASCII 字符行. 正文只有两个限制:

  • CR 和 LF 必须只作为 CRLF 一起出现; 它们禁止在正文中单独出现.
  • 正文中的字符行必须限制为 998 个字符, 并且应当限制为 78 个字符, 不包括 CRLF.

注意: 如前所述, 还有其他文档, 尤其是 MIME 文档 (RFC 2045, RFC 2046, RFC 2049, RFC 4288, RFC 4289), 扩展并限制了本规范, 以允许不同类型的消息正文. 再次说明, 这些机制超出本文档范围.

正文限制摘要:

限制类型要求描述
行终止符必须使用 CRLFCR 和 LF 不能单独出现
行长度 (硬限制)必须不超过 998 个字符不包括 CRLF
行长度 (建议)应当不超过 78 个字符不包括 CRLF

合法正文示例:

Hello Bob,CRLF
CRLF
Let's meet tomorrow at 10am.CRLF
CRLF
Best regards,CRLF
Alice CRLF

非法正文示例:

Contains independent CR or LF:
Hello BobCR (missing LF)
LineLF (missing CR)

Line too long (exceeds 998 characters):
[Continuous text exceeding 998 characters...]

第 2 章摘要

关键概念

  1. 字符集: US-ASCII (1-127)
  2. 行终止符: CRLF (CR+LF)
  3. 消息结构: 头部字段段 + 空行 + 正文
  4. 行长度: 998 个字符 (必须), 78 个字符 (应该)

头部字段类型比较

Unstructured Fields         Structured Fields
↓ ↓
Subject: Any text From: user@domain
Comments: ... To: user1, user2
Date: Day, DD Mon YYYY
↓ ↓
Process as Parse by syntax
whole

折叠机制

Long field                       Folding
↓ ↓
To: [email protected], To: [email protected],
[email protected] --> [email protected]
↑ ↑
Single line (logical) Multi-line (transmission)
←--- Unfolding ---

后续内容

第 2 章提供了消息的词法概览. 第 3 节将定义用于创建合规消息的精确 ABNF 语法规则.


下一节: 3. 语法

上一节: 1. 简介