Вложения электронной почты Base64 не загружаются - PullRequest
3 голосов
/ 10 января 2012

Я использую следующий сценарий http://stuporglue.org/recieve-e-mail-and-save-attachments-with-a-php-script/ для обработки моих электронных писем, которые мне отправляют, однако кажется, что пользователь отправляет электронное письмо от mail или outlook или любого другого почтового клиента, который отправляет вложения base64, которыми он не является сохраняются в базе данных, а основной текст письма также пропускается.

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

При ближайшем рассмотрении видно следующее Mail.app отправляет свой base64 следующим образом.

    --Apple-Mail=_9E76B10A-4086-43B8-B835-78F184FA43FC
Content-Disposition: inline;
    filename=CV-IT.pdf
Content-Type: application/pdf;
    name="CV-IT.pdf"
Content-Transfer-Encoding: base64

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
1NVM1hk3kE1G3rlPZKL2CeZ+Hdp

пока Gmail отправляет это так.

Content-Type: application/pdf; name="CV-IT.pdf"
Content-Disposition: attachment; filename="CV-IT.pdf"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_gx86pbon0

JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURl
Y29kZT4+CnN0cmVhbQp4nM1aS4/jNgy+z6/wucCkFmXJNjAwkMwkBXrbdoAeip76Aopuge5l/34l
kpKol+NseygGq01sPSiS30eKynhSw+env4dxGN0ns5qTHpZJndbh06/DD18Nf9E79/fp96fL+xOM
ywmGeR5d+/7L8PVNDcoM77/9+DKqDV5G2J7Vy6i3Zx3aaXONwY/U2s31mPHj4t/hOGxWfHj27yd6
89P7t0/X96cPhRRqVqdlmM1EMsCgdJDBzwDZ8m424xbVadEooVsQ/IKuufgOr7HBZ9TpTWzp6t+l
rjcWGF7UiFP5uZWKCyjwTxV9nrBHNadCrSiLLUnY3Teo2Vlp1kvQfty58qokIdRKG1VnnMwLqi68
1iuv84btlZ/ehAT1Z9HCyKNL+U5mVKsVPuKkhOk0k5R6UMD2GaFwDm8dr2tsbDQRyMcLOYdis9jx
Qt+U+3vlIRM9cBszzkzUETstYvabf/DqXgr5Fe5ADVLqnz8+je6/z9nmvvvmaRyelev0cVDz6oCC
X/4cvq/906zujV3BeWlACXvohZzt/9R0nM1YJ721WiCd9+BgM3nH8j785ue4+uZGHogAQNfX9MK5
v1f+htDvAXry9CMWA7kYCGSCEnD0VgZAo246YRRswCMBdI6dGRkJrDymZAaCLOh93Wh1sqVuNLMg
Al5R4yb2MqsA96STHXVk8yd1+Plg2uwLmAhvsO3NwUwcQC0speZmQRG0eZwGvxruaIPiHa3Qk0qn
QvdG8iJ2gZVmfo3MKeadCyuS7hOVCaotDA6zsBacxXoXpxs3pGc4bR1wa836md7/6JtamQDlaAqn
T8v6n0nQm2A2fD55jTvrpM3PucKFEXueKALLuexRaT7sPticRoNFnRZ2lnHq2CI4C2/W4dDKWJkG
wCpmJp2wGEaYyftex0bTAg2F37PQOJZQSdKfAwMJt8qIZF972ebY5dj/TPgK1v3DDVaEdEs2vmSr
uK9qcnN2vRVGH2GMXU5Ti2dS0jCFdqEMIKB+4m1fvGWJsPH7G3a2bFQ/xGc2RNzYDT8SpdP7ROw4
V0gHmoE0CZ0H0jyErnovhM6TM6pHK3vBFLxAdbwAg60YUFHmA1A0HTDCG4cF1/3qVQi3HEjtDhwP
BCq8tqmv+6imNZuDBhJbY/TTo6e9Yimt4isNGcO6oavqdBXJKo4SLqu6aee0WHcgqHXbhyQZQ60h
A2yG8yVf30GKk1RSmmTWRZ4ZkGKucn8aJzUx/82yAdYKQ9+IbRMv3ErjCBErvJZUKDwkxcIlBSjh
VZXANWX0ghaopjeXKVPnsCQTKnvDC3YuekODuJcsbjmLFdO9e2nAAQVTeXNZI2IjK
lzZMfgp/yLNYqBAxcirAE2OoApaneMQC8vG/8u4r9DAl32PymNLwAeJS53Zw4Dz5BpggNvJ+LJ83
cV8BN/hQWrTQ1JgPeKjAAiHjarRjCrer9+kZ4QbkCgPImY1Rx/
xKzWTUqYLR72s9ElZMvobeo21seOQIz10egQrILR2rFPuE7uC5SDdhxHvrEheuTjOBa+W46N/Syw
FEy4fzYUYnx0vJdJYdNEv+SP93prSS27XFcbtywJolTJ7LcV27psAzbWZovda2CVjMyM+oxgBgth
+V5ks2Ucy0W5i3JX5zJKP32fRE/Dv8me9Cpp/N0Ql5g0JYXkTrdCqkA54gz7tqsjyvw8GuDwtI5Z
/SP1L83NXeuaG7D7yI0HAqUdaelxS/PyB+ffsG920fxFM2fdN3/u7TOyql2pBS0F8wfj1zQ04MST
oPRrG9sdFpvfrh6ILlGU9JyiwhMmIbkfHctNSAenMp3yF0gKEmwtPDfxSnv9OU01wyG7d/JvKxwJ+Iqf
X9iuCOOPLV9Q8/ajoxtIybOHq5Yu6W7d95RqT/ZP7V+fNHPlYPJ05cb8kowfLquOe/SOopkZ+Oft
RwpKCrjT0Wm+vXXtT0wT45/H/55cYZUZ9VXeEjV/9K15C21Got5JYmKWjP8GZZb2G5R4NDMwtda6
1NVM1hk3kE1G3rlPZKL2CeZ+Hdp

