Я разбираю электронные письма с помощью 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-сервер просто сломан.
Первыми вещами, которые я бы сделал, являются:
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 только считывает внутренний буфер, таким образом останавливаясь до того, как все сообщение было прочитано.
Код, на который вы говорите, здесь ?
Скорее всего, одно из ваших аппаратных средств сервера скомпрометировано, и вы хотите полностью его изменить или просто изменить модули RAM или Disk-Drives. У меня есть опыт работы с кодировкой на основе Web и Mail, и я могу подтвердить, что строка с кодировкой base64 очень безопасна. По крайней мере, он использует алгоритм отображения текстур.