From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 7294A1F4D3; Mon, 28 Oct 2019 10:45:31 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Cc: "Eric W . Biederman" Subject: [PATCH 12/14] mda: support multiple List-ID matches Date: Mon, 28 Oct 2019 10:45:26 +0000 Message-Id: <20191028104528.10140-13-e@80x24.org> In-Reply-To: <20191028104528.10140-1-e@80x24.org> References: <20191028104528.10140-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: While it's not RFC2919-conformant, mail software can theoretically set multiple List-ID headers. Deliver to all inboxes which match a given List-ID since that's likely the intended. Cc: Eric W. Biederman Link: https://public-inbox.org/meta/87pniltscf.fsf@x220.int.ebiederm.org/ --- lib/PublicInbox/MDA.pm | 19 +++++++++++++------ script/public-inbox-learn | 5 +++-- script/public-inbox-mda | 7 +++---- t/mda.t | 19 +++++++++++++++++++ 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/lib/PublicInbox/MDA.pm b/lib/PublicInbox/MDA.pm index ce2c870f..933d82a8 100644 --- a/lib/PublicInbox/MDA.pm +++ b/lib/PublicInbox/MDA.pm @@ -84,18 +84,25 @@ sub set_list_headers { } # TODO: deal with multiple List-ID headers? -sub inbox_for_list_id ($$) { +sub inboxes_for_list_id ($$) { my ($klass, $config, $simple) = @_; # newer Email::Simple allows header_raw, as does Email::MIME: - my $list_id = $simple->can('header_raw') ? + my @list_ids = $simple->can('header_raw') ? $simple->header_raw('List-Id') : $simple->header('List-Id'); - my $ibx; - if (defined $list_id && $list_id =~ /<[ \t]*(.+)?[ \t]*>/) { - $ibx = $config->lookup_list_id($1); + my @dests; + for my $list_id (@list_ids) { + $list_id =~ /<[ \t]*(.+)?[ \t]*>/ or next; + if (my $ibx = $config->lookup_list_id($1)) { + push @dests, $ibx; + } + } + if (scalar(@list_ids) > 1) { + warn "W: multiple List-IDs in message:\n"; + warn "W: List-ID: $_\n" for @list_ids } - $ibx; + \@dests; } 1; diff --git a/script/public-inbox-learn b/script/public-inbox-learn index 79f3ead5..3073294a 100644 --- a/script/public-inbox-learn +++ b/script/public-inbox-learn @@ -95,8 +95,9 @@ if ($train eq 'spam') { next if $seen{"$ibx"}++; remove_or_add($ibx, $train, $addr); } - my $ibx = PublicInbox::MDA->inbox_for_list_id($pi_config, $mime); - if ($ibx && !$seen{"$ibx"}) { + my $dests = PublicInbox::MDA->inboxes_for_list_id($pi_config, $mime); + for my $ibx (@$dests) { + next if !$seen{"$ibx"}++; remove_or_add($ibx, $train, $ibx->{-primary_address}); } } diff --git a/script/public-inbox-mda b/script/public-inbox-mda index 821bd9cc..dca8a0ea 100755 --- a/script/public-inbox-mda +++ b/script/public-inbox-mda @@ -44,12 +44,11 @@ if (defined $recipient) { push @$dests, $ibx if $ibx; } if (!scalar(@$dests)) { - my $ibx = PublicInbox::MDA->inbox_for_list_id($config, $simple); - if (!defined($ibx) && !defined($recipient)) { + $dests = PublicInbox::MDA->inboxes_for_list_id($config, $simple); + if (!scalar(@$dests) && !defined($recipient)) { die "ORIGINAL_RECIPIENT not defined in ENV\n"; } - defined($ibx) or do_exit(67); # EX_NOUSER 5.1.1 user unknown - push @$dests, $ibx; + scalar(@$dests) or do_exit(67); # EX_NOUSER 5.1.1 user unknown } my $err; diff --git a/t/mda.t b/t/mda.t index 99592b2d..35811ac6 100644 --- a/t/mda.t +++ b/t/mda.t @@ -308,6 +308,25 @@ EOF my $cur = `git --git-dir=$maindir diff HEAD~1..HEAD`; like($cur, qr/this message would not be accepted without --no-precheck/, '--no-precheck delivered message anyways'); + + # try a message with multiple List-ID headers + $in = < +List-ID: <$list_id> +Message-ID: <2lids\@example> +Subject: two List-IDs +From: user +To: $addr +Date: Fri, 02 Oct 1993 00:00:00 +0000 + +EOF + ($out, $err) = ('', ''); + IPC::Run::run([$mda], \$in, \$out, \$err); + is($?, 0, 'mda OK with multiple List-Id matches'); + $cur = `git --git-dir=$maindir diff HEAD~1..HEAD`; + like($cur, qr/Message-ID: <2lids\@example>/, + 'multi List-ID match delivered'); + like($err, qr/multiple List-ID/, 'warned about multiple List-ID'); } done_testing();