Procedural macros to generate C callback functions and a thin wrapping layer.
Callback results
The result type may be wrapped in a milter::Result
where desired. This is
a convenience as most Context
methods return milter::Result
s these can
then be propagated with the ?
operator.
For example, the end-of-message handler may return plain Status
:
# #[macro_use] extern crate milter_callback;
# use milter::{ActionContext, Status};
#[on_eom(eom_callback)]
fn handle_eom(context: ActionContext<()>) -> Status {
Status::Continue
}
Or it may return milter::Result<Status>
. The example shows use of the ?
operator enabled by choosing this return type.
# #[macro_use] extern crate milter_callback;
# use milter::{ActionContext, Status};
#[on_eom(eom_callback)]
fn handle_eom(context: ActionContext<()>) -> milter::Result<Status> {
if let Some(version) = context.macro_value("v")? {
println!("{}", version);
}
Ok(Status::Continue)
}
This feature is supported on all the callback functions.
Errors
An error result returned from a callback leads to a Status::Tempfail
response returned to the MTA. The milter will continue processing.
Panicking leads to shutdown of the milter. That is, Milter::run
returns.
It could then be restarted by invoking Milter::run
again. However,
restarting is potentially hazardous as panic exits without going through
potential cleanup paths in close
or abort
. That is, there is a
possibility of memory leakage.
Returning an error result does not have this problem. Returning an error
leads to tempfail and then the ordinary cleanup path on connection close
.