如何在Dovecot Pigeonhole的Sieve规则中匹配原始邮件头值?
我完全懂你的困扰——之前用Procmail能轻松识别To:/From:头里带UTF-8编码前缀(也就是=?utf-8?B?)的内容,但切换到Dovecot Pigeonhole的Sieve后,不管用header还是address测试,都匹配不到这些原始的编码字符串。核心原因是:Sieve的默认头测试会自动解码MIME编码的头字段,你看到的匹配值已经是解码后的文本(比如"CUST" <moses@example.com>),而非原始的编码内容。
要解决这个问题,你需要用到Dovecot Pigeonhole提供的专属扩展rawheader,它能直接读取未解码的原始邮件头内容。具体步骤如下:
1. 确认并启用rawheader扩展
首先在你的Sieve脚本开头,添加对rawheader的依赖声明(同时保留fileinto,因为你要用到归档功能):
require ["fileinto", "rawheader"];
注:这个扩展是Dovecot特有的,不属于标准Sieve(RFC5228),但目前主流版本的Pigeonhole都支持它。
2. 用rawheader替换header/address测试
把原来的规则改成用rawheader来匹配原始头内容,示例如下:
if rawheader :contains ["to", "from"] "=?utf-8?B?" { fileinto "Junk"; }
3. 可选:字节级精确匹配(如果需要)
如果你需要严格按原始字节匹配(不忽略大小写),可以加上:comparator "i;octet"参数:
if rawheader :contains :comparator "i;octet" ["to", "from"] "=?utf-8?B?" { fileinto "Junk"; }
为什么这个方法有效?
rawheader会绕过Sieve对MIME头的解码流程,直接读取邮件头的原始字节数据,所以你要匹配的=?utf-8?B?前缀会被准确识别,不会被转换成解码后的文本。拿你提供的测试邮件来说,现在rawheader会直接看到"=?utf-8?B?Q1VTVA==?=" <moses@example.com>这样的原始内容,自然能匹配成功。
你可以再用sieve-test工具验证一下,这次应该会触发fileinto "Junk"的规则,而不是默认保留到INBOX了。
备注:内容来源于stack exchange,提问作者Moses Moore

