2. Lexical Analysis of Messages (消息的词法分析)
2.1. General Description (一般描述)
在最基本的层面上,消息是一系列字符。符合本规范的消息由值在1到127范围内的字符组成,并被解释为US-ASCII [ANSI.X3-4.1986] 字符。为简便起见,本文档有时将这一字符范围简称为"US-ASCII字符"。
注意: 本文档规定消息由US-ASCII范围1到127的字符组成。还有其他文档,特别是MIME文档系列 ([RFC2045], [RFC2046], [RFC2047], [RFC2049], [RFC4288], [RFC4289]),扩展了本规范以允许该范围之外的值。这些机制的讨论不在本规范的范围内。
消息被划分为多行字符。一行是由两个字符——回车符和换行符——分隔的一系列字符; 即回车符 (CR, Carriage Return) (ASCII值13) 紧跟换行符 (LF, Line Feed) (ASCII值10)。(回车/换行对在本文档中通常写作"CRLF"。)
消息由头部字段 (Header Fields) (统称为"消息的头部区域") 组成,可选地后跟消息体 (Body)。头部区域是具有特殊语法的字符行序列,如本规范中所定义。消息体只是跟在头部区域后面的字符序列,并通过空行 (即,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. Line Length Limits (行长度限制)
本规范对一行中的字符数设置了两个限制。每行字符必须 (MUST) 不超过998个字符,并且应该 (SHOULD) 不超过78个字符,不包括CRLF。
998字符限制的原因是许多发送、接收或存储IMF消息的实现存在限制,它们根本无法处理一行超过998个字符的情况。接收实现为了鲁棒性应该能够处理一行中任意大量的字符。但是,有许多实现 (符合 [RFC5321] 的传输要求) 不接受每行包含超过1000个字符 (包括CR和LF) 的消息,因此实现不创建此类消息非常重要。
78字符建议这一更保守的限制是为了适应许多显示这些消息的用户界面实现,它们可能会截断或灾难性地换行显示每行超过78个字符的内容,尽管这样的实现不符合本规范的意图 (如果它们实际上导致信息丢失,也不符合 [RFC5321] 的意图)。同样,即使对消息设置了这种限制,显示消息的实现也有责任为了鲁棒性而处理一行中任意大量的字符 (当然至少要达到998字符限制)。
行长度限制总结:
| 限制类型 | 长度 (不含CRLF) | 要求等级 | 原因 |
|---|---|---|---|
| 硬限制 | 998字符 | MUST | 许多实现无法处理更长的行 |
| 推荐限制 | 78字符 | SHOULD | 兼容显示截断的用户界面 |
行长度示例:
✅ 符合推荐 (78字符以内):
Subject: This is a short subject line
✅ 符合要求但超过推荐 (78-998字符):
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
❌ 违反要求 (超过998字符):
Subject: [超过998字符的超长内容...]
2.2. Header Fields (头部字段)
头部字段是以字段名 (Field Name) 开头的行,后跟冒号 (":"),再后跟字段体 (Field Body),并以CRLF终止。字段名必须 (MUST) 由可打印的US-ASCII字符 (即,值在33到126之间的字符,包括边界值) 组成,冒号除外。字段体可以由可打印的US-ASCII字符以及空格 (SP, ASCII值32) 和水平制表符 (HTAB, ASCII值9) 字符 (统称为空白字符, WSP) 组成。字段体禁止 (MUST NOT) 包含CR和LF,除非在"折叠" (Folding) 和"展开" (Unfolding) 中使用,如第2.2.3节所述。所有字段体必须 (MUST) 符合本规范第3节和第4节中描述的语法。
头部字段格式:
字段名: 字段体CRLF
↑ ↑ ↑ ↑
| | | +--- 换行符对
| | +-------- 字段内容
| +------------- 冒号分隔符
+----------------- 字段名称
示例:
From: [email protected]
Subject: Meeting Tomorrow
Date: Mon, 20 Dec 2025 10:00:00 +0800
2.2.1. Unstructured Header Field Bodies (非结构化头部字段体)
本规范中的某些字段体被简单定义为"非结构化" (Unstructured) (在第3.2.5节中规定为任何可打印的US-ASCII字符加上空白字符),没有进一步的限制。这些被称为非结构化字段体。从语义上讲,非结构化字段体被简单地视为一行字符,无需进一步处理 (除了第2.2.3节中描述的"折叠"和"展开")。
非结构化字段示例:
Subject: This is any text I want to write
Comments: Here's a free-form comment
特点:
- 内容自由,任意可打印ASCII字符
- 无需遵循特定语法结构
- 仅需处理折叠/展开
2.2.2. Structured Header Field Bodies (结构化头部字段体)
本规范中的某些字段体具有比上述非结构化字段体更严格的语法。这些被称为"结构化" (Structured) 字段体。结构化字段体是本规范第3节和第4节中描述的特定词法标记 (Lexical Tokens) 的序列。根据它们的语法,这些标记中的许多允许以注释 (如第3.2.2节所述) 以及空白字符开始或结束,并且这些空白字符遵循第2.2.3节中描述的"折叠"和"展开"。结构化字段体的语义分析与其语法一起给出。
结构化字段示例:
From: Alice Smith <[email protected]>
To: [email protected], [email protected]
Date: Mon, 20 Dec 2025 10:00:00 +0800
特点:
- 必须遵循严格的语法规则
- 包含特定的词法标记 (如邮箱地址、日期时间)
- 可以包含注释和空白
- 需要按照语法进行解析
对比:
| 类型 | 语法严格度 | 处理方式 | 典型示例 |
|---|---|---|---|
| 非结构化 | 宽松,自由文本 | 作为整体字符串 | Subject, Comments |
| 结构化 | 严格,特定语法 | 按词法标记解析 | From, To, Date |
2.2.3. Long Header Fields (长头部字段)
每个头部字段在逻辑上是由字段名、冒号和字段体组成的单行字符。但是,为了方便起见,并且为了处理每行998/78字符的限制,头部字段的字段体部分可以拆分为多行表示; 这称为"折叠" (Folding)。一般规则是,本规范允许折叠空白 (不仅仅是WSP字符) 的地方,可以在任何WSP之前插入CRLF。
折叠示例:
原始头部字段:
Subject: This is a test
可以表示为 (折叠后):
Subject: This
is a test
注意: 尽管结构化字段体的定义允许在许多词法标记之间 (甚至在某些词法标记内部) 进行折叠,但折叠应该 (SHOULD) 限于将CRLF放置在较高级别的语法断点处。例如,如果字段体被定义为逗号分隔的值,建议在分隔结构化项的逗号之后进行折叠,优先于字段可以折叠的其他位置,即使在其他地方也允许折叠。
折叠规则:
- 插入位置: 在WSP (空格或制表符) 之前插入CRLF
- 继续行: 下一行必须以WSP开始
- 推荐位置: 在高级语法断点 (如逗号后)
多地址折叠示例:
推荐折叠方式 (在逗号后):
To: [email protected],
[email protected],
[email protected]
不推荐但合法的折叠:
To: [email protected], bob@
example.com, [email protected]
展开 (Unfolding) 过程是将此折叠的多行表示移动到其单行表示的过程。展开通过简单地删除紧跟WSP的任何CRLF来完成。每个头部字段应该在其展开形式中进行进一步的语法和语义评估。展开的头部字段没有长度限制,因此可能是无限长的。
展开过程:
折叠前 (逻辑):
Subject: This is a very long subject line
折叠后 (传输):
Subject: This is a
very long subject line
展开后 (解析):
Subject: This is a very long subject line
展开算法:
1. 识别: 找到 CRLF + WSP 模式
2. 删除: 移除 CRLF,保留 WSP
3. 结果: 连续的单行字符串
2.3. Body (消息体)
消息的消息体只是US-ASCII字符的行。消息体的唯一两个限制如下:
- CR和LF必须 (MUST) 仅作为CRLF一起出现; 它们禁止 (MUST NOT) 在消息体中独立出现。
- 消息体中的字符行必须 (MUST) 限制为998个字符,并且应该 (SHOULD) 限制为78个字符,不包括CRLF。
注意: 如前所述,还有其他文档,特别是MIME文档 ([RFC2045], [RFC2046], [RFC2049], [RFC4288], [RFC4289]),扩展 (和限制) 本规范以允许不同类型的消息体。同样,这些机制超出了本文档的范围。
消息体限制总结:
| 限制类型 | 要求 | 说明 |
|---|---|---|
| 换行符 | MUST使用CRLF | CR和LF不能单独出现 |
| 行长度 (硬限制) | MUST ≤ 998字符 | 不含CRLF |
| 行长度 (推荐) | SHOULD ≤ 78字符 | 不含CRLF |
合法的消息体示例:
Hello Bob,CRLF
CRLF
Let's meet tomorrow at 10am.CRLF
CRLF
Best regards,CRLF
Alice CRLF
非法的消息体示例:
❌ 包含单独的CR或LF:
Hello BobCR (缺少LF)
LineLF (缺少CR)
❌ 行太长 (超过998字符):
[超过998字符的连续文本...]
第2章总结
关键概念
- 字符集: US-ASCII (1-127)
- 行终止符: CRLF (CR+LF)
- 消息结构: 头部区域 + 空行 + 消息体
- 行长度: 998字符 (MUST), 78字符 (SHOULD)
头部字段类型对比
非结构化字段 结构化字段
↓ ↓
Subject: Any text From: user@domain
Comments: ... To: user1, user2
Date: Day, DD Mon YYYY
↓ ↓
作为整体 按语法解析
处理 处理
折叠机制
长字段 折叠
↓ ↓
To: [email protected], To: [email protected],
[email protected] --> [email protected]
↑ ↑
单行 (逻辑) 多行 (传输)
←---展开----
下一步
第2章提供了消息的词法概述。第3节将定义精确的ABNF语法规则,用于创建符合规范的消息。
下一节: 3. Syntax (语法)
上一节: 1. Introduction (简介)