Config struct for http server
This commit is contained in:
parent
9d44593e73
commit
254d9c63d0
18
src/main.rs
18
src/main.rs
@ -123,16 +123,14 @@ async fn main() {
|
|||||||
let _ = domani::service::http::new(
|
let _ = domani::service::http::new(
|
||||||
&mut task_stack,
|
&mut task_stack,
|
||||||
domain_manager.clone(),
|
domain_manager.clone(),
|
||||||
config.domain_checker_target_a,
|
domain_manager.clone(),
|
||||||
config.passphrase,
|
domani::service::http::Config {
|
||||||
config.http_listen_addr,
|
http_addr: config.http_listen_addr,
|
||||||
config.http_domain,
|
https_addr: config.https_listen_addr,
|
||||||
config
|
primary_domain: config.http_domain,
|
||||||
.https_listen_addr
|
target_a: config.domain_checker_target_a,
|
||||||
.map(|listen_addr| domani::service::http::HTTPSParams {
|
passphrase: config.passphrase,
|
||||||
listen_addr,
|
},
|
||||||
cert_resolver: domain_manager.clone(),
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut signals =
|
let mut signals =
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
mod config;
|
||||||
mod tasks;
|
mod tasks;
|
||||||
mod tpl;
|
mod tpl;
|
||||||
|
|
||||||
|
pub use config::*;
|
||||||
|
|
||||||
use hyper::{Body, Method, Request, Response};
|
use hyper::{Body, Method, Request, Response};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -12,57 +15,30 @@ use crate::{domain, service, util};
|
|||||||
|
|
||||||
pub struct Service {
|
pub struct Service {
|
||||||
domain_manager: sync::Arc<dyn domain::manager::Manager>,
|
domain_manager: sync::Arc<dyn domain::manager::Manager>,
|
||||||
target_a: net::Ipv4Addr,
|
cert_resolver: sync::Arc<dyn rustls::server::ResolvesServerCert>,
|
||||||
passphrase: String,
|
|
||||||
http_domain: domain::Name,
|
|
||||||
handlebars: handlebars::Handlebars<'static>,
|
handlebars: handlebars::Handlebars<'static>,
|
||||||
}
|
config: Config,
|
||||||
|
|
||||||
pub struct HTTPSParams {
|
|
||||||
pub listen_addr: net::SocketAddr,
|
|
||||||
pub cert_resolver: sync::Arc<dyn rustls::server::ResolvesServerCert>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
task_stack: &mut util::TaskStack<unexpected::Error>,
|
task_stack: &mut util::TaskStack<unexpected::Error>,
|
||||||
domain_manager: sync::Arc<dyn domain::manager::Manager>,
|
domain_manager: sync::Arc<dyn domain::manager::Manager>,
|
||||||
target_a: net::Ipv4Addr,
|
cert_resolver: sync::Arc<dyn rustls::server::ResolvesServerCert>,
|
||||||
passphrase: String,
|
config: Config,
|
||||||
http_listen_addr: net::SocketAddr,
|
|
||||||
http_domain: domain::Name,
|
|
||||||
https_params: Option<HTTPSParams>,
|
|
||||||
) -> sync::Arc<Service> {
|
) -> sync::Arc<Service> {
|
||||||
|
let https_enabled = config.https_addr.is_some();
|
||||||
let service = sync::Arc::new(Service {
|
let service = sync::Arc::new(Service {
|
||||||
domain_manager: domain_manager.clone(),
|
domain_manager: domain_manager.clone(),
|
||||||
target_a,
|
cert_resolver,
|
||||||
passphrase,
|
|
||||||
http_domain: http_domain.clone(),
|
|
||||||
handlebars: tpl::get(),
|
handlebars: tpl::get(),
|
||||||
|
config,
|
||||||
});
|
});
|
||||||
|
|
||||||
task_stack.push_spawn(|canceller| {
|
task_stack.push_spawn(|canceller| tasks::listen_http(service.clone(), canceller));
|
||||||
tasks::listen_http(
|
|
||||||
service.clone(),
|
|
||||||
canceller,
|
|
||||||
http_listen_addr,
|
|
||||||
http_domain.clone(),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(https_params) = https_params {
|
if https_enabled {
|
||||||
task_stack.push_spawn(|canceller| {
|
task_stack.push_spawn(|canceller| tasks::listen_https(service.clone(), canceller));
|
||||||
tasks::listen_https(
|
task_stack.push_spawn(|canceller| tasks::cert_refresher(service.clone(), canceller));
|
||||||
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())
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
service
|
service
|
||||||
@ -277,7 +253,7 @@ impl<'svc> Service {
|
|||||||
Response {
|
Response {
|
||||||
domain: args.domain,
|
domain: args.domain,
|
||||||
flat_config: config.into(),
|
flat_config: config.into(),
|
||||||
target_a: self.target_a,
|
target_a: self.config.target_a,
|
||||||
challenge_token: config_hash,
|
challenge_token: config_hash,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -288,7 +264,7 @@ impl<'svc> Service {
|
|||||||
args: DomainSyncArgs,
|
args: DomainSyncArgs,
|
||||||
domain_config: service::util::FlatConfig,
|
domain_config: service::util::FlatConfig,
|
||||||
) -> Response<Body> {
|
) -> 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");
|
return self.render_error_page(401, "Incorrect passphrase");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,8 +334,8 @@ impl<'svc> Service {
|
|||||||
.map(strip_port),
|
.map(strip_port),
|
||||||
req.uri().host().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.config.primary_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),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
.and_then(|h| domain::Name::from_str(h).ok());
|
.and_then(|h| domain::Name::from_str(h).ok());
|
||||||
|
12
src/service/http/config.rs
Normal file
12
src/service/http/config.rs
Normal 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,
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
use crate::error::unexpected::{self, Mappable};
|
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 futures::StreamExt;
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
@ -9,9 +9,10 @@ use tokio_util::sync::CancellationToken;
|
|||||||
pub async fn listen_http(
|
pub async fn listen_http(
|
||||||
service: sync::Arc<service::http::Service>,
|
service: sync::Arc<service::http::Service>,
|
||||||
canceller: CancellationToken,
|
canceller: CancellationToken,
|
||||||
addr: net::SocketAddr,
|
|
||||||
domain: domain::Name,
|
|
||||||
) -> Result<(), unexpected::Error> {
|
) -> 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 make_service = hyper::service::make_service_fn(move |_| {
|
||||||
let service = service.clone();
|
let service = service.clone();
|
||||||
|
|
||||||
@ -25,7 +26,11 @@ pub async fn listen_http(
|
|||||||
async move { Ok::<_, convert::Infallible>(hyper_service) }
|
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 server = hyper::Server::bind(&addr).serve(make_service);
|
||||||
|
|
||||||
let graceful = server.with_graceful_shutdown(async {
|
let graceful = server.with_graceful_shutdown(async {
|
||||||
@ -38,10 +43,11 @@ pub async fn listen_http(
|
|||||||
pub async fn listen_https(
|
pub async fn listen_https(
|
||||||
service: sync::Arc<service::http::Service>,
|
service: sync::Arc<service::http::Service>,
|
||||||
canceller: CancellationToken,
|
canceller: CancellationToken,
|
||||||
cert_resolver: sync::Arc<dyn rustls::server::ResolvesServerCert>,
|
|
||||||
addr: net::SocketAddr,
|
|
||||||
domain: domain::Name,
|
|
||||||
) -> Result<(), unexpected::Error> {
|
) -> 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 make_service = hyper::service::make_service_fn(move |_| {
|
||||||
let service = service.clone();
|
let service = service.clone();
|
||||||
|
|
||||||
@ -77,7 +83,11 @@ pub async fn listen_https(
|
|||||||
|
|
||||||
let incoming = hyper::server::accept::from_stream(incoming);
|
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);
|
let server = hyper::Server::builder(incoming).serve(make_service);
|
||||||
|
|
||||||
@ -89,12 +99,13 @@ pub async fn listen_https(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn cert_refresher(
|
pub async fn cert_refresher(
|
||||||
domain_manager: sync::Arc<dyn domain::manager::Manager>,
|
service: sync::Arc<service::http::Service>,
|
||||||
canceller: CancellationToken,
|
canceller: CancellationToken,
|
||||||
http_domain: domain::Name,
|
|
||||||
) -> Result<(), unexpected::Error> {
|
) -> Result<(), unexpected::Error> {
|
||||||
use tokio::time;
|
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));
|
let mut interval = time::interval(time::Duration::from_secs(60 * 60));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@ -104,12 +115,12 @@ pub async fn cert_refresher(
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ = domain_manager
|
_ = domain_manager
|
||||||
.sync_cert(http_domain.clone())
|
.sync_cert(primary_domain.clone())
|
||||||
.await
|
.await
|
||||||
.inspect_err(|err| {
|
.inspect_err(|err| {
|
||||||
log::error!(
|
log::error!(
|
||||||
"Error while getting cert for {}: {err}",
|
"Error while getting cert for {}: {err}",
|
||||||
http_domain.as_str()
|
primary_domain.as_str()
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user