Config struct for http server

This commit is contained in:
Brian Picciano 2023-07-09 13:43:38 +02:00
parent 9d44593e73
commit 254d9c63d0
4 changed files with 62 additions and 65 deletions

View File

@ -123,16 +123,14 @@ async fn main() {
let _ = domani::service::http::new(
&mut task_stack,
domain_manager.clone(),
config.domain_checker_target_a,
config.passphrase,
config.http_listen_addr,
config.http_domain,
config
.https_listen_addr
.map(|listen_addr| domani::service::http::HTTPSParams {
listen_addr,
cert_resolver: domain_manager.clone(),
}),
domain_manager.clone(),
domani::service::http::Config {
http_addr: config.http_listen_addr,
https_addr: config.https_listen_addr,
primary_domain: config.http_domain,
target_a: config.domain_checker_target_a,
passphrase: config.passphrase,
},
);
let mut signals =

View File

@ -1,6 +1,9 @@
mod config;
mod tasks;
mod tpl;
pub use config::*;
use hyper::{Body, Method, Request, Response};
use serde::{Deserialize, Serialize};
@ -12,57 +15,30 @@ use crate::{domain, service, util};
pub struct Service {
domain_manager: sync::Arc<dyn domain::manager::Manager>,
target_a: net::Ipv4Addr,
passphrase: String,
http_domain: domain::Name,
cert_resolver: sync::Arc<dyn rustls::server::ResolvesServerCert>,
handlebars: handlebars::Handlebars<'static>,
}
pub struct HTTPSParams {
pub listen_addr: net::SocketAddr,
pub cert_resolver: sync::Arc<dyn rustls::server::ResolvesServerCert>,
config: Config,
}
pub fn new(
task_stack: &mut util::TaskStack<unexpected::Error>,
domain_manager: sync::Arc<dyn domain::manager::Manager>,
target_a: net::Ipv4Addr,
passphrase: String,
http_listen_addr: net::SocketAddr,
http_domain: domain::Name,
https_params: Option<HTTPSParams>,
cert_resolver: sync::Arc<dyn rustls::server::ResolvesServerCert>,
config: Config,
) -> sync::Arc<Service> {
let https_enabled = config.https_addr.is_some();
let service = sync::Arc::new(Service {
domain_manager: domain_manager.clone(),
target_a,
passphrase,
http_domain: http_domain.clone(),
cert_resolver,
handlebars: tpl::get(),
config,
});
task_stack.push_spawn(|canceller| {
tasks::listen_http(
service.clone(),
canceller,
http_listen_addr,
http_domain.clone(),
)
});
task_stack.push_spawn(|canceller| tasks::listen_http(service.clone(), canceller));
if let Some(https_params) = https_params {
task_stack.push_spawn(|canceller| {
tasks::listen_https(
service.clone(),
canceller,
https_params.cert_resolver.clone(),
https_params.listen_addr,
http_domain.clone(),
)
});
task_stack.push_spawn(|canceller| {
tasks::cert_refresher(domain_manager.clone(), canceller, http_domain.clone())
});
if https_enabled {
task_stack.push_spawn(|canceller| tasks::listen_https(service.clone(), canceller));
task_stack.push_spawn(|canceller| tasks::cert_refresher(service.clone(), canceller));
}
service
@ -277,7 +253,7 @@ impl<'svc> Service {
Response {
domain: args.domain,
flat_config: config.into(),
target_a: self.target_a,
target_a: self.config.target_a,
challenge_token: config_hash,
},
)
@ -288,7 +264,7 @@ impl<'svc> Service {
args: DomainSyncArgs,
domain_config: service::util::FlatConfig,
) -> Response<Body> {
if args.passphrase != self.passphrase.as_str() {
if args.passphrase != self.config.passphrase.as_str() {
return self.render_error_page(401, "Incorrect passphrase");
}
@ -358,8 +334,8 @@ impl<'svc> Service {
.map(strip_port),
req.uri().host().map(strip_port),
) {
(Some(h), _) if h != self.http_domain.as_str() => Some(h),
(_, Some(h)) if h != self.http_domain.as_str() => Some(h),
(Some(h), _) if h != self.config.primary_domain.as_str() => Some(h),
(_, Some(h)) if h != self.config.primary_domain.as_str() => Some(h),
_ => None,
}
.and_then(|h| domain::Name::from_str(h).ok());

View File

@ -0,0 +1,12 @@
use crate::domain;
use serde::Deserialize;
use std::net;
#[derive(Deserialize)]
pub struct Config {
pub http_addr: net::SocketAddr,
pub https_addr: Option<net::SocketAddr>,
pub primary_domain: domain::Name,
pub target_a: net::Ipv4Addr,
pub passphrase: String,
}

View File

@ -1,7 +1,7 @@
use crate::error::unexpected::{self, Mappable};
use crate::{domain, service};
use crate::service;
use std::{convert, future, net, sync};
use std::{convert, future, sync};
use futures::StreamExt;
use tokio_util::sync::CancellationToken;
@ -9,9 +9,10 @@ use tokio_util::sync::CancellationToken;
pub async fn listen_http(
service: sync::Arc<service::http::Service>,
canceller: CancellationToken,
addr: net::SocketAddr,
domain: domain::Name,
) -> Result<(), unexpected::Error> {
let addr = service.config.http_addr.clone();
let primary_domain = service.config.primary_domain.clone();
let make_service = hyper::service::make_service_fn(move |_| {
let service = service.clone();
@ -25,7 +26,11 @@ pub async fn listen_http(
async move { Ok::<_, convert::Infallible>(hyper_service) }
});
log::info!("Listening on http://{}:{}", domain.as_str(), addr.port());
log::info!(
"Listening on http://{}:{}",
primary_domain.as_str(),
addr.port(),
);
let server = hyper::Server::bind(&addr).serve(make_service);
let graceful = server.with_graceful_shutdown(async {
@ -38,10 +43,11 @@ pub async fn listen_http(
pub async 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,
) -> Result<(), unexpected::Error> {
let cert_resolver = service.cert_resolver.clone();
let addr = service.config.https_addr.unwrap().clone();
let primary_domain = service.config.primary_domain.clone();
let make_service = hyper::service::make_service_fn(move |_| {
let service = service.clone();
@ -77,7 +83,11 @@ pub async fn listen_https(
let incoming = hyper::server::accept::from_stream(incoming);
log::info!("Listening on https://{}:{}", domain.as_str(), addr.port());
log::info!(
"Listening on https://{}:{}",
primary_domain.as_str(),
addr.port()
);
let server = hyper::Server::builder(incoming).serve(make_service);
@ -89,12 +99,13 @@ pub async fn listen_https(
}
pub async fn cert_refresher(
domain_manager: sync::Arc<dyn domain::manager::Manager>,
service: sync::Arc<service::http::Service>,
canceller: CancellationToken,
http_domain: domain::Name,
) -> Result<(), unexpected::Error> {
use tokio::time;
let domain_manager = service.domain_manager.clone();
let primary_domain = service.config.primary_domain.clone();
let mut interval = time::interval(time::Duration::from_secs(60 * 60));
loop {
@ -104,12 +115,12 @@ pub async fn cert_refresher(
}
_ = domain_manager
.sync_cert(http_domain.clone())
.sync_cert(primary_domain.clone())
.await
.inspect_err(|err| {
log::error!(
"Error while getting cert for {}: {err}",
http_domain.as_str()
primary_domain.as_str()
)
});