diff --git a/src/domain/manager.rs b/src/domain/manager.rs index 7a398bc..468e7a1 100644 --- a/src/domain/manager.rs +++ b/src/domain/manager.rs @@ -1,7 +1,6 @@ use crate::domain::{self, acme, checker, store}; use crate::error::unexpected::{self, Mappable}; -use crate::origin; -use crate::util; +use crate::{origin, task_stack, util}; use std::sync; use tokio_util::sync::CancellationToken; @@ -187,7 +186,7 @@ impl ManagerImpl { DomainStore: store::Store + Send + Sync + 'static, AcmeManager: acme::manager::Manager + Send + Sync + 'static, >( - task_stack: &mut util::TaskStack, + task_stack: &mut task_stack::TaskStack, origin_store: OriginStore, domain_store: DomainStore, domain_checker: checker::DNSChecker, diff --git a/src/lib.rs b/src/lib.rs index 16b4918..ae44030 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,8 +4,10 @@ pub mod config; pub mod domain; -pub mod error; pub mod origin; pub mod service; +pub mod task_stack; pub mod token; -pub mod util; + +mod error; +mod util; diff --git a/src/main.rs b/src/main.rs index 58b09a5..a28c321 100644 --- a/src/main.rs +++ b/src/main.rs @@ -128,7 +128,7 @@ async fn main() { None }; - let mut task_stack = domani::util::TaskStack::new(); + let mut task_stack = domani::task_stack::TaskStack::new(); let domain_manager = domani::domain::manager::ManagerImpl::new( &mut task_stack, diff --git a/src/service.rs b/src/service.rs index 82ec5be..f038173 100644 --- a/src/service.rs +++ b/src/service.rs @@ -1,5 +1,4 @@ mod config; pub mod http; -mod util; pub use config::*; diff --git a/src/service/http.rs b/src/service/http.rs index 40df33a..d42df63 100644 --- a/src/service/http.rs +++ b/src/service/http.rs @@ -2,6 +2,7 @@ mod config; mod proxy; mod tasks; mod tpl; +mod util; pub use config::*; @@ -13,7 +14,7 @@ use std::str::FromStr; use std::{future, net, sync}; use crate::error::unexpected; -use crate::{domain, service, util}; +use crate::{domain, service, task_stack}; pub struct Service { domain_manager: sync::Arc, @@ -23,7 +24,7 @@ pub struct Service { } pub fn new( - task_stack: &mut util::TaskStack, + task_stack: &mut task_stack::TaskStack, domain_manager: sync::Arc, cert_resolver: sync::Arc, config: service::Config, @@ -64,7 +65,7 @@ struct DomainInitArgs { domain: domain::Name, #[serde(flatten)] - flat_domain_settings: service::util::FlatDomainSettings, + url_encoded_domain_settings: util::UrlEncodedDomainSettings, } #[derive(Deserialize)] @@ -73,7 +74,7 @@ struct DomainSyncArgs { passphrase: String, #[serde(flatten)] - flat_domain_settings: service::util::FlatDomainSettings, + url_encoded_domain_settings: util::UrlEncodedDomainSettings, } impl<'svc> Service { @@ -267,7 +268,7 @@ impl<'svc> Service { #[derive(Serialize)] struct Data<'a> { domain: domain::Name, - flat_domain_settings: service::util::FlatDomainSettings, + url_encoded_domain_settings: util::UrlEncodedDomainSettings, dns_records: &'a [service::ConfigDNSRecord], challenge_token: String, @@ -275,7 +276,7 @@ impl<'svc> Service { dns_records_have_cname: bool, } - let settings: domain::Settings = match args.flat_domain_settings.try_into() { + let settings: domain::Settings = match args.url_encoded_domain_settings.try_into() { Ok(settings) => settings, Err(e) => { return self @@ -298,7 +299,7 @@ impl<'svc> Service { _ => false, }); - let flat_domain_settings = match settings.try_into() { + let url_encoded_domain_settings = match settings.try_into() { Ok(s) => s, Err(e) => { return self @@ -310,7 +311,7 @@ impl<'svc> Service { "/domain_init.html", Data { domain: args.domain, - flat_domain_settings, + url_encoded_domain_settings, dns_records: &self.config.dns_records, challenge_token: settings_hash, @@ -325,7 +326,7 @@ impl<'svc> Service { return self.render_error_page(401, "Incorrect passphrase"); } - let settings: domain::Settings = match args.flat_domain_settings.try_into() { + let settings: domain::Settings = match args.url_encoded_domain_settings.try_into() { Ok(settings) => settings, Err(e) => { return self diff --git a/src/service/util.rs b/src/service/http/util.rs similarity index 86% rename from src/service/util.rs rename to src/service/http/util.rs index e821422..243a234 100644 --- a/src/service/util.rs +++ b/src/service/http/util.rs @@ -7,7 +7,7 @@ use crate::{domain, error::unexpected, origin}; #[serde_as] #[derive(Serialize, Deserialize, Default, Debug)] -pub struct FlatDomainSettings { +pub struct UrlEncodedDomainSettings { domain_setting_origin_descr_kind: String, domain_setting_origin_descr_git_url: Option, @@ -20,10 +20,10 @@ pub struct FlatDomainSettings { domain_setting_add_path_prefix: Option, } -impl TryFrom for domain::Settings { +impl TryFrom for domain::Settings { type Error = String; - fn try_from(v: FlatDomainSettings) -> Result { + fn try_from(v: UrlEncodedDomainSettings) -> Result { let origin_descr = match v.domain_setting_origin_descr_kind.as_str() { "git" => Ok(origin::Descr::Git { url: v @@ -44,11 +44,11 @@ impl TryFrom for domain::Settings { } } -impl TryFrom for FlatDomainSettings { +impl TryFrom for UrlEncodedDomainSettings { type Error = unexpected::Error; fn try_from(v: domain::Settings) -> Result { - let mut res = FlatDomainSettings::default(); + let mut res = UrlEncodedDomainSettings::default(); match v.origin_descr { origin::Descr::Git { url, branch_name } => { diff --git a/src/task_stack.rs b/src/task_stack.rs new file mode 100644 index 0000000..2dc44f2 --- /dev/null +++ b/src/task_stack.rs @@ -0,0 +1,66 @@ +use crate::util::BoxFuture; +use std::error; +use tokio_util::sync::CancellationToken; + +pub struct TaskStack +where + E: error::Error + Send + 'static, +{ + wait_group: Vec>>, +} + +impl TaskStack +where + E: error::Error + Send + 'static, +{ + pub fn new() -> TaskStack { + TaskStack { + wait_group: Vec::new(), + } + } + + /// push adds the given Future to the stack, to be executed once stop is called. + pub fn push(&mut self, f: Fut) + where + Fut: futures::Future> + Send + 'static, + { + self.wait_group.push(Box::pin(f)) + } + + /// push_spawn will spawn the given closure in a tokio task. Once the CancellationToken is + /// cancelled the closure is expected to return. + pub fn push_spawn(&mut self, mut f: F) + where + Fut: futures::Future> + Send + 'static, + F: FnMut(CancellationToken) -> Fut, + { + let canceller = CancellationToken::new(); + let handle = tokio::spawn(f(canceller.clone())); + self.push(async move { + canceller.cancel(); + handle.await.expect("failed to join task") + }); + } + + /// stop will process all operations which have been pushed onto the stack in the reverse order + /// they were pushed. + pub async fn stop(mut self) -> Result<(), E> { + // reverse wait_group in place, so we stop the most recently added first. Since this method + // consumes self this is fine. + self.wait_group.reverse(); + + for fut in self.wait_group { + fut.await?; + } + Ok(()) + } +} + +impl Default for TaskStack +where + E: error::Error + Send + 'static, +{ + fn default() -> Self { + Self::new() + } +} diff --git a/src/util.rs b/src/util.rs index e22c5d1..c29a995 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,6 +1,4 @@ -use std::{error, fs, io, path, pin}; - -use tokio_util::sync::CancellationToken; +use std::{fs, io, path, pin}; pub fn open_file(path: &path::Path) -> io::Result> { match fs::File::open(path) { @@ -15,66 +13,3 @@ pub fn open_file(path: &path::Path) -> io::Result> { pub type BoxByteStream = futures::stream::BoxStream<'static, io::Result>>; pub type BoxFuture<'a, O> = pin::Pin + Send + 'a>>; - -pub struct TaskStack -where - E: error::Error + Send + 'static, -{ - wait_group: Vec>>, -} - -impl TaskStack -where - E: error::Error + Send + 'static, -{ - pub fn new() -> TaskStack { - TaskStack { - wait_group: Vec::new(), - } - } - - /// push adds the given Future to the stack, to be executed once stop is called. - pub fn push(&mut self, f: Fut) - where - Fut: futures::Future> + Send + 'static, - { - self.wait_group.push(Box::pin(f)) - } - - /// push_spawn will spawn the given closure in a tokio task. Once the CancellationToken is - /// cancelled the closure is expected to return. - pub fn push_spawn(&mut self, mut f: F) - where - Fut: futures::Future> + Send + 'static, - F: FnMut(CancellationToken) -> Fut, - { - let canceller = CancellationToken::new(); - let handle = tokio::spawn(f(canceller.clone())); - self.push(async move { - canceller.cancel(); - handle.await.expect("failed to join task") - }); - } - - /// stop will process all operations which have been pushed onto the stack in the reverse order - /// they were pushed. - pub async fn stop(mut self) -> Result<(), E> { - // reverse wait_group in place, so we stop the most recently added first. Since this method - // consumes self this is fine. - self.wait_group.reverse(); - - for fut in self.wait_group { - fut.await?; - } - Ok(()) - } -} - -impl Default for TaskStack -where - E: error::Error + Send + 'static, -{ - fn default() -> Self { - Self::new() - } -}