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

Dominik Csapak d.csapak at proxmox.com
Mon Sep 30 14:55:27 CEST 2019


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');
+		$self->{mime}->{$ct} = 1 if $ct && length ($ct) < 256;
 
+		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);
+	}
 
-    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 {
-- 
2.20.1




More information about the pmg-devel mailing list