diff --git a/crates/mako/src/dev/mod.rs b/crates/mako/src/dev/mod.rs index f54233a9e..141a97c59 100644 --- a/crates/mako/src/dev/mod.rs +++ b/crates/mako/src/dev/mod.rs @@ -21,7 +21,7 @@ use {hyper, hyper_staticfile, hyper_tungstenite, open}; use crate::compiler::{Compiler, Context}; use crate::plugin::{PluginGenerateEndParams, PluginGenerateStats}; -use crate::utils::tokio_runtime; +use crate::utils::{process_req_url, tokio_runtime}; pub struct DevServer { root: PathBuf, @@ -124,7 +124,19 @@ impl DevServer { staticfile: hyper_staticfile::Static, txws: broadcast::Sender, ) -> Result> { - let path = req.uri().path(); + let mut path = req.uri().path().to_string(); + let public_path = &context.config.public_path; + if !public_path.is_empty() && public_path.starts_with('/') && public_path != "/" { + path = match process_req_url(public_path, &path) { + Ok(p) => p, + Err(_) => { + return Ok(hyper::Response::builder() + .status(hyper::StatusCode::BAD_REQUEST) + .body(hyper::Body::from("Bad Request")) + .unwrap()); + } + }; + } let path_without_slash_start = path.trim_start_matches('/'); let not_found_response = || { hyper::Response::builder() @@ -132,7 +144,7 @@ impl DevServer { .body(hyper::Body::empty()) .unwrap() }; - match path { + match path.as_str() { "/__/hmr-ws" => { if hyper_tungstenite::is_upgrade_request(&req) { debug!("new websocket connection"); diff --git a/crates/mako/src/utils/mod.rs b/crates/mako/src/utils/mod.rs index 787a71a6a..85920f13f 100644 --- a/crates/mako/src/utils/mod.rs +++ b/crates/mako/src/utils/mod.rs @@ -32,3 +32,32 @@ impl ParseRegex for Option { }) } } + +pub fn process_req_url(public_path: &str, req_url: &str) -> Result { + let public_path = format!("/{}/", public_path.trim_matches('/')); + if req_url.starts_with(&public_path) { + return Ok(req_url[public_path.len() - 1..].to_string()); + } + Ok(req_url.to_string()) +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_process_req_url() { + assert_eq!( + process_req_url("/public/", "/public/index.html").unwrap(), + "/index.html" + ); + assert_eq!( + process_req_url("/public/foo/", "/public/foo/index.html").unwrap(), + "/index.html" + ); + assert_eq!(process_req_url("/", "/index.html").unwrap(), "/index.html"); + assert_eq!( + process_req_url("/#/", "/#/index.html").unwrap(), + "/index.html" + ); + } +}