lib/PublicInbox/MDA.pm | 20 +++++++++++++------- script/public-inbox-learn | 5 +++-- script/public-inbox-mda | 7 +++---- t/mda.t | 19 +++++++++++++++++++ diff --git a/lib/PublicInbox/MDA.pm b/lib/PublicInbox/MDA.pm index ce2c870f89edcd353d263d1c8fed28a0d08ede1f..b0dfac4564cfe12425a1ece5d31caa06f63069d4 100644 --- a/lib/PublicInbox/MDA.pm +++ b/lib/PublicInbox/MDA.pm @@ -83,19 +83,25 @@ $simple->header_set("List-Id", "<$pa>"); } } -# 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; + } } - $ibx; + if (scalar(@list_ids) > 1) { + warn "W: multiple List-IDs in message:\n"; + warn "W: List-ID: $_\n" for @list_ids + } + \@dests; } 1; diff --git a/script/public-inbox-learn b/script/public-inbox-learn index 79f3ead5c722cda3d17cea9f4fc8ea185fa39530..3073294a18bb526138d24e6898325157726c9586 100644 --- a/script/public-inbox-learn +++ b/script/public-inbox-learn @@ -95,8 +95,9 @@ next unless ref($ibx); # $ibx may be 0 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 821bd9cca36bb00d33d074c0c8e37d22f3387be5..dca8a0ea0e8aa64f859676773e736d4cae77a3a1 100755 --- a/script/public-inbox-mda +++ b/script/public-inbox-mda @@ -44,12 +44,11 @@ my $ibx = $config->lookup($recipient); # first check 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 99592b2d9e901874f9a271f512c1b943897808e5..35811ac6f19e9a103d338fc7a40c31dc0ede67f8 100644 --- a/t/mda.t +++ b/t/mda.t @@ -308,6 +308,25 @@ is($?, 0, 'mda OK with List-Id match and --no-precheck'); 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();