Закодированная строка base64 получает усечение через вызов fgets при разборе IMAP

Я разбираю электронные письма с помощью Zend_Mail, и, как ни странно, некоторый контент обрезается без очевидной причины и порождает детали электронной почты.

Например

Content-Disposition: attachment; filename="file.sdv" DQogICAgICBTT05FO0xBTkRJTkdTREE7U0FMR1NEQVRPIDtOQVNKIDtSRURTS0FQICAgICAgICAg ICAgIDsgRklTS0VTTEFHO1BSRVNFUlYgICA7ICBUSUxTVEFORDsgU1TYUlJFTFNFOyAgS1ZBTElU RVQ7T01TVFlQRSAgO01JTlNURVBSSVM7ICAgICBWRVJESTsgICBLVkFOVFVNOyAgUlVORFZFS1Qg IA0KLS0tLS0tLS0tLTstLS0tLS0tLS0tOy0tLS0tLS0tLS07LS0tLS07LS0tLS0tLS0tLS0tLS0t LS0tLS07LS0tLS0tLS0tLTstLS0tLS0tLS0tOy0tLS0tLS0tLS07LS0tLS0tLS0tLTstLS0tLS0t LS0tOy0tLS0tLS0tLTstLS0tLS0tLS0tOy0tLS0tLS0tLS07LS0tLS0tLS0tLTstLS0tLS0tLS0t ICANCiAgICAgICAgIDA7MjAxMC4wOS4wODsyMDEwLjA5LjA4O05vcnNrO0dhcm4gICAgICAgICAg ICAgICAgOyAgICAgIDEwMjE7RkVSU0sgICAgIDsgICAgICAgMjEwOyAgIDQwMjA5OTk7ICAgICAg ICAyMDtFZ2Vub3ZlcnQ7ICAgICAgICAgIDsgICAzMDcyLDE2OyAgICAgICAyMTE7ICAgICAyNTMs MiAgDQogICAgICAgICAwOzIwMTAuMDkuMDg7MjAxMC4wOS4wODtOb3JzaztHYXJuICAgICAgICAg 

Получается усеченный

 Content-Disposition: attachment; filename="file.sdv" DQogICAgICBTT05FO0xBTkRJTkdTREE7U0FMR1NEQVRPIDtOQVNKIDtSRURTS0FQICAgICAgICAg ICAgIDsgRklTS0VTTEFHO1BSRVNFUlYgICA7ICBUSUxTVEFORDsgU1TYUlJFTFNFOyAgS1ZBTElU RVQ7T01TVFlQRSAgO01JTlNURVBSSVM7ICAgICBWRVJESTsgICBLVkFOVFVNOyAgUlVORFZFS1Qg IA0KLS0tLS0tLS0tLTstLS0tLS0tLS0tOy0tLS0tLS0tLS07LS0tLS07LS0tLS0tLS0tLS0tLS0t LS0tLS07LS0tLS0tLS0tLTstLS0tLS0tLS0tOy0tLS0tLS0tLS07LS0tLS0tLS0tLTstLS0tLS0t LS 

var_dump в каждой строке показывает это.

 string(78) "DQogICAgICBTT05FO0xBTkRJTkdTREE7U0FMR1NEQVRPIDtOQVNKIDtSRURTS0FQICAgICAgICAg " string(78) "ICAgIDsgRklTS0VTTEFHO1BSRVNFUlYgICA7ICBUSUxTVEFORDsgU1TYUlJFTFNFOyAgS1ZBTElU " string(78) "RVQ7T01TVFlQRSAgO01JTlNURVBSSVM7ICAgICBWRVJESTsgICBLVkFOVFVNOyAgUlVORFZFS1Qg " string(78) "IA0KLS0tLS0tLS0tLTstLS0tLS0tLS0tOy0tLS0tLS0tLS07LS0tLS07LS0tLS0tLS0tLS0tLS0t " string(78) "LS0tLS07LS0tLS0tLS0tLTstLS0tLS0tLS0tOy0tLS0tLS0tLS07LS0tLS0tLS0tLTstLS0tLS0t " string(5) "LS) " string(17) "TAG5 OK Success " 

