X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FWwwAttach.pm;h=754da13ffded9b0bb00360397140f133b8b7ec39;hb=88645f747bd43c7fc374d8bfb908dab4e6028825;hp=96103cb028e09b014e4bf29fb7e711c4e567ec08;hpb=f8c8ca04d47620d390092000ca09aab071442fac;p=public-inbox.git diff --git a/lib/PublicInbox/WwwAttach.pm b/lib/PublicInbox/WwwAttach.pm index 96103cb0..754da13f 100644 --- a/lib/PublicInbox/WwwAttach.pm +++ b/lib/PublicInbox/WwwAttach.pm @@ -1,4 +1,4 @@ -# Copyright (C) 2016-2018 all contributors +# Copyright (C) 2016-2020 all contributors # License: AGPL-3.0+ # For retrieving attachments from messages in the WWW interface @@ -6,38 +6,42 @@ package PublicInbox::WwwAttach; # internal package use strict; use warnings; use bytes (); # only for bytes::length -use Email::MIME::ContentType qw(parse_content_type); -use PublicInbox::MIME; -use PublicInbox::MsgIter; +use PublicInbox::EmlContentFoo qw(parse_content_type); +use PublicInbox::Eml; + +sub get_attach_i { # ->each_part callback + my ($part, $depth, $idx) = @{$_[0]}; + my $res = $_[1]; + return if $idx ne $res->[3]; # [0-9]+(?:\.[0-9]+)+ + $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; + $mime = PublicInbox::Eml->new($mime); + $res->[3] = $idx; + $mime->each_part(\&get_attach_i, $res, 1); + pop @$res; # cleanup before letting PSGI server see it + $res } 1;