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