| POE-Filter-Postfix documentation | Contained in the POE-Filter-Postfix distribution. |
POE::Filter::Postfix - Postfix (MTA) text attribute communication
version 0.003
This filter translates between hashrefs and the key-value attribute protocols that the Postfix MTA uses for its internal communications.
Unless you're doing something complicated, you can probably use POE::Component::Server::Postfix instead of this module.
Don't use this module directly. See POE::Filter::Postfix::Null, POE::Filter::Postfix::Base64, and POE::Filter::Postfix::Plain instead.
Return a new POE::Filter::Postfix.
Call this on a subclass, not on POE::Filter::Postfix directly.
See clone in POE::Filter.
After parsing keys and values, these methods are called to decode them. See POE::Filter::Postfix::Base64 for an example.
The default is to pass keys and values through unchanged.
You do not need to call these methods by hand; get_one calls them
automatically.
See put in POE::Filter.
Before packing keys and values into a string, these methods are called to encode them. See POE::Filter::Postfix::Base64 for an example.
The default is to pass keys and values through unchanged.
You do not need to call these methods by hand; put calls them automatically.
These methods must be overridden by subclasses.
Each returns a string that will be used to parse and construct requests.
See existing subclasses for examples.
Hans Dieter Pearcey <hdp@cpan.org>
This software is copyright (c) 2008 by Hans Dieter Pearcey.
This is free software; you can redistribute it and/or modify it under the same terms as perl itself.
| POE-Filter-Postfix documentation | Contained in the POE-Filter-Postfix distribution. |
use strict; use warnings; package POE::Filter::Postfix; our $VERSION = '0.003'; # ABSTRACT: Postfix (MTA) text attribute communication use base qw(POE::Filter); sub _abstract { my $name = shift; eval sprintf <<'', ($name) x 2; sub %s { my $class = ref($_[0]) || $_[0]; require Carp; Carp::croak("$class must override %s()"); } } BEGIN { _abstract($_) for qw( attribute_separator attribute_terminator request_terminator ) } sub new { my $class = shift; bless { @_, buffer => '', } => $class; } sub clone { my $self = shift; $self->new(%$self); } sub get_one_start { my ($self, $buf) = @_; $self->{buffer} .= $_ for @$buf; } sub get_one { my ($self) = @_; my %attr; my $buf = $self->{buffer}; my ($a_s, $a_t, $r_t) = ( $self->attribute_separator, $self->attribute_terminator, $self->request_terminator, ); while ($buf =~ s/^([^$r_t]+?)\Q$a_s\E//) { my $key = $self->decode_key("$1"); $buf =~ s/^([^$r_t]*)?\Q$a_t\E// or return []; $attr{$key} = $self->decode_value("$1"); } return [] unless $buf =~ s/^\Q$r_t\E//; $self->{buffer} = $buf; return [ \%attr ]; } sub get_pending { my ($self) = @_; return [ $self->{buffer} ] if length $self->{buffer}; return undef; } sub decode_key { $_[1] } sub decode_value { $_[1] } sub put { my ($self, $chunks) = @_; return [ map { $self->_encode($_) } @$chunks ]; } sub _encode { my ($self, $attr) = @_; return join $self->attribute_terminator, (map { join $self->attribute_separator, $self->encode_key($_), $self->encode_value($attr->{$_}) } keys %$attr), $self->request_terminator; } sub encode_key { $_[1] } sub encode_value { $_[1] } 1; __END__