use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let suffix =
Arc::new(std::env::var("ALLOWED_SUFFIX").unwrap_or_else(|_| ".example.com".into()));
let cache = certmagic::Cache::new(Default::default())?;
let options = certmagic::ConfigOptions {
issuers: vec![Arc::new(certmagic::AcmeIssuer::lets_encrypt())],
on_demand: Some(certmagic::OnDemandConfig::default().with_sync_decision({
let suffix = Arc::clone(&suffix);
move |name| name.ends_with(suffix.as_str())
})),
..Default::default()
};
let config = certmagic::Config::new(cache, options)?;
let _config = &config; let acceptor = Arc::new(config.certmagic_acceptor()?);
let listener = tokio::net::TcpListener::bind("0.0.0.0:443").await?;
println!("serving on-demand TLS on :443 for *{suffix}");
loop {
let (tcp, _) = listener.accept().await?;
let acceptor = Arc::clone(&acceptor);
tokio::spawn(async move {
if let Ok(tls) = acceptor.accept(tcp).await
&& let Ok(mut tls) = tls.await
{
use tokio::io::{AsyncReadExt, AsyncWriteExt};
let mut buf = [0u8; 1024];
let _ = tls.read(&mut buf).await;
let _ = tls
.write_all(
b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\nConnection: close\r\n\r\nok",
)
.await;
let _ = tls.shutdown().await;
}
});
}
}