Helper traits in callbacks
This commit is contained in:
parent
2335c8bd93
commit
3e8375efef
6 changed files with 32 additions and 31 deletions
|
@ -15,7 +15,7 @@ The minimum supported Rust version is now 1.56.1.
|
|||
- Use <code>inet:<em>host</em>:<em>port</em></code> for a TCP socket.
|
||||
- Use <code>unix:<em>path</em></code> for a UNIX domain socket.
|
||||
* The command-line help information has changed its appearance slightly with the
|
||||
update of the underlying Clap CLI library.
|
||||
update of the underlying clap CLI library.
|
||||
* The changelog is now maintained in a more structured format, similar to
|
||||
https://keepachangelog.com.
|
||||
|
||||
|
|
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -83,9 +83,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.1.0"
|
||||
version = "3.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5f1fea81f183005ced9e59cdb01737ef2423956dac5a6d731b06b2ecfaa3467"
|
||||
checksum = "5177fac1ab67102d8989464efd043c6ff44191b1557ec1ddd489b4f7e1447e77"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
|
|
|
@ -54,6 +54,22 @@ impl ConnectionMut for Option<Connection> {
|
|||
}
|
||||
}
|
||||
|
||||
trait MacrosExt {
|
||||
fn get_string(&self, name: &CStr) -> Option<Cow<'_, str>>;
|
||||
fn queue_id(&self) -> Cow<'_, str>;
|
||||
}
|
||||
|
||||
impl MacrosExt for Macros {
|
||||
fn get_string(&self, name: &CStr) -> Option<Cow<'_, str>> {
|
||||
self.get(name).map(|v| v.to_string_lossy())
|
||||
}
|
||||
|
||||
fn queue_id(&self) -> Cow<'_, str> {
|
||||
self.get_string(c_str!("i"))
|
||||
.unwrap_or_else(|| "NONE".into())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_callbacks(config: Config) -> Callbacks<Connection> {
|
||||
let config = Arc::new(config);
|
||||
let config_connect = config.clone();
|
||||
|
@ -148,7 +164,7 @@ async fn handle_mail(
|
|||
smtp_args: Vec<CString>,
|
||||
) -> Status {
|
||||
if !config.auth_untrusted() {
|
||||
if let Some(login) = lookup(&context.macros, c_str!("{auth_authen}")) {
|
||||
if let Some(login) = context.macros.get_string(c_str!("{auth_authen}")) {
|
||||
verbose!(config, "accepted message from sender authenticated as \"{}\"", login);
|
||||
return Status::Accept;
|
||||
}
|
||||
|
@ -179,7 +195,7 @@ async fn handle_data(context: &mut Context<Connection>) -> Status {
|
|||
let conn = context.data.connection();
|
||||
let client = conn.client.as_mut().unwrap();
|
||||
|
||||
let id = queue_id(&context.macros);
|
||||
let id = context.macros.queue_id();
|
||||
|
||||
if let Err(e) = client.connect() {
|
||||
eprintln!("{}: failed to start spamc: {}", id, e);
|
||||
|
@ -196,11 +212,11 @@ async fn handle_data(context: &mut Context<Connection>) -> Status {
|
|||
let info = ReceivedInfo {
|
||||
client_ip: conn.client_ip,
|
||||
helo_host: conn.helo_host.as_deref(),
|
||||
client_name_addr: lookup(&context.macros, c_str!("_")),
|
||||
my_hostname: lookup(&context.macros, c_str!("j")),
|
||||
mta: lookup(&context.macros, c_str!("v")),
|
||||
tls: lookup(&context.macros, c_str!("{tls_version}")),
|
||||
auth: lookup(&context.macros, c_str!("{auth_authen}")),
|
||||
client_name_addr: context.macros.get_string(c_str!("_")),
|
||||
my_hostname: context.macros.get_string(c_str!("j")),
|
||||
mta: context.macros.get_string(c_str!("v")),
|
||||
tls: context.macros.get_string(c_str!("{tls_version}")),
|
||||
auth: context.macros.get_string(c_str!("{auth_authen}")),
|
||||
queue_id: &id,
|
||||
date_time: Local::now().to_rfc2822(),
|
||||
};
|
||||
|
@ -243,7 +259,7 @@ async fn handle_body(
|
|||
|
||||
let max = config.max_message_size();
|
||||
if client.bytes_written() > max {
|
||||
let id = queue_id(&context.macros);
|
||||
let id = context.macros.queue_id();
|
||||
verbose!(config, "{}: skipping rest of message larger than {} bytes", id, max);
|
||||
client.skip_body();
|
||||
Status::Skip
|
||||
|
@ -256,7 +272,7 @@ async fn handle_eom(config: Arc<Config>, context: &mut EomContext<Connection>) -
|
|||
let conn = context.data.connection();
|
||||
let client = conn.client.take().unwrap();
|
||||
|
||||
let id = queue_id(&context.macros);
|
||||
let id = context.macros.queue_id();
|
||||
|
||||
match client.process(&id, &mut context.reply, &context.actions, &config).await {
|
||||
Ok(status) => status,
|
||||
|
@ -280,11 +296,3 @@ async fn handle_close(context: &mut Context<Connection>) -> Status {
|
|||
|
||||
Status::Continue
|
||||
}
|
||||
|
||||
fn queue_id(macros: &Macros) -> Cow<'_, str> {
|
||||
lookup(macros, c_str!("i")).unwrap_or_else(|| "NONE".into())
|
||||
}
|
||||
|
||||
fn lookup<'a>(macros: &'a Macros, name: &CStr) -> Option<Cow<'a, str>> {
|
||||
macros.get(name).map(|v| v.to_string_lossy())
|
||||
}
|
||||
|
|
|
@ -500,7 +500,7 @@ mod tests {
|
|||
|
||||
async fn quarantine<'cx, 'a>(
|
||||
&'cx self,
|
||||
_reason: impl IntoCString + Send + 'a,
|
||||
_: impl IntoCString + Send + 'a,
|
||||
) -> result::Result<(), ActionError> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
|
|
@ -95,8 +95,6 @@ async fn main() {
|
|||
}
|
||||
};
|
||||
|
||||
// Install a signal handler for the `TERM` and `INT` (Control-C) signals.
|
||||
|
||||
let (shutdown_tx, shutdown) = oneshot::channel();
|
||||
|
||||
let signals = Signals::new(&[SIGTERM, SIGINT]).expect("failed to install signal handler");
|
||||
|
@ -301,7 +299,7 @@ async fn handle_signals(mut signals: Signals, shutdown_milter: oneshot::Sender<(
|
|||
let _ = shutdown_milter.send(());
|
||||
break;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
_ => panic!("unexpected signal"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use tokio::{
|
|||
net::{TcpListener, ToSocketAddrs},
|
||||
process::Command,
|
||||
sync::oneshot,
|
||||
task::{self, JoinHandle},
|
||||
task::JoinHandle,
|
||||
time::timeout,
|
||||
};
|
||||
|
||||
|
@ -46,8 +46,7 @@ where
|
|||
|
||||
Ok(tokio::spawn(async move {
|
||||
// This server expects and handles only a single connection, so that we
|
||||
// can `join` this thread in the tests and detect panics. A panic can be
|
||||
// triggered both in the handling code as well as due to the timeout.
|
||||
// can `join` this task in the tests and detect errors and panics.
|
||||
let (mut stream, _) = timeout(Duration::from_secs(10), listener.accept())
|
||||
.await
|
||||
.map_err(|e| io::Error::new(ErrorKind::Other, e))??;
|
||||
|
@ -129,10 +128,6 @@ impl SpamAssassinMilter {
|
|||
}
|
||||
|
||||
pub async fn shutdown(self) -> io::Result<()> {
|
||||
for _ in 0..10 {
|
||||
task::yield_now().await;
|
||||
}
|
||||
|
||||
let _ = self.shutdown.send(());
|
||||
|
||||
self.milter_handle.await?
|
||||
|
|
Loading…
Reference in a new issue