From d2eae3d5b36d6d6423372b752d0f022573e3a426 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Wed, 29 Nov 2017 15:07:49 -0800 Subject: [PATCH] simplify Handler trait --- guide/src/qs_3.md | 2 +- src/application.rs | 2 +- src/httprequest.rs | 12 ++++++++++++ src/route.rs | 12 ++---------- src/staticfiles.rs | 20 +++++++------------- 5 files changed, 23 insertions(+), 25 deletions(-) diff --git a/guide/src/qs_3.md b/guide/src/qs_3.md index d7ead5fa1..89bef34c0 100644 --- a/guide/src/qs_3.md +++ b/guide/src/qs_3.md @@ -71,7 +71,7 @@ fn main() { ## Handler -A request handler can have several different forms. +A request handler can have different forms. * Simple function that accepts `HttpRequest` and returns `HttpResponse` or any type that can be converted into `HttpResponse`. diff --git a/src/application.rs b/src/application.rs index 53236b0ce..db9be1bf8 100644 --- a/src/application.rs +++ b/src/application.rs @@ -34,6 +34,7 @@ impl Application { } else { for (prefix, handler) in &self.handlers { if req.path().starts_with(prefix) { + req.set_prefix(prefix.len()); handler.handle(req, task); return } @@ -232,7 +233,6 @@ impl ApplicationBuilder where S: 'static { for (path, mut handler) in parts.handlers { let path = prefix.clone() + path.trim_left_matches('/'); - handler.set_prefix(path.clone()); handlers.insert(path, handler); } Application { diff --git a/src/httprequest.rs b/src/httprequest.rs index f2d9904ce..49f1da246 100644 --- a/src/httprequest.rs +++ b/src/httprequest.rs @@ -19,6 +19,7 @@ struct HttpMessage { version: Version, method: Method, path: String, + prefix: usize, query: String, headers: HeaderMap, extensions: Extensions, @@ -35,6 +36,7 @@ impl Default for HttpMessage { HttpMessage { method: Method::GET, path: String::new(), + prefix: 0, query: String::new(), version: Version::HTTP_11, headers: HeaderMap::new(), @@ -61,6 +63,7 @@ impl HttpRequest<()> { Rc::new(HttpMessage { method: method, path: path, + prefix: 0, query: query, version: version, headers: headers, @@ -123,6 +126,15 @@ impl HttpRequest { &self.0.path } + pub(crate) fn set_prefix(&mut self, idx: usize) { + self.as_mut().prefix = idx; + } + + #[doc(hidden)] + pub fn prefix_len(&self) -> usize { + self.0.prefix + } + /// Remote IP of client initiated HTTP request. /// /// The IP is resolved through the following headers, in this order: diff --git a/src/route.rs b/src/route.rs index f97106384..d23376890 100644 --- a/src/route.rs +++ b/src/route.rs @@ -30,13 +30,12 @@ impl Frame { /// Trait defines object that could be regestered as route handler #[allow(unused_variables)] pub trait Handler: 'static { + + /// The type of value that handler will return. type Result: Into; /// Handle request fn handle(&self, req: HttpRequest) -> Self::Result; - - /// Set route prefix - fn set_prefix(&mut self, prefix: String) {} } /// Handler for Fn() @@ -124,9 +123,6 @@ impl>, S: 'static> From> fo pub(crate) trait RouteHandler: 'static { /// Handle request fn handle(&self, req: HttpRequest, task: &mut Task); - - /// Set route prefix - fn set_prefix(&mut self, _prefix: String) {} } /// Route handler wrapper for Handler @@ -158,10 +154,6 @@ impl RouteHandler for WrapHandler fn handle(&self, req: HttpRequest, task: &mut Task) { self.h.handle(req).into().into(task) } - - fn set_prefix(&mut self, prefix: String) { - self.h.set_prefix(prefix) - } } /// Async route handler diff --git a/src/staticfiles.rs b/src/staticfiles.rs index 04089b1d9..858ee5f6b 100644 --- a/src/staticfiles.rs +++ b/src/staticfiles.rs @@ -33,7 +33,6 @@ pub struct StaticFiles { _show_index: bool, _chunk_size: usize, _follow_symlinks: bool, - prefix: String, } impl StaticFiles { @@ -65,12 +64,11 @@ impl StaticFiles { _show_index: index, _chunk_size: 0, _follow_symlinks: false, - prefix: String::new(), } } - fn index(&self, relpath: &str, filename: &PathBuf) -> Result { - let index_of = format!("Index of {}/{}", self.prefix, relpath); + fn index(&self, prefix: &str, relpath: &str, filename: &PathBuf) -> Result { + let index_of = format!("Index of {}{}", prefix, relpath); let mut body = String::new(); for entry in filename.read_dir()? { @@ -78,7 +76,7 @@ impl StaticFiles { let entry = entry.unwrap(); // show file url as relative to static path let file_url = format!( - "{}/{}", self.prefix, + "{}{}", prefix, entry.path().strip_prefix(&self.directory).unwrap().to_string_lossy()); // if file is a directory, add '/' to the end of the name @@ -130,18 +128,12 @@ impl StaticFiles { impl Handler for StaticFiles { type Result = Result; - fn set_prefix(&mut self, prefix: String) { - if prefix != "/" { - self.prefix += &prefix; - } - } - fn handle(&self, req: HttpRequest) -> Self::Result { if !self.accessible { Ok(HTTPNotFound.into()) } else { let mut hidden = false; - let filepath = req.path()[self.prefix.len()..] + let filepath = req.path()[req.prefix_len()..] .split('/').filter(|s| { if s.starts_with('.') { hidden = true; @@ -167,7 +159,9 @@ impl Handler for StaticFiles { }; if filename.is_dir() { - match self.index(&filepath[idx..], &filename) { + match self.index( + &req.path()[..req.prefix_len()], &filepath[idx..], &filename) + { Ok(resp) => Ok(resp), Err(err) => match err.kind() { io::ErrorKind::NotFound => Ok(HTTPNotFound.into()),