=head1 NAME

Mail::Rspamd - Interface for accessing rspamd internals

=head1 SYNOPSIS

  use Mail::Rspamd;
    
  sub mime_filter {
      my ($task) = @_;
      my $msg = $task->get_message();
      $msg->set_subject ( 'Re: ' . $msg->get_subject () );
      if ($msg->get_mime_part->get_content_type->to_string =~ /text/) {
          # Do something
      }
      my %header;
      tie %header, 'Mail::Rspamd::Hash::Header', $msg;
      
      $header{'From'} = 'John Doe <john@domain>';
      $header{'X-Info'} = 'Normal one arbitrary header';
      $header{'X-Info'} = ['This is','Multiline X-Info header'];
      
      my $old_header = $header{'X-Info'};
      $header{'X-Info'} = [ 'First header', @{$old_header}, 'Last header'];
  }


=head1 DESCRIPTION

Mail::Rspamd is a perl module for accessing internal structures of rspamd, such as
task, message, config, logger e.t.c. Module is based on ideas from MIME::Fast.

=head1 INHERITANCE

This is a reformatted snipped from the official GMime documentation:

  Not a real objects:

  Mail::Rspamd::ContentType
  Mail::Rspamd::Disposition
  Mail::Rspamd::Header
  Mail::Rspamd::Param
  Mail::Rspamd::Hash::Header    (only in perl module)

  Glib objects:

  Mail::Rspamd::Object
    Mail::Rspamd::Message
    Mail::Rspamd::Part
  InternetAddress

=head1 PUBLIC CLASSES

=head2 Mail::Rspamd::Message

=over 4

=item I<new>()

=item I<new>(pretty_headers)

Class method. Create a new Mail::Rspamd::Message object.
Such object have no headers or any mime parts.
If you need to parse any message data use construct_message()
method from the Mail::Rspamd::Parser submodule.
Optional parameter I<pretty_headers> (default 0) if set to 1,
initializes friendly order of the header items.
The object is destroyed during the perl garbage collection.
E.g.:

    my $msg = new Mail::Rspamd::Message;

=item I<set_sender>(address)

=item I<get_sender>()

Set and get the sender's name and address on the Mail::Rspamd::Message object.
E.g.

    $msg->set_sender("\"Joe Sixpack\" <joe\@sixpack.org>");
    $sender = $msg->get_sender;

=item I<set_reply_to>(address)

=item I<get_reply_to>(address)

Set and get the sender's Reply-To address of the MIME message.

=item I<add_recipient>(type, name, email)

Add a recipient of a chosen type to the MIME Message.
Available recipient types include: GMIME_RECIPIENT_TYPE_TO,
GMIME_RECIPIENT_TYPE_CC and GMIME_RECIPIENT_TYPE_BCC.

=item I<add_recipients_from_string>(type, string)

Add recipients of a chosen type to the MIME Message.
E.g.:

    $msg->add_recipients_from_string(GMIME_RECIPIENT_TYPE_TO,
        "\"Mickey Mouse\" <mickey\@example>," .
        "\"John Doe\" <john\@home>");

=item I<get_recipients>(type)

Returns a list of recipients of a chosen type from the MIME Message.
The I<type> parameter is the same as in the add_recipient() method.

=item I<set_subject>(subject)

=item I<get_subject>()

Set and get the subject of the MIME message.

=item I<set_date>(date, gmt_offset)

=item I<set_date_from_string>(str)

Set the sent-date on the MIME message. You can give a date string
or the numbers (time in seconds and offset in hours and minutes).
E.g.

    $msg->set_date(991697409, '+0100');
    $msg->set_date("Wed, 7 Mar 2001 03:00:01 +0100 (CET)");

=item I<get_date>()

Get the sent-date of the MIME message. In scalar
context returns date as a string value,
otherwise two element array - time in seconds and gmt_offset.

=item I<set_message_id>(message_id)

=item I<get_message_id>()

Set and get the Message-Id of the message.

=item I<set_header>(field, value)

Set a message header to the MIME Message. This can be
such headers as X-Mailer, X-Priority, or In-Reply-To
as well as From etc. If you want to delete
any header - use remove_header() method.

=item I<add_header>(field, value)

Add a header to the message header.

=item I<remove_header>(field)

Removes the given field from the message header.

=item I<get_header>(field)

Get the header from the MIME message. This is the only (besides the
tied header hash) way you can retrieve any arbitrary header
(as X-Mailer etc.). Other headers can be accessed also with e.g.
get_sender (From header), get_content_type (Mail::Rspamd::Part method), etc.

=item I<set_mime_part>(mime_part)

=item I<get_mime_part>()

Set and get the root-level MIME part of the message.
Parameter mime_part should be valid Mail::Rspamd::Object object.

B<NOTE>: get_mime_part() does not exists in C gmime library.

=item I<get_body>(want_plain = 1, is_html = 0)

