Received(3pm)

๐Ÿ“ฆ
version 0.26 ยท 2 versions
, in debian bookworm, debian trixie, ubuntu jammy, ubuntu noble

๐Ÿ’Œ Received(3pm) โ€” the bestie guide to Mail::Field::Received

okay so picture this: it's Received(3pm) from the User Contributed Perl Documentation, and it's here to help you parse those Received: headers that every email collects like friendship bracelets on the way to your inbox. Let's get into it ๐Ÿ’–


โœจ NAME โœจ

Mail::Field::Received โ€” a mostly RFC822-compliant parser of Received headers. slay, but with asterisks, iykyk.


๐ŸŒธ SYNOPSIS ๐ŸŒธ

use Mail::Field;

my $received = Mail::Field->new('Received', $header);
my $results = $received->parse_tree();
my $parsed_ok = $received->parsed_ok();
my $diagnostics = $received->diagnostics();

like. four lines. that's the whole vibe. ๐Ÿฆ‹


๐Ÿ’… DESCRIPTION ๐Ÿ’…

Don't use this class directly! fr fr, do NOT. Instead, ask Mail::Field for new instances based on the field name. let the grown-up class do the introductions, bestie.

Mail::Field::Received provides subroutines for parsing Received headers from e-mails. It mostly complies with RFC822, but it deviates to accommodate a number of broken MTAs which are in common use โ€” not naming names but we all know who you are ๐Ÿ˜ญ. It also attempts to extract useful information which MTAs often embed within the (comments). so like, the tea is in the parentheses.

It is a subclass derived from the Mail::Field and Mail::Field::Generic classes. so it's got family. ๐Ÿ‘‘


๐ŸŽ€ ROUTINES ๐ŸŽ€

  • debug โ€” Returns the current debugging level obtained via the diagnostics method. If a parameter is given, the debugging level is changed. The default level is 3. three is the magic number, no cap.
  • diagnose โ€” Appends stuff to the parser's diagnostics buffer.
$received->diagnose("foo", "\n");
  • diagnostics โ€” Returns the contents of the parser's diagnostics buffer.
my $diagnostics = $received->diagnostics();
  • parse โ€” The actual parser. Returns the object (Mail::Field barfs otherwise). ๐Ÿคฎ yes, literally barfs. keep the object coming or it's over.
  • parsed_ok โ€” Returns true if the parse succeed, or if it failed, but was permitted to fail for some reason, such as encountering evidence of a known broken (non-RFC822-compliant) format mid-parse.
if ($received->parsed_ok()) {
  ...
}
  • parse_tree โ€” Returns the actual parse tree, which is where you get all the useful information. It is returned as a hashref whose keys are strings like from, by, with, id, via etc., corresponding to the components of Received headers as defined by RFC822:
received    =  "Received"    ":"            ; one per relay
                  ["from" domain]           ; sending host
                  ["by"   domain]           ; receiving host
                  ["via"  atom]             ; physical path
                 *("with" atom)             ; link/mail protocol
                  ["id"   msg-id]           ; receiver msg id
                  ["for"  addr-spec]        ; initial form
                   ";"    date-time         ; time received

The corresponding values are more hashrefs which are mini-parse-trees for these individual components. A typical parse tree looks something like:

{
 'by' => {
          'domain' => 'host5.hostingcheck.com',
          'whole' => 'by host5.hostingcheck.com',
          'comments' => [
                         '(8.9.3/8.9.3)'
                        ],
         },
 'date_time' => {
                 'year' => 2000,
                 'week_day' => 'Tue',
                 'minute' => 57,
                 'day_of_year' => '1 Feb',
                 'month_day' => ' 1',
                 'zone' => '-0500',
                 'second' => 18,
                 'hms' => '21:57:18',
                 'date_time' => 'Tue, 1 Feb 2000 21:57:18 -0500',
                 'hour' => 21,
                 'month' => 'Feb',
                 'rest' => '2000 21:57:18 -0500',
                 'whole' => 'Tue, 1 Feb 2000 21:57:18 -0500'
                },
 'with' => {
            'with' => 'ESMTP',
            'whole' => 'with ESMTP'
           },
 'from' => {
            'domain' => 'mediacons.tecc.co.uk',
            'HELO' => 'tr909.mediaconsult.com',
            'from' => 'tr909.mediaconsult.com',
            'address' => '193.128.6.132',
            'comments' => [
                           '(mediacons.tecc.co.uk [193.128.6.132])',
                          ],
            'whole' => 'from tr909.mediaconsult.com (mediacons.tecc.co.uk [193.128.6.132])
 '
           },
 'id' => {
          'id' => 'VAA24164',
          'whole' => 'id VAA24164'
         },
 'comments' => [
                '(mediacons.tecc.co.uk [193.128.6.132])',
                '(8.9.3/8.9.3)'
               ],
 'for' => {
           'for' => '<adam@spiers.net>',
           'whole' => 'for <adam@spiers.net>'
          },
 'whole' => 'from tr909.mediaconsult.com (mediacons.tecc.co.uk [193.128.6.132]) by host5.hostingcheck.com (8.9.3/8.9.3) with ESMTP id VAA24164 for <adam@spiers.net>; Tue, 1 Feb 2000 21:57:18 -0500'
}

it's giving nested hashrefs. it's giving main character data structure. ๐ŸŒˆ


๐Ÿ’€ BUGS ๐Ÿ’€

  • Doesn't use Parse::RecDescent, which it maybe should. we've all got that one library we're avoiding, bestie.
  • Doesn't offer a strict RFC822 parsing mode. To implement that would be a royal pain in the arse, unless we move to Parse::RecDescent. ๐Ÿ˜ญ author said what they said.

๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

  • Mail::Field
  • Mail::Header

go read those too, they're the extended universe. ๐Ÿซถ


โญ AUTHOR โญ

Adam Spiers <adam@spiers.net> โ€” the icon who wrote this. ๐Ÿ’œ


๐Ÿ“œ LICENSE ๐Ÿ“œ

All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


and that's the whole page, bestie! this one's perl v5.32.0, dated 2021-01-08, straight from the User Contributed Perl Documentation for Received(3pm). mwah ๐Ÿ’…โœจ

๐Ÿ“ฆ where this page comes from