Search code examples
perlemailencodingheadermime

MIME::Entity headers encoding correct?


I use MIME::Entity module in Perl to create a MIME message. Some of the headers seem to be encoded OK, while other seem to have issues with folding.

Code:

use strict;
use Encode;
use MIME::Entity;

my %build_params = (
    'Charset'    => 'UTF-8',
    'From'       => encode('MIME-Header', 'Fantasy Email <vujerldujhgurtelhwgutrwhgunwlhvulhgvnuwlhvuwlnhvgnulwh@gmail.com>'),
    'Subject'    => encode('MIME-Header', "A very long subject that will span on multiple lines in the headers, with a leading sp\
ace at the beginning of each new line."),
    'Type'       => 'multipart/alternative',
);


my $top = MIME::Entity->build(%build_params);

$top->print_header();

Output:

Content-Type: multipart/alternative;
 boundary="----------=_1312196104-11708-0";
 charset="UTF-8"
Content-Transfer-Encoding: binary
MIME-Version: 1.0
X-Mailer: MIME-tools 5.427 (Entity 5.427)
Subject: A very long subject that will span on multiple lines in the
 headers,  with a leading space at the beginning of each new line.
From: Fantasy Email
 <vujerldujhgurtelhwgutrwhgunwlhvulhgvnuwlhvuwlnhvgnulwh@gmail .com>

The Subject seems to be correctly split into multiple lines. The From doesn't, leaving a space before the com, but the newline is gone.

Is this standard behavior or have I found a bug in MIME::Entity?


Solution

  • Encode::MIME::Header (called as encode('MIME-Header', ...)) does some line splitting (called folding in the RFC 822).

    Unfortunately, MIME::Entity does some line splitting too, probably in a different way. It also gets rid of the newline generated by Encode::MIME::Header. It leaves the spaces though.

    I would be happy to leave MIME::Entity deal with the encoding of my headers, but it looks like it just does the line splitting part. So I guess I still have to encode them myself.

    As a workaround, I removed the line splitting markers from my encoded headers with

     my $encoded_from = encode('MIME-Header', 'Fantasy Email <vujerldujhgurtelhwgutrwhgunwlhvulhgvnuwlhvuwlnhvgnulwh@gmail.com>');
     $encoded_from =~ s/\r?\n\s//g;
    

    (And same thing for the subject.)

    Now the output looks like this:

    Subject: A very long subject that will span on multiple lines in the
     headers, with a leading space at the beginning of each new line.
    From: Fantasy Email
     <vujerldujhgurtelhwgutrwhgunwlhvulhgvnuwlhvuwlnhvgnulwh@gmail.com>
    

    I'm wondering if there's a more elegant solution, like Encode::MIME::Header featuring a MIME::Entity compatibility mode or something like that.