~janbaudisch/epistula

ref: 6f1e423b618e64ca10741b70712b315fda9e595a epistula/src/main.rs -rw-r--r-- 3.0 KiB
6f1e423bJan Baudisch builds: use archlinux 1 year, 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
mod env;
mod request;

use env::Config;
use lettre::smtp::authentication::{Credentials, Mechanism};
use lettre::smtp::ConnectionReuseParameters;
use lettre::{ClientSecurity, ClientTlsParameters, SmtpClient, Transport};
use log::info;
use native_tls::TlsConnector;
use request::Request;
use std::sync::{mpsc, Arc, Mutex};
use std::thread;
#[cfg(unix)]
use tokio::net::UnixListener;
use warp::Filter;

#[tokio::main]
async fn main() {
    color_backtrace::install();

    #[cfg(debug_assertions)]
    dotenv::dotenv().ok();

    pretty_env_logger::init_custom_env("LOGGING");

    let config = match envy::from_env::<Config>() {
        Ok(config) => config,
        Err(error) => panic!("{:#?}", error),
    };

    #[cfg(unix)]
    let unix_socket = config.unix_socket.clone();
    let http_address = config.http_address;

    let (tx, rx) = mpsc::channel::<Option<Request>>();
    let tx = Arc::new(Mutex::new(tx));

    let thread = thread::spawn(move || {
        info!("Email thread starting ...");

        let security = if config.smtp_tls {
            let tls_connector = TlsConnector::new().unwrap();
            let tls_parameters = ClientTlsParameters::new(config.smtp_host.clone(), tls_connector);
            ClientSecurity::Wrapper(tls_parameters)
        } else {
            ClientSecurity::None
        };

        let mut mailer = SmtpClient::new((config.smtp_host.as_str(), config.smtp_port), security)
            .unwrap()
            .authentication_mechanism(Mechanism::Login)
            .credentials(Credentials::new(
                config.clone().smtp_user,
                config.clone().smtp_password,
            ))
            .connection_reuse(ConnectionReuseParameters::ReuseUnlimited)
            .transport();

        info!("Email thread started.");

        loop {
            let received = rx.recv();
            if let Ok(Some(request)) = received {
                info!("Sending email ...");
                mailer.send(request.into_mail(config.clone())).unwrap();
                info!("Email sent.");
            } else if let Ok(None) = received {
                info!("Email thread shutting down ...");
                break;
            } else {
                break;
            }
        }
    });

    let send = warp::post()
        .and(warp::path("send"))
        .and(warp::body::json())
        .map(move |request: Request| {
            info!("Received send request.");
            tx.clone()
                .lock()
                .unwrap()
                .send(Some(request.clone()))
                .unwrap();
            warp::reply::json(&request)
        });

    #[cfg(unix)]
    {
        if let Some(socket) = unix_socket {
            let mut listener = UnixListener::bind(socket).unwrap();
            warp::serve(send).run_incoming(listener.incoming()).await;
        } else {
            warp::serve(send).run(http_address).await;
        }
    }

    #[cfg(not(unix))]
    warp::serve(send).run(http_address).await;

    thread.join().unwrap();
}