Ruby Milter多收件人时SMFIR_CHGHEADER响应异常,如何正确修改From头?
解决Postfix Milter多收件人场景下修改From头的问题
问题根源
Postfix Milter协议对邮件头修改的时机有严格约束:只有在邮件头解析完成前(SMFIC_EOH事件之前)才能调用SMFIR_CHGHEADER。你遇到的各种报错,都是因为在不允许修改头的阶段(比如SMFIC_RCPT、SMFIC_BODY)执行了头修改操作。
正确实现步骤
按以下方式调整你的脚本:
标记修改需求
在rcpt_to方法中收集收件人地址,判断是否包含目标地址,用实例变量标记是否需要修改From头:def rcpt_to(ctx, rcpt) rcpt_addr = rcpt.gsub(/^<|>$/, '') @modify_from = true if addresses.include?(rcpt_addr) SMFIS_CONTINUE end合法阶段执行修改
end_headers对应Milter的SMFIC_EOH事件,这是修改邮件头的最后合法阶段。在这里检查标记并执行修改:def end_headers(ctx) return SMFIS_CONTINUE unless @modify_from current_from = ctx.get_header('From') return SMFIS_CONTINUE unless current_from new_from = current_from.match(/(<.*?>)/)&.[](1) ctx.chgheader('From', 0, new_from) if new_from SMFIS_CONTINUE end初始化状态变量
在connect方法中初始化标记变量,避免请求间状态残留:def connect(ctx, hostname, address) @modify_from = false SMFIS_CONTINUE end
重要说明
- 所有Milter方法必须返回合法状态码(如
SMFIC_CONTINUE),否则Postfix会中断邮件处理。 - 如果你需要仅给目标收件人发送修改后的邮件,其他收件人保持原邮件,Milter无法直接实现——因为Milter是在邮件进入队列前统一处理,此时邮件还未拆分到单个收件人。这种场景需要结合Postfix的邮件拆分机制(如
recipient_delimiter或自定义transport)来实现。
内容的提问来源于stack exchange,提问作者tajgerON
相关产品推荐
相关产品推荐

