mids references/;
use URI::Escape qw(uri_escape_utf8);
use Digest::SHA qw/sha1_hex/;
-use constant MID_MAX => 40; # SHA-1 hex length
+use constant {
+ MID_MAX => 40, # SHA-1 hex length # TODO: get rid of this
+ MAX_MID_SIZE => 244, # max term size (Xapian limitation) - length('Q')
+};
sub mid_clean {
my ($mid) = @_;
"$x2/$x38";
}
-sub mid_mime ($) { $_[0]->header_obj->header_raw('Message-ID') }
+# Only for v1 code paths:
+sub mid_mime ($) { mids($_[0]->header_obj)->[0] }
-sub uniq_mids {
- my ($hdr, @fields) = @_;
- my %seen;
- my @raw;
- foreach my $f (@fields) {
- push @raw, $hdr->header_raw($f);
+sub mids ($) {
+ my ($hdr) = @_;
+ my @mids;
+ my @v = $hdr->header_raw('Message-Id');
+ foreach my $v (@v) {
+ my @cur = ($v =~ /<([^>]+)>/sg);
+ if (@cur) {
+ push(@mids, @cur);
+ } else {
+ push(@mids, $v);
+ }
+ }
+ foreach my $i (0..$#mids) {
+ next if length($mids[$i]) <= MAX_MID_SIZE;
+ warn "Message-ID: <$mids[$i]> too long, truncating\n";
+ $mids[$i] = substr($mids[$i], 0, MAX_MID_SIZE);
+ }
+
+ uniq_mids(\@mids);
+}
+
+# last References should be IRT, but some mail clients do things
+# out of order, so trust IRT over References iff IRT exists
+sub references ($) {
+ my ($hdr) = @_;
+ my @mids;
+ foreach my $f (qw(References In-Reply-To)) {
+ my @v = $hdr->header_raw($f);
+ foreach my $v (@v) {
+ push(@mids, ($v =~ /<([^>]+)>/sg));
+ }
}
- my @mids = (join(' ', @raw) =~ /<([^>]+)>/g);
- my $mids = scalar(@mids) == 0 ? \@raw: \@mids;
+ uniq_mids(\@mids);
+}
+
+sub uniq_mids ($) {
+ my ($mids) = @_;
my @ret;
+ my %seen;
foreach (@$mids) {
next if $seen{$_};
push @ret, $_;
\@ret;
}
-sub mids { uniq_mids($_[0], 'Message-Id') }
-
-# last References should be IRT, but some mail clients do things
-# out of order, so trust IRT over References iff IRT exists
-sub references { uniq_mids($_[0], 'References', 'In-Reply-To') }
-
# RFC3986, section 3.3:
sub MID_ESC () { '^A-Za-z0-9\-\._~!\$\&\';\(\)\*\+,;=:@' }
sub mid_escape ($) { uri_escape_utf8($_[0], MID_ESC) }