parent
7ea97b2617
commit
506037dcd0
@ -0,0 +1,140 @@ |
|||||||
|
use crate::{domain, service}; |
||||||
|
|
||||||
|
use std::{convert, future, net, sync}; |
||||||
|
|
||||||
|
use futures::StreamExt; |
||||||
|
use tokio_util::sync::CancellationToken; |
||||||
|
|
||||||
|
pub fn listen_http( |
||||||
|
service: sync::Arc<service::http::Service>, |
||||||
|
canceller: CancellationToken, |
||||||
|
addr: net::SocketAddr, |
||||||
|
domain: domain::Name, |
||||||
|
) -> tokio::task::JoinHandle<()> { |
||||||
|
let make_service = hyper::service::make_service_fn(move |_| { |
||||||
|
let service = service.clone(); |
||||||
|
|
||||||
|
// Create a `Service` for responding to the request.
|
||||||
|
let hyper_service = hyper::service::service_fn(move |req| { |
||||||
|
service::http::handle_request(service.clone(), req) |
||||||
|
}); |
||||||
|
|
||||||
|
// Return the service to hyper.
|
||||||
|
async move { Ok::<_, convert::Infallible>(hyper_service) } |
||||||
|
}); |
||||||
|
|
||||||
|
tokio::spawn(async move { |
||||||
|
log::info!("Listening on http://{}:{}", domain.as_str(), addr.port()); |
||||||
|
let server = hyper::Server::bind(&addr).serve(make_service); |
||||||
|
|
||||||
|
let graceful = server.with_graceful_shutdown(async { |
||||||
|
canceller.cancelled().await; |
||||||
|
}); |
||||||
|
|
||||||
|
if let Err(e) = graceful.await { |
||||||
|
panic!("server error: {}", e); |
||||||
|
}; |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn listen_https( |
||||||
|
service: sync::Arc<service::http::Service>, |
||||||
|
canceller: CancellationToken, |
||||||
|
cert_resolver: sync::Arc<dyn rustls::server::ResolvesServerCert>, |
||||||
|
addr: net::SocketAddr, |
||||||
|
domain: domain::Name, |
||||||
|
) -> tokio::task::JoinHandle<()> { |
||||||
|
let make_service = hyper::service::make_service_fn(move |_| { |
||||||
|
let service = service.clone(); |
||||||
|
|
||||||
|
// Create a `Service` for responding to the request.
|
||||||
|
let hyper_service = hyper::service::service_fn(move |req| { |
||||||
|
service::http::handle_request(service.clone(), req) |
||||||
|
}); |
||||||
|
|
||||||
|
// Return the service to hyper.
|
||||||
|
async move { Ok::<_, convert::Infallible>(hyper_service) } |
||||||
|
}); |
||||||
|
|
||||||
|
tokio::spawn(async move { |
||||||
|
let server_config: tokio_rustls::TlsAcceptor = sync::Arc::new( |
||||||
|
rustls::server::ServerConfig::builder() |
||||||
|
.with_safe_defaults() |
||||||
|
.with_no_client_auth() |
||||||
|
.with_cert_resolver(cert_resolver), |
||||||
|
) |
||||||
|
.into(); |
||||||
|
|
||||||
|
let addr_incoming = hyper::server::conn::AddrIncoming::bind(&addr) |
||||||
|
.expect("https listen socket creation failed"); |
||||||
|
|
||||||
|
let incoming = |
||||||
|
tls_listener::TlsListener::new(server_config, addr_incoming).filter(|conn| { |
||||||
|
if let Err(err) = conn { |
||||||
|
log::error!("Error accepting TLS connection: {:?}", err); |
||||||
|
future::ready(false) |
||||||
|
} else { |
||||||
|
future::ready(true) |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
let incoming = hyper::server::accept::from_stream(incoming); |
||||||
|
|
||||||
|
log::info!("Listening on https://{}:{}", domain.as_str(), addr.port()); |
||||||
|
|
||||||
|
let server = hyper::Server::builder(incoming).serve(make_service); |
||||||
|
|
||||||
|
let graceful = server.with_graceful_shutdown(async { |
||||||
|
canceller.cancelled().await; |
||||||
|
}); |
||||||
|
|
||||||
|
if let Err(e) = graceful.await { |
||||||
|
panic!("server error: {}", e); |
||||||
|
}; |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
pub fn cert_refresher( |
||||||
|
domain_manager: sync::Arc<dyn domain::manager::Manager>, |
||||||
|
canceller: CancellationToken, |
||||||
|
http_domain: domain::Name, |
||||||
|
) -> tokio::task::JoinHandle<()> { |
||||||
|
tokio::spawn(async move { |
||||||
|
use tokio::time; |
||||||
|
|
||||||
|
let mut interval = time::interval(time::Duration::from_secs(60 * 60)); |
||||||
|
|
||||||
|
loop { |
||||||
|
tokio::select! { |
||||||
|
_ = interval.tick() => (), |
||||||
|
_ = canceller.cancelled() => return, |
||||||
|
} |
||||||
|
|
||||||
|
_ = domain_manager |
||||||
|
.sync_cert(http_domain.clone()) |
||||||
|
.await |
||||||
|
.inspect_err(|err| { |
||||||
|
log::error!( |
||||||
|
"Error while getting cert for {}: {err}", |
||||||
|
http_domain.as_str() |
||||||
|
) |
||||||
|
}); |
||||||
|
|
||||||
|
let domains_iter = domain_manager.all_domains(); |
||||||
|
|
||||||
|
if let Err(err) = domains_iter { |
||||||
|
log::error!("Got error calling all_domains: {err}"); |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
for domain in domains_iter.unwrap().into_iter() { |
||||||
|
let _ = domain_manager |
||||||
|
.sync_cert(domain.clone()) |
||||||
|
.await |
||||||
|
.inspect_err(|err| { |
||||||
|
log::error!("Error while getting cert for {}: {err}", domain.as_str(),) |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
Loading…
Reference in new issue