Perl MIME :: Парсер и кодирование во вложенных телах (message / rfc_822)

аххх, это непросто. Я пытаюсь разобрать несколько писем с помощью perl. Возьмем пример:

From: [email protected]
Content-Type: multipart/mixed;
        boundary="----_=_NextPart_001_01CBE273.65A0E7AA"
To: [email protected]

This is a multi-part message in MIME format.

------_=_NextPart_001_01CBE273.65A0E7AA
Content-Type: multipart/alternative;
        boundary="----_=_NextPart_002_01CBE273.65A0E7AA"


------_=_NextPart_002_01CBE273.65A0E7AA
Content-Type: text/plain;
        charset="UTF-8"
Content-Transfer-Encoding: base64

[base64-content]
------_=_NextPart_002_01CBE273.65A0E7AA
Content-Type: text/html;
        charset="UTF-8"
Content-Transfer-Encoding: base64

[base64-content]
------_=_NextPart_002_01CBE273.65A0E7AA--
------_=_NextPart_001_01CBE273.65A0E7AA
Content-Type: message/rfc822
Content-Transfer-Encoding: 7bit

X-MimeOLE: Produced By Microsoft Exchange V6.5
Content-class: urn:content-classes:message
MIME-Version: 1.0
Content-Type: multipart/mixed;
        boundary="----_=_NextPart_003_01CBE272.13692C80"
From: [email protected]
To: [email protected]

This is a multi-part message in MIME format.

------_=_NextPart_003_01CBE272.13692C80
Content-Type: multipart/alternative;
        boundary="----_=_NextPart_004_01CBE272.13692C80"


------_=_NextPart_004_01CBE272.13692C80
Content-Type: text/plain;
        charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

=20

Viele Gr=FC=DFe

------_=_NextPart_004_01CBE272.13692C80
Content-Type: text/html;
        charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<html>...</html>
------_=_NextPart_004_01CBE272.13692C80--
------_=_NextPart_003_01CBE272.13692C80
Content-Type: application/x-zip-compressed;
        name="abc.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
        filename="abc.zip"

[base64-content]

------_=_NextPart_003_01CBE272.13692C80--
------_=_NextPart_001_01CBE273.65A0E7AA--

Это письмо отправлено из Outlook с другим вложенным сообщением. Как видите, это очень сложное письмо с множеством различных типов содержимого (text / plain, text / html, message / rfc_822, application / xyz) ... И часть rfc_822 является проблемой. Я написал сценарий на Perl 5.8 (Debian Squeeze) для анализа этого сообщения с помощью MIME :: Parser.

use MIME::Parser;
my $parser = MIME::Parser->new;
$parser->output_to_core(1);
my $top_entity = $parser->parse(\*STDIN);
my $plain_body = "";
my $html_body = "";
my $content_type;
foreach my $part ($top_entity->parts_DFS) {
    $content_type = $part->effective_type;
    $body = $part->bodyhandle;
    if ($body) {
        if ($content_type eq 'text/plain') {
            $plain_body = $plain_body . "\n" if ($plain_body ne '');
            $plain_body = $plain_body . $body->as_string;
        } elsif ($content_type eq 'text/html') {
            $html_body = $html_body . "\n" if ($html_body ne '');
            $html_body = $html_body . $body->as_string;
        }
    }
}
# parsing of attachment comes later
print $plain_body;

Первая часть сообщения (base64-content) содержит немецкие умляуты, которые корректно отображаются в STDOUT. Вложенное сообщение rfc_822 автоматически анализируется MIME :: Parser и объединяется с телом верхнего уровня как единое целое. Этот вложенный rfc_822 также содержит немецкие умляуты в кавычках, как вы можете видеть. Но они не отображаются правильно в STDOUT. При выполнении

utf8::encode($plain_body);

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

С Уважением


person rabudde    schedule 08.04.2011    source источник


Ответы (1)


Предполагая, что ваша консоль отображает UTF-8, это имеет смысл. Он правильно показывает то, что вы декодировали, но, конечно, символы latin1 отображаются неправильно.
Позже вы выполняете преобразование в UTF-8, но это не имеет смысла, если данные уже имеют формат UTF8. Таким образом, показаны только бывшие умляуты latin1.

Невозможно сделать это правильно, не глядя на "кодировку" в типе содержимого и не действуя соответствующим образом.

person Ingo    schedule 08.04.2011
comment
Хорошо спасибо. Я понимаю в чем проблема. Сейчас я использую PHP-скрипт, с которым я раньше работал. - person rabudde; 16.05.2011