[pmg-devel] [PATCH pmg-api v2 03/10] use the refactored helpers from PMG::MIMEUtils

Stoiko Ivanov s.ivanov at proxmox.com
Thu Oct 3 18:56:52 CEST 2019


On Mon, 30 Sep 2019 14:55:27 +0200
Dominik Csapak <d.csapak at proxmox.com> wrote:

> Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
> ---
>  src/PMG/HTMLMail.pm  | 23 ++++--------
>  src/PMG/MailQueue.pm | 88 +++++++++++++++++++-------------------------
>  src/PMG/Unpack.pm    | 58 +++++++++++------------------
>  src/PMG/Utils.pm     | 22 +++++------
>  4 files changed, 77 insertions(+), 114 deletions(-)
> 
> diff --git a/src/PMG/HTMLMail.pm b/src/PMG/HTMLMail.pm
> index e30ede1..668be48 100644
> --- a/src/PMG/HTMLMail.pm
> +++ b/src/PMG/HTMLMail.pm
> @@ -12,6 +12,9 @@ use MIME::Base64;
>  use HTML::TreeBuilder;
>  use HTML::Scrubber;
>  
> +use PMG::Utils;
> +use PMG::MIMEUtils;
> +
>  sub dump_html {
>      my ($tree, $cid_hash) = @_;
>  
> @@ -314,25 +317,13 @@ sub email_to_html {
>  
>  	} else {
>  
> -	    my $parser = new MIME::Parser;
> -	    $parser->extract_nested_messages(0);
> -
> -	    rmtree $dumpdir;
> -
> -	    # Create and set the output directory:
> -	    (-d $dumpdir || mkdir($dumpdir ,0755)) ||
> -		die "can't create $dumpdir: $! : ERROR";
> -	    (-w $dumpdir) ||
> -		die "can't write to directory $dumpdir: $! : ERROR";
> -
> -	    $parser->output_dir($dumpdir);
> +	    my $parser = PMG::MIMEUtils::new_mime_parser({
> +		dumpdir => $dumpdir,
> +	    });
>  
>  	    my $entity = $parser->parse_open($path);
>  
> -	    # bug fix for bin/tests/content/mimeparser.txt
> -	    if ($entity->mime_type =~ m|multipart/|i && !$entity->head->multipart_boundary) {
> -		$entity->head->mime_attr('Content-type' => "application/x-unparseable-multipart");
> -	    }
> +	    PMG::MIMEUtils::fixup_multipart($entity);
>  
>  	    $html = entity_to_html($entity, {}, $viewimages, $allowhref);
>  	}
> diff --git a/src/PMG/MailQueue.pm b/src/PMG/MailQueue.pm
> index 37d30d7..61cb166 100644
> --- a/src/PMG/MailQueue.pm
> +++ b/src/PMG/MailQueue.pm
> @@ -14,6 +14,7 @@ use Time::HiRes qw(gettimeofday);
>  use Mail::Header;
>  
>  use PMG::LDAPSet;
> +use PMG::MIMEUtils;
>  
>  our $spooldir = "/var/spool/pmg";
>  
> @@ -344,25 +345,14 @@ sub close {
>  sub _new_mime_parser {
>      my ($self, $maxfiles) = shift;
>  
> -    # Create a new MIME parser:
> -    my $parser = new MIME::Parser;
> -    #$parser->decode_headers(1);
> -    $parser->extract_nested_messages (1);
> -    $parser->ignore_errors (1);
> -    $parser->extract_uuencode (0);
> -    $parser->decode_bodies (0);
> -
> -    $parser->max_parts ($maxfiles) if $maxfiles;
> -
> -    rmtree $self->{dumpdir};
> -
> -    # Create and set the output directory:
> -    (-d $self->{dumpdir} || mkdir ($self->{dumpdir} ,0755)) ||
> -	die "can't create $self->{dumpdir}: $! : ERROR";
> -    (-w $self->{dumpdir}) ||
> -	die "can't write to directory $self->{dumpdir}: $! : ERROR";
> -
> -    $parser->output_dir($self->{dumpdir});
> +    my $parser = PMG::MIMEUtils::new_mime_parser({
> +	nested => 1,
> +	ignore_errors => 1,
> +	extract_uuencode => 0,
> +	decode_bodies => 0,
> +	maxfiles => $maxfiles,
> +	dumpdir => $self->{dumpdir},
> +    });
>  
>      return $parser;
>  }
> @@ -385,10 +375,7 @@ sub parse_mail {
>  
>      die "$self->{logid}: unable to parse message - $@" if $@;
>  
> -    # bug fix for bin/tests/content/mimeparser.txt
> -    if ($entity->mime_type =~ m|multipart/|i && !$entity->head->multipart_boundary) {
> -	$entity->head->mime_attr('Content-type' => "application/x-unparseable-multipart");
> -    }
> +    PMG::MIMEUtils::fixup_multipart($entity);
>  
>      if ((my $idcount = $entity->head->count ('Message-Id')) > 0) {
>  	$self->msgid ($entity->head->get ('Message-Id', $idcount - 1));
> @@ -412,51 +399,50 @@ sub parse_mail {
>  sub decode_entities {
>      my ($parser, $logid, $entity) = @_;
>  
> -    if ($entity->bodyhandle && (my $path = $entity->bodyhandle->path)) {
> +    PMG::MIMEUtils::traverse_mime_parts($entity, sub {
> +	my ($part) = @_;
> +	if ($part->bodyhandle && (my $path = $part->bodyhandle->path)) {
>  
> -	eval {
> -	    my $head = $entity->head;
> -	    my $encoding = $head->mime_encoding;
> -	    my $decoder = new MIME::Decoder $encoding;
> +	    eval {
> +		my $head = $part->head;
> +		my $encoding = $head->mime_encoding;
> +		my $decoder = new MIME::Decoder $encoding;
>  
> -	    if (!$decoder || ($decoder eq 'none' || $decoder eq 'binary')) {
> +		if (!$decoder || ($decoder eq 'none' || $decoder eq 'binary')) {
>  
> -		$entity->{PMX_decoded_path} = $path; # no need to decode
> +		    $part->{PMX_decoded_path} = $path; # no need to decode
>  
> -	    } else {
> +		} else {
>  
> -		my $body = $parser->new_body_for ($head);
> -		$body->binmode(1);
> -		$body->is_encoded(0);
> +		    my $body = $parser->new_body_for ($head);
> +		    $body->binmode(1);
> +		    $body->is_encoded(0);
>  
> -		my $in = $entity->bodyhandle->open ("r") ||
> +		    my $in = $part->bodyhandle->open ("r") ||
>  		    die "unable to read raw data '$path'";
>  
> -		my $decfh = $body->open ("w") ||
> +		    my $decfh = $body->open ("w") ||
>  		    die "unable to open body: $!";
>  
> -		$decoder->decode ($in, $decfh);
> +		    $decoder->decode ($in, $decfh);
>  
> -		$in->close;
> +		    $in->close;
>  
> -		$decfh->close ||
> +		    $decfh->close ||
>  		    die "can't close bodyhandle: $!";
>  
> -		$entity->{PMX_decoded_path} = $body->path;
> -	    }
> -	};
> -
> -	my $err = $@;
> +		    $part->{PMX_decoded_path} = $body->path;
> +		}
> +	    };
>  
> -	if ($err) {
> -	    syslog ('err', "$logid: $err");
> -	}
> +	    my $err = $@;
>  
> -    }
> +	    if ($err) {
> +		syslog ('err', "$logid: $err");
> +	    }
>  
> -    foreach my $part ($entity->parts)  {
> -	decode_entities ($parser, $logid, $part);
> -    }
> +	}
> +    });
>  }
>  
>  1;
> diff --git a/src/PMG/Unpack.pm b/src/PMG/Unpack.pm
> index c608aed..edb0f74 100755
> --- a/src/PMG/Unpack.pm
> +++ b/src/PMG/Unpack.pm
> @@ -18,6 +18,7 @@ use LibArchive;
>  use MIME::Parser;
>  
>  use PMG::Utils;
> +use PMG::MIMEUtils;
>  
>  my $unpackers = {
>  
> @@ -498,32 +499,6 @@ sub add_glob_mime_type {
>      }
>  }
>  
> -sub walk_mime_entity {
> -    my ($self, $entity) = @_;
> -
> -    my $count = 0;
> -    my $size = 0;
> -
> -    my $ct = $entity->head->mime_attr ('content-type');
> -    $self->{mime}->{$ct} = 1 if $ct && length ($ct) < 256;
> -
> -    if (my $body = $entity->bodyhandle) {
> -	my $path = $body->path;
> -	$size = -s $path;
> -	$count = 1;
> -    }
> -
> -    foreach my $part ($entity->parts)  {
> -	if (my ($n, $s) = $self->walk_mime_entity ($part)) {
> -	    $count += $n;
> -	    $size += $s;
> -	}
> -    }
> -
> -    return ($count, $size);
> -}
> -
> -
>  sub unpack_mime {
>      my ($self, $app, $filename, $tmpdir, $csize, $filesize) = @_;
>  
> @@ -536,22 +511,33 @@ sub unpack_mime {
>  	run_with_timeout ($timeout, sub {
>  
>  	    # Create a new MIME parser:
> -	    my $parser = new MIME::Parser;
> -	    $parser->output_under ($tmpdir);
> -	    $parser->extract_nested_messages (1);
> -	    $parser->ignore_errors (1);
> -	    $parser->extract_uuencode (1);
> -	    $parser->filer->ignore_filename(1);
> -
> +	    my $max;
>  	    if ($self->{maxfiles}) {
> -		my $max = $self->{maxfiles} - $self->{files};
> -		$parser->max_parts ($max);
> +		$max = $self->{maxfiles} - $self->{files};
>  	    }
>  
> +	    my $parser = PMG::MIMEUtils::new_mime_parser({
> +		dumpdir => $tmpdir,
> +		nested => 1,
> +		ignore_errors => 1,
> +		extract_uuencode => 1,
> +		ignore_filename => 1,
> +		maxfiles => $max,
> +	    }, 1);
> +
>  	    my $entity = $parser->parse_open ($filename);
>  
> -	    ($files, $size) = $self->walk_mime_entity ($entity);
> +	    PMG::MIMEUtils::traverse_mime_parts($entity, sub {
> +		my ($part) = @_;
> +		my $ct = $part->head->mime_attr ('content-type');
cosmetic nit - optionally remove the space before the opening '('
(noting it here since this is in the output of `git diff -w`
and I'd definitely leave the whitespace-only changes untouched)

> +		$self->{mime}->{$ct} = 1 if $ct && length ($ct) < 256;
see above

>  
> +		if (my $body = $part->bodyhandle) {
> +		    my $path = $body->path;
> +		    $size += -s $path;
> +		    $files++;
> +		}
> +	    });
>  	});
>      };
>  
> diff --git a/src/PMG/Utils.pm b/src/PMG/Utils.pm
> index 2dc22ad..7d24055 100644
> --- a/src/PMG/Utils.pm
> +++ b/src/PMG/Utils.pm
> @@ -37,6 +37,7 @@ use PVE::ProcFSTools;
>  use PMG::AtomicFile;
>  use PMG::MailQueue;
>  use PMG::SMTPPrinter;
> +use PMG::MIMEUtils;
>  
>  use base 'Exporter';
>  
> @@ -169,21 +170,20 @@ sub extract_filename {
>  }
>  
>  sub remove_marks {
> -    my ($entity, $add_id, $id) = @_;
> +    my ($entity, $add_id) = @_;
>  
> -    $id //= 1;
> +    my $id = 1;
>  
> -    foreach my $tag (grep {/^x-proxmox-tmp/i} $entity->head->tags) {
> -	$entity->head->delete ($tag);
> -    }
> -
> -    $entity->head->replace('X-Proxmox-tmp-AID', $id) if $add_id;
> +    PMG::MIMEUtils::traverse_mime_parts($entity, sub {
> +	my ($part) = @_;
> +	foreach my $tag (grep {/^x-proxmox-tmp/i} $part->head->tags) {
> +	    $part->head->delete ($tag);
see above
> +	}
>  
> -    foreach my $part ($entity->parts)  {
> -	$id = remove_marks($part, $add_id, $id + 1);
> -    }
> +	$part->head->replace('X-Proxmox-tmp-AID', $id) if $add_id;
>  
> -    return $id;
> +	$id++;
> +    });
>  }
>  
>  sub subst_values {




More information about the pmg-devel mailing list