RFC 1870《SMTP 服务扩展:消息尺寸声明》中文导读

非官方中文导读声明:本页为 IETF RFC 1870《SMTP Service Extension for Message Size Declaration》非官方中文技术导读,按原文章节顺序梳理规范要点,并非逐字全文翻译;任何规范性判断均以英文原文为准。英文原文见 rfc-editor.org/rfc/rfc1870.txt

1. 为什么需要预先声明尺寸

在互联网邮件早期,SMTP 没有机制让发送方在上传整封邮件之前知道对方能否收下。结果是一封远超接收方磁盘或策略限额的大邮件,要等到被完整传输、甚至被接收方开始落盘之后,才以某种错误被拒——白白占用带宽与 I/O。

RFC 1870 给 SMTP 增加 SIZE 扩展,让双方在传输正文之前交换尺寸信息:服务端说“我最多能收多大”,客户端说“我这封有多大”,超限则立刻停下。它被收录进 STD 10,是邮件尺寸协商的规范基础。

2. EHLO 中的 SIZE 关键字

服务端在 EHLO 响应中以带可选参数的 SIZE 关键字通告能力。参数是一个十进制数字,表示本服务端愿意接收的单封消息最大八位组(octet)数;若省略参数,则只表示“我支持 SIZE 参数”,不承诺具体上限。

S: 250-mx.example.net Hello
S: 250-SIZE 35882577
S: 250 HELP

值为 0 表示服务端未声明上限(仍支持 SIZE 参数,但不限制大小)。当服务端不支持该扩展时,EHLO 响应中不会出现 SIZE 行,客户端也就不得发送 SIZE 参数。

3. MAIL FROM 的 SIZE 参数

客户端在 MAIL FROM 命令中携带 SIZE= 参数,给出本封邮件的八位组总数。这个计数的口径必须一致:包含每行的 CRLF,但不包含 DATA 阶段用于终止邮件的那个“单独一行的点”。

C: MAIL FROM: SIZE=1000000
S: 250 OK

如果服务端已通告具体上限,而客户端的 SIZE 超过了该上限,服务端可以在收到 MAIL FROM 时直接回绝,而不必等到 DATA 之后。规范使用的回绝码是 552(请求的动作被中止:超出了存储分配)。

4. 服务端如何处置超限与不足

关键在于:一旦判定无法接收,服务端必须丢弃后续正文,而不是边收边报错——否则会留下半截邮件与浪费的带宽。

5. 与转发和加密的交互

当一封邮件经多个中继转发时,SIZE 限制是逐跳生效的:每一跳都按本跳通告的上限判断。若某中间 MTA 本身支持 SIZE 但上游传来的尺寸超过了它下一跳能接收的限度,它需要在自己这一跳就拒收,而不是转发后才失败。

对于使用 STARTTLS 或 AUTH 的场景,SIZE 参数仍然挂在 MAIL FROM 上,不受加密/认证影响;加密只保护传输,不改尺寸语义。

6. 部署提示

实际运维中,SIZE 是防大附件压垮服务器的第一道闸门。把它与 8BITMIME、PIPELINING 等扩展一起通告是常见做法。需要注意的是:客户端申报的 SIZE 应是最终落盘字节数,若经过编码(如 base64 会膨胀约 33%),申报值应当反映编码后的实际传输量,否则可能出现“申报未超、实际超”的边界误判。

参考:https://www.rfc-editor.org/rfc/rfc1870.txt