diff --git a/src/handler.rs b/src/handler.rs
index 72da14e2..734f04ef 100644
--- a/src/handler.rs
+++ b/src/handler.rs
@@ -383,12 +383,14 @@ impl<S> Handler<S> 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 560f7de7..b1e31151 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");