global::msg

Inspect incoming messages.

fn to_string

fn to_string(message: Message) -> String
Generate the `.eml` representation of the message.

fn has_header

fn has_header(header: SharedObject) -> bool
fn has_header(header: String) -> bool
Checks if the message contains a specific header.
  • header - the name of the header to search.

All of them, although it is most useful in the preq stage because the email is received at this point.

// Message example.
"X-My-Header: foo\r\n",
"Subject: Unit test are cool\r\n",
"\r\n",
"Hello world!\r\n",
#{
  preq: [
    rule "check if header exists" || {
      if msg::has_header("X-My-Header") && msg::has_header(identifier("Subject")) {
        state::accept();
      } else {
        state::deny();
      }
    }
  ]
}

fn count_header

fn count_header(header: String) -> int
fn count_header(header: SharedObject) -> int
Count the number of headers with the given name.
  • header - the name of the header to count.
  • number - the number headers with the same name.

All of them, although it is most useful in the preq stage because this is when the email body is received.

"X-My-Header: foo\r\n",
"X-My-Header: bar\r\n",
"X-My-Header: baz\r\n",
"Subject: Unit test are cool\r\n",
"\r\n",
"Hello world!\r\n",
#{
  preq: [
    rule "count_header" || {
      state::accept(`250 count is ${msg::count_header("X-My-Header")} and ${msg::count_header(identifier("Subject"))}`);
    }
  ]
}

fn get_header

fn get_header(header: SharedObject) -> String
fn get_header(header: String) -> String
Get a specific header from the incoming message.
  • header - the name of the header to get.
  • string - the header value, or an empty string if the header was not found.

All of them, although it is most useful in the preq stage because this is when the email body is received.

X-My-Header: 250 foo
Subject: Unit test are cool

Hello world!
; // .eml ends here

let rules = r#"
#{
  preq: [
    rule "get_header" || {
      if msg::get_header("X-My-Header") != "250 foo"
        || msg::get_header(identifier("Subject")) != "Unit test are cool" {
        state::deny();
      } else {
        state::accept(`${msg::get_header("X-My-Header")} ${msg::get_header(identifier("Subject"))}`);
      }
    }
  ]
}

fn get_all_headers

fn get_all_headers() -> Array
fn get_all_headers(name: String) -> Array
fn get_all_headers(name: SharedObject) -> Array
Get a list of all headers.
  • header - the name of the header to search. (optional, if not set, returns every header)
  • array - all of the headers found in the message.

All of them, although it is most useful in the preq stage because this is when the email body is received.

X-My-Header: 250 foo
Subject: Unit test are cool

Hello world!
; // .eml ends here

#{
  preq: [
    rule "display headers" || {
        log("info", `all headers: ${msg::get_all_headers()}`);
        log("info", `all "Return-Path" headers: ${msg::get_all_headers("Return-Path")}`);
    }
  ]
}

fn get_header_untouched

fn get_header_untouched(name: String) -> Array
Get a list of all headers of a specific name with it's name and value separated by a column.
  • header - the name of the header to search.
  • array - all header values, or an empty array if the header was not found.

All of them, although it is most useful in the preq stage because this is when the email body is received.

X-My-Header: 250 foo
Subject: Unit test are cool

Hello world!
; // .eml ends here

#{
    postq: [
        action "display return path" || {
            // Will display "Return-Path: value".
            log("info", msg::get_header_untouched("Return-Path"));
        }
    ],
}

fn append_header

fn append_header(header: String, value: SharedObject) -> ()
fn append_header(header: String, value: String) -> ()
Add a new header **at the end** of the header list in the message.
  • header - the name of the header to append.
  • value - the value of the header to append.

All of them. Even though the email is not received at the current stage, vsmtp stores new headers and will add them on top of the ones received once the preq stage is reached.

"X-My-Header: 250 foo\r\n",
"Subject: Unit test are cool\r\n",
"\r\n",
"Hello world!\r\n",
#{
  preq: [
    rule "append_header" || {
      msg::append_header("X-My-Header-2", "bar");
      msg::append_header("X-My-Header-3", identifier("baz"));
    }
  ]
}

fn prepend_header

fn prepend_header(header: String, value: String) -> ()
fn prepend_header(header: String, value: SharedObject) -> ()
Add a new header on top all other headers in the message.
  • header - the name of the header to prepend.
  • value - the value of the header to prepend.

All of them. Even though the email is not received at the current stage, vsmtp stores new headers and will add them on top of the ones received once the preq stage is reached.

"X-My-Header: 250 foo\r\n",
"Subject: Unit test are cool\r\n",
"\r\n",
"Hello world!\r\n",
#{
  preq: [
    rule "prepend_header" || {
      msg::prepend_header("X-My-Header-2", "bar");
      msg::prepend_header("X-My-Header-3", identifier("baz"));
    }
  ]
}

