]> Humopery - waterslager.git/commitdiff
support relocating the application
authorfozzie <fozzie@humopery.space>
Sat, 19 Jul 2025 19:20:53 +0000 (14:20 -0500)
committerfozzie <fozzie@humopery.space>
Sat, 19 Jul 2025 19:20:53 +0000 (14:20 -0500)
.env
src/handler.rs
src/main.rs
templates/showcheckform.html

diff --git a/.env b/.env
index 3015b73bddd00466db756d99d5b57e659e64f0ec..6575ac82295e5d1e1f03603197ad2cb3cb8f9738 100644 (file)
--- 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=/
index 572ce6e21c1838754c3ab6636b811c941464f948..a06fcde3c29f29a810799cafb6987a82381d1e3c 100644 (file)
@@ -21,9 +21,10 @@ struct ShowCheckFormTemplate{
     key_fingerprint: Option<String>,
     key_description: Option<String>,
     error: Option<String>,
+    post_target: Option<String>,
 }
 
-pub async fn show_check_form() -> impl IntoResponse {
+pub async fn show_check_form(State(state): State<AppState>) -> 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<AppState>,
+    state: State<AppState>,
     Form(form_data): Form<CheckCanaryFormData>,
 ) -> 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<AppState>) -> 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<u8>, helper: Helper, url: String) -> CheckResponse {
+fn decode_message_bytes(content: Vec<u8>, helper: Helper, url: String, State(state): State<AppState>) -> 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<u8>, 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<AppState>) -> 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())
     }
index ded6233b46be6138f60368218c5418add7cf0d9c..09670b440b886c67ee6487f6c8be55f5d7cb32af 100644 (file)
@@ -11,6 +11,7 @@ use tokio::net::TcpListener;
 #[derive(Clone)]
 struct AppState {
     certs: CertMap,
+    root_path: String,
 }
 
 pub type CertMap = HashMap<String,(String,String)>;
@@ -38,23 +39,26 @@ async fn load_certs_from_fs() -> Result<CertMap,Box<dyn std::error::Error>> {
 #[tokio::main]
 async fn main() -> Result<(),Box<dyn std::error::Error>> {
     
-    // 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(
index 9c6cacb8530eb30ed5b93478054d956192eb21ee..e06da43425f11e8299400b9204a253ee356cbd57 100644 (file)
@@ -2,17 +2,19 @@
 
 {% block body %}
 <div>URL to check:
-  <form method="POST" action="/">
+{% if let Some(post_target) = post_target %}
+  <form method="POST" action="{{post_target}}">
 {% match url %}
   {% when Some with (val) %}
     <input type="text" id="checkurl" name="checkurl" value="{{val}}" />
   {% when None %}
     <input type="text" id="checkurl" name="checkurl" />
-  {% endmatch %}
+{% endmatch %}
     <br/>
     <input type="submit" name="submit" value="Submit"/>
   </form>
 </div>
+{% endif %}
 
 {% match message %}
   {% when Some with (val) %}