или в другом электронном письме по адресу

 DQogICAgICBTT05FO0xBTkRJTkdTREE7U0FMR1NEQVRPIDtOQVNKIDtSRURTS0FQICAgICAgICAg ICAgIDsgRklTS0VTTEFHO1BSRVNFUlYgICA7ICBUSUxTVEFORDsgU1TYUlJFTFNFOyAgS1ZBTElU RVQ7T01TVFlQRSAgO01JTlNURVBSSVM7ICAgICBWRVJESTsgICBLVkFOVFVNOyAgUlVORFZFS1Qg IA0KLS0tLS0tLS0tLTstLS0tLS0tLS0tOy0tLS0tLS0tLS07LS0tLS07LS0tLS0tLS0tLS0tLS0t LS0tLS07LS0tLS0tLS0tLTstLS0tLS0tLS0tOy0tLS0tLS0tLS07LS0tLS0tLS0tLTstLS0tLS0t LS0tOy0tLS0tLS0tLTstLS0tLS0tLS0tO 

Я не могу понять, почему здесь останавливается. Передачи должны быть остановлены только в конце строки. Это строка, которая получает строку с сервера IMAP.

 $line = @fgets($this->_socket); 

Закодированный текст содержит строку типа, но снова это усекается в разных частях в разных письмах.

 ----------;----------;----------;-----;--------------------;----------;----------;-- 

Я попытался добавить размер к fgets (), но никаких результатов. Я также включил / отключил параметр «auto_detect_line_endings» php_ini, опять же без результата.

Я также открыл отчет об ошибке с ZF, хотя ошибка, похоже, не в библиотеке.

Вы видите что-то странное в этой закодированной строке?

ОБНОВИТЬ

Новые исследования показывают, что электронные письма усекаются после 584 символов. Все еще не знаю почему. Отправил вопрос и Google. См. Здесь .

Плохие заголовки электронной почты:

 Delivered-To: email@removed.com Received: by 10.216.3.208 with SMTP id 58cs248812weh; Fri, 20 Nov 2009 05:14:14 -0800 (PST) Received: by 10.204.153.217 with SMTP id l25mr1285471bkw.108.1258722853863; Fri, 20 Nov 2009 05:14:13 -0800 (PST) Return-Path: <> Received: from MTX4.mbn1.net (mtx4.mbn1.net [213.188.129.252]) by mx.google.com with SMTP id 2si1800716bwz.60.2009.11.20.05.14.12; Fri, 20 Nov 2009 05:14:13 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of MTX4.mbn1.net designates 213.188.129.252 as permitted sender) client-ip=213.188.129.252; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of MTX4.mbn1.net designates 213.188.129.252 as permitted sender) smtp.mail= Resent-From: <email@removed.com> Content-Type: multipart/mixed; boundary="===============1703099044==" MIME-Version: 1.0 From: <email@removed.com> To: <email@removed.com> CC: Subject: some subject Message-ID: <FLYNDRElQ080Gxw8Zw500000f46email@removed.com> X-OriginalArrivalTime: 20 Nov 2009 13:14:08.0121 (UTC) FILETIME=[5792C690:01CA69E3] Date: Fri, 20 Nov 2009 14:14:08 +0100 X-STA-Metric: 0 (engine=030) X-STA-NotSpam: tlf: vedlagt skip:__ 40 fil cc:2**0 X-STA-Spam: header:MIME-Version: charset:us-ascii header:Subject:1 to:2**0 header:From:1 X-BTI-AntiSpam: score:0,sta:0/030,dnsbl:passed,sw:off,bsn:38/passed,spf:off,bsctr:passed/1,dk:off,pbmf:none,ipr:0/3,trusted:no,ts:no,bs:no,ubl:passed X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply Resent-Message-Id: <19740416124736.CF5804B33EF632B0email@removed.com> Resent-Date: Fri, 20 Nov 2009 14:14:11 +0100 (CET) --===============1703099044== Content-Type: application/octet-stream MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="file.sdv" DQpHUlVQUEVOQVZOICAgICAgICAgIDtLSthQRTtQUk9EQU5MO1BBS0tFTlI7TU9UVEFLTkFWTiAg ICAgICAgICAgICAgICAgICAgO1NPTjtMQU5ESU5HU0RBO1NBTEdTREFUTyA7TkFTSiA7UkVEU0tB UCAgIDtGSVNLRVNMQUcgO1BSRVNFUlYgICA7VElMU1RBTkQ7U1TYUlJFTFM7S1ZBTElURVQ7TUlO U1RFUFJJUzsgICAgICAgIFZFUkRJOyAgICAgS1ZBTlRVTTsgICAgUlVORFZFS1QgICAgDQotLS0t LS0tLS0tLS0tLS0tLS0tLTstLS0tLTstLS0tLS0tOy0tLS0tLS07LS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tOy0tLTstLS0tLS0tLS0tOy0tLS0tLS0tLS07LS0tLS07LS0tLS0tLS0tLTst LS0tLS0tLS0tOy0tLS0tLS0tLS07LS0tLS0tLS07LS0tLS0tLS07LS0tLS0tLS07LS0tLS0tLS0t LTstLS0tLS0tLS0tLS0tOy0tLS0tLS0tLS0tLTstLS0tLS0tLS0tLS0gICAgDQpMb3JlbnR6ZW4g .... 

