[Mimedefang] API discussion (was Re: MIMEDefang 3.0-rc1)

Dianne Skoll dianne at skoll.ca
Sat May 14 09:29:58 EDT 2022


I think this discussion might belong on the Mailmunge list more than
the MIMEDefang list, so list admins... let me know if you'd prefer me
to move it there.

> As a specific concern in my situation: mimedefang is currently
> packaged in Debian, and mailmunge is not. While I certainly could
> package mailmunge (I'm a Debian Developer.), that's a new burden I'd
> be taking on.

Actually, I build .debs of mailmunge as part of the docker test suite.
It comes with a debian/ directory and dpkg-buildpackage works.  I've
put in a request to package into Debian, but haven't had a response.

I do not have a .spec file since I don't run any RPM-based systems, but
would be open to including that.

>   * Most annoyingly, there are still the two return styles for message
>     dispositions depending on whether we are in filter_message() or
>     something earlier. filter_message()'s return value is ignored and
>     action_{bounce,discard,tempfail}() are used.

Hmm.  This is easy enough to change.  I could check if the return value
of one of the filter_message-time functions is a Mailmunge::Response
object and take appropriate action if so.  Thanks!

>   * Most significantly, it seems to have retained the add_*() and
>     delete_*() APIs for things like headers and recipients. I think it
>     should instead have a mutable representation that Does The Right
>     Thing.

These API calls were modeled after the lower-level Milter APIs.  I'm
not religious about which style is better; just explaining why the
design is as it is.

> o Looking at recipients, for example, I want to be able to
> modify $ctx->recipients. If I add or delete one, it should do the work
>         of add_recipient() or delete_recipient() under the hood.

OK.  It would be pretty easy to make $ctx->recipients a setter as well
as a getter and do what you want.  I'm not convinced we gain much and
there's also IMO something to be said *against* having more than one way
to do something (this is where Larry Wall and I disagree. :) )


>   * Unless it's impossible (or unreasonable) to do optional arguments
> in Perl, I don't see why there are both action_add_header() and
>     action_insert_header(). Just have the insert, with $pos defaulting
>     to -1 or something to get the add behavior.

Again, these are modeled after the Milter API calls.  However, making
action_insert_header punt to action_add_header if pos is -1 is easy

> Likewise for
>     action_{accept,drop}_with_warning(); just have an optional
> $warning parameter on action_{accept,drop}().

Those are part of the Compat module, designed to be compatible
with MIMEDefang.  They're not part of the official Mailmunge API.
But sure... easy enough to check for an optional $warning parameter
(since no existing filters should have it) and do the right thing.

>   * I'm confused by the idea (as Dianne posted on the mailmunge list)
>     that a module named "Compat" is expected to be a thing that people
>     use indefinitely and in new installations as opposed to as a
> bridge while porting their MIMEDefang 2.x filter.

In retrospect, Compat was possibly a bad name.  MD_Like might have
been better.

>   * In the Mailmunge example video, $ctx->recipients[0] is
>     '<bob at example.org>'. IMHO, mailmunge should be stripping off the
>     angle brackets before the filter see it. They are just an
> annoyance. Perhaps it should be lowercasing too, i.e. using
> canonical_email().

No, I disagree on this.  We should IMO give addresses back exactly
as they came in.  For the sender address specifically, a null
return path of <> would be changed to the empty string, which could
be confusing.  And for normal email addresses, the local part could
be case-sensitive (ie, if it's an SRS-rewritten address) and
lowercasing it could cause information loss.

I think a good compromise would be to add accessors
$ctx->canon_recipients and $ctx->canon_sender if you only ever care
about lower-cased addresses with angle brackets stripped.

>   * This is minor, since it's boilerplate, but I'm not sure what the
>     run() method is about. What is "server mode" (as opposed to
>     multiplexor mode)?

Server mode is left-over documentation from MIMEDefang.  I will update
the docs; basically, the filter is *always* running in server mode.

As for why the boilerplate: Mailmunge works differently from
MIMEDefang; its filter is just a normal program that doesn't even have
to be written in Perl.

The Perl run() method just sets up the communication with the C code
and is always needed.  The reason the C code doesn't invoke run()
itself is (as I mentioned) technically the filter doesn't need to be
written in Perl at all.  However, if you *are* using embedded Perl, then
run() needs to behave slightly differently... but all of this is
internal to the filter.  You just need to call run() and it will work



More information about the MIMEDefang mailing list