Обнаружено недопустимое значение заголовка: прием почты imap с заголовком, имеющим французские акценты utf-8

Я работаю над проектом с Zend Framework 2.4.13, и мне нужно получать почту из почтового ящика imap. Для этого я использую \Zend\Mail\Storage\Imap:

foreach ($this->imap as $index => $message) {
    // ...
}

Он работает хорошо, за исключением определенного письма, которое не может быть проанализировано. Заголовок From недействителен, так как содержит необработанные символы UTF-8 (французские акценты):

From: "Stéph" <[email protected]>

Затем я получаю следующую ошибку Zend:

An error occurred during execution; please try again later.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Informations complémentaires:

Zend\Mail\Header\Exception\InvalidArgumentException

Fichier:

    /var/www/project/vendor/zendframework/zendframework/library/Zend/Mail/Header/GenericHeader.php:61

Message:

    Invalid header value detected

Pile d'exécution:

    #0 /var/www/project/vendor/zendframework/zendframework/library/Zend/Mail/Header/GenericHeader.php(35): Zend\Mail\Header\GenericHeader::splitHeaderLine('From: "St\xC3\xA9ph" ...')
    #1 /var/www/project/vendor/zendframework/zendframework/library/Zend/Mail/Headers.php(230): Zend\Mail\Header\GenericHeader::fromString('From: "St\xC3\xA9ph" ...')
    #2 /var/www/project/vendor/zendframework/zendframework/library/Zend/Mail/Headers.php(95): Zend\Mail\Headers->addHeaderLine('From: "St\xC3\xA9ph" ...')
    #3 /var/www/project/vendor/zendframework/zendframework/library/Zend/Mime/Decode.php(141): Zend\Mail\Headers::fromString('MIME-Version: 1...', '\n')
    #4 /var/www/project/vendor/zendframework/zendframework/library/Zend/Mail/Storage/Part.php(106): Zend\Mime\Decode::splitMessage('MIME-Version: 1...', 'MIME-Version: 1...', '')
    #5 /var/www/project/vendor/zendframework/zendframework/library/Zend/Mail/Storage/Message.php(54): Zend\Mail\Storage\Part->__construct(Array)
    #6 /var/www/project/vendor/zendframework/zendframework/library/Zend/Mail/Storage/Imap.php(118): Zend\Mail\Storage\Message->__construct(Array)
    #7 /var/www/project/vendor/zendframework/zendframework/library/Zend/Mail/Storage/AbstractStorage.php(267): Zend\Mail\Storage\Imap->getMessage(1)
    #8 /var/www/project/module/Application/src/Application/Helpers/LeadParser/Mail/Inbox.php(52): Zend\Mail\Storage\AbstractStorage->current()
    #9 /var/www/project/module/Application/src/Application/Helpers/LeadParser/InboxProcessor.php(81): Application\Helpers\LeadParser\Mail\Inbox->getMails()
    #10 /var/www/project/module/Application/src/WebService/Controller/LeadParserController.php(52): Application\Helpers\LeadParser\InboxProcessor->process()
    #11 /var/www/project/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractActionController.php(82): WebService\Controller\LeadParserController->indexAction()
    #12 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
    #13 /var/www/project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(444): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
    #14 /var/www/project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(205): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
    #15 /var/www/project/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php(118): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
    #16 /var/www/project/vendor/zendframework/zendframework/library/Zend/Mvc/DispatchListener.php(93): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
    #17 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
    #18 /var/www/project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(444): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
    #19 /var/www/project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(205): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
    #20 /var/www/project/vendor/zendframework/zendframework/library/Zend/Mvc/Application.php(314): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
    #21 /var/www/project/public/index.php(69): Zend\Mvc\Application->run()
    #22 {main}

Я предполагаю, что проблемы касаются RFC. В соответствии с RFC-2822 этот заголовок недействителен из-за UTF- 8 символов, и Zend жалуется на это когда заголовок проверен.

Я видел много проблем, связанных с этим в Интернете, но большинство из них касалось создания электронной почты, а не приема.

