1pub(crate) mod auth;
9pub(crate) mod cache;
10pub(crate) mod compression;
11pub(crate) mod http;
12pub(crate) mod server;
13pub(crate) mod types;
14pub(crate) mod websocket;
15
16use std::io;
17use std::net::Ipv6Addr;
18use std::path::PathBuf;
19use std::sync::Arc;
20use tokio::sync::Semaphore;
21use tokio::sync::mpsc;
22use tokio_stream::wrappers::ReceiverStream;
23use warp::Filter;
24
25const TASK_BUF: usize = 16;
26const DEFAULT_CACHE_SIZE_MB: usize = 10;
27
28#[derive(Debug, Clone)]
30pub struct ServerConfig {
31 pub domains: Vec<String>,
33 pub email: Vec<String>,
35 pub cache: Option<PathBuf>,
37 pub limit: u32,
39 pub filelimit: usize,
41 pub wwwroot: PathBuf,
43 pub staging: bool,
45 pub port: u16,
47 pub redirect: bool,
49 pub max_cache_size_mb: Option<usize>,
51}
52
53pub async fn run(config: ServerConfig) -> io::Result<()> {
55 let limit = config.limit;
56 let www_root_dir = config.wwwroot;
57 let filelimit = config.filelimit;
58 let max_cache_size_mb = match config.max_cache_size_mb {
59 Some(size) => size,
60 None => DEFAULT_CACHE_SIZE_MB,
61 };
62 let semaphore = Arc::new(Semaphore::new(filelimit));
63
64 let (tx, rx) = mpsc::channel::<types::WsEvent>(TASK_BUF);
66 let rx = ReceiverStream::new(rx);
67
68 websocket::spawn_event_loop(rx, limit);
70
71 let addr = format!("[{}]:{}", Ipv6Addr::UNSPECIFIED, config.port)
73 .parse()
74 .unwrap();
75 let tcp_incoming = server::create_tcp_incoming(addr)?;
76
77 let tls_incoming = server::create_tls_incoming(
79 config.domains.clone(),
80 config.email,
81 config.cache,
82 config.staging,
83 tcp_incoming,
84 semaphore.clone(),
85 );
86
87 if config.redirect {
89 http::spawn_http_redirect_server(config.domains.clone());
90 }
91
92 let ws = websocket::create_ws_handler(tx.clone());
94
95 let compression_cache = cache::create_cache(max_cache_size_mb);
96 let index = http::create_http_file_routes(
98 config.domains,
99 www_root_dir,
100 semaphore.clone(),
101 compression_cache,
102 );
103
104 let tlsroutes = ws.or(index);
106
107 server::serve_tls(tls_incoming, tlsroutes).await;
109
110 unreachable!()
111}