littlelion has asked for the wisdom of the Perl Monks concerning the following question:
I have been using Perl for a good long time and I am tripping over something simple (I just know it). What am I doing wrong here?
My test case is pulled fairly directly from the examples in the documentation.
The environment:The problem:% perl --version This is perl 5, version 16, subversion 3 (v5.16.3) built for x86_6 +4-linux-thread-multi % cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core)
The code:% testmail.pl no data in this part at ./testmail.pp line 25.
#!/usr/bin/perl -w use strict; use warnings; use MIME::Lite; use Data::Dumper; my $msg = MIME::Lite->new(); dumpObject($msg); $msg->build(to => 'user1 <user@fqdn.org>', from => 'user2 <user2@fqdn. +org>'); $msg->build(subject => 'a message subject'); dumpObject($msg); $msg->attach( Type => 'text/plain', Data => 'This is the body text of the email', ); dumpObject($msg); $msg->send; # <------ 'no data' error here sub dumpObject { my ($object) = @_; my $output = Data::Dumper->Dump([$object], ['foo']); $output =~ s/\$foo = //; print $output; }
Full output with dumpObject() on. Notice that MIME::Lite::attach() created 2 parts, one (part0) master with no data and part1 with the text data, but send() barfs on this. Is this a bug in the module or am I doing something wrong?
After MIME::Lite->new:After the build()s:./testmail.pp bless( { 'SubAttrs' => {}, 'Parts' => [], 'Attrs' => {}, 'Header' => [] }, 'MIME::Lite' );
After the attach():bless( { 'SubAttrs' => {}, 'Parts' => [], 'Attrs' => { 'content-disposition' => 'inline', 'content-type' => 'text/plain', 'mime-version' => '1.0', 'content-length' => undef, 'content-transfer-encoding' => '8bit' }, 'Header' => [ [ 'date', 'Sat, 29 Jul 2017 12:31:40 -0700' ], [ 'to', 'user1 <user@fqdn.org>' ], [ 'from', 'user2 <user2@fqdn.org>' ], [ 'x-mailer', 'MIME::Lite 3.030 (F2.84; T1.38; B3.13; Q3.13)' ], [ 'date', 'Sat, 29 Jul 2017 12:31:40 -0700' ], [ 'subject', 'a message' ] ] }, 'MIME::Lite' );
From MIME::Lite->print_simple_body():bless( { 'SubAttrs' => { 'content-type' => { 'boundary' => '_----------=_1501356700259120' } }, 'Parts' => [ bless( { 'SubAttrs' => {}, 'Parts' => [], 'FH' => undef, 'Attrs' => { 'content-disposition' => 'inline', 'content-type' => 'text/plain', 'content-length' => undef, 'content-transfer-encoding' => '8bit' }, 'Path' => undef, 'Data' => undef, 'Header' => [] }, 'MIME::Lite' ), bless( { 'SubAttrs' => {}, 'Parts' => [], 'Attrs' => { 'content-disposition' => 'inline', 'content-type' => 'text/plain', 'content-length' => undef, 'content-transfer-encoding' => '8bit' }, 'Data' => 'This is the body text of the email', 'Header' => [] }, 'MIME::Lite' ) ], 'Attrs' => { 'content-type' => 'multipart/mixed', 'mime-version' => '1.0', 'content-transfer-encoding' => '7bit' }, 'Header' => [ [ 'date', 'Sat, 29 Jul 2017 12:31:40 -0700' ], [ 'to', 'user1 <user@fqdn.org>' ], [ 'from', 'user2 <user2@fqdn.org>' ], [ 'date', 'Sat, 29 Jul 2017 12:31:40 -0700' ], [ 'subject', 'a message' ], [ 'x-mailer', 'MIME::Lite 3.030 (F2.84; T1.38; B3.13; Q3.13)' ] ] }, 'MIME::Lite' ); no data in this part at ./testmail.pp line 21.
From MIME::Lite->attach():if ( defined( $self->{Data} ) ) { ... elsif ( defined( $self->{Path} ) || defined( $self->{FH} ) ) { ... else { Carp::croak "no data in this part\n";
It looks like MIME::Lite expects to be created either with content in new() or with 'Type' set to /^(multipart|message)/ before you can add additional content. I did not find this obvious from the documentation. Thanks for any thoughts, Matt=item attach PART =item attach PARAMHASH... I<Instance method.> Add a new part to this message, and return the new part. If you supply a single PART argument, it will be regarded as a MIME::Lite object to be attached. Otherwise, this method assumes that you are giving in the pairs of a PARAMHASH which will be sent into C<new()> to create the new part. One of the possibly-quite-useful hacks thrown into this is the "attach-to-singlepart" hack: if you attempt to attach a part (let's call it "part 1") to a message that doesn't have a content-type of "multipart" or "message", the following happens: =over 4 =item * A new part (call it "part 0") is made. =item * The MIME attributes and data (but I<not> the other headers) are cut from the "self" message, and pasted into "part 0". =item * The "self" is turned into a "multipart/mixed" message. =item * The new "part 0" is added to the "self", and I<then> "part 1" is added +. =back One of the nice side-effects is that you can create a text message and then add zero or more attachments to it, much in the same way that a user agent like Netscape allows you to do. =cut sub attach { my $self = shift; my $attrs = $self->{Attrs}; my $sub_attrs = $self->{SubAttrs}; ### Create new part, if necessary: my $part1 = ( ( @_ == 1 ) ? shift: ref($self)->new( Top => 0, @_ ) + ); ### Do the "attach-to-singlepart" hack: if ( $attrs->{'content-type'} !~ m{^(multipart|message)/}i ) { ### Create part zero: my $part0 = ref($self)->new; ### Cut MIME stuff from self, and paste into part zero: foreach (qw(SubAttrs Attrs Data Path FH)) { $part0->{$_} = $self->{$_}; delete( $self->{$_} ); } $part0->top_level(0); ### clear top-level attributes ### Make self a top-level multipart: $attrs = $self->{Attrs} ||= {}; ### reset (sam: bug? th +is doesn't reset anything since Attrs is already a hash-ref) $sub_attrs = $self->{SubAttrs} ||= {}; ### reset $attrs->{'content-type'} = 'multipart/mixed'; $sub_attrs->{'content-type'}{'boundary'} = gen_boundary() +; $attrs->{'content-transfer-encoding'} = '7bit'; $self->top_level(1); ### activate top-level attributes ### Add part 0: push @{ $self->{Parts} }, $part0; } ### Add the new part: push @{ $self->{Parts} }, $part1; $part1; }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Error in MIME::Lite?
by shmem (Chancellor) on Jul 30, 2017 at 00:51 UTC | |
|
Re: Error in MIME::Lite?
by Anonymous Monk on Jul 29, 2017 at 20:12 UTC | |
by littlelion (Novice) on Jul 29, 2017 at 20:21 UTC | |
by Anonymous Monk on Jul 29, 2017 at 20:36 UTC | |
by littlelion (Novice) on Jul 29, 2017 at 21:00 UTC | |
by Anonymous Monk on Jul 29, 2017 at 21:18 UTC | |
|