1

我正在尝试使用miltercrate 在 Rust 中编写邮件过滤器。我在 Linux VM 上构建了示例,一切正常。但是,该示例使用 u32 作为注入其处理程序的上下文类型,这是一个非常简单的示例。相反,我需要将一个字符串从handle_header回调存储到handle_eom处理程序,这样我就可以使用传入的标头来设置信封。

如果我将标头的值记录handle_header到控制台,它会正确写入,但是当它到达时handle_eom,它已经被损坏/覆盖了。我认为上下文应该是专门针对这种情况的,但它使用类型推断而不是例如指向一个对象的指针似乎很奇怪,你可以将任何你想要的东西分配给它。

我对上下文的理解是错误的还是代码不正确?

我尝试使用valueand &valuein handle_header,它的行为方式相同。

use milter::*;

fn main() {
    Milter::new("inet:3000@localhost")
        .name("BounceRewriteFilter")
        .on_header(header_callback)
        .on_eom(eom_callback)
        .on_abort(abort_callback)
        .actions(Actions::ADD_HEADER | Actions::REPLACE_SENDER)
        .run()
        .expect("milter execution failed");
}

#[on_header(header_callback)]
fn handle_header<'a>(mut context: Context<&'a str>, header: &str, value: &'a str) -> milter::Result<Status> {
    if header == "Set-Return-Path" {
        match context.data.borrow_mut() {
            Some(retpath) => *retpath = &value,
            None => {
                context.data.replace(value)?;
            }
        }
    }

    Ok(Status::Continue)
}

#[on_eom(eom_callback)]
fn handle_eom(mut context: Context<&str>) -> milter::Result<Status> {
    match context.data.take() {
        Ok(result) => {
            println!("Set-return-path header is {}", result.unwrap());
            context.api.replace_sender(result.unwrap(), None::<&str>)?;
        }
        Err(_error) => {}

    }

    Ok(Status::Continue)
}
4

1 回答 1

0

感谢Github上的glts,箱子的作者,问题是传递给handle_header方法的字符串切片没有被存储数据指针的外部代码借用,所以在handle_eom调用的时候,内存已经被重用了别的。

我所要做的就是使用and 反向Context<&str>转换Context<String>和转换字符串mystr.to_owned()val = &*mystring

于 2022-03-02T16:19:37.657 回答