fn set_header

fn set_header(header: String, value: String) -> ()
fn set_header(header: String, value: SharedObject) -> ()
Replace an existing header value by a new value, or append a new header to the message.
  • header - the name of the header to set or add.
  • value - the value of the header to set or add.

All of them. Even though the email is not received at the current stage, vsmtp stores new headers and will add them on top to the ones received once the preq stage is reached.

Be aware that if you want to set a header value from the original message, you must use set_header in the preq stage and onwards.

"Subject: The initial header value\r\n",
"\r\n",
"Hello world!\r\n",
#{
  preq: [
    rule "set_header" || {
      msg::set_header("Subject", "The header value has been updated");
      msg::set_header("Subject", identifier("The header value has been updated again"));
      state::accept(`250 ${msg::get_header("Subject")}`);
    }
  ]
}

fn rename_header

fn rename_header(old: String, new: SharedObject) -> ()
fn rename_header(old: SharedObject, new: SharedObject) -> ()
fn rename_header(old: String, new: String) -> ()
fn rename_header(old: SharedObject, new: String) -> ()
Replace an existing header name by a new value.
  • old - the name of the header to rename.
  • new - the new new of the header.

All of them, although it is most useful in the preq stage because this is when the email body is received.

"Subject: The initial header value\r\n",
"\r\n",
"Hello world!\r\n",

#{
  preq: [
    rule "rename_header" || {
      msg::rename_header("Subject", "bob");
      if msg::has_header("Subject") { return state::deny(); }

      msg::rename_header("bob", identifier("Subject"));
      if msg::has_header("bob") { return state::deny(); }

      msg::rename_header(identifier("Subject"), "foo");
      if msg::has_header("Subject") { return state::deny(); }

      msg::rename_header(identifier("foo"), identifier("Subject"));
      if msg::has_header("foo") { return state::deny(); }

      state::accept(`250 ${msg::get_header("Subject")}`);
    }
  ]
}

fn mail

fn mail() -> String
Get a copy of the whole email as a string.

preq and onwards.

#{
    postq: [
       action "display email content" || log("trace", `email content: ${msg::mail()}`),
    ]
}

fn rm_header

fn rm_header(header: String) -> bool
fn rm_header(header: SharedObject) -> bool
Remove an existing header from the message.
  • header - the name of the header to remove.
  • a boolean value, true if a header has been removed, false otherwise.

All of them, although it is most useful in the preq stage because this is when the email body is received.

"Subject: The initial header value\r\n",
"\r\n",
"Hello world!\r\n",
#{
  preq: [
    rule "remove_header" || {
      msg::rm_header("Subject");
      if msg::has_header("Subject") { return state::deny(); }

      msg::prepend_header("Subject-2", "Rust is good");
      msg::rm_header(identifier("Subject-2"));

      msg::prepend_header("Subject-3", "Rust is good !!!!!");

      state::accept(`250 ${msg::get_header("Subject-3")}`);
    }
  ]
}

fn rw_mail_from

fn rw_mail_from(new_addr: SharedObject) -> ()
fn rw_mail_from(new_addr: String) -> ()
Change the sender's address in the `From` header of the message.
  • new_addr - the new sender address to set.

preq and onwards.

#{
    preq: [
       action "replace sender" || msg::rw_mail_from("john.server@example.com"),
    ]
}

fn rw_rcpt

fn rw_rcpt(old_addr: SharedObject, new_addr: SharedObject) -> ()
fn rw_rcpt(old_addr: String, new_addr: String) -> ()
fn rw_rcpt(old_addr: SharedObject, new_addr: String) -> ()
fn rw_rcpt(old_addr: String, new_addr: SharedObject) -> ()
Replace a recipient by an other in the `To` header of the message.
  • old_addr - the recipient to replace.
  • new_addr - the new address to use when replacing old_addr.

preq and onwards.

#{
    preq: [
       action "rewrite recipient" || msg::rw_rcpt("john.doe@example.com", "john-mta@example.com"),
    ]
}

fn add_rcpt

fn add_rcpt(new_addr: String) -> ()
fn add_rcpt(new_addr: SharedObject) -> ()
Add a recipient to the `To` header of the message.
  • addr - the recipient address to add to the To header.

preq and onwards.

#{
    preq: [
       action "update recipients" || msg::add_rcpt("john.doe@example.com"),
    ]
}

fn rm_rcpt

fn rm_rcpt(addr: SharedObject) -> ()
fn rm_rcpt(addr: String) -> ()
Remove a recipient from the `To` header of the message.
  • addr - the recipient to remove to the To header.

preq and onwards.

#{
    preq: [
       action "update recipients" || msg::rm_rcpt("john.doe@example.com"),
    ]
}