NAME

Mail::Colander::Session

SYNOPSIS

use Mail::Colander::Session;

# The session is used during the SMTP dialog to collect data, and
# then by Mail::Colander/Data::Annotation to evaluate conditions and
# rules based on that data, via Data::Annotation::Overlay. The
# accessors are of interest for actually "using" this module.

# set after the TCP handshake, available since "connect"
my $peer_ip = $session->peer_ip;
my $peer_port = $session->peer_port;
my $ip_port = $session->peer_ip_port;  # like "10.20.30.40:2222"

# set after HELO/EHLO
my $peer_identity = $session->peer_identity;

# set after MAIL (FROM)
my $from = $session->reverse_path;

# set/updated after each RCPT (TO)
my $to = $session->forward_path;

# set/updated after each DATA-PART and DATA
my $size = $session->mail_min_size;

# set after DATA
my $eml_as_string = $session->mail_data;

DESCRIPTION

This module encapsulate a session that is then easily consumed through Data::Annotation::Overlay, which eventually means that it can be easily consumed in Data::Annotation rules.

Some methods in the interface are not really supposed to be called by the consumer; they are named after each (E)SMTP command and are called by Mail::Colander::Server during the exchange with a connecting peer. These methods make sure to save the relevant data in the accessors, so that they can be later consumed as described above.

As an example, at TCP session setup the "peer_ip"/"peer_port"/peer_ip_port accessors become available; this means that it's possible to use them in a chain for the connect event:

	 # ... chain for Data::Annotation, named "connect"...
    connect:
      default: reject
      rules:
        - condition:
            is_element_of:
              - '.peer_ip'
              - type: data
                value:
                  - '127.0.0.1'
                  - '10.20.30.40'
                  - '172.16.17.18'
          return: accept

Each following (E)SMTP command triggers some addition of data to the session, which can be consumed in the corresponding chain. E.g. after the HELO or EHLO, the peer identity is available and it can be used to do some filtering and/or set some variables in the overlay:

EHLO:
  default: reject
  rules:
    - condition:
        and:
          - eq: [ '.peer_ip', '=127.0.0.1' ]
          - eq: [ '.peer_identity', '=localhost.localdomain' ]
      record:
        set:
          '.caller': localhost
      return: accept
    - condition:
        and:
          - eq: [ '.peer_ip', '=10.20.30.40' ]
          - eq: [ '.peer_identity', '=foo.example.com' ]
      record:
        set:
          '.caller': foo
      return: accept
- condition:
        and:
          - eq: [ '.peer_ip', '=10.20.30.40' ]
          - eq: [ '.peer_identity', '=bar.example.com' ]
      record:
        set:
          '.caller': bar
      return: accept
    - condition:
        and:
          - eq: [ '.peer_ip', '=172.16.17.18' ]
          - eq: [ '.peer_identity', '=galook.example.com' ]
      record:
        set:
          '.caller': galook
      return: accept

Setting variables (like caller above) allows implementing dispatch tables later in the analysis, to make things more readable.

When the DATA part has been completed, everything is available and the corresponding Data::Annotation chain condition can leverage all attributes. This is also an occasion where it's handy to implement a dispatch table:

DATA:
  default: reject
  rules:
    - condition:
        eq: [ '.caller', '=localhost' ]
      return: { goto: 'localhost' }
    - condition:
        eq: [ '.caller', '=foo' ]
      return: { goto: 'foo' }
    ...

localhost:
  default: reject  # default for this chain
  rules:
    - condition:
        and:
          - '<': [ '.mail_size', '=2500' ]
          - eq: [ '.reverse_path', '=foo@example.com' ]
          - '=~': [ '.subject', '=(?mxs:\A ciao)' ]
          - is_subset_of:
              - '.forward_path'
              - type: data
                value:
                  - 'bar@example.com'
                  - 'foo@bar.com'
      return: accept
...

INTERFACE

Constructor

Accessors

These methods are normally consumed in Data::Annotation/Mail::Colander during the evaluation of conditions, by means of a Data::Annotation::Overlay mediator. The sections below indicate where it is meaningful to consume each accessor.

last_op

my $name = $session->last_op;

The last operation that was called for setting a value, see "Methods for tracking messages".

mail_data

my $eml_as_string = $session->mail_data;

The mail data, as a string. AVailable for chain DATA.

mail_min_size

my $size = $session->mail_min_size;

The minimum size of the email, updated as new data comes in. This is useful in the DATA-PART chain as it allows to check if the message is getting too big before it has all been received.

mail_size

my $size = $session->mail_size;

The definitive size of the message, available for chain DATA.

message

my $message = $session->message;

The received message, as a Mail::Colander::Message. This also sets additional accessors directly mapped from the underlying object, namely:

bare_addresses
bcc
cc
from
header_all
header_first
recipients
subject
to

peer_ip

my $ip_address = $session->peer_ip;

The IP address of the peer, available for chain connect and following.

peer_ip_port

my $ip_colon_port = $session->peer_ip_port;

The IP:port string of the peer, available for chain connect and following.

peer_port

my $port_number = $session->peer_port;

The port number of the peer, available for chain connect and following.

Methods for tracking messages

These methods are normally consumed by Mail::Colander::Server. They are called after Net::Server::Mail::ESMTP has done its job, and their first call parameter is always the Net::Server::Mail::ESMTP object that is handling the dialog, then specific parameters.

DATA

$session->DATA($nsm, $eml_as_string);

DATA_INIT

$session->DATA($nsm);

DATA_PART

$session->DATA($nsm, $ref_to_chunk_as_string);

EHLO

$session->EHLO($nsm, $peer_identity, $extensions);

HELO

$session->HELO($nsm, $peer_identity);

MAIL

$session->MAIL($nsm, $reverse_path);

QUIT

$session->QUIT($nsm);

RCPT

$session->RCPT($nsm, $forward_path);

RST

$session->RST($nsm);

Other methods for setting values

reset

$session->reset;

Reset the state of the session.

reset_transaction

$session->reset_transaction;

Reset the state of the current transaction.

ANYTHING ELSE (INCLUDING AUTHOR, COPYRIGHT AND LICENSE)

See documentation for Mail::Colander.