Email::Received(3pm)
π Email::Received β the manual page, but make it a group chat π
okay bestie, welcome to Email::Received (yes that's Email::Received(3pm), we're being fancy) β the module that reads a Received: header and tells you what's actually going on in there. no cap.
β¨ NAME β¨
Email::Received β parse an email Received: header. that's it. that's the whole vibe. π
β¨ SYNOPSIS β¨
here's the whole flow, look how cute it is:
use Email::Received;
for ($mail->header("Received")) {
my $data = parse_received($_);
return "SPAM" if rbl_lookup($data->{ip});
}
like. it pulls the header, it parses it, it checks the IP against an RBL, and if that comes back spicy it screams "SPAM". iconic. π
β¨ DESCRIPTION β¨
so this module is a Perl Email Project rewrite of SpamAssassin's email header parser. the way they did that? the SpamAssassin girlies went and analysed pretty much every possible Received header format in existence π and we wanted that glorious work to be usable in apps that are not SpamAssassin itself. so we yoinked it. respectfully. π«Ά
the module gives you exactly one function, parse_received, which takes a single Received line. and then it does one of three things:
- it produces nothing, if the line is unparsable π
- it gives you a hash reference like this, if the line should be ignored for some good reason:
{ reason => "gateway noise" }
- or it gives you one like this, if it actually parsed the message β¨:
{ ip => '64.12.136.4', id => '875522', by => 'xxx.com',
helo => 'imo-m01.mx.aol.com' }
possible keys are, in the original order, no edits:
ip rdns helo ident envfrom auth by id
slay. π
β¨ RULE FORMAT β¨
so where SpamAssassin used one big static subroutine absolutely stuffed with regular expressions to parse the data, we instead build up a big subroutine full of regular expressions dynamically, from a set of rules. glow up π
the rules live at the bottom of this module. iykyk. the basic format for a rule looks like this:
((var=~)?/REGEXP/)? [ACTION; ]+
and the ACTION is one of these four things, exactly:
SET variable = $valueIGNORE "reason"?UNPARSABLEDONE
there's also one control structure provided, and honestly it's basically just an if statement wearing a little outfit:
GIVEN (NOT)? /REGEXP/ {
ACTION+
}
β¨ EXPORT β¨
parse_received
that's the one, bestie. that's what you get. π
β¨ SEE ALSO β¨
Mail::SpamAssassin::Message::Metadata::Receivedβ from which the rules and some of the IP address matching constants were blatantly stolen. no shame, we said it ourselves. thanks guys, for doing such a comprehensive job! ππ
β¨ AUTHOR β¨
simon, <simon@> π«Ά
β¨ COPYRIGHT AND LICENSE β¨
Copyright (C) 2006 by simon
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.7 or, at your option, any later version of Perl 5 you may have available.
ok that's the legal bit and we're keeping it exactly as written, because licensing is not the place for creative liberties, bestie. periodt. π
and that's the whole page!! this one shipped as perl v5.36.0, dated 2022-12-12 β so yeah, a little vintage, but still serving. go parse some headers, you absolute main character. πππ
π¦ where this page comes from
- debian bookworm: libemail-received-perl 1.00-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- debian trixie: libemail-received-perl 1.00-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libemail-received-perl 1.00-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libemail-received-perl 1.00-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libemail-received-perl 1.00-3 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms