rs-smtp 0.1.1

An ESMTP server library written in Rust.
Documentation
# rs-smtp

An ESMTP server library written in Rust.

## Features


- ESMTP client & server implementing RFC 5321
- Support for SMTP AUTH and PIPELINING
- UTF-8 support for subject and message body


## Usage


Add this to your `Cargo.toml`:

```toml
[dependencies]
rs-smtp = "0.1.1"

anyhow = "1.0"
tokio = { version = "1.26.0", features = ["full"] }
async-trait = "0.1.67"
```

## Example


```rust
use anyhow::Result;
use async_trait::async_trait;
use tokio::io::{self, AsyncReadExt, AsyncRead};

use rs_smtp::backend::{Backend, Session, MailOptions};
use rs_smtp::server::Server;

struct MyBackend;

struct MySession;

impl Backend for MyBackend {
    type S = MySession;

    fn new_session(&self) -> Result<MySession> {
        Ok(MySession)
    }
}

#[async_trait]

impl Session for MySession {
    fn auth_plain(&mut self, _username: &str, _password: &str) -> Result<()> {
        Ok(())
    }
    
    async fn mail(&mut self, from: &str, _: &MailOptions) -> Result<()> {
        println!("mail from: {}", from);
        Ok(())
    }

    async fn rcpt(&mut self, to: &str) -> Result<()> {
        println!("rcpt to: {}", to);
        Ok(())
    }
    
    async fn data<R: AsyncRead + Send + Unpin>(&mut self, r: R) -> Result<()> {
        // print whole message
        let mut data = Vec::new();
        let mut reader = io::BufReader::new(r);
        reader.read_to_end(&mut data).await?;
        println!("data: {}", String::from_utf8_lossy(&data));

        Ok(())
    }

    fn reset(&mut self) {}

    fn logout(&mut self) -> Result<()> {
        Ok(())
    }
}

#[tokio::main]

async fn main() -> Result<()> {
    let be = MyBackend;

    let mut s = Server::new(be);

    s.addr = "127.0.0.1:2525".to_string();
    s.domain = "localhost".to_string();
    s.read_timeout = std::time::Duration::from_secs(10);
    s.write_timeout = std::time::Duration::from_secs(10);
    s.max_message_bytes = 10 * 1024 * 1024;
    s.max_recipients = 50;
    s.max_line_length = 1000;
    s.allow_insecure_auth = true;

    println!("Starting server on {}", s.addr);
    match s.listen_and_serve().await {
        Ok(_) => println!("Server stopped"),
        Err(e) => println!("Server error: {}", e),
    }

    Ok(())
}
```

You can use the server manually with telnet:
    
```bash
telnet localhost 2525
EHLO localhost
MAIL FROM:<root@nsa.gov>
RCPT TO:<root@gchq.gov.uk>
DATA
Hey <3
.
```

## License


MIT