User Tools

Site Tools


programming:python:python-libmilter

This is an old revision of the document!


About

python-libmilter started as a project to maximize the portability of libmilter. I know about, and have used, the excellent CPython implementation by Stuart D. Gathman py-milter. Though I liked this library for it's thin wrapper around the C libmilter library (and thereby speed), I had some issues with getting it to install, having to find and download the appropriate source code for libmilter version installed, etc. This is why I went with a ground up implementation of libmilter in pure Python. I want something I could just “drop in” to a project and have a milter up and running in almost no time, no matter what OS environment I was in.

I also wanted some more choices for getting things done than the default thread approach. This is why I modularized the milter itself to working as a traditional threading milter wherein each client connection gets its own thread, but I also added factories for single thread asynchronous operation and forking. Do note that the threaded version of python-libmilter is constrained by the GIL, whereas py-milter is not since the threading is implemented in C. If you really want to maximize speed, py-milter might be for you, but be aware that I've been able to get excellent performance from this library in production environments with very heavy processing load (evaluating many regular expressions) using the forking factory.

Note that this documentation assumes a good working knowledge of the SMTP protocol as defined in RFC 2822.

The Library

You will find that the library file is split up into sections defining the constants for client server options and flags. Note that there are multiple milter versions (2, 3, 4, 6) and not everything is available in earlier versions than 6. See libmilter documentation for specifics on what is available in what versions. I will show where the version 2 compatibility ends so that if you wish to write your app to be compatible with all milter versions, you can do so.

Constants

SMFIF_*

These are flags that are set defining mutations that we wish to make in our app. This first set is compatible with version 2 of the milter protocol.

SMFIF_ADDHDRS States that we may add headers to the email
SMFIF_CHGBODY States that we may replace the body
SMFIF_ADDRCPT States that we may add recipients
SMFIF_DELRCPT States that we may delete recipients
SMFIF_CHGHDRS States that we may change/delete headers (note that this is different from the body)
SMFIF_QUARANTINE States that we may quarantine the message (how this is done is up to the MTA. Postfix will put the message in its HOLD queue)

This next set is available in later milter protocol versions.

SMFIF_CHGFROM States that we may replace the envelope sender
SMFIF_ADDRCPT_PAR States that we may add recipients + args
SMFIF_SETSYMLIST We may send macro names (CURRENTLY UNSUPPORTED)

There are also some convenience flags.

SMFIF_ALLOPTS_V2 This sets all flags from the first section
SMFIF_ALLOPTS_V6 This sets all flags from the second section
SMFIF_ALLOPTS This sets all flags

SMFIP_*

These are protocol options, and can be set in a couple of different ways. The first way is to simply set them when setting up your factory (TODO: link to the factory section). The other way, at least for the SMFIP_NO* and SMFIP_NR_* options, is to use decorators. That will be explained later. First, we will define the protocol options.

Again, this first section is available to version 2 of the milter protocol.

SMFIP_NOCONNECT Tell the MTA we don't want connection info
SMFIP_NOHELO Tell the MTA we don't want HELO info
SMFIP_NOMAIL Tell the MTA we don't want MAIL info
SMFIP_NORCPT Tell the MTA we don't want RCPT info
SMFIP_NOBODY Tell the MTA we don't want the body
SMFIP_NOHDRS Tell the MTA we don't want the headers
SMFIP_NOEOH Tell the MTA we don't want the end of headers notification

These other protocol options are defined for new versions of the milter protocol than version 2.

SMFIP_NR_HDR Tell the MTA we don't reply to the headers
SMFIP_NOUNKNOWN Tell the MTA we don't want any unknown commands
SMFIP_NODATA Tell the MTA we don't want the DATA command sent to us
SMFIP_RCPT_REJ Tell the MTA we want the rejected recipients
SMFIP_NR_CONN Tell the MTA we don't reply to the headers
SMFIP_NR_HELO Tell the MTA we don't reply to HELO info
SMFIP_NR_MAIL Tell the MTA we don't reply to MAIL info
SMFIP_NR_RCPT Tell the MTA we don't reply to RCPT info
SMFIP_NR_DATA Tell the MTA we don't reply to the DATA command
SMFIP_NR_UNKN Tell the MTA we don't reply to UNKNOWNs
SMFIP_NR_EOH Tell the MTA we don't reply to the end of headers
SMFIP_NR_BODY Tell the MTA we don't reply to the body chunks
SMFIP_HDR_LEADSPC Header value has leading space

And just like the OPTS, there are some convenience variables for setting all protocol options.

SMFIP_ALLPROTOS_V2 Set all protocol options for version 2 of the protocol
SMFIP_ALLPROTOS_V6 Set all the protocol options for everything post version 2
SMFIP_ALLPROTOS Sets all protocol options

All the Rest

All the rest of the standard constants are defined as well. I've only documented the ones above as these are the only ones directly used.

Overridable Callbacks

programming/python/python-libmilter.1329589618.txt.gz · Last modified: 2012/02/18 18:26 by jay