Returns the body of the message. Parameters are optional.
If want_plain is 1 (default)  plain text is returned.
If HTML is in the return string, is_html is set to 1.
Binary parts are omitted.

=item I<get_headers>()

Returns an allocated string containing the raw message headers.

=item I<foreach_part>(function, data)

Calls callback on each of the mime parts in the mime message.
Parameters: function is the reference to the callback function,
and data is a scalar (or any reference) that would be passed
to each callback function call.
E.g.:

    $msg->foreach_part(\&parse,$data);

=back

=head2 Mail::Rspamd::Header

=over 4

=item *

Mail::Rspamd::Header is a private structure. This structure contains
all the headers except special ones (Content-* MIME-Version).
Look for L<Header tied hash> for easy maintaining for header.
Use also the Mail::Rspamd::Message::get_header() and set_header() methods.

=back

=head2 Mail::Rspamd::Part

=over 4

=item I<new> ()

=item I<new> (type = "text", subtype = "plain")

Class method. Create a new Mail::Rspamd::Part object (MIME part).
It supports a few special headers (Content-* and MIME-Version),
and has contents of specified type.
If you do not issue any parameter to the new function,
"text/plain" would be the default type for the new Mail::Rspamd::Part object.


=item I<set_content_header> ($header)

=item I<get_content_header> ()

Sets or gets an arbitrary MIME content header.

=item I<set_content_description> (description)

=item I<get_content_description> ()

Set and get content description (Content-Description) on the MIME part.

=item I<set_content_md5> (content_md5)

=item I<verify_content_md5> ()

=item I<get_content_md5> ()

Set, get and verify content MD5 hash (Content-MD5) on the MIME part contents.

=item I<set_content_location> (location)

=item I<get_content_location> ()

Set and get content location (Content-Location) on the MIME part.

=item I<set_encoding> (encoding)

=item I<encoding_from_string> (encoding_string)

=item I<get_encoding> ()

=item I<encoding_to_string> ()

Set and get encoding on the MIME part. Encoding could be one of these
constants (or strings):

    GMIME_PART_ENCODING_DEFAULT # string '8 bit'
    GMIME_PART_ENCODING_7BIT # string '7 bit'
    GMIME_PART_ENCODING_8BIT # '8 bit'
    GMIME_PART_ENCODING_BASE64 # 'base64'
    GMIME_PART_ENCODING_QUOTEDPRINTABLE # 'quoted-printable'

E.g.
    Mail::Rspamd::Part::encoding_to_string("GMIME_PART_ENCODING_BASE64");

=item I<set_content_disposition> (disposition)

=item I<set_content_disposition_object> (Mail::Rspamd::Disposition)

=item I<get_content_disposition> ()

=item I<get_content_disposition> ()

Set and get content disposition (Content-Disposition) on the MIME part.
As the parameter one can issue usualy 'inline' or 'attachment'.
Function get_content_disposition() returns only the main part of this
header (no parameters).

=item I<add_content_disposition_parameter> (name, value)

=item I<get_content_disposition_parameter> (name)

Add and get content disposition parameter.

=item I<set_filename> (filename)

Add the 'filename' content disposition parameter to the Content-Disposition
header, and 'name' parameter to the Content-Type header.

=item I<get_filename> ()

Get filename suggested by the MIME part headers (either from the
Content-Disposition or Content-Type header).

=item I<set_content> (content_object)

Set content of the MIME part based on the supplied argument (text
Mail::Rspamd::Stream object, Mail::Rspamd::DataWrapper object
or FILEHANDLE).

=item I<get_content> ()

Get text content of the MIME part (readonly).

=item I<get_content_object> ()

Get Mail::Rspamd::DataWrapper object of the MIME part.

=item I<set_pre_encoded_content> (content, encoding)

Set pre-encoded content on the MIME part. The 'encoding'
parameter can have values described in encoding_to_string() function above.
These function are used by the parser. You can write your own.

=back

=head2 Mail::Rspamd::Object

This is the base class for Mail::Rspamd objects (messages,
parts, multiparts, filters, streams etc.). 

=over 4

=item I<set_content_type> ($type)

=item I<get_content_type> ()

Set and get content type on the Mail::Rspamd::Object. The 'type' parameter
should be a Mail::Rspamd::ContentType object.
E.g.

    $type = $part->get_content_type;
    print "Type of $part is " . $type->to_string;

=item I<set_content_type_parameter> ($name, $value)

=item I<get_content_type_parameter> ($name)

Sets or gets the value of the content-type param $name set on the MIME part object.

=item I<set_content_id> (content_id)

=item I<get_content_id> ()

Set and get content id (Content-Id) on the MIME part object.

=item I<set_header>(field, value)

Set a message header to the MIME object.

=item I<add_header>(field, value)

Add a header field to the MIME object header.

=item I<remove_header>(field)

Removes the given field from the header.

=item I<get_header>(field)

Gets the value of the requested header.

=item I<get_content_length> ()

