строка в кодировке 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(), но безрезультатно. Я также включил/отключил настройку php_ini "auto_detect_line_endings", снова без результата.
Я также открыл отчет об ошибке с помощью ZF, хотя ошибки, похоже, нет в библиотеке.
Видите ли вы что-нибудь странное в этом закодированном строка?
ОБНОВЛЕНИЕ
Новое исследование показывает, что электронные письма усекаются после 584 символов. До сих пор не знаю, почему. Также отправил вопрос в Google. Смотрите здесь.
Плохие заголовки электронной почты:
Delivered-To: [email protected]
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 protected]>
Content-Type: multipart/mixed; boundary="===============1703099044=="
MIME-Version: 1.0
From: <[email protected]>
To: <[email protected]>
CC:
Subject: some subject
Message-ID: <[email protected]>
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: <[email protected]>
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
....
Для тех, кого интересует ответ, а не (бывшая) награда, больше подсказок.
5 answers
Я думаю, что вы ищете не в том месте.
Сервер imap выдает вам усеченное почтовое сообщение, а затем возвращает его строку состояния TAG5 OK Success
.
Я не понимаю, как ваша (/php) обработка сокета приведет к исчезновению потока на несколько кб, чтобы волшебным образом исправить поток прямо перед этой строкой состояния.
Таким образом, либо сообщение усекается само по себе (вы проверили содержимое сообщения каким-либо другим способом?), либо сервер imap просто сломанный.
Первое, что я бы сделал, это:
- найдите достаточно тихую среду для размещения вашего проекта, где вы можете
strace -f -s 10240 -p <pid>
процесс apache для проверки взаимодействия сокетов (при условии, что среда linux/apache) - и/или: использовать
tcpdump
,ethereal
или эквивалент, чтобы проверить, что поступает на линию
Я предполагаю, что вы увидите точно такие же усеченные строки, поступающие по проводу. Это означает, что вы можете переключить свое внимание на imap сервер.
Убеждение себя в том, что вы ищете в нужном месте, может сэкономить много времени.
1: попробуйте удалить @
для большей детализации
2: попробуйте использовать http://www.php.net/manual/en/function .fread.php вместо fgets
Это может иметь какое-то отношение к серверу IMAP, потому что я вижу TAG5 OK Success
как ответ, даже если его там не должно быть.
Вы пробовали выдавать другие fgets и посмотреть, получите ли вы остальные данные? Возможно, вы получаете электронное письмо, состоящее из нескольких частей, для которого потребуется несколько запросов.
Но, несмотря на это, вы используете функции, предназначенные для доступа к файлам в сети. Обычно это работает нормально, но в зависимости от сети могут возникнуть проблемы. Например, вы можете использовать file_get_contents для извлечения веб-страницы. Но если проблема вызывает перенаправление, то она завершается неудачей. Но использование curl будет намного больше успешно.
Если вы действительно хотите прочитать сетевой сокет, вам следует попробовать socket_read. Это разработано с учетом сети, как curl.
Не знаю Zend и совсем забыл о PHP, но раньше играл с MIME и HTTP (C++).
Я предлагаю вам начать искать способ добавления записи заголовка длиной содержимого . Это дает подсказку "декодеру/загрузчику сообщений" ожидать определенного размера содержимого (полезной нагрузки сообщения). (Не уверен, что IMAP делает это)
В приведенном выше коде я бы попытался убедить fgets считывать определенный объем ожидаемых данных из сети. Возможно, данные буферизованы или еще не отправлено по сети (асинхронная связь), и fgets считывает только внутренний буфер, останавливаясь, таким образом, до того, как было прочитано все сообщение.
- Чтобы убедиться, так ли это, отправьте небольшое сообщение, которое подпадает под ваш "критический момент 584".
- Выполните трассировку сети, чтобы увидеть, действительно ли все данные передаются. (Вам, вероятно, потребуется выполнить некоторую локальную настройку)
Код, на который вы ссылаетесь, находится здесь?
Скорее всего, одно из ваших серверных устройств скомпрометировано, и поэтому вы хотите полностью изменить его или просто заменить модули оперативной памяти или дисководы. У меня есть некоторый опыт работы с кодировкой на основе Интернета и почты, и я могу подтвердить вам, что строка в кодировке base64 очень безопасна. По крайней мере, он использует алгоритм отображения текстур.