From bfb48dcf75907a4ad28ed6a3479fcc71a784c8a3 Mon Sep 17 00:00:00 2001 From: fozzie Date: Sat, 19 Jul 2025 14:20:53 -0500 Subject: [PATCH] support relocating the application --- .env | 6 ++++++ src/handler.rs | 20 ++++++++++++-------- src/main.rs | 14 +++++++++----- templates/showcheckform.html | 6 ++++-- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/.env b/.env index 3015b73..6575ac8 100644 --- a/.env +++ b/.env @@ -1,2 +1,8 @@ +# What address to listen on # BIND_HOST=127.0.0.1 + +# What port to listen on # BIND_PORT=3000 + +# Locate app at / or e.g. /certcheck +# ROOT_PATH=/ diff --git a/src/handler.rs b/src/handler.rs index 572ce6e..a06fcde 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -21,9 +21,10 @@ struct ShowCheckFormTemplate{ key_fingerprint: Option, key_description: Option, error: Option, + post_target: Option, } -pub async fn show_check_form() -> impl IntoResponse { +pub async fn show_check_form(State(state): State) -> impl IntoResponse { let signed_doc_url = "https://socialistra.org/canary/dl/27/matt.asc"; Html(ShowCheckFormTemplate{ @@ -32,6 +33,7 @@ pub async fn show_check_form() -> impl IntoResponse { key_fingerprint: None, key_description: None, error: None, + post_target: Some(state.root_path), }.render().unwrap()) } @@ -50,12 +52,13 @@ fn error_response(code: StatusCode, error: String) -> CheckResponse { error: Some(error), key_fingerprint: None, key_description: None, + post_target: None, }.render().unwrap() )) } pub async fn check_canary_result( - State(state): State, + state: State, Form(form_data): Form, ) -> CheckResponse { @@ -66,7 +69,7 @@ pub async fn check_canary_result( match ureq::get(uri.clone()).call() { Ok(mut resp) => match resp.body_mut().read_to_string() { - Ok(signed_message) => do_verify(signed_message, state.certs, uri).await, + Ok(signed_message) => do_verify(signed_message,state.certs.clone(), uri,state).await, Err(e) => error_response(StatusCode::BAD_REQUEST, format!("Error decoding signed message to string: {}",e)) @@ -78,16 +81,16 @@ pub async fn check_canary_result( } -fn read_verifier(mut verifier: Verifier<'_,Helper>, url: String) -> CheckResponse { +fn read_verifier(mut verifier: Verifier<'_,Helper>, url: String, state: State) -> CheckResponse { let mut content = Vec::new(); match verifier.read_to_end(&mut content) { - Ok(_) => decode_message_bytes(content,verifier.into_helper(),url), + Ok(_) => decode_message_bytes(content,verifier.into_helper(),url, state), _ => error_response(StatusCode::BAD_REQUEST, "Unable to read signed doc".to_string()) } } -fn decode_message_bytes(content: Vec, helper: Helper, url: String) -> CheckResponse { +fn decode_message_bytes(content: Vec, helper: Helper, url: String, State(state): State) -> CheckResponse { match String::from_utf8(content) { Ok(content) => (StatusCode::OK,Html(ShowCheckFormTemplate{ url: Some(url), @@ -95,13 +98,14 @@ fn decode_message_bytes(content: Vec, helper: Helper, url: String) -> CheckR error: None, key_fingerprint: helper.get_fingerprint(), key_description: helper.get_description(), + post_target: Some(state.root_path), }.render().unwrap())), _ => error_response(StatusCode::BAD_REQUEST, "Unable to decode signed doc into UTF-8".to_string()) } } -async fn do_verify(signed_message: String, certs: CertMap, url: String) -> CheckResponse { +async fn do_verify(signed_message: String, certs: CertMap, url: String, state: State) -> CheckResponse { let policy = &StandardPolicy::new(); let verbuilder = @@ -111,7 +115,7 @@ async fn do_verify(signed_message: String, certs: CertMap, url: String) -> Check verbuilder.with_policy(policy,None, Helper::new(certs)); match verifier_result { - Ok(verifier) => read_verifier(verifier,url), + Ok(verifier) => read_verifier(verifier,url,state), Err(err) => error_response(StatusCode::BAD_REQUEST, err.to_string()) } diff --git a/src/main.rs b/src/main.rs index ded6233..09670b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ use tokio::net::TcpListener; #[derive(Clone)] struct AppState { certs: CertMap, + root_path: String, } pub type CertMap = HashMap; @@ -38,23 +39,26 @@ async fn load_certs_from_fs() -> Result> { #[tokio::main] async fn main() -> Result<(),Box> { - // Set config from .env, ignoring any error (file may not be there) - let _ = dotenvy::dotenv(); - // ... then override with defaults + // set defaults unsafe { env::set_var("BIND_HOST","127.0.0.1"); env::set_var("BIND_PORT","3000"); + env::set_var("ROOT_PATH", "/"); } + // ... then override from .env, ignoring any error (file may not be there) + let _ = dotenvy::dotenv_override(); let certs = load_certs_from_fs().await.unwrap(); + let root_path = env::var("ROOT_PATH")?; let app_state = AppState{ certs, + root_path: root_path.clone(), }; let all_routes = Router::new() - .route("/", get(handler::show_check_form)) - .route("/", post(handler::check_canary_result)) + .route(&root_path, get(handler::show_check_form)) + .route(&root_path, post(handler::check_canary_result)) .with_state(app_state); let addr = SocketAddr::new( diff --git a/templates/showcheckform.html b/templates/showcheckform.html index 9c6cacb..e06da43 100644 --- a/templates/showcheckform.html +++ b/templates/showcheckform.html @@ -2,17 +2,19 @@ {% block body %}
URL to check: -
+{% if let Some(post_target) = post_target %} + {% match url %} {% when Some with (val) %} {% when None %} - {% endmatch %} +{% endmatch %}
+{% endif %} {% match message %} {% when Some with (val) %} -- 2.52.0