Использование Zend Framework 1.12, PHP 5.3.1. При указании нескольких получателей почты для Zend_Mail и использовании транспорта Smtp заголовок «Кому:» содержит список получателей, разделенных запятыми. Например.
To: [email protected],[email protected]
Похоже, это правильный синтаксис в соответствии с RFC 2822. Я добавил подпись DKIM (используя https://github.com/louisameline/php-mail-signature), который отлично работает, создавая проходящие подписи, принятые Gmail и другими верификаторами, с одним получателем To :. Но для нескольких получателей подпись не работает.
Отправка подписанного письма на [email protected]
возвращает электронное письмо на Return-path, содержащее, среди результатов различных проверок, канонизированную версию заголовков и тела, которые оно вычислило. Я вижу, что он добавил пробел после каждой запятой при канонизации заголовка To: (я указываю расслабленную канонизацию как для заголовков, так и для тела). И действительно, я взломал свою генерацию подписи, чтобы добавить это пространство при канонизации заголовка To :, и это решило проблему: верификатор port25.com, gmail и другие теперь передают подпись.
Но в любом описании DKIM, которое я видел, смягченная канонизация, включая довольно внимательное прочтение раздела 3.4 RFC 6376, а также код в классе подписи, который я загрузил с github, упомянутого выше, нет ничего, что добавляет пробелов там, где их нет в оригинале; все указанные канонизации связаны с изменением существующих пробелов.
Мне кажется, что канонизация, выполняемая верификатором port25, противоречит RFC 6376 - за исключением того, что другие верификаторы DKIM, такие как gmail, [email protected] и http://www.appmaildev.com/en/dkim/ все согласны с окончательным результатом (они не показывают канонизации что они выполняются так же, как порт25, но если я не канонизирую с пробелом после запятых, они отклонят подпись).
Есть ли у кого-нибудь здесь представление об этом? Поскольку практика в этой области, похоже, постоянно отличается от RFC от 2011 года, не следует ли обновлять RFC? И, конечно же, возникает вопрос о том, следует ли все запятые в значении заголовка To: преобразовать в пробел до того, как WSP будет заменен одним пробелом, и затронуты ли какие-либо другие заголовки.
Сводка окончательного разрешения
Ответ Эвана был совершенно правильным в отношении OP: мой MTA добавлял пространство, а не канонизацию валидатора. Я просто недостаточно внимательно посмотрел на фактически полученный заголовок To :.
Но знание этого не дает совершенно тривиального решения проблемы генерации правильных подписей. «Корневая» проблема заключается в том, что Zend_Mail генерирует значения списка адресов в заголовках, используя запятую без следующего пробела в качестве разделителя - хотя это совершенно допустимый синтаксис, также вполне допустим, что MTA вводит пробел после каждого из них. А упрощенная канонизация, указанная в RFC 6376 и широко применяемая, не поддерживает такую перезапись MTA. Изменение кода Zend_Mail на использование пробела в качестве разделителя было бы тривиальным, за исключением того, что это делается в середине довольно длинного и сложного метода, который потребовал бы большого количества копий-вставок для переопределения, что казалось неправильным. В итоге я написал предварительный фильтр, который помещает пробелы в заголовки перед их подписанием. Хотя это не на 100% идеально по сравнению со всеми возможными вариациями синтаксиса, включая комментарии, применение следующего preg_replace к значениям заголовков To :, Cc: и Reply-To: помогает мне:
preg_replace('/(@[a-z0-9]+(\.[a-z0-9-]+)*>?,)([^ ])/i', '\1 \3', $header_value)