Я также видел RFC-6532, в котором говорится об интернационализированных заголовках электронной почты, но почта не похоже, соблюдают этот стандарт (нет части message/global).

Фактический обходной путь

Единственное решение, которое я нашел на данный момент, это использовать barbushin/php-imap, обертку вокруг собственные функции php imap. Этот пакет кажется более терпимым/обновленным и корректно извлекает почту.

Вопрос

Мне нужно найти решение, чтобы сделать процесс приема почты более терпимым, чтобы принимать такие почтовые заголовки. Но меня не устраивает мой обходной путь, который добавляет зависимости от поставщика для чего-то, что уже реализовано в фреймворке.

Можно ли решить эту проблему напрямую через фреймворк ZF2?


person yolenoyer    schedule 02.08.2019    source источник
comment
Два комментария, ни один из которых не представляет решения. Во-первых, вам не нужно message/global-anything для соответствия 6532. Это тестовое сообщение допустимо. Во-вторых, 6532 в основном относится к адресам, в вашем случае [email protected]. Это позволяет Стефу, но на самом деле это просто упрощение. Это узаконено в результате разрешения é почти везде, мотивация состоит в том, чтобы разрешить é в адресах. Что касается вашей проблемы... вы можете сказать, что Zend плохо обрабатывает синтаксические ошибки в тех случаях, когда ошибки не имеют негативных последствий. Удачи.   -  person arnt    schedule 02.08.2019
comment
@arnt Приятно это знать, спасибо; Я говорю о 6532 в своем вопросе, но, к сожалению, я думаю, что ZF2 соответствует только 2822   -  person yolenoyer    schedule 02.08.2019
comment
Я знаю, и именно поэтому я сказал, что 6532 не решение вашей проблемы. Но подумайте, действительно ли исправление ZF2 для реализации 6532 решит вашу проблему и может быть самым простым способом ее решения. Реализовать поддержку чтения для 6532 чрезвычайно просто.   -  person arnt    schedule 02.08.2019
comment
Должен признаться, я не полностью прочитал rfc... Чтобы реализовать это в ZF2, означало бы просто разрешить больше кодов символов, просто удалив/обновив условия проверки, такие как if ($ord === 10 || $ord > 127) { return false; } ? Или, по-вашему, это будет больше работы?   -  person yolenoyer    schedule 02.08.2019
comment
Вот бы почитать (ну плюс юнит-тесты конечно). Возможность генерировать и отправлять такую ​​почту потребовала бы больше работы, и поддержка 6533 — это еще один кусок, но поддержка 6532 только для чтения полезна и очень проста.   -  person arnt    schedule 02.08.2019
comment
@arnt ваши комментарии могут быть ответом, спасибо   -  person yolenoyer    schedule 02.08.2019


Ответы (1)


Хотя RFC 6532 не имеет прямого отношения к проблеме, реализация поддержки чтения для него в ZF2 вероятно, самый простой способ решить вашу проблему.

Это связано с тем, что 6532 расширяет формат сообщений для поддержки таких адресов, как sté[email protected], и делает это таким образом, который напоминает обычное поведение на протяжении многих лет. Люди делают много неуместных просто-отправить-8, и авторы 6532 решили соответствовать наиболее распространенному типу наблюдаемого поведения пользователей. В сообщении, которое вы хотите прочитать, используется именно тот неуместный вариант just-send-8, который систематизирует и разрешает 6532.

Добавление поддержки чтения сообщений, совместимых с 6532, должно быть таким же простым, как редактирование различных проверок синтаксиса и пропуск большего количества кодовых точек. У меня есть несколько тестовых сообщений на github; если ZF2 может анализировать те, которые вы сможете читать и действовать в соответствии с сообщениями EAI, которые отправляют реальные пользователи.

Для обработки сообщений, отправленных почтовым демоном, также требуется поддержка 6533, а для ответа может потребоваться больше 6532 -актуальная работа. Этот бит сложен. Но чтение почты — полезная способность сама по себе.

person arnt    schedule 02.08.2019