From 40f250660b42caa69f5533da5501f8d3f31f30ac Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 25 Dec 2019 07:51:01 +0000 Subject: wwwattach: avoid anonymous sub for msg_iter We can pass arguments to msg_iter for msg_iter to pass to our user-supplied callback, now. --- lib/PublicInbox/WwwAttach.pm | 49 ++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'lib/PublicInbox') diff --git a/lib/PublicInbox/WwwAttach.pm b/lib/PublicInbox/WwwAttach.pm index 2de56804..cda1c6c8 100644 --- a/lib/PublicInbox/WwwAttach.pm +++ b/lib/PublicInbox/WwwAttach.pm @@ -10,34 +10,39 @@ use Email::MIME::ContentType qw(parse_content_type); use PublicInbox::MIME; use PublicInbox::MsgIter; +sub get_attach_i { # msg_iter callback + my ($part, $depth, @idx) = @{$_[0]}; + my $res = $_[1]; + return if join('.', @idx) ne $res->[3]; # $idx + $res->[0] = 200; + my $ct = $part->content_type; + $ct = parse_content_type($ct) if $ct; + + # discrete == type, we remain Debian wheezy-compatible + if ($ct && (($ct->{discrete} || '') eq 'text')) { + # display all text as text/plain: + my $cset = $ct->{attributes}->{charset}; + if ($cset && ($cset =~ /\A[a-zA-Z0-9_\-]+\z/)) { + $res->[1]->[1] .= qq(; charset=$cset); + } + } else { # TODO: allow user to configure safe types + $res->[1]->[1] = 'application/octet-stream'; + } + $part = $part->body; + push @{$res->[1]}, 'Content-Length', bytes::length($part); + $res->[2]->[0] = $part; +} + # /$LISTNAME/$MESSAGE_ID/$IDX-$FILENAME sub get_attach ($$$) { my ($ctx, $idx, $fn) = @_; my $res = [ 404, [ 'Content-Type', 'text/plain' ], [ "Not found\n" ] ]; my $mime = $ctx->{-inbox}->msg_by_mid($ctx->{mid}) or return $res; $mime = PublicInbox::MIME->new($mime); - msg_iter($mime, sub { - my ($part, $depth, @idx) = @{$_[0]}; - return if join('.', @idx) ne $idx; - $res->[0] = 200; - my $ct = $part->content_type; - $ct = parse_content_type($ct) if $ct; - - # discrete == type, we remain Debian wheezy-compatible - if ($ct && (($ct->{discrete} || '') eq 'text')) { - # display all text as text/plain: - my $cset = $ct->{attributes}->{charset}; - if ($cset && ($cset =~ /\A[a-zA-Z0-9_\-]+\z/)) { - $res->[1]->[1] .= qq(; charset=$cset); - } - } else { # TODO: allow user to configure safe types - $res->[1]->[1] = 'application/octet-stream'; - } - $part = $part->body; - push @{$res->[1]}, 'Content-Length', bytes::length($part); - $res->[2]->[0] = $part; - }); - $res; + $res->[3] = $idx; + msg_iter($mime, \&get_attach_i, $res); + pop @$res; # cleanup before letting PSGI server see it + $res } 1; -- cgit v1.2.3-24-ge0c7