Closed emersion closed 4 years ago
As a MTA implementer, I expect a flow somehow like this:
// Create new client (may maintain connection pool internally or something)
c, _ := milter.NewClient("unix", "/var/lib/whatever.sock")
// Start new session (may internally create a new connection or reuse old one)
// Argument is the "command codes" we are allowed to use.
s, _ := c.Session(milter.Conn|milter.Whatever|...)
// Provide "macro" for connection command.
s.Macro(milter.Conn, "tls_cipher", "...")
// Provide connection information.
resp, _ := s.Conn(...)
// Inspect resp and determine if we stop here or continue.
defer s.Abort() // abort in case something goes wrong
// No-op if End() below is called.
// All that stuff in envelope and header ...
// Provide HELO info, commands are silently ignored if milter does not include them in OPTNEG.
resp, _ = s.Helo(...)
// Inspect resp and determine if we stop here or continue.
// Send body chunk.
resp, _ = s.Body([]byte{"heya"})
modify, resp, err := s.End()
// resp is the same thing as all previous ones, modify is the slice of "modification actions" MTA should apply
for _, action := range modify {
// Inspect action and apply it.
}
Not sure about types for modify
and resp
, perhaps some server constructs can be reused? WDYT, in general?
Thought dump: It would be nice to have interoperability tests using Sendmail's libmilter.
Could be used to implement a MTA