Для тех, кто интересуется ответом, а не в (бывшей) щедрости, больше подсказок.

Gmail возвращает короткое значение в ответ на RFC822.SIZE, что может привести к усеченным сообщениям. (Они отключены на один байт для каждой строки заголовка, по-видимому, не считая двух символов для CR / LF.)

Я думаю, вы ищете не то место.

Сервер imap дает вам усеченное сообщение, а затем возвращает свою строку состояния TAG5 OK Success .

Я не вижу, как ваша обработка (/ php) сокета приведет к исчезновению потока в несколько килобайт, чтобы магически исправить поток прямо перед этой статусной строкой.

Таким образом, либо сообщение усечено само по себе (вы проверили содержимое сообщения каким-либо другим способом?), Либо imap-сервер просто сломан.

Первыми вещами, которые я бы сделал, являются:

  • найти достаточно тихую среду для размещения вашего проекта, где вы можете провести процесс apache strace -f -s 10240 -p <pid> , чтобы проверить взаимодействие сокетов (при условии, что среда linux / apache)
  • и / или: используйте tcpdump , ethereal или эквивалент, чтобы проверить, что происходит на линии

Я предполагаю, что вы увидите точно такие же усеченные строки, которые появляются на проводе. Это означает, что вы можете переключить фокус на сервер imap.

Удовлетворение себя тем, что вы смотрите в нужном месте, может сэкономить много времени.

1: попробуйте удалить @ для большей детализации

2: попробуйте использовать http://www.php.net/manual/en/function.fread.php вместо fgets

Это может иметь какое-то отношение к серверу IMAP, потому что я вижу TAG5 OK Success в качестве ответа, даже если он не должен быть там.

Вы пробовали выпустить еще один фейс и посмотреть, будете ли вы получать остальную информацию? Возможно, вы получаете многостраничное электронное письмо, которое потребует нескольких запросов.

Но независимо от того, вы используете функции, предназначенные для доступа к файлам в сети. Обычно это работает нормально, но в зависимости от сети могут возникать проблемы. Например, вы можете использовать file_get_contents для извлечения веб-страницы. Но если проблема выдает переадресацию, то она терпит неудачу. Но использование curl будет намного успешнее.

Если вы действительно хотите прочитать сетевой сокет, попробуйте socket_read. Это спроектировано с учетом сети, как завиток.

Не знаю Zend и забыл о PHP, но играл с MIME и HTTP до (C ++).

Я предлагаю вам начать поиск пути добавления записи заголовка Content-Length . Он дает подсказку «декодер / загрузчик сообщений», чтобы ожидать определенного размера в содержимом (полезная нагрузка сообщения). (Не уверен, что IMAP делает это)

В приведенном выше коде я попытался бы убедить fgets в том, чтобы читать определенное количество ожидаемых данных из сети. Возможно, данные буферизованы или еще не отправлены по сети (асинхронная связь), и fgets только считывает внутренний буфер, таким образом останавливаясь до того, как все сообщение было прочитано.

  • Чтобы убедиться, что это так, отправьте небольшое сообщение, которое подпадает под «точку прерывания 584».
  • Проведите некоторую трассировку сети, чтобы увидеть, все ли фактические потоки данных. (Вам, вероятно, потребуется выполнить локальную настройку)

Код, на который вы говорите, здесь ?

Скорее всего, одно из ваших аппаратных средств сервера скомпрометировано, и вы хотите полностью его изменить или просто изменить модули RAM или Disk-Drives. У меня есть опыт работы с кодировкой на основе Web и Mail, и я могу подтвердить, что строка с кодировкой base64 очень безопасна. По крайней мере, он использует алгоритм отображения текстур.