Get content length of the MIME object.

B<NOTE>: This methoid does not exists in the C gmime.

B<NOTE>: Encoded content length is only prediction, not the exact number of bytes
you would get after final encoding. Predicted encoded length is 
greater or equal to size of the encoded parts, though. The length
of the part/message headers is not counted.

=item I<is_multipart> ()

Returns 1 if the MIME object is of type multipart, 0 otherwise.

B<NOTE>: This methoid does not exists in the C gmime.

=item I<effective_type> ()

Returns content type of the given object as a lowercase text string.

B<NOTE>: This methoid does not exists in the C gmime.

=item I<to_string>()

Returns the contents of the MIME object as a string.

=back

=head2 Mail::Rspamd::ContentType

=over 4

=item I<new> (type, subtype)

=item I<new> (str)

Create new Mail::Rspamd::ContentType object with type of 'type/subtype'
or type read from the string 'str'.

=item I<type> ()

Get the 'type' part (string) of the Mail::Rspamd::ContentType object.
B<NOTE>: this method is not in gmime C library.

=item I<subtype> ()

Get the 'subtype' part (string) of the Mail::Rspamd::ContentType object.
B<NOTE>: this method is not in gmime C library.

=item I<to_string> ()

Get the string representation for the Mail::Rspamd::ContentType object.

=item I<is_type> (type, subtype)

Returns 1 if content type match the given type and subtype, 0 otherwise.
You can use '*' in place of type or subtype as a wildcard.
This function is case insensitive.
E.g.

    $is_multipart = $content_type->is_type('multipart','*');
    $is_text = $content_type->is_type('text','*');

=item I<add_parameter> (attribute, value)

=item I<get_parameter> ()

Add and get parameter to/of the content type header.
E.g.

    $content_type->add_parameter('name', 'test.gif');

=back

=head2 Mail::Rspamd::Task

This is the base class for Mail::Rspamd objects (messages,
parts, multiparts, filters, streams etc.). 

=over 4

=item I<get_message> ()

=item I<set_message> (message)

Get and set Mail::Rspamd::Message object from task.

=item I<ip> ()

Get ip address of client.

=item I<from> ()

Get MAIL FROM address.

=item I<save_point> ()

Set save point to task for delayed filter's processing.

=item I<recall_filter> ()

Restore filter's processing

=item I<insert_result> (metric, symbol, flag)

Insert to task result to metric <metric>, that have symbol <symbol> and value <flag>.

=item I<get_conf> ()

Return Mail::Rspamd::Config object.

=item I<get_urls> ()

Return message's urls as array of strings.

=back

=head2 Mail::Rspamd::Config

Object that allows access to rspamd config (read and write).

=over 4

=item I<get_scalar> (scalar)

=item I<set_scalar> (scalar, value)

Gets and sets specified parameter in config.

=item I<get_metric> (metric)

Returns hash of parameters of specified metric:
{
'name'             => name of metric
'func_name'        => consolidation function
'required_score'   => score for metric
}

=item I<get_statfile> (statfile)

Returns parameters of specified statfile:
{
'alias'         => alias of statfile
'pattern'       => fs pattern
'metric'        => metric of statfile
'weight'        => weigth of statfile
'size'          => size of statfile
}

=item I<get_module_param> (modulename, paramname)

Return parameter's value for specified module.

=back

=head1 CONSTANT VARIABLES

    GMIME_LENGTH_ENCODED
    GMIME_LENGTH_CUMULATIVE

    GMIME_PART_ENCODING_DEFAULT
    GMIME_PART_ENCODING_7BIT
    GMIME_PART_ENCODING_8BIT
    GMIME_PART_ENCODING_BASE64
    GMIME_PART_ENCODING_QUOTEDPRINTABLE
    GMIME_PART_NUM_ENCODINGS

    GMIME_RECIPIENT_TYPE_TO
    GMIME_RECIPIENT_TYPE_CC
    GMIME_RECIPIENT_TYPE_BCC

    INTERNET_ADDRESS_NONE
    INTERNET_ADDRESS_NAME
    INTERNET_ADDRESS_GROUP

=head1 REQUIREMENTS

This module Mail::Rspamd requires perl 5.8.x and gmime 2.0.9 or higher.


=head1 BUGS

Quoted-printable binary parts could be wrongly decoded (when
the new line is "\n" instead of "\r\n", and there is no equal sign
at the end of line. RFC says that binary parts should be encoded with
BASE64 not Q-P (it is also best compression for such parts).
Then there is no harm.

=head1 AUTHOR

Piotr Klaban, post@klaban.torun.pl (original author of MIME::Fast)
Vsevolod Stakhov, vsevolod@highsecure.ru

=head1 SEE ALSO

perl(1).

The homepage of gmime C library at http://spruce.sourceforge.net/gmime/
The homepage of MIME::Fast perl module is available at http://search.cpan.org/dist/MIME-Fast/