[Mimedefang] Using ARF

Philip Prindeville philipp_subx at redfish-solutions.com
Sat Nov 30 16:45:07 EST 2013


On Nov 18, 2013, at 11:07 PM, Philip Prindeville <philipp_subx at redfish-solutions.com> wrote:

>> 
>> Maybe... can you detect the difference between Disposition =>
>> undef and a missing Disposition?  I have to look into this.

Didn’t hear back about this, so I did some of my own looking.

It seems to happen here:

package MIME::Entity;
...

sub suggest_encoding {
    my $self = shift;

    my ($type) = split '/', $self->effective_type;
    if (($type eq 'text') || ($type eq 'message')) {    ### scan message body
        $self->bodyhandle || return ($self->parts ? 'binary' : '7bit');
        my ($IO, $unclean);
        if ($IO = $self->bodyhandle->open("r")) {
            ### Scan message for 7bit-cleanliness
            local $_;
            while (defined($_ = $IO->getline)) {
                last if ($unclean = ((length($_) > 999) or /[\200-\377]/));
            }

            ### Return '7bit' if clean; try and encode if not...
            ### Note that encodings are not permitted for messages!
            return ($unclean
                    ? (($type eq 'message') ? 'binary' : 'quoted-printable')
                    : '7bit');
        }
    }
    else {
        return ($type eq 'multipart') ? ‘binary' : 'base64';
    }
}

sub suggest_encoding_lite {
    my $self = shift;
    my ($type) = split '/', $self->effective_type;
    return (($type =~ /^(text|message|multipart)$/) ? ‘binary' : 'base64');
}


which gets called from here:

sub build {
…
    my $encoding     = $params{Encoding} || ‘';
…
    my $disposition  = $params{Disposition} || 'inline’;
…
    ### Type-check sanity:
    if ($type =~ m{^(multipart|message)/}) {
        ($encoding =~ /^(|7bit|8bit|binary|-suggest)$/i)
            or croak "can't have encoding $encoding for message type $type!";
    }
…
    ### Now that both body and content-type are available, we can suggest
    ### content-transfer-encoding (if desired);
    if (!$encoding) {
        $encoding = $self->suggest_encoding_lite;
    }
    elsif (lc($encoding) eq '-suggest') {
        $encoding = $self->suggest_encoding;
    }
…
    ### Add content-disposition field (if not multipart):
    unless ($is_multipart) {
        $field = new Mail::Field 'Content_disposition';  ### not a typo :-(
        $field->type($disposition);
        $field->filename($filename) if defined($filename);
        $head->replace('Content-disposition', $field->stringify);
    }

    ### Add other MIME fields:
    $head->replace('Content-transfer-encoding', $encoding) if $encoding;


thus it looks like the encoding hasn’t been set, so it gets set to whatever suggest_encoding_lite() returns, which in this case would be ‘binary’ for ‘text/plain’, which I don’t really get (since it should default to ‘7bit’ if it fits into that encoding, and ‘base64’ otherwise).

Similarly, if I had called:

$entity => MIME::Entity->build(
	…
	Type => ‘multipart/mixed’,
	…
);

then I would get ‘binary’ for the content-transfer-encoding as well.  Which again, doesn’t seem correct, since a multipart/mixed doesn’t have any content of its own to encoding… only subordinate parts, which will each have their own (explicit or defaulted) encoding.

Conclusion: leaving the Encoding unset isn’t the same as setting it to ‘-suggest’, yet that’s how it’s effectively handled.  And suggest_encoding_list() doesn’t need to return a type for ‘multipart’ or ‘message’, since the former doesn’t even require a type, and the latter will have its own implied default if it’s absent.

Also not clear that we need to explicitly add a Content-Disposition.  If one hasn’t been set, why not just omit it? At the very least, a Content-Disposition shouldn’t be needed if Top != 0.

And here was the test that I used:



> Not sure I understand what you’re asking.  If I don’t set it or if I set it to undef, it ends up taking the default value:
> 
> 
> [philipp at builder ~]$ cat /tmp/foo.pl
> #!/usr/bin/perl 
> 
> use strict;
> use warnings;
> 
> use MIME::Entity;
> 
> my $msg = MIME::Entity->build(
> 	Top => 0,
> 	Disposition => undef,
> 	Type => 'text/plain',
> 	Encoding => undef,
> 	Data => [
> "Some random MIME part.\n",
> 	],
> );
> 
> print $msg->as_string();
> [philipp at builder ~]$ /tmp/foo.pl
> Content-Type: text/plain
> Content-Disposition: inline
> Content-Transfer-Encoding: binary
> 
> Some random MIME part.
> [philipp at builder ~]$ 




More information about the MIMEDefang mailing list