diff --git a/src/handler.rs b/src/handler.rs index 72da14e26..734f04ef6 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -383,12 +383,14 @@ impl Handler for NormalizePath { // try to remove trailing slash if p.ends_with('/') { let p = p.as_ref().trim_right_matches('/'); - if router.has_route(&p) { - let p = p.to_owned(); - let p = if !query.is_empty() { p + "?" + query } else { p }; - return HttpResponse::build(self.redirect) - .header(header::LOCATION, p.as_str()) - .body(Body::Empty); + if router.has_route(p) { + let mut req = HttpResponse::build(self.redirect); + return if !query.is_empty() { + req.header(header::LOCATION, (p.to_owned() + "?" + query).as_str()) + } else { + req.header(header::LOCATION, p) + } + .body(Body::Empty); } } } diff --git a/src/router.rs b/src/router.rs index 560f7de79..b1e31151d 100644 --- a/src/router.rs +++ b/src/router.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use std::hash::{Hash, Hasher}; use std::collections::HashMap; -use regex::{Regex, RegexSet}; +use regex::{Regex, RegexSet, escape}; use error::UrlGenerationError; use resource::Resource; @@ -299,7 +299,7 @@ impl Pattern { elems.push(PatternElement::Str(el.clone())); el.clear(); } else { - re.push(ch); + re.push_str(escape(&ch.to_string()).as_str()); el.push(ch); } } @@ -336,6 +336,7 @@ mod tests { routes.insert(Pattern::new("", "/name/{val}", "^/"), Some(Resource::default())); routes.insert(Pattern::new("", "/name/{val}/index.html", "^/"), Some(Resource::default())); + routes.insert(Pattern::new("", "/file/{file}.{ext}", "^/"), Some(Resource::default())); routes.insert(Pattern::new("", "/v{val}/{val2}/index.html", "^/"), Some(Resource::default())); routes.insert(Pattern::new("", "/v/{tail:.*}", "^/"), Some(Resource::default())); @@ -355,6 +356,11 @@ mod tests { assert!(rec.recognize(&mut req).is_some()); assert_eq!(req.match_info().get("val").unwrap(), "value2"); + let mut req = TestRequest::with_uri("/file/file.gz").finish(); + assert!(rec.recognize(&mut req).is_some()); + assert_eq!(req.match_info().get("file").unwrap(), "file"); + assert_eq!(req.match_info().get("ext").unwrap(), "gz"); + let mut req = TestRequest::with_uri("/vtest/ttt/index.html").finish(); assert!(rec.recognize(&mut req).is_some()); assert_eq!(req.match_info().get("val").unwrap(), "test");