Строка в кодировке base64 усекается при вызове fgets при анализе IMAP - PullRequest
6 голосов
/ 16 марта 2011

Я анализирую электронные письма с помощью 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, хотя, похоже, ошибки нет в библиотеке.

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

UPDATE

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

Плохие заголовки писем:

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.)

Ответы [ 5 ]

5 голосов
/ 26 марта 2011

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

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

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

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

Первое, что я хотел бы сделать, это:

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

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

Уверенность в том, что вы смотрите в правильном месте, может сэкономить много времени.

2 голосов
/ 25 марта 2011

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

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

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

0 голосов
/ 20 марта 2011

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

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

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

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

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

0 голосов
/ 25 марта 2011

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

0 голосов
/ 20 марта 2011

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

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

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

...