Subject: | Header gets screwed up when fetching mail from an IMAP server |
Problem description
===================
When reading Mails from an IMAP server with Mail::Box::IMAP4, the
header of the mail gets screwed up. Example: I have the following
mail at the server (slightly edited):
Return-Path: <rotkraut@cpan.org>
Received: from mail.example.org ([unix socket])
by mail (Cyrus v2.3.11) with LMTPA;
Wed, 30 Jan 2013 14:35:09 +0100
X-Sieve: CMU Sieve 2.3
Received: from x1.develooper.com (x1.develooper.com [207.171.7.70])
by mail.example.org (8.14.3/8.14.3/SuSE Linux 0.8) with SMTP id
r0UDZ0nv013870
for <user@example.org>; Wed, 30 Jan 2013 14:35:00 +0100
Received: (qmail 20353 invoked by uid 225); 30 Jan 2013 13:34:59 -0000
Delivered-To: rotkraut@cpan.org
Received: (qmail 20347 invoked by uid 103); 30 Jan 2013 13:34:58 -0000
Received: from xx1.dev (10.0.100.115)
by x1.dev with QMQP; 30 Jan 2013 13:34:58 -0000
Received: from localhost (HELO xx1.develooper.com) (127.0.0.1)
by xx1.develooper.com (qpsmtpd/0.84/v0.84-36-g0b0e4e9) with ESMTP;
Wed, 30 Jan 2013 05:34:58 -0800
Received: from xx1.develooper.com (xx1.develooper.com [127.0.0.1])
by localhost (Postfix) with SMTP id B466611F640
for <rotkraut@cpan.org>; Wed, 30 Jan 2013 05:34:58 -0800 (PST)
Received: from mail.example.org (mail.example.org [203.0.113.202])
by xx1.develooper.com (Postfix) with ESMTP id 81B7511F650
for <rotkraut@cpan.org>; Wed, 30 Jan 2013 05:34:56 -0800 (PST)
Received: from mail.example.org (localhost [127.0.0.1])
by mail.example.org (8.14.3/8.14.3/SuSE Linux 0.8) with SMTP id
r0UDYDwx013863
for <rotkraut@cpan.org>; Wed, 30 Jan 2013 14:34:35 +0100
Message-Id: <201301301334.r0UDYDwx013863@mail.example.org>
From: Rolf Krahl <rotkraut@cpan.org>
To: Rolf Krahl <rotkraut@cpan.org>
Subject: Test
Date: Wed, 30 Jan 2013 14:33:18 +0100
User-Agent: telnet
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"
Test.
Sending a testmail to myself to demonstrate problems with accessing
IMAP folders with Mail::Box.
Add some more blind text =E2=80=93 bla bla bla =E2=
=80=93 blind text =E2=80=93 bla bla bla =E2=80=93 blind text =E2=80=93 bl=
a bla bla =E2=80=93=
blind text =E2=80=93 bla bla bla =E2=80=93 blind text
When i download this mail using the following script:
#! /usr/bin/perl
use Mail::Box::IMAP4;
my $imaphost = 'mail.example.org';
my $imapuser = 'USER';
my $imappass = 'PASS';
my $mailbox = 'INBOX.test';
my $folder= new Mail::Box::IMAP4(server_name => $imaphost,
starttls => 1,
username => $imapuser,
password => $imappass,
folder => $mailbox);
my @msgs = $folder->messages;
my $msg = pop @msgs;
my $msgstr = $msg->string();
$msgstr =~ s/\r\n/\n/g;
print "$msgstr";
I get the following result:
MIME-Version: 1.0
X-Sieve: CMU Sieve 2.3
Content-Type: text/plain; charset="utf-8"
Received: from mail.example.org ([unix socket]) by mail (Cyrus
v2.3.11)
with LMTPA; Wed, 30 Jan 2013 14:35:09 +0100
Received: from x1.develooper.com (x1.develooper.com [207.171.7.70]) by
mail.example.org (8.14.3/8.14.3/SuSE Linux 0.8) with SMTP id
r0UDZ0nv013870 for <user@example.org>; Wed, 30 Jan 2013
14:35:00 +0100
Received: (qmail 20353 invoked by uid 225); 30 Jan 2013 13:34:59 -0000
Received: (qmail 20347 invoked by uid 103); 30 Jan 2013 13:34:58 -0000
Received: from xx1.dev (10.0.100.115) by x1.dev with QMQP;
30 Jan 2013 13:34:58 -0000
Received: from localhost (HELO xx1.develooper.com) (127.0.0.1) by
xx1.develooper.com (qpsmtpd/0.84/v0.84-36-g0b0e4e9) with ESMTP; Wed,
30 Jan 2013 05:34:58 -0800
Received: from xx1.develooper.com (xx1.develooper.com [127.0.0.1]) by
localhost (Postfix) with SMTP id B466611F640 for <rotkraut@cpan.org>;
Wed,
30 Jan 2013 05:34:58 -0800 (PST)
Received: from mail.example.org (mail.example.org [203.0.113.202]) by
xx1.develooper.com (Postfix) with ESMTP id 81B7511F650 for
<rotkraut@cpan.org>; Wed, 30 Jan 2013 05:34:56 -0800 (PST)
Received: from mail.example.org (localhost [127.0.0.1]) by
mail.example.org (8.14.3/8.14.3/SuSE Linux 0.8) with SMTP id
r0UDYDwx013863 for <rotkraut@cpan.org>; Wed, 30 Jan 2013
14:34:35 +0100
Delivered-To: rotkraut@cpan.org
Subject: Test
User-Agent: telnet
Return-Path: <rotkraut@cpan.org>
Date: Wed, 30 Jan 2013 14:33:18 +0100
Message-Id: <201301301334.r0UDYDwx013863@mail.example.org>
To: Rolf Krahl <rotkraut@cpan.org>
Content-Transfer-Encoding: quoted-printable
From: Rolf Krahl <rotkraut@cpan.org>
Test.
Sending a testmail to myself to demonstrate problems with accessing
IMAP folders with Mail::Box.
Add some more blind text =E2=80=93 bla bla bla =E2=
=80=93 blind text =E2=80=93 bla bla bla =E2=80=93 blind text =E2=80=93 bl=
a bla bla =E2=80=93=
blind text =E2=80=93 bla bla bla =E2=80=93 blind text
The order of the headers lines is mixed up and the folding is altered.
The same thing happens when the mail is copied to a local folder. If
I download the mail using Mail::IMAPClient::message_string directly, I
get the original mail unmodified.
Analysis & Discussion
=====================
The invocation of $msg->string() fetches header and body of the mail
separately using Mail::IMAPClient::parse_headers and
Mail::IMAPClient::message_string respectively. parse_headers returns
a hash with the field names of the header as keys and an array of the
unfolded field bodies of the respective field as value. The original
order of the header lines as well as the original folding is lost at
this point.
I guess, there is no easy and quick solution to the problem.
Apparently, Mail::IMAPClient::parse_headers is intended to fetch
single header lines, but it is simply not suitable to fetch the entire
header. Unfortunately, if I didn't miss something, there is no other
method in Mail::IMAPClient besides message_string that is capable to
fetch an intact message header. Using message_string to fetch just
the header is probably not a good idea as this might significantly
hurt the performance of any program that needs just the headers and
not the bodies.