diff --git a/src/webserver/http.rs b/src/webserver/http.rs index ac0bc1e6..63ccdc25 100644 --- a/src/webserver/http.rs +++ b/src/webserver/http.rs @@ -533,24 +533,25 @@ pub async fn run_server(config: &AppConfig, state: AppState) -> anyhow::Result<( } #[cfg(not(target_family = "unix"))] anyhow::bail!("Unix sockets are not supported on your operating system. Use listen_on instead of unix_socket."); - } else { - if let Some(domain) = &config.https_domain { - let mut listen_on_https = listen_on; - listen_on_https.set_port(443); - log::debug!("Will start HTTPS server on {listen_on_https}"); - let config = make_auto_rustls_config(domain, config); - server = server - .bind_rustls_0_23(listen_on_https, config) - .map_err(|e| bind_error(e, listen_on_https))?; - } else if listen_on.port() == 443 { - bail!("Please specify a value for https_domain in the configuration file. This is required when using HTTPS (port 443)"); - } - if listen_on.port() != 443 { - log::debug!("Will start HTTP server on {listen_on}"); - server = server - .bind(listen_on) - .map_err(|e| bind_error(e, listen_on))?; - } + } + + if let Some(domain) = &config.https_domain { + let mut listen_on_https = listen_on; + listen_on_https.set_port(443); + log::debug!("Will start HTTPS server on {listen_on_https}"); + let config = make_auto_rustls_config(domain, config); + server = server + .bind_rustls_0_23(listen_on_https, config) + .map_err(|e| bind_error(e, listen_on_https))?; + } else if listen_on.port() == 443 { + bail!("Please specify a value for https_domain in the configuration file. This is required when using HTTPS (port 443)"); + } + + if listen_on.port() != 443 { + log::debug!("Will start HTTP server on {listen_on}"); + server = server + .bind(listen_on) + .map_err(|e| bind_error(e, listen_on))?; } log_welcome_message(config); diff --git a/src/webserver/routing.rs b/src/webserver/routing.rs index 4fce3c05..125cce8d 100644 --- a/src/webserver/routing.rs +++ b/src/webserver/routing.rs @@ -117,12 +117,33 @@ where { if path_and_query.path().ends_with(FORWARD_SLASH) { path.push(INDEX); - find_file_or_not_found(&path, SQL_EXTENSION, store).await + if let Ok(NotFound) = find_file_or_not_found(&path, SQL_EXTENSION, store).await { + let target_sql = path + .parent() + .unwrap_or_else(|| Path::new("/")) + .join("_.sql"); + if store.contains(&target_sql).await? { + Ok(Execute(target_sql)) + } else { + Ok(NotFound) + } + } else { + find_file_or_not_found(&path, SQL_EXTENSION, store).await + } } else { let path_with_ext = path.with_extension(SQL_EXTENSION); - match find_file(&path_with_ext, SQL_EXTENSION, store).await? { - Some(action) => Ok(action), - None => Ok(Redirect(append_to_path(path_and_query, FORWARD_SLASH))), + if let Some(action) = find_file(&path_with_ext, SQL_EXTENSION, store).await? { + Ok(action) + } else { + let mut parent = path.parent(); + while let Some(p) = parent { + let target_sql = p.join("_.sql"); + if store.contains(&target_sql).await? { + return find_file_or_not_found(&path, SQL_EXTENSION, store).await; + } + parent = p.parent(); + } + Ok(Redirect(append_to_path(path_and_query, FORWARD_SLASH))) } } } @@ -136,11 +157,33 @@ where T: FileStore, { match find_file(path, extension, store).await? { - None => find_not_found(path, store).await, + None => find_up_path_tree(path, store).await, Some(execute) => Ok(execute), } } +async fn find_up_path_tree(path: &Path, store: &T) -> anyhow::Result +where + T: FileStore, +{ + let mut parent = path.parent(); + while let Some(p) = parent { + let target_404 = p.join(NOT_FOUND); + if store.contains(&target_404).await? { + return Ok(CustomNotFound(target_404)); + } + + let target_sql = p.join("_.sql"); + if store.contains(&target_sql).await? { + return Ok(Execute(target_sql)); + } + + parent = p.parent(); + } + + Ok(NotFound) +} + async fn find_file( path: &Path, extension: &str, @@ -160,22 +203,6 @@ where } } -async fn find_not_found(path: &Path, store: &T) -> anyhow::Result -where - T: FileStore, -{ - let mut parent = path.parent(); - while let Some(p) = parent { - let target = p.join(NOT_FOUND); - if store.contains(&target).await? { - return Ok(CustomNotFound(target)); - } - parent = p.parent(); - } - - Ok(NotFound) -} - fn append_to_path(path_and_query: &PathAndQuery, append: &str) -> String { let mut full_uri = path_and_query.to_string(); full_uri.insert_str(path_and_query.path().len(), append);