maj/site/src/main.rs

106 lines
2.8 KiB
Rust
Raw Normal View History

2020-07-28 01:03:50 +00:00
use rustls::{
2020-08-01 22:51:14 +00:00
internal::pemfile::{certs, pkcs8_private_keys},
2020-07-28 01:03:50 +00:00
AllowAnyAnonymousOrAuthenticatedClient, Certificate, PrivateKey, RootCertStore, ServerConfig,
};
2020-12-11 15:07:01 +00:00
2020-08-01 20:47:34 +00:00
use std::{
fs::File,
io::{self, BufReader},
path::{Path, PathBuf},
sync::Arc,
2020-08-02 02:42:44 +00:00
thread,
2020-08-01 20:47:34 +00:00
};
2020-07-26 00:16:07 +00:00
use structopt::StructOpt;
2020-08-02 02:42:44 +00:00
mod http;
mod server;
2020-07-26 00:16:07 +00:00
#[derive(StructOpt, Debug)]
struct Options {
/// host to listen on
#[structopt(short = "H", long, env = "HOST", default_value = "0.0.0.0")]
host: String,
/// port to listen on
#[structopt(short = "p", long, env = "PORT", default_value = "1965")]
port: u16,
/// cert file
#[structopt(short = "c", long = "cert", env = "CERT_FILE")]
cert: PathBuf,
/// key file
#[structopt(short = "k", long = "key", env = "KEY_FILE")]
key: PathBuf,
2020-07-26 12:21:02 +00:00
/// static path
2020-07-31 17:38:33 +00:00
#[structopt(short = "s", long, env = "STATIC_PATH", default_value = "./static")]
static_path: PathBuf,
2020-08-08 15:23:36 +00:00
/// CGI path
#[structopt(short = "C", long, env = "CGI_PATH", default_value = "./cgi-bin")]
cgi_path: PathBuf,
2020-07-26 12:21:02 +00:00
/// server hostname
#[structopt(
long = "hostname",
env = "SERVER_HOSTNAME",
2020-08-01 20:47:34 +00:00
default_value = "cetacean.club"
2020-07-26 12:21:02 +00:00
)]
hostname: String,
2020-08-02 02:42:44 +00:00
/// HTTP port
2020-08-02 02:44:55 +00:00
#[structopt(long, default_value = "34587")]
2020-08-02 02:42:44 +00:00
http_port: u16,
2020-07-26 00:16:07 +00:00
}
fn load_certs(path: &Path) -> io::Result<Vec<Certificate>> {
certs(&mut BufReader::new(File::open(path)?))
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid cert"))
}
fn load_keys(path: &Path) -> io::Result<Vec<PrivateKey>> {
2020-08-01 21:55:08 +00:00
pkcs8_private_keys(&mut BufReader::new(File::open(path)?))
2020-07-26 00:16:07 +00:00
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid key"))
}
2020-12-11 15:07:01 +00:00
#[tokio::main]
async fn main() -> Result<(), maj::server::Error> {
env_logger::init();
2020-07-26 00:16:07 +00:00
let opts = Options::from_args();
2020-08-01 21:55:08 +00:00
let certs = load_certs(&opts.cert).unwrap();
let mut keys = load_keys(&opts.key).unwrap();
2020-07-26 00:16:07 +00:00
2020-07-28 00:50:42 +00:00
log::info!(
"serving gemini://{} on {}:{}",
opts.hostname,
opts.host,
opts.port
);
2020-07-26 12:21:02 +00:00
2020-07-28 01:03:50 +00:00
let mut config = ServerConfig::new(AllowAnyAnonymousOrAuthenticatedClient::new(
RootCertStore::empty(),
));
2020-07-26 00:16:07 +00:00
config
.set_single_cert(certs, keys.remove(0))
.map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?;
2020-08-02 02:42:44 +00:00
let h = Arc::new(server::Handler {
hostname: opts.hostname,
files: maj::server::files::Handler::new(opts.static_path),
2020-08-08 15:23:36 +00:00
cgi: maj::server::cgi::Handler::new(opts.cgi_path),
2020-08-02 02:42:44 +00:00
});
{
let port = opts.http_port.clone();
let h = h.clone();
2020-08-02 02:44:55 +00:00
thread::spawn(move || http::run(h.clone(), port));
}
2020-08-02 02:42:44 +00:00
2020-12-11 15:07:01 +00:00
maj::server::serve(h.clone(), config, opts.host, opts.port).await?;
2020-07-26 00:16:07 +00:00
Ok(())
}
2020-08-02 02:42:44 +00:00
include!(concat!(env!("OUT_DIR"), "/templates.rs"));