Вложение gmail сохраняется, а mail.app - нет.

Ответы [ 3 ]

3 голосов
/ 18 января 2012

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

Существуют две основные проблемы.

Проблема 1: разделенные строки заголовка

Посмотрите на эти заголовки:

Content-Disposition: inline;
    filename=CV-IT.pdf
Content-Type: application/pdf;
    name="CV-IT.pdf"

против

Content-Type: application/pdf; name="CV-IT.pdf"
Content-Disposition: attachment; filename="CV-IT.pdf"

Теперь рассмотрим часть, которая обрабатывает эти строки:

$info = split("\n",$parts[0]);
..
foreach($info as $line)
{
    if( preg_match("/Content-Type: (.*);/",$line,$matches) )
    {
        $type = $matches[1];
    }
    if( preg_match("/Content-Disposition: attachment; filename=\"(.*)\"/",
        $line,$matches) ) {
        $name = time() . "_" . $matches[1];
    }
    ..
}

Это разбивает заголовок на строки, а затем пытается сопоставить каждую строку.Теперь посмотрим на два заголовка.Второй (рабочий) имеет 2 строки, которые идеально совпадают.

Первый (не работает) имеет 4 (!) Строки.Ни одна из этих 4 строк не соответствует шаблонам.

Существует множество способов решения этой проблемы, и я возьму быстрый и грязный вкладыш.Добавьте эту строку перед $info = split("\n",$parts[0]);

$parts[0] = preg_replace("/\r?\n\s+/"," ",$parts[0]);

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

Проблема 2: неправильный шаблон

Предполагая, что вы применили вышеуказанное исправление, у вас есть этот шаблон:

if( preg_match("/Content-Disposition: attachment; filename=\"(.*)\"/", ...

, пытаясь сопоставить эту строку:

Content-Disposition: inline; filename=CV-IT.pdf

Здесь две вещи идут не так, как надо:

проблема 2a: расположение inline / attachment

Шаблон явно ищет слово «attachment», в то время как строка говорит «inline».Это исправлено заменой attachment на (attachment|inline), что указывает на альтернативу.(обратите внимание, что это также фиксирует тип расположения)

проблема 2b: двойные кавычки имени файла

В шаблоне также выполняется поиск filename="(.*)", в то время как в строке есть имя файла без кавычек.

Это также не является большой проблемой, если вы вставите ? после ", чтобы указать, что " является необязательным, все будет работать.Чтобы сделать его идеальным, вы также должны убедиться, что . не будет соответствовать окончанию ", если доступно, поэтому замените filename="(.*)" на:

filename="?([^"]+)"?

, где [^"]+ означает «что угодно, кроме" '.

Так что если вы измените эти строки:

if( preg_match("/Content-Disposition: attachment; filename=\"(.*)\"/",
    $line,$matches) ) {
    $name = time() . "_" . $matches[1];
}

на

if( preg_match('/Content-Disposition: (attachment|inline); filename="?([^"]*)"?/',
    $line,$matches) ) {
    $disposition = $matches[1];
    $name = time() . "_" . $matches[2];
}

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

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

2 голосов
/ 12 января 2012

Проблема в том, что мой скрипт не ищет встроенный контент, только для вложенного контента.С тем, как вы прикрепили файл, он встроен, следовательно,

Content-Disposition: inline;имя_файла = CV-IT.pdf

Если вы прикрепите его, вместо этого вы увидите Content-Disposition: attachment;filename = "CV-IT.pdf"

Обработка Content-Disposition находится вокруг строки 54-64 сценария на моем сайте (ссылка на исходный вопрос).

0 голосов
/ 12 января 2012

кажется, что вы использовали preg_match, чтобы получить границу почты около строки 166:

if (preg_match("/boundary=(.*boundary)$/",$line,$matches)){
    $boundary = $matches[1];

Вы использовали символ "/" в качестве разделителя шаблона регулярного выражения, и в то же время у вас есть символ "/" в содержимом границы.

Так что это может быть причиной того, что ваш код не работает.

Попробуйте это:

if (preg_match("{boundary=(.*boundary)$}",$line,$matches)){
    $boundary = $matches[1];
...