mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-24 07:53:00 +01:00
use read only self for Middleware
This commit is contained in:
parent
3de9284592
commit
65ca563579
@ -1,4 +1,3 @@
|
|||||||
use std::cell::RefCell;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -21,9 +20,9 @@ pub struct HttpApplication<S = ()> {
|
|||||||
prefix: String,
|
prefix: String,
|
||||||
prefix_len: usize,
|
prefix_len: usize,
|
||||||
router: Router,
|
router: Router,
|
||||||
inner: Rc<RefCell<Inner<S>>>,
|
inner: Rc<Inner<S>>,
|
||||||
filters: Option<Vec<Box<Predicate<S>>>>,
|
filters: Option<Vec<Box<Predicate<S>>>>,
|
||||||
middlewares: Rc<RefCell<Vec<Box<Middleware<S>>>>>,
|
middlewares: Rc<Vec<Box<Middleware<S>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
@ -41,12 +40,13 @@ enum PrefixHandlerType<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<S: 'static> PipelineHandler<S> for Inner<S> {
|
impl<S: 'static> PipelineHandler<S> for Inner<S> {
|
||||||
|
#[inline]
|
||||||
fn encoding(&self) -> ContentEncoding {
|
fn encoding(&self) -> ContentEncoding {
|
||||||
self.encoding
|
self.encoding
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle(
|
fn handle(
|
||||||
&mut self, req: HttpRequest<S>, htype: HandlerType,
|
&self, req: HttpRequest<S>, htype: HandlerType,
|
||||||
) -> AsyncResult<HttpResponse> {
|
) -> AsyncResult<HttpResponse> {
|
||||||
match htype {
|
match htype {
|
||||||
HandlerType::Normal(idx) => match self.resources[idx].handle(req) {
|
HandlerType::Normal(idx) => match self.resources[idx].handle(req) {
|
||||||
@ -57,8 +57,8 @@ impl<S: 'static> PipelineHandler<S> for Inner<S> {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
HandlerType::Handler(idx) => match self.handlers[idx] {
|
HandlerType::Handler(idx) => match self.handlers[idx] {
|
||||||
PrefixHandlerType::Handler(_, ref mut hnd) => hnd.handle(req),
|
PrefixHandlerType::Handler(_, ref hnd) => hnd.handle(req),
|
||||||
PrefixHandlerType::Scope(_, ref mut hnd, _) => hnd.handle(req),
|
PrefixHandlerType::Scope(_, ref hnd, _) => hnd.handle(req),
|
||||||
},
|
},
|
||||||
HandlerType::Default => match self.default.handle(req) {
|
HandlerType::Default => match self.default.handle(req) {
|
||||||
Ok(result) => result,
|
Ok(result) => result,
|
||||||
@ -74,14 +74,13 @@ impl<S: 'static> HttpApplication<S> {
|
|||||||
if let Some(idx) = self.router.recognize(req) {
|
if let Some(idx) = self.router.recognize(req) {
|
||||||
HandlerType::Normal(idx)
|
HandlerType::Normal(idx)
|
||||||
} else {
|
} else {
|
||||||
let inner = self.inner.borrow();
|
|
||||||
req.match_info_mut().set_tail(0);
|
req.match_info_mut().set_tail(0);
|
||||||
|
|
||||||
'outer: for idx in 0..inner.handlers.len() {
|
'outer: for idx in 0..self.inner.handlers.len() {
|
||||||
match inner.handlers[idx] {
|
match self.inner.handlers[idx] {
|
||||||
PrefixHandlerType::Handler(ref prefix, _) => {
|
PrefixHandlerType::Handler(ref prefix, _) => {
|
||||||
let m = {
|
let m = {
|
||||||
let path = &req.path()[inner.prefix..];
|
let path = &req.path()[self.inner.prefix..];
|
||||||
let path_len = path.len();
|
let path_len = path.len();
|
||||||
|
|
||||||
path.starts_with(prefix)
|
path.starts_with(prefix)
|
||||||
@ -90,7 +89,7 @@ impl<S: 'static> HttpApplication<S> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if m {
|
if m {
|
||||||
let prefix_len = (inner.prefix + prefix.len()) as u16;
|
let prefix_len = (self.inner.prefix + prefix.len()) as u16;
|
||||||
let url = req.url().clone();
|
let url = req.url().clone();
|
||||||
req.set_prefix_len(prefix_len);
|
req.set_prefix_len(prefix_len);
|
||||||
req.match_info_mut().set_url(url);
|
req.match_info_mut().set_url(url);
|
||||||
@ -100,7 +99,7 @@ impl<S: 'static> HttpApplication<S> {
|
|||||||
}
|
}
|
||||||
PrefixHandlerType::Scope(ref pattern, _, ref filters) => {
|
PrefixHandlerType::Scope(ref pattern, _, ref filters) => {
|
||||||
if let Some(prefix_len) =
|
if let Some(prefix_len) =
|
||||||
pattern.match_prefix_with_params(req, inner.prefix)
|
pattern.match_prefix_with_params(req, self.inner.prefix)
|
||||||
{
|
{
|
||||||
for filter in filters {
|
for filter in filters {
|
||||||
if !filter.check(req) {
|
if !filter.check(req) {
|
||||||
@ -108,7 +107,7 @@ impl<S: 'static> HttpApplication<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let prefix_len = (inner.prefix + prefix_len) as u16;
|
let prefix_len = (self.inner.prefix + prefix_len) as u16;
|
||||||
let url = req.url().clone();
|
let url = req.url().clone();
|
||||||
req.set_prefix_len(prefix_len);
|
req.set_prefix_len(prefix_len);
|
||||||
let params = req.match_info_mut();
|
let params = req.match_info_mut();
|
||||||
@ -124,9 +123,9 @@ impl<S: 'static> HttpApplication<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) fn run(&mut self, mut req: HttpRequest<S>) -> AsyncResult<HttpResponse> {
|
pub(crate) fn run(&self, mut req: HttpRequest<S>) -> AsyncResult<HttpResponse> {
|
||||||
let tp = self.get_handler(&mut req);
|
let tp = self.get_handler(&mut req);
|
||||||
self.inner.borrow_mut().handle(req, tp)
|
self.inner.handle(req, tp)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -629,7 +628,7 @@ where
|
|||||||
resources.push((pattern, None));
|
resources.push((pattern, None));
|
||||||
}
|
}
|
||||||
|
|
||||||
for ref mut handler in parts.handlers.iter_mut() {
|
for handler in &mut parts.handlers {
|
||||||
if let PrefixHandlerType::Scope(_, ref mut route_handler, _) = handler {
|
if let PrefixHandlerType::Scope(_, ref mut route_handler, _) = handler {
|
||||||
if !route_handler.has_default_resource() {
|
if !route_handler.has_default_resource() {
|
||||||
route_handler.default_resource(Rc::clone(&parts.default));
|
route_handler.default_resource(Rc::clone(&parts.default));
|
||||||
@ -639,13 +638,13 @@ where
|
|||||||
|
|
||||||
let (router, resources) = Router::new(&prefix, parts.settings, resources);
|
let (router, resources) = Router::new(&prefix, parts.settings, resources);
|
||||||
|
|
||||||
let inner = Rc::new(RefCell::new(Inner {
|
let inner = Rc::new(Inner {
|
||||||
prefix: prefix_len,
|
prefix: prefix_len,
|
||||||
default: Rc::clone(&parts.default),
|
default: Rc::clone(&parts.default),
|
||||||
encoding: parts.encoding,
|
encoding: parts.encoding,
|
||||||
handlers: parts.handlers,
|
handlers: parts.handlers,
|
||||||
resources,
|
resources,
|
||||||
}));
|
});
|
||||||
let filters = if parts.filters.is_empty() {
|
let filters = if parts.filters.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
@ -655,7 +654,7 @@ where
|
|||||||
HttpApplication {
|
HttpApplication {
|
||||||
state: Rc::new(parts.state),
|
state: Rc::new(parts.state),
|
||||||
router: router.clone(),
|
router: router.clone(),
|
||||||
middlewares: Rc::new(RefCell::new(parts.middlewares)),
|
middlewares: Rc::new(parts.middlewares),
|
||||||
prefix,
|
prefix,
|
||||||
prefix_len,
|
prefix_len,
|
||||||
inner,
|
inner,
|
||||||
@ -765,7 +764,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_default_resource() {
|
fn test_default_resource() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.resource("/test", |r| r.f(|_| HttpResponse::Ok()))
|
.resource("/test", |r| r.f(|_| HttpResponse::Ok()))
|
||||||
.finish();
|
.finish();
|
||||||
|
|
||||||
@ -777,7 +776,7 @@ mod tests {
|
|||||||
let resp = app.run(req);
|
let resp = app.run(req);
|
||||||
assert_eq!(resp.as_msg().status(), StatusCode::NOT_FOUND);
|
assert_eq!(resp.as_msg().status(), StatusCode::NOT_FOUND);
|
||||||
|
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.default_resource(|r| r.f(|_| HttpResponse::MethodNotAllowed()))
|
.default_resource(|r| r.f(|_| HttpResponse::MethodNotAllowed()))
|
||||||
.finish();
|
.finish();
|
||||||
let req = TestRequest::with_uri("/blah").finish();
|
let req = TestRequest::with_uri("/blah").finish();
|
||||||
@ -787,7 +786,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_unhandled_prefix() {
|
fn test_unhandled_prefix() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.prefix("/test")
|
.prefix("/test")
|
||||||
.resource("/test", |r| r.f(|_| HttpResponse::Ok()))
|
.resource("/test", |r| r.f(|_| HttpResponse::Ok()))
|
||||||
.finish();
|
.finish();
|
||||||
@ -796,7 +795,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_state() {
|
fn test_state() {
|
||||||
let mut app = App::with_state(10)
|
let app = App::with_state(10)
|
||||||
.resource("/", |r| r.f(|_| HttpResponse::Ok()))
|
.resource("/", |r| r.f(|_| HttpResponse::Ok()))
|
||||||
.finish();
|
.finish();
|
||||||
let req =
|
let req =
|
||||||
@ -807,7 +806,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_prefix() {
|
fn test_prefix() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.prefix("/test")
|
.prefix("/test")
|
||||||
.resource("/blah", |r| r.f(|_| HttpResponse::Ok()))
|
.resource("/blah", |r| r.f(|_| HttpResponse::Ok()))
|
||||||
.finish();
|
.finish();
|
||||||
@ -830,7 +829,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_handler() {
|
fn test_handler() {
|
||||||
let mut app = App::new().handler("/test", |_| HttpResponse::Ok()).finish();
|
let app = App::new().handler("/test", |_| HttpResponse::Ok()).finish();
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/test").finish();
|
let req = TestRequest::with_uri("/test").finish();
|
||||||
let resp = app.run(req);
|
let resp = app.run(req);
|
||||||
@ -855,7 +854,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_handler2() {
|
fn test_handler2() {
|
||||||
let mut app = App::new().handler("test", |_| HttpResponse::Ok()).finish();
|
let app = App::new().handler("test", |_| HttpResponse::Ok()).finish();
|
||||||
|
|
||||||
let req = TestRequest::with_uri("/test").finish();
|
let req = TestRequest::with_uri("/test").finish();
|
||||||
let resp = app.run(req);
|
let resp = app.run(req);
|
||||||
@ -880,7 +879,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_handler_with_prefix() {
|
fn test_handler_with_prefix() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.prefix("prefix")
|
.prefix("prefix")
|
||||||
.handler("/test", |_| HttpResponse::Ok())
|
.handler("/test", |_| HttpResponse::Ok())
|
||||||
.finish();
|
.finish();
|
||||||
@ -908,7 +907,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_route() {
|
fn test_route() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.route("/test", Method::GET, |_: HttpRequest| HttpResponse::Ok())
|
.route("/test", Method::GET, |_: HttpRequest| HttpResponse::Ok())
|
||||||
.route("/test", Method::POST, |_: HttpRequest| {
|
.route("/test", Method::POST, |_: HttpRequest| {
|
||||||
HttpResponse::Created()
|
HttpResponse::Created()
|
||||||
@ -930,7 +929,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_handler_prefix() {
|
fn test_handler_prefix() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.prefix("/app")
|
.prefix("/app")
|
||||||
.handler("/test", |_| HttpResponse::Ok())
|
.handler("/test", |_| HttpResponse::Ok())
|
||||||
.finish();
|
.finish();
|
||||||
@ -980,7 +979,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_option_responder() {
|
fn test_option_responder() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.resource("/none", |r| r.f(|_| -> Option<&'static str> { None }))
|
.resource("/none", |r| r.f(|_| -> Option<&'static str> { None }))
|
||||||
.resource("/some", |r| r.f(|_| Some("some")))
|
.resource("/some", |r| r.f(|_| Some("some")))
|
||||||
.finish();
|
.finish();
|
||||||
|
@ -1204,7 +1204,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_redirect_to_index() {
|
fn test_redirect_to_index() {
|
||||||
let mut st = StaticFiles::new(".").index_file("index.html");
|
let st = StaticFiles::new(".").index_file("index.html");
|
||||||
let mut req = HttpRequest::default();
|
let mut req = HttpRequest::default();
|
||||||
req.match_info_mut().add_static("tail", "tests");
|
req.match_info_mut().add_static("tail", "tests");
|
||||||
|
|
||||||
@ -1230,7 +1230,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_redirect_to_index_nested() {
|
fn test_redirect_to_index_nested() {
|
||||||
let mut st = StaticFiles::new(".").index_file("mod.rs");
|
let st = StaticFiles::new(".").index_file("mod.rs");
|
||||||
let mut req = HttpRequest::default();
|
let mut req = HttpRequest::default();
|
||||||
req.match_info_mut().add_static("tail", "src/client");
|
req.match_info_mut().add_static("tail", "src/client");
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_normalize_path_trailing_slashes() {
|
fn test_normalize_path_trailing_slashes() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.resource("/resource1", |r| r.method(Method::GET).f(index))
|
.resource("/resource1", |r| r.method(Method::GET).f(index))
|
||||||
.resource("/resource2/", |r| r.method(Method::GET).f(index))
|
.resource("/resource2/", |r| r.method(Method::GET).f(index))
|
||||||
.default_resource(|r| r.h(NormalizePath::default()))
|
.default_resource(|r| r.h(NormalizePath::default()))
|
||||||
@ -222,7 +222,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_normalize_path_trailing_slashes_disabled() {
|
fn test_normalize_path_trailing_slashes_disabled() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.resource("/resource1", |r| r.method(Method::GET).f(index))
|
.resource("/resource1", |r| r.method(Method::GET).f(index))
|
||||||
.resource("/resource2/", |r| r.method(Method::GET).f(index))
|
.resource("/resource2/", |r| r.method(Method::GET).f(index))
|
||||||
.default_resource(|r| {
|
.default_resource(|r| {
|
||||||
@ -255,7 +255,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_normalize_path_merge_slashes() {
|
fn test_normalize_path_merge_slashes() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.resource("/resource1", |r| r.method(Method::GET).f(index))
|
.resource("/resource1", |r| r.method(Method::GET).f(index))
|
||||||
.resource("/resource1/a/b", |r| r.method(Method::GET).f(index))
|
.resource("/resource1/a/b", |r| r.method(Method::GET).f(index))
|
||||||
.default_resource(|r| r.h(NormalizePath::default()))
|
.default_resource(|r| r.h(NormalizePath::default()))
|
||||||
@ -344,7 +344,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_normalize_path_merge_and_append_slashes() {
|
fn test_normalize_path_merge_and_append_slashes() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.resource("/resource1", |r| r.method(Method::GET).f(index))
|
.resource("/resource1", |r| r.method(Method::GET).f(index))
|
||||||
.resource("/resource2/", |r| r.method(Method::GET).f(index))
|
.resource("/resource2/", |r| r.method(Method::GET).f(index))
|
||||||
.resource("/resource1/a/b", |r| r.method(Method::GET).f(index))
|
.resource("/resource1/a/b", |r| r.method(Method::GET).f(index))
|
||||||
|
@ -412,7 +412,7 @@ mod tests {
|
|||||||
fn test_with_json() {
|
fn test_with_json() {
|
||||||
let mut cfg = JsonConfig::default();
|
let mut cfg = JsonConfig::default();
|
||||||
cfg.limit(4096);
|
cfg.limit(4096);
|
||||||
let mut handler = With::new(|data: Json<MyObject>| data, cfg);
|
let handler = With::new(|data: Json<MyObject>| data, cfg);
|
||||||
|
|
||||||
let req = HttpRequest::default();
|
let req = HttpRequest::default();
|
||||||
assert!(handler.handle(req).as_err().is_some());
|
assert!(handler.handle(req).as_err().is_some());
|
||||||
|
@ -356,7 +356,7 @@ impl Cors {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Middleware<S> for Cors {
|
impl<S> Middleware<S> for Cors {
|
||||||
fn start(&mut self, req: &mut HttpRequest<S>) -> Result<Started> {
|
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
|
||||||
if self.inner.preflight && Method::OPTIONS == *req.method() {
|
if self.inner.preflight && Method::OPTIONS == *req.method() {
|
||||||
self.validate_origin(req)?;
|
self.validate_origin(req)?;
|
||||||
self.validate_allowed_method(req)?;
|
self.validate_allowed_method(req)?;
|
||||||
@ -434,7 +434,7 @@ impl<S> Middleware<S> for Cors {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn response(
|
fn response(
|
||||||
&mut self, req: &mut HttpRequest<S>, mut resp: HttpResponse,
|
&self, req: &mut HttpRequest<S>, mut resp: HttpResponse,
|
||||||
) -> Result<Response> {
|
) -> Result<Response> {
|
||||||
match self.inner.origins {
|
match self.inner.origins {
|
||||||
AllOrSome::All => {
|
AllOrSome::All => {
|
||||||
@ -944,7 +944,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn validate_origin_allows_all_origins() {
|
fn validate_origin_allows_all_origins() {
|
||||||
let mut cors = Cors::default();
|
let cors = Cors::default();
|
||||||
let mut req =
|
let mut req =
|
||||||
TestRequest::with_header("Origin", "https://www.example.com").finish();
|
TestRequest::with_header("Origin", "https://www.example.com").finish();
|
||||||
|
|
||||||
@ -1013,7 +1013,7 @@ mod tests {
|
|||||||
// #[test]
|
// #[test]
|
||||||
// #[should_panic(expected = "MissingOrigin")]
|
// #[should_panic(expected = "MissingOrigin")]
|
||||||
// fn test_validate_missing_origin() {
|
// fn test_validate_missing_origin() {
|
||||||
// let mut cors = Cors::build()
|
// let cors = Cors::build()
|
||||||
// .allowed_origin("https://www.example.com")
|
// .allowed_origin("https://www.example.com")
|
||||||
// .finish();
|
// .finish();
|
||||||
// let mut req = HttpRequest::default();
|
// let mut req = HttpRequest::default();
|
||||||
@ -1023,7 +1023,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "OriginNotAllowed")]
|
#[should_panic(expected = "OriginNotAllowed")]
|
||||||
fn test_validate_not_allowed_origin() {
|
fn test_validate_not_allowed_origin() {
|
||||||
let mut cors = Cors::build()
|
let cors = Cors::build()
|
||||||
.allowed_origin("https://www.example.com")
|
.allowed_origin("https://www.example.com")
|
||||||
.finish();
|
.finish();
|
||||||
|
|
||||||
@ -1035,7 +1035,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_validate_origin() {
|
fn test_validate_origin() {
|
||||||
let mut cors = Cors::build()
|
let cors = Cors::build()
|
||||||
.allowed_origin("https://www.example.com")
|
.allowed_origin("https://www.example.com")
|
||||||
.finish();
|
.finish();
|
||||||
|
|
||||||
@ -1048,7 +1048,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_no_origin_response() {
|
fn test_no_origin_response() {
|
||||||
let mut cors = Cors::build().finish();
|
let cors = Cors::build().finish();
|
||||||
|
|
||||||
let mut req = TestRequest::default().method(Method::GET).finish();
|
let mut req = TestRequest::default().method(Method::GET).finish();
|
||||||
let resp: HttpResponse = HttpResponse::Ok().into();
|
let resp: HttpResponse = HttpResponse::Ok().into();
|
||||||
@ -1074,7 +1074,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_response() {
|
fn test_response() {
|
||||||
let mut cors = Cors::build()
|
let cors = Cors::build()
|
||||||
.send_wildcard()
|
.send_wildcard()
|
||||||
.disable_preflight()
|
.disable_preflight()
|
||||||
.max_age(3600)
|
.max_age(3600)
|
||||||
@ -1109,7 +1109,7 @@ mod tests {
|
|||||||
resp.headers().get(header::VARY).unwrap().as_bytes()
|
resp.headers().get(header::VARY).unwrap().as_bytes()
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut cors = Cors::build()
|
let cors = Cors::build()
|
||||||
.disable_vary_header()
|
.disable_vary_header()
|
||||||
.allowed_origin("https://www.example.com")
|
.allowed_origin("https://www.example.com")
|
||||||
.finish();
|
.finish();
|
||||||
|
@ -209,7 +209,7 @@ impl CsrfFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Middleware<S> for CsrfFilter {
|
impl<S> Middleware<S> for CsrfFilter {
|
||||||
fn start(&mut self, req: &mut HttpRequest<S>) -> Result<Started> {
|
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
|
||||||
self.validate(req)?;
|
self.validate(req)?;
|
||||||
Ok(Started::Done)
|
Ok(Started::Done)
|
||||||
}
|
}
|
||||||
@ -223,7 +223,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_safe() {
|
fn test_safe() {
|
||||||
let mut csrf = CsrfFilter::new().allowed_origin("https://www.example.com");
|
let csrf = CsrfFilter::new().allowed_origin("https://www.example.com");
|
||||||
|
|
||||||
let mut req = TestRequest::with_header("Origin", "https://www.w3.org")
|
let mut req = TestRequest::with_header("Origin", "https://www.w3.org")
|
||||||
.method(Method::HEAD)
|
.method(Method::HEAD)
|
||||||
@ -234,7 +234,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_csrf() {
|
fn test_csrf() {
|
||||||
let mut csrf = CsrfFilter::new().allowed_origin("https://www.example.com");
|
let csrf = CsrfFilter::new().allowed_origin("https://www.example.com");
|
||||||
|
|
||||||
let mut req = TestRequest::with_header("Origin", "https://www.w3.org")
|
let mut req = TestRequest::with_header("Origin", "https://www.w3.org")
|
||||||
.method(Method::POST)
|
.method(Method::POST)
|
||||||
@ -245,7 +245,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_referer() {
|
fn test_referer() {
|
||||||
let mut csrf = CsrfFilter::new().allowed_origin("https://www.example.com");
|
let csrf = CsrfFilter::new().allowed_origin("https://www.example.com");
|
||||||
|
|
||||||
let mut req = TestRequest::with_header(
|
let mut req = TestRequest::with_header(
|
||||||
"Referer",
|
"Referer",
|
||||||
@ -258,9 +258,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_upgrade() {
|
fn test_upgrade() {
|
||||||
let mut strict_csrf = CsrfFilter::new().allowed_origin("https://www.example.com");
|
let strict_csrf = CsrfFilter::new().allowed_origin("https://www.example.com");
|
||||||
|
|
||||||
let mut lax_csrf = CsrfFilter::new()
|
let lax_csrf = CsrfFilter::new()
|
||||||
.allowed_origin("https://www.example.com")
|
.allowed_origin("https://www.example.com")
|
||||||
.allow_upgrade();
|
.allow_upgrade();
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ impl DefaultHeaders {
|
|||||||
|
|
||||||
impl<S> Middleware<S> for DefaultHeaders {
|
impl<S> Middleware<S> for DefaultHeaders {
|
||||||
fn response(
|
fn response(
|
||||||
&mut self, _: &mut HttpRequest<S>, mut resp: HttpResponse,
|
&self, _: &mut HttpRequest<S>, mut resp: HttpResponse,
|
||||||
) -> Result<Response> {
|
) -> Result<Response> {
|
||||||
for (key, value) in self.headers.iter() {
|
for (key, value) in self.headers.iter() {
|
||||||
if !resp.headers().contains_key(key) {
|
if !resp.headers().contains_key(key) {
|
||||||
@ -100,7 +100,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_default_headers() {
|
fn test_default_headers() {
|
||||||
let mut mw = DefaultHeaders::new().header(CONTENT_TYPE, "0001");
|
let mw = DefaultHeaders::new().header(CONTENT_TYPE, "0001");
|
||||||
|
|
||||||
let mut req = HttpRequest::default();
|
let mut req = HttpRequest::default();
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ impl<S> ErrorHandlers<S> {
|
|||||||
|
|
||||||
impl<S: 'static> Middleware<S> for ErrorHandlers<S> {
|
impl<S: 'static> Middleware<S> for ErrorHandlers<S> {
|
||||||
fn response(
|
fn response(
|
||||||
&mut self, req: &mut HttpRequest<S>, resp: HttpResponse,
|
&self, req: &mut HttpRequest<S>, resp: HttpResponse,
|
||||||
) -> Result<Response> {
|
) -> Result<Response> {
|
||||||
if let Some(handler) = self.handlers.get(&resp.status()) {
|
if let Some(handler) = self.handlers.get(&resp.status()) {
|
||||||
handler(req, resp)
|
handler(req, resp)
|
||||||
@ -99,7 +99,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_handler() {
|
fn test_handler() {
|
||||||
let mut mw =
|
let mw =
|
||||||
ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500);
|
ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500);
|
||||||
|
|
||||||
let mut req = HttpRequest::default();
|
let mut req = HttpRequest::default();
|
||||||
@ -121,7 +121,7 @@ mod tests {
|
|||||||
struct MiddlewareOne;
|
struct MiddlewareOne;
|
||||||
|
|
||||||
impl<S> Middleware<S> for MiddlewareOne {
|
impl<S> Middleware<S> for MiddlewareOne {
|
||||||
fn start(&mut self, _req: &mut HttpRequest<S>) -> Result<Started, Error> {
|
fn start(&self, _req: &mut HttpRequest<S>) -> Result<Started, Error> {
|
||||||
Err(ErrorInternalServerError("middleware error"))
|
Err(ErrorInternalServerError("middleware error"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ impl<T> IdentityService<T> {
|
|||||||
struct IdentityBox(Box<Identity>);
|
struct IdentityBox(Box<Identity>);
|
||||||
|
|
||||||
impl<S: 'static, T: IdentityPolicy<S>> Middleware<S> for IdentityService<T> {
|
impl<S: 'static, T: IdentityPolicy<S>> Middleware<S> for IdentityService<T> {
|
||||||
fn start(&mut self, req: &mut HttpRequest<S>) -> Result<Started> {
|
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
|
||||||
let mut req = req.clone();
|
let mut req = req.clone();
|
||||||
|
|
||||||
let fut = self
|
let fut = self
|
||||||
@ -195,7 +195,7 @@ impl<S: 'static, T: IdentityPolicy<S>> Middleware<S> for IdentityService<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn response(
|
fn response(
|
||||||
&mut self, req: &mut HttpRequest<S>, resp: HttpResponse,
|
&self, req: &mut HttpRequest<S>, resp: HttpResponse,
|
||||||
) -> Result<Response> {
|
) -> Result<Response> {
|
||||||
if let Some(mut id) = req.extensions_mut().remove::<IdentityBox>() {
|
if let Some(mut id) = req.extensions_mut().remove::<IdentityBox>() {
|
||||||
id.0.write(resp)
|
id.0.write(resp)
|
||||||
|
@ -124,14 +124,14 @@ impl Logger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Middleware<S> for Logger {
|
impl<S> Middleware<S> for Logger {
|
||||||
fn start(&mut self, req: &mut HttpRequest<S>) -> Result<Started> {
|
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
|
||||||
if !self.exclude.contains(req.path()) {
|
if !self.exclude.contains(req.path()) {
|
||||||
req.extensions_mut().insert(StartTime(time::now()));
|
req.extensions_mut().insert(StartTime(time::now()));
|
||||||
}
|
}
|
||||||
Ok(Started::Done)
|
Ok(Started::Done)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(&mut self, req: &mut HttpRequest<S>, resp: &HttpResponse) -> Finished {
|
fn finish(&self, req: &mut HttpRequest<S>, resp: &HttpResponse) -> Finished {
|
||||||
self.log(req, resp);
|
self.log(req, resp);
|
||||||
Finished::Done
|
Finished::Done
|
||||||
}
|
}
|
||||||
@ -322,7 +322,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_logger() {
|
fn test_logger() {
|
||||||
let mut logger = Logger::new("%% %{User-Agent}i %{X-Test}o %{HOME}e %D test");
|
let logger = Logger::new("%% %{User-Agent}i %{X-Test}o %{HOME}e %D test");
|
||||||
|
|
||||||
let mut headers = HeaderMap::new();
|
let mut headers = HeaderMap::new();
|
||||||
headers.insert(
|
headers.insert(
|
||||||
|
@ -51,20 +51,20 @@ pub enum Finished {
|
|||||||
pub trait Middleware<S>: 'static {
|
pub trait Middleware<S>: 'static {
|
||||||
/// Method is called when request is ready. It may return
|
/// Method is called when request is ready. It may return
|
||||||
/// future, which should resolve before next middleware get called.
|
/// future, which should resolve before next middleware get called.
|
||||||
fn start(&mut self, req: &mut HttpRequest<S>) -> Result<Started> {
|
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
|
||||||
Ok(Started::Done)
|
Ok(Started::Done)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Method is called when handler returns response,
|
/// Method is called when handler returns response,
|
||||||
/// but before sending http message to peer.
|
/// but before sending http message to peer.
|
||||||
fn response(
|
fn response(
|
||||||
&mut self, req: &mut HttpRequest<S>, resp: HttpResponse,
|
&self, req: &mut HttpRequest<S>, resp: HttpResponse,
|
||||||
) -> Result<Response> {
|
) -> Result<Response> {
|
||||||
Ok(Response::Done(resp))
|
Ok(Response::Done(resp))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Method is called after body stream get sent to peer.
|
/// Method is called after body stream get sent to peer.
|
||||||
fn finish(&mut self, req: &mut HttpRequest<S>, resp: &HttpResponse) -> Finished {
|
fn finish(&self, req: &mut HttpRequest<S>, resp: &HttpResponse) -> Finished {
|
||||||
Finished::Done
|
Finished::Done
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -246,7 +246,7 @@ impl<S, T: SessionBackend<S>> SessionStorage<T, S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<S: 'static, T: SessionBackend<S>> Middleware<S> for SessionStorage<T, S> {
|
impl<S: 'static, T: SessionBackend<S>> Middleware<S> for SessionStorage<T, S> {
|
||||||
fn start(&mut self, req: &mut HttpRequest<S>) -> Result<Started> {
|
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
|
||||||
let mut req = req.clone();
|
let mut req = req.clone();
|
||||||
|
|
||||||
let fut = self.0.from_request(&mut req).then(move |res| match res {
|
let fut = self.0.from_request(&mut req).then(move |res| match res {
|
||||||
@ -261,7 +261,7 @@ impl<S: 'static, T: SessionBackend<S>> Middleware<S> for SessionStorage<T, S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn response(
|
fn response(
|
||||||
&mut self, req: &mut HttpRequest<S>, resp: HttpResponse,
|
&self, req: &mut HttpRequest<S>, resp: HttpResponse,
|
||||||
) -> Result<Response> {
|
) -> Result<Response> {
|
||||||
if let Some(s_box) = req.extensions_mut().remove::<Arc<SessionImplCell>>() {
|
if let Some(s_box) = req.extensions_mut().remove::<Arc<SessionImplCell>>() {
|
||||||
s_box.0.borrow_mut().write(resp)
|
s_box.0.borrow_mut().write(resp)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::cell::{RefCell, UnsafeCell};
|
use std::cell::UnsafeCell;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::{io, mem};
|
use std::{io, mem};
|
||||||
@ -31,7 +31,7 @@ pub trait PipelineHandler<S> {
|
|||||||
fn encoding(&self) -> ContentEncoding;
|
fn encoding(&self) -> ContentEncoding;
|
||||||
|
|
||||||
fn handle(
|
fn handle(
|
||||||
&mut self, req: HttpRequest<S>, htype: HandlerType,
|
&self, req: HttpRequest<S>, htype: HandlerType,
|
||||||
) -> AsyncResult<HttpResponse>;
|
) -> AsyncResult<HttpResponse>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ impl<S: 'static, H: PipelineHandler<S>> PipelineState<S, H> {
|
|||||||
struct PipelineInfo<S> {
|
struct PipelineInfo<S> {
|
||||||
req: UnsafeCell<HttpRequest<S>>,
|
req: UnsafeCell<HttpRequest<S>>,
|
||||||
count: u16,
|
count: u16,
|
||||||
mws: Rc<RefCell<Vec<Box<Middleware<S>>>>>,
|
mws: Rc<Vec<Box<Middleware<S>>>>,
|
||||||
context: Option<Box<ActorHttpContext>>,
|
context: Option<Box<ActorHttpContext>>,
|
||||||
error: Option<Error>,
|
error: Option<Error>,
|
||||||
disconnected: Option<bool>,
|
disconnected: Option<bool>,
|
||||||
@ -86,7 +86,7 @@ impl<S> PipelineInfo<S> {
|
|||||||
PipelineInfo {
|
PipelineInfo {
|
||||||
req: UnsafeCell::new(req),
|
req: UnsafeCell::new(req),
|
||||||
count: 0,
|
count: 0,
|
||||||
mws: Rc::new(RefCell::new(Vec::new())),
|
mws: Rc::new(Vec::new()),
|
||||||
error: None,
|
error: None,
|
||||||
context: None,
|
context: None,
|
||||||
disconnected: None,
|
disconnected: None,
|
||||||
@ -123,8 +123,8 @@ impl<S> PipelineInfo<S> {
|
|||||||
|
|
||||||
impl<S: 'static, H: PipelineHandler<S>> Pipeline<S, H> {
|
impl<S: 'static, H: PipelineHandler<S>> Pipeline<S, H> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
req: HttpRequest<S>, mws: Rc<RefCell<Vec<Box<Middleware<S>>>>>,
|
req: HttpRequest<S>, mws: Rc<Vec<Box<Middleware<S>>>>, handler: Rc<H>,
|
||||||
handler: Rc<RefCell<H>>, htype: HandlerType,
|
htype: HandlerType,
|
||||||
) -> Pipeline<S, H> {
|
) -> Pipeline<S, H> {
|
||||||
let mut info = PipelineInfo {
|
let mut info = PipelineInfo {
|
||||||
mws,
|
mws,
|
||||||
@ -133,7 +133,7 @@ impl<S: 'static, H: PipelineHandler<S>> Pipeline<S, H> {
|
|||||||
error: None,
|
error: None,
|
||||||
context: None,
|
context: None,
|
||||||
disconnected: None,
|
disconnected: None,
|
||||||
encoding: handler.borrow().encoding(),
|
encoding: handler.encoding(),
|
||||||
};
|
};
|
||||||
let state = StartMiddlewares::init(&mut info, handler, htype);
|
let state = StartMiddlewares::init(&mut info, handler, htype);
|
||||||
|
|
||||||
@ -238,7 +238,7 @@ type Fut = Box<Future<Item = Option<HttpResponse>, Error = Error>>;
|
|||||||
|
|
||||||
/// Middlewares start executor
|
/// Middlewares start executor
|
||||||
struct StartMiddlewares<S, H> {
|
struct StartMiddlewares<S, H> {
|
||||||
hnd: Rc<RefCell<H>>,
|
hnd: Rc<H>,
|
||||||
htype: HandlerType,
|
htype: HandlerType,
|
||||||
fut: Option<Fut>,
|
fut: Option<Fut>,
|
||||||
_s: PhantomData<S>,
|
_s: PhantomData<S>,
|
||||||
@ -246,18 +246,17 @@ struct StartMiddlewares<S, H> {
|
|||||||
|
|
||||||
impl<S: 'static, H: PipelineHandler<S>> StartMiddlewares<S, H> {
|
impl<S: 'static, H: PipelineHandler<S>> StartMiddlewares<S, H> {
|
||||||
fn init(
|
fn init(
|
||||||
info: &mut PipelineInfo<S>, hnd: Rc<RefCell<H>>, htype: HandlerType,
|
info: &mut PipelineInfo<S>, hnd: Rc<H>, htype: HandlerType,
|
||||||
) -> PipelineState<S, H> {
|
) -> PipelineState<S, H> {
|
||||||
// execute middlewares, we need this stage because middlewares could be
|
// execute middlewares, we need this stage because middlewares could be
|
||||||
// non-async and we can move to next state immediately
|
// non-async and we can move to next state immediately
|
||||||
let len = info.mws.borrow().len() as u16;
|
let len = info.mws.len() as u16;
|
||||||
loop {
|
loop {
|
||||||
if info.count == len {
|
if info.count == len {
|
||||||
let reply = hnd.borrow_mut().handle(info.req().clone(), htype);
|
let reply = hnd.handle(info.req().clone(), htype);
|
||||||
return WaitingResponse::init(info, reply);
|
return WaitingResponse::init(info, reply);
|
||||||
} else {
|
} else {
|
||||||
let state =
|
let state = info.mws[info.count as usize].start(info.req_mut());
|
||||||
info.mws.borrow_mut()[info.count as usize].start(info.req_mut());
|
|
||||||
match state {
|
match state {
|
||||||
Ok(Started::Done) => info.count += 1,
|
Ok(Started::Done) => info.count += 1,
|
||||||
Ok(Started::Response(resp)) => {
|
Ok(Started::Response(resp)) => {
|
||||||
@ -278,7 +277,7 @@ impl<S: 'static, H: PipelineHandler<S>> StartMiddlewares<S, H> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&mut self, info: &mut PipelineInfo<S>) -> Option<PipelineState<S, H>> {
|
fn poll(&mut self, info: &mut PipelineInfo<S>) -> Option<PipelineState<S, H>> {
|
||||||
let len = info.mws.borrow().len() as u16;
|
let len = info.mws.len() as u16;
|
||||||
'outer: loop {
|
'outer: loop {
|
||||||
match self.fut.as_mut().unwrap().poll() {
|
match self.fut.as_mut().unwrap().poll() {
|
||||||
Ok(Async::NotReady) => return None,
|
Ok(Async::NotReady) => return None,
|
||||||
@ -289,14 +288,11 @@ impl<S: 'static, H: PipelineHandler<S>> StartMiddlewares<S, H> {
|
|||||||
}
|
}
|
||||||
loop {
|
loop {
|
||||||
if info.count == len {
|
if info.count == len {
|
||||||
let reply = self
|
let reply = self.hnd.handle(info.req().clone(), self.htype);
|
||||||
.hnd
|
|
||||||
.borrow_mut()
|
|
||||||
.handle(info.req().clone(), self.htype);
|
|
||||||
return Some(WaitingResponse::init(info, reply));
|
return Some(WaitingResponse::init(info, reply));
|
||||||
} else {
|
} else {
|
||||||
let state = info.mws.borrow_mut()[info.count as usize]
|
let state =
|
||||||
.start(info.req_mut());
|
info.mws[info.count as usize].start(info.req_mut());
|
||||||
match state {
|
match state {
|
||||||
Ok(Started::Done) => info.count += 1,
|
Ok(Started::Done) => info.count += 1,
|
||||||
Ok(Started::Response(resp)) => {
|
Ok(Started::Response(resp)) => {
|
||||||
@ -366,10 +362,10 @@ impl<S: 'static, H> RunMiddlewares<S, H> {
|
|||||||
return ProcessResponse::init(resp);
|
return ProcessResponse::init(resp);
|
||||||
}
|
}
|
||||||
let mut curr = 0;
|
let mut curr = 0;
|
||||||
let len = info.mws.borrow().len();
|
let len = info.mws.len();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let state = info.mws.borrow_mut()[curr].response(info.req_mut(), resp);
|
let state = info.mws[curr].response(info.req_mut(), resp);
|
||||||
resp = match state {
|
resp = match state {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
info.count = (curr + 1) as u16;
|
info.count = (curr + 1) as u16;
|
||||||
@ -396,7 +392,7 @@ impl<S: 'static, H> RunMiddlewares<S, H> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&mut self, info: &mut PipelineInfo<S>) -> Option<PipelineState<S, H>> {
|
fn poll(&mut self, info: &mut PipelineInfo<S>) -> Option<PipelineState<S, H>> {
|
||||||
let len = info.mws.borrow().len();
|
let len = info.mws.len();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// poll latest fut
|
// poll latest fut
|
||||||
@ -413,8 +409,7 @@ impl<S: 'static, H> RunMiddlewares<S, H> {
|
|||||||
if self.curr == len {
|
if self.curr == len {
|
||||||
return Some(ProcessResponse::init(resp));
|
return Some(ProcessResponse::init(resp));
|
||||||
} else {
|
} else {
|
||||||
let state =
|
let state = info.mws[self.curr].response(info.req_mut(), resp);
|
||||||
info.mws.borrow_mut()[self.curr].response(info.req_mut(), resp);
|
|
||||||
match state {
|
match state {
|
||||||
Err(err) => return Some(ProcessResponse::init(err.into())),
|
Err(err) => return Some(ProcessResponse::init(err.into())),
|
||||||
Ok(Response::Done(r)) => {
|
Ok(Response::Done(r)) => {
|
||||||
@ -739,8 +734,7 @@ impl<S: 'static, H> FinishingMiddlewares<S, H> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
info.count -= 1;
|
info.count -= 1;
|
||||||
let state = info.mws.borrow_mut()[info.count as usize]
|
let state = info.mws[info.count as usize].finish(info.req_mut(), &self.resp);
|
||||||
.finish(info.req_mut(), &self.resp);
|
|
||||||
match state {
|
match state {
|
||||||
Finished::Done => {
|
Finished::Done => {
|
||||||
if info.count == 0 {
|
if info.count == 0 {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use std::cell::RefCell;
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -38,7 +37,7 @@ pub struct ResourceHandler<S = ()> {
|
|||||||
name: String,
|
name: String,
|
||||||
state: PhantomData<S>,
|
state: PhantomData<S>,
|
||||||
routes: SmallVec<[Route<S>; 3]>,
|
routes: SmallVec<[Route<S>; 3]>,
|
||||||
middlewares: Rc<RefCell<Vec<Box<Middleware<S>>>>>,
|
middlewares: Rc<Vec<Box<Middleware<S>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Default for ResourceHandler<S> {
|
impl<S> Default for ResourceHandler<S> {
|
||||||
@ -47,7 +46,7 @@ impl<S> Default for ResourceHandler<S> {
|
|||||||
name: String::new(),
|
name: String::new(),
|
||||||
state: PhantomData,
|
state: PhantomData,
|
||||||
routes: SmallVec::new(),
|
routes: SmallVec::new(),
|
||||||
middlewares: Rc::new(RefCell::new(Vec::new())),
|
middlewares: Rc::new(Vec::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,7 +57,7 @@ impl<S> ResourceHandler<S> {
|
|||||||
name: String::new(),
|
name: String::new(),
|
||||||
state: PhantomData,
|
state: PhantomData,
|
||||||
routes: SmallVec::new(),
|
routes: SmallVec::new(),
|
||||||
middlewares: Rc::new(RefCell::new(Vec::new())),
|
middlewares: Rc::new(Vec::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +276,6 @@ impl<S: 'static> ResourceHandler<S> {
|
|||||||
pub fn middleware<M: Middleware<S>>(&mut self, mw: M) {
|
pub fn middleware<M: Middleware<S>>(&mut self, mw: M) {
|
||||||
Rc::get_mut(&mut self.middlewares)
|
Rc::get_mut(&mut self.middlewares)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.borrow_mut()
|
|
||||||
.push(Box::new(mw));
|
.push(Box::new(mw));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,7 +284,7 @@ impl<S: 'static> ResourceHandler<S> {
|
|||||||
) -> Result<AsyncResult<HttpResponse>, HttpRequest<S>> {
|
) -> Result<AsyncResult<HttpResponse>, HttpRequest<S>> {
|
||||||
for route in &self.routes {
|
for route in &self.routes {
|
||||||
if route.check(&mut req) {
|
if route.check(&mut req) {
|
||||||
return if self.middlewares.borrow().is_empty() {
|
return if self.middlewares.is_empty() {
|
||||||
Ok(route.handle(req))
|
Ok(route.handle(req))
|
||||||
} else {
|
} else {
|
||||||
Ok(route.compose(req, Rc::clone(&self.middlewares)))
|
Ok(route.compose(req, Rc::clone(&self.middlewares)))
|
||||||
|
29
src/route.rs
29
src/route.rs
@ -1,4 +1,4 @@
|
|||||||
use std::cell::{RefCell, UnsafeCell};
|
use std::cell::UnsafeCell;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ impl<S: 'static> Route<S> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn compose(
|
pub(crate) fn compose(
|
||||||
&self, req: HttpRequest<S>, mws: Rc<RefCell<Vec<Box<Middleware<S>>>>>,
|
&self, req: HttpRequest<S>, mws: Rc<Vec<Box<Middleware<S>>>>,
|
||||||
) -> AsyncResult<HttpResponse> {
|
) -> AsyncResult<HttpResponse> {
|
||||||
AsyncResult::async(Box::new(Compose::new(req, mws, self.handler.clone())))
|
AsyncResult::async(Box::new(Compose::new(req, mws, self.handler.clone())))
|
||||||
}
|
}
|
||||||
@ -340,7 +340,7 @@ struct Compose<S: 'static> {
|
|||||||
struct ComposeInfo<S: 'static> {
|
struct ComposeInfo<S: 'static> {
|
||||||
count: usize,
|
count: usize,
|
||||||
req: HttpRequest<S>,
|
req: HttpRequest<S>,
|
||||||
mws: Rc<RefCell<Vec<Box<Middleware<S>>>>>,
|
mws: Rc<Vec<Box<Middleware<S>>>>,
|
||||||
handler: InnerHandler<S>,
|
handler: InnerHandler<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,8 +366,7 @@ impl<S: 'static> ComposeState<S> {
|
|||||||
|
|
||||||
impl<S: 'static> Compose<S> {
|
impl<S: 'static> Compose<S> {
|
||||||
fn new(
|
fn new(
|
||||||
req: HttpRequest<S>, mws: Rc<RefCell<Vec<Box<Middleware<S>>>>>,
|
req: HttpRequest<S>, mws: Rc<Vec<Box<Middleware<S>>>>, handler: InnerHandler<S>,
|
||||||
handler: InnerHandler<S>,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut info = ComposeInfo {
|
let mut info = ComposeInfo {
|
||||||
count: 0,
|
count: 0,
|
||||||
@ -410,13 +409,13 @@ type Fut = Box<Future<Item = Option<HttpResponse>, Error = Error>>;
|
|||||||
|
|
||||||
impl<S: 'static> StartMiddlewares<S> {
|
impl<S: 'static> StartMiddlewares<S> {
|
||||||
fn init(info: &mut ComposeInfo<S>) -> ComposeState<S> {
|
fn init(info: &mut ComposeInfo<S>) -> ComposeState<S> {
|
||||||
let len = info.mws.borrow().len();
|
let len = info.mws.len();
|
||||||
loop {
|
loop {
|
||||||
if info.count == len {
|
if info.count == len {
|
||||||
let reply = info.handler.handle(info.req.clone());
|
let reply = info.handler.handle(info.req.clone());
|
||||||
return WaitingResponse::init(info, reply);
|
return WaitingResponse::init(info, reply);
|
||||||
} else {
|
} else {
|
||||||
let state = info.mws.borrow_mut()[info.count].start(&mut info.req);
|
let state = info.mws[info.count].start(&mut info.req);
|
||||||
match state {
|
match state {
|
||||||
Ok(MiddlewareStarted::Done) => info.count += 1,
|
Ok(MiddlewareStarted::Done) => info.count += 1,
|
||||||
Ok(MiddlewareStarted::Response(resp)) => {
|
Ok(MiddlewareStarted::Response(resp)) => {
|
||||||
@ -435,7 +434,7 @@ impl<S: 'static> StartMiddlewares<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&mut self, info: &mut ComposeInfo<S>) -> Option<ComposeState<S>> {
|
fn poll(&mut self, info: &mut ComposeInfo<S>) -> Option<ComposeState<S>> {
|
||||||
let len = info.mws.borrow().len();
|
let len = info.mws.len();
|
||||||
'outer: loop {
|
'outer: loop {
|
||||||
match self.fut.as_mut().unwrap().poll() {
|
match self.fut.as_mut().unwrap().poll() {
|
||||||
Ok(Async::NotReady) => return None,
|
Ok(Async::NotReady) => return None,
|
||||||
@ -449,8 +448,7 @@ impl<S: 'static> StartMiddlewares<S> {
|
|||||||
let reply = info.handler.handle(info.req.clone());
|
let reply = info.handler.handle(info.req.clone());
|
||||||
return Some(WaitingResponse::init(info, reply));
|
return Some(WaitingResponse::init(info, reply));
|
||||||
} else {
|
} else {
|
||||||
let state =
|
let state = info.mws[info.count].start(&mut info.req);
|
||||||
info.mws.borrow_mut()[info.count].start(&mut info.req);
|
|
||||||
match state {
|
match state {
|
||||||
Ok(MiddlewareStarted::Done) => info.count += 1,
|
Ok(MiddlewareStarted::Done) => info.count += 1,
|
||||||
Ok(MiddlewareStarted::Response(resp)) => {
|
Ok(MiddlewareStarted::Response(resp)) => {
|
||||||
@ -513,10 +511,10 @@ struct RunMiddlewares<S> {
|
|||||||
impl<S: 'static> RunMiddlewares<S> {
|
impl<S: 'static> RunMiddlewares<S> {
|
||||||
fn init(info: &mut ComposeInfo<S>, mut resp: HttpResponse) -> ComposeState<S> {
|
fn init(info: &mut ComposeInfo<S>, mut resp: HttpResponse) -> ComposeState<S> {
|
||||||
let mut curr = 0;
|
let mut curr = 0;
|
||||||
let len = info.mws.borrow().len();
|
let len = info.mws.len();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let state = info.mws.borrow_mut()[curr].response(&mut info.req, resp);
|
let state = info.mws[curr].response(&mut info.req, resp);
|
||||||
resp = match state {
|
resp = match state {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
info.count = curr + 1;
|
info.count = curr + 1;
|
||||||
@ -542,7 +540,7 @@ impl<S: 'static> RunMiddlewares<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&mut self, info: &mut ComposeInfo<S>) -> Option<ComposeState<S>> {
|
fn poll(&mut self, info: &mut ComposeInfo<S>) -> Option<ComposeState<S>> {
|
||||||
let len = info.mws.borrow().len();
|
let len = info.mws.len();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// poll latest fut
|
// poll latest fut
|
||||||
@ -559,8 +557,7 @@ impl<S: 'static> RunMiddlewares<S> {
|
|||||||
if self.curr == len {
|
if self.curr == len {
|
||||||
return Some(FinishingMiddlewares::init(info, resp));
|
return Some(FinishingMiddlewares::init(info, resp));
|
||||||
} else {
|
} else {
|
||||||
let state =
|
let state = info.mws[self.curr].response(&mut info.req, resp);
|
||||||
info.mws.borrow_mut()[self.curr].response(&mut info.req, resp);
|
|
||||||
match state {
|
match state {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return Some(FinishingMiddlewares::init(info, err.into()))
|
return Some(FinishingMiddlewares::init(info, err.into()))
|
||||||
@ -630,7 +627,7 @@ impl<S: 'static> FinishingMiddlewares<S> {
|
|||||||
|
|
||||||
info.count -= 1;
|
info.count -= 1;
|
||||||
|
|
||||||
let state = info.mws.borrow_mut()[info.count as usize]
|
let state = info.mws[info.count as usize]
|
||||||
.finish(&mut info.req, self.resp.as_ref().unwrap());
|
.finish(&mut info.req, self.resp.as_ref().unwrap());
|
||||||
match state {
|
match state {
|
||||||
MiddlewareFinished::Done => {
|
MiddlewareFinished::Done => {
|
||||||
|
77
src/scope.rs
77
src/scope.rs
@ -1,4 +1,4 @@
|
|||||||
use std::cell::{RefCell, UnsafeCell};
|
use std::cell::UnsafeCell;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -57,7 +57,7 @@ type NestedInfo<S> = (Resource, Route<S>, Vec<Box<Predicate<S>>>);
|
|||||||
pub struct Scope<S: 'static> {
|
pub struct Scope<S: 'static> {
|
||||||
filters: Vec<Box<Predicate<S>>>,
|
filters: Vec<Box<Predicate<S>>>,
|
||||||
nested: Vec<NestedInfo<S>>,
|
nested: Vec<NestedInfo<S>>,
|
||||||
middlewares: Rc<RefCell<Vec<Box<Middleware<S>>>>>,
|
middlewares: Rc<Vec<Box<Middleware<S>>>>,
|
||||||
default: Option<ScopeResource<S>>,
|
default: Option<ScopeResource<S>>,
|
||||||
resources: ScopeResources<S>,
|
resources: ScopeResources<S>,
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ impl<S: 'static> Scope<S> {
|
|||||||
filters: Vec::new(),
|
filters: Vec::new(),
|
||||||
nested: Vec::new(),
|
nested: Vec::new(),
|
||||||
resources: Rc::new(Vec::new()),
|
resources: Rc::new(Vec::new()),
|
||||||
middlewares: Rc::new(RefCell::new(Vec::new())),
|
middlewares: Rc::new(Vec::new()),
|
||||||
default: None,
|
default: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ impl<S: 'static> Scope<S> {
|
|||||||
filters: Vec::new(),
|
filters: Vec::new(),
|
||||||
nested: Vec::new(),
|
nested: Vec::new(),
|
||||||
resources: Rc::new(Vec::new()),
|
resources: Rc::new(Vec::new()),
|
||||||
middlewares: Rc::new(RefCell::new(Vec::new())),
|
middlewares: Rc::new(Vec::new()),
|
||||||
default: None,
|
default: None,
|
||||||
};
|
};
|
||||||
let mut scope = f(scope);
|
let mut scope = f(scope);
|
||||||
@ -178,7 +178,7 @@ impl<S: 'static> Scope<S> {
|
|||||||
filters: Vec::new(),
|
filters: Vec::new(),
|
||||||
nested: Vec::new(),
|
nested: Vec::new(),
|
||||||
resources: Rc::new(Vec::new()),
|
resources: Rc::new(Vec::new()),
|
||||||
middlewares: Rc::new(RefCell::new(Vec::new())),
|
middlewares: Rc::new(Vec::new()),
|
||||||
default: None,
|
default: None,
|
||||||
};
|
};
|
||||||
let mut scope = f(scope);
|
let mut scope = f(scope);
|
||||||
@ -332,7 +332,6 @@ impl<S: 'static> Scope<S> {
|
|||||||
pub fn middleware<M: Middleware<S>>(mut self, mw: M) -> Scope<S> {
|
pub fn middleware<M: Middleware<S>>(mut self, mw: M) -> Scope<S> {
|
||||||
Rc::get_mut(&mut self.middlewares)
|
Rc::get_mut(&mut self.middlewares)
|
||||||
.expect("Can not use after configuration")
|
.expect("Can not use after configuration")
|
||||||
.borrow_mut()
|
|
||||||
.push(Box::new(mw));
|
.push(Box::new(mw));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -345,7 +344,7 @@ impl<S: 'static> RouteHandler<S> for Scope<S> {
|
|||||||
// recognize resources
|
// recognize resources
|
||||||
for &(ref pattern, ref resource) in self.resources.iter() {
|
for &(ref pattern, ref resource) in self.resources.iter() {
|
||||||
if pattern.match_with_params(&mut req, tail, false) {
|
if pattern.match_with_params(&mut req, tail, false) {
|
||||||
if self.middlewares.borrow().is_empty() {
|
if self.middlewares.is_empty() {
|
||||||
return match resource.handle(req) {
|
return match resource.handle(req) {
|
||||||
Ok(result) => result,
|
Ok(result) => result,
|
||||||
Err(req) => {
|
Err(req) => {
|
||||||
@ -393,7 +392,7 @@ impl<S: 'static> RouteHandler<S> for Scope<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// default handler
|
// default handler
|
||||||
if self.middlewares.borrow().is_empty() {
|
if self.middlewares.is_empty() {
|
||||||
if let Some(ref default) = self.default {
|
if let Some(ref default) = self.default {
|
||||||
match default.handle(req) {
|
match default.handle(req) {
|
||||||
Ok(result) => result,
|
Ok(result) => result,
|
||||||
@ -459,7 +458,7 @@ struct Compose<S: 'static> {
|
|||||||
struct ComposeInfo<S: 'static> {
|
struct ComposeInfo<S: 'static> {
|
||||||
count: usize,
|
count: usize,
|
||||||
req: HttpRequest<S>,
|
req: HttpRequest<S>,
|
||||||
mws: Rc<RefCell<Vec<Box<Middleware<S>>>>>,
|
mws: Rc<Vec<Box<Middleware<S>>>>,
|
||||||
resource: Rc<ResourceHandler<S>>,
|
resource: Rc<ResourceHandler<S>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,7 +484,7 @@ impl<S: 'static> ComposeState<S> {
|
|||||||
|
|
||||||
impl<S: 'static> Compose<S> {
|
impl<S: 'static> Compose<S> {
|
||||||
fn new(
|
fn new(
|
||||||
req: HttpRequest<S>, mws: Rc<RefCell<Vec<Box<Middleware<S>>>>>,
|
req: HttpRequest<S>, mws: Rc<Vec<Box<Middleware<S>>>>,
|
||||||
resource: Rc<ResourceHandler<S>>,
|
resource: Rc<ResourceHandler<S>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut info = ComposeInfo {
|
let mut info = ComposeInfo {
|
||||||
@ -529,7 +528,7 @@ type Fut = Box<Future<Item = Option<HttpResponse>, Error = Error>>;
|
|||||||
|
|
||||||
impl<S: 'static> StartMiddlewares<S> {
|
impl<S: 'static> StartMiddlewares<S> {
|
||||||
fn init(info: &mut ComposeInfo<S>) -> ComposeState<S> {
|
fn init(info: &mut ComposeInfo<S>) -> ComposeState<S> {
|
||||||
let len = info.mws.borrow().len();
|
let len = info.mws.len();
|
||||||
loop {
|
loop {
|
||||||
if info.count == len {
|
if info.count == len {
|
||||||
let reply = {
|
let reply = {
|
||||||
@ -538,7 +537,7 @@ impl<S: 'static> StartMiddlewares<S> {
|
|||||||
};
|
};
|
||||||
return WaitingResponse::init(info, reply);
|
return WaitingResponse::init(info, reply);
|
||||||
} else {
|
} else {
|
||||||
let state = info.mws.borrow_mut()[info.count].start(&mut info.req);
|
let state = info.mws[info.count].start(&mut info.req);
|
||||||
match state {
|
match state {
|
||||||
Ok(MiddlewareStarted::Done) => info.count += 1,
|
Ok(MiddlewareStarted::Done) => info.count += 1,
|
||||||
Ok(MiddlewareStarted::Response(resp)) => {
|
Ok(MiddlewareStarted::Response(resp)) => {
|
||||||
@ -557,7 +556,7 @@ impl<S: 'static> StartMiddlewares<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&mut self, info: &mut ComposeInfo<S>) -> Option<ComposeState<S>> {
|
fn poll(&mut self, info: &mut ComposeInfo<S>) -> Option<ComposeState<S>> {
|
||||||
let len = info.mws.borrow().len();
|
let len = info.mws.len();
|
||||||
'outer: loop {
|
'outer: loop {
|
||||||
match self.fut.as_mut().unwrap().poll() {
|
match self.fut.as_mut().unwrap().poll() {
|
||||||
Ok(Async::NotReady) => return None,
|
Ok(Async::NotReady) => return None,
|
||||||
@ -574,8 +573,7 @@ impl<S: 'static> StartMiddlewares<S> {
|
|||||||
};
|
};
|
||||||
return Some(WaitingResponse::init(info, reply));
|
return Some(WaitingResponse::init(info, reply));
|
||||||
} else {
|
} else {
|
||||||
let state =
|
let state = info.mws[info.count].start(&mut info.req);
|
||||||
info.mws.borrow_mut()[info.count].start(&mut info.req);
|
|
||||||
match state {
|
match state {
|
||||||
Ok(MiddlewareStarted::Done) => info.count += 1,
|
Ok(MiddlewareStarted::Done) => info.count += 1,
|
||||||
Ok(MiddlewareStarted::Response(resp)) => {
|
Ok(MiddlewareStarted::Response(resp)) => {
|
||||||
@ -638,10 +636,10 @@ struct RunMiddlewares<S> {
|
|||||||
impl<S: 'static> RunMiddlewares<S> {
|
impl<S: 'static> RunMiddlewares<S> {
|
||||||
fn init(info: &mut ComposeInfo<S>, mut resp: HttpResponse) -> ComposeState<S> {
|
fn init(info: &mut ComposeInfo<S>, mut resp: HttpResponse) -> ComposeState<S> {
|
||||||
let mut curr = 0;
|
let mut curr = 0;
|
||||||
let len = info.mws.borrow().len();
|
let len = info.mws.len();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let state = info.mws.borrow_mut()[curr].response(&mut info.req, resp);
|
let state = info.mws[curr].response(&mut info.req, resp);
|
||||||
resp = match state {
|
resp = match state {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
info.count = curr + 1;
|
info.count = curr + 1;
|
||||||
@ -667,7 +665,7 @@ impl<S: 'static> RunMiddlewares<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&mut self, info: &mut ComposeInfo<S>) -> Option<ComposeState<S>> {
|
fn poll(&mut self, info: &mut ComposeInfo<S>) -> Option<ComposeState<S>> {
|
||||||
let len = info.mws.borrow().len();
|
let len = info.mws.len();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// poll latest fut
|
// poll latest fut
|
||||||
@ -684,8 +682,7 @@ impl<S: 'static> RunMiddlewares<S> {
|
|||||||
if self.curr == len {
|
if self.curr == len {
|
||||||
return Some(FinishingMiddlewares::init(info, resp));
|
return Some(FinishingMiddlewares::init(info, resp));
|
||||||
} else {
|
} else {
|
||||||
let state =
|
let state = info.mws[self.curr].response(&mut info.req, resp);
|
||||||
info.mws.borrow_mut()[self.curr].response(&mut info.req, resp);
|
|
||||||
match state {
|
match state {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return Some(FinishingMiddlewares::init(info, err.into()))
|
return Some(FinishingMiddlewares::init(info, err.into()))
|
||||||
@ -754,7 +751,7 @@ impl<S: 'static> FinishingMiddlewares<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
info.count -= 1;
|
info.count -= 1;
|
||||||
let state = info.mws.borrow_mut()[info.count as usize]
|
let state = info.mws[info.count as usize]
|
||||||
.finish(&mut info.req, self.resp.as_ref().unwrap());
|
.finish(&mut info.req, self.resp.as_ref().unwrap());
|
||||||
match state {
|
match state {
|
||||||
MiddlewareFinished::Done => {
|
MiddlewareFinished::Done => {
|
||||||
@ -798,7 +795,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scope() {
|
fn test_scope() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app", |scope| {
|
.scope("/app", |scope| {
|
||||||
scope.resource("/path1", |r| r.f(|_| HttpResponse::Ok()))
|
scope.resource("/path1", |r| r.f(|_| HttpResponse::Ok()))
|
||||||
})
|
})
|
||||||
@ -811,7 +808,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scope_root() {
|
fn test_scope_root() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app", |scope| {
|
.scope("/app", |scope| {
|
||||||
scope
|
scope
|
||||||
.resource("", |r| r.f(|_| HttpResponse::Ok()))
|
.resource("", |r| r.f(|_| HttpResponse::Ok()))
|
||||||
@ -830,7 +827,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scope_root2() {
|
fn test_scope_root2() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app/", |scope| {
|
.scope("/app/", |scope| {
|
||||||
scope.resource("", |r| r.f(|_| HttpResponse::Ok()))
|
scope.resource("", |r| r.f(|_| HttpResponse::Ok()))
|
||||||
})
|
})
|
||||||
@ -847,7 +844,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scope_root3() {
|
fn test_scope_root3() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app/", |scope| {
|
.scope("/app/", |scope| {
|
||||||
scope.resource("/", |r| r.f(|_| HttpResponse::Ok()))
|
scope.resource("/", |r| r.f(|_| HttpResponse::Ok()))
|
||||||
})
|
})
|
||||||
@ -864,7 +861,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scope_route() {
|
fn test_scope_route() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("app", |scope| {
|
.scope("app", |scope| {
|
||||||
scope
|
scope
|
||||||
.route("/path1", Method::GET, |_: HttpRequest<_>| {
|
.route("/path1", Method::GET, |_: HttpRequest<_>| {
|
||||||
@ -895,7 +892,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scope_filter() {
|
fn test_scope_filter() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app", |scope| {
|
.scope("/app", |scope| {
|
||||||
scope
|
scope
|
||||||
.filter(pred::Get())
|
.filter(pred::Get())
|
||||||
@ -918,7 +915,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_scope_variable_segment() {
|
fn test_scope_variable_segment() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/ab-{project}", |scope| {
|
.scope("/ab-{project}", |scope| {
|
||||||
scope.resource("/path1", |r| {
|
scope.resource("/path1", |r| {
|
||||||
r.f(|r| {
|
r.f(|r| {
|
||||||
@ -950,7 +947,7 @@ mod tests {
|
|||||||
fn test_scope_with_state() {
|
fn test_scope_with_state() {
|
||||||
struct State;
|
struct State;
|
||||||
|
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app", |scope| {
|
.scope("/app", |scope| {
|
||||||
scope.with_state("/t1", State, |scope| {
|
scope.with_state("/t1", State, |scope| {
|
||||||
scope.resource("/path1", |r| r.f(|_| HttpResponse::Created()))
|
scope.resource("/path1", |r| r.f(|_| HttpResponse::Created()))
|
||||||
@ -967,7 +964,7 @@ mod tests {
|
|||||||
fn test_scope_with_state_root() {
|
fn test_scope_with_state_root() {
|
||||||
struct State;
|
struct State;
|
||||||
|
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app", |scope| {
|
.scope("/app", |scope| {
|
||||||
scope.with_state("/t1", State, |scope| {
|
scope.with_state("/t1", State, |scope| {
|
||||||
scope
|
scope
|
||||||
@ -990,7 +987,7 @@ mod tests {
|
|||||||
fn test_scope_with_state_root2() {
|
fn test_scope_with_state_root2() {
|
||||||
struct State;
|
struct State;
|
||||||
|
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app", |scope| {
|
.scope("/app", |scope| {
|
||||||
scope.with_state("/t1/", State, |scope| {
|
scope.with_state("/t1/", State, |scope| {
|
||||||
scope.resource("", |r| r.f(|_| HttpResponse::Ok()))
|
scope.resource("", |r| r.f(|_| HttpResponse::Ok()))
|
||||||
@ -1011,7 +1008,7 @@ mod tests {
|
|||||||
fn test_scope_with_state_root3() {
|
fn test_scope_with_state_root3() {
|
||||||
struct State;
|
struct State;
|
||||||
|
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app", |scope| {
|
.scope("/app", |scope| {
|
||||||
scope.with_state("/t1/", State, |scope| {
|
scope.with_state("/t1/", State, |scope| {
|
||||||
scope.resource("/", |r| r.f(|_| HttpResponse::Ok()))
|
scope.resource("/", |r| r.f(|_| HttpResponse::Ok()))
|
||||||
@ -1032,7 +1029,7 @@ mod tests {
|
|||||||
fn test_scope_with_state_filter() {
|
fn test_scope_with_state_filter() {
|
||||||
struct State;
|
struct State;
|
||||||
|
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app", |scope| {
|
.scope("/app", |scope| {
|
||||||
scope.with_state("/t1", State, |scope| {
|
scope.with_state("/t1", State, |scope| {
|
||||||
scope
|
scope
|
||||||
@ -1057,7 +1054,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_nested_scope() {
|
fn test_nested_scope() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app", |scope| {
|
.scope("/app", |scope| {
|
||||||
scope.nested("/t1", |scope| {
|
scope.nested("/t1", |scope| {
|
||||||
scope.resource("/path1", |r| r.f(|_| HttpResponse::Created()))
|
scope.resource("/path1", |r| r.f(|_| HttpResponse::Created()))
|
||||||
@ -1072,7 +1069,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_nested_scope_root() {
|
fn test_nested_scope_root() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app", |scope| {
|
.scope("/app", |scope| {
|
||||||
scope.nested("/t1", |scope| {
|
scope.nested("/t1", |scope| {
|
||||||
scope
|
scope
|
||||||
@ -1093,7 +1090,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_nested_scope_filter() {
|
fn test_nested_scope_filter() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app", |scope| {
|
.scope("/app", |scope| {
|
||||||
scope.nested("/t1", |scope| {
|
scope.nested("/t1", |scope| {
|
||||||
scope
|
scope
|
||||||
@ -1118,7 +1115,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_nested_scope_with_variable_segment() {
|
fn test_nested_scope_with_variable_segment() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app", |scope| {
|
.scope("/app", |scope| {
|
||||||
scope.nested("/{project_id}", |scope| {
|
scope.nested("/{project_id}", |scope| {
|
||||||
scope.resource("/path1", |r| {
|
scope.resource("/path1", |r| {
|
||||||
@ -1148,7 +1145,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_nested2_scope_with_variable_segment() {
|
fn test_nested2_scope_with_variable_segment() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app", |scope| {
|
.scope("/app", |scope| {
|
||||||
scope.nested("/{project}", |scope| {
|
scope.nested("/{project}", |scope| {
|
||||||
scope.nested("/{id}", |scope| {
|
scope.nested("/{id}", |scope| {
|
||||||
@ -1185,7 +1182,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_default_resource() {
|
fn test_default_resource() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app", |scope| {
|
.scope("/app", |scope| {
|
||||||
scope
|
scope
|
||||||
.resource("/path1", |r| r.f(|_| HttpResponse::Ok()))
|
.resource("/path1", |r| r.f(|_| HttpResponse::Ok()))
|
||||||
@ -1204,7 +1201,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_default_resource_propagation() {
|
fn test_default_resource_propagation() {
|
||||||
let mut app = App::new()
|
let app = App::new()
|
||||||
.scope("/app1", |scope| {
|
.scope("/app1", |scope| {
|
||||||
scope.default_resource(|r| r.f(|_| HttpResponse::BadRequest()))
|
scope.default_resource(|r| r.f(|_| HttpResponse::BadRequest()))
|
||||||
})
|
})
|
||||||
|
@ -564,7 +564,7 @@ impl<S: 'static> TestRequest<S> {
|
|||||||
/// with generated request.
|
/// with generated request.
|
||||||
///
|
///
|
||||||
/// This method panics is handler returns actor or async result.
|
/// This method panics is handler returns actor or async result.
|
||||||
pub fn run<H: Handler<S>>(self, h: H) -> Result<HttpResponse, Error> {
|
pub fn run<H: Handler<S>>(self, h: &H) -> Result<HttpResponse, Error> {
|
||||||
let req = self.finish();
|
let req = self.finish();
|
||||||
let resp = h.handle(req.clone());
|
let resp = h.handle(req.clone());
|
||||||
|
|
||||||
|
@ -20,23 +20,21 @@ struct MiddlewareTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<S> middleware::Middleware<S> for MiddlewareTest {
|
impl<S> middleware::Middleware<S> for MiddlewareTest {
|
||||||
fn start(&mut self, _: &mut HttpRequest<S>) -> Result<middleware::Started> {
|
fn start(&self, _: &mut HttpRequest<S>) -> Result<middleware::Started> {
|
||||||
self.start
|
self.start
|
||||||
.store(self.start.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
|
.store(self.start.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
|
||||||
Ok(middleware::Started::Done)
|
Ok(middleware::Started::Done)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn response(
|
fn response(
|
||||||
&mut self, _: &mut HttpRequest<S>, resp: HttpResponse,
|
&self, _: &mut HttpRequest<S>, resp: HttpResponse,
|
||||||
) -> Result<middleware::Response> {
|
) -> Result<middleware::Response> {
|
||||||
self.response
|
self.response
|
||||||
.store(self.response.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
|
.store(self.response.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
|
||||||
Ok(middleware::Response::Done(resp))
|
Ok(middleware::Response::Done(resp))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(
|
fn finish(&self, _: &mut HttpRequest<S>, _: &HttpResponse) -> middleware::Finished {
|
||||||
&mut self, _: &mut HttpRequest<S>, _: &HttpResponse,
|
|
||||||
) -> middleware::Finished {
|
|
||||||
self.finish
|
self.finish
|
||||||
.store(self.finish.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
|
.store(self.finish.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
|
||||||
middleware::Finished::Done
|
middleware::Finished::Done
|
||||||
@ -434,7 +432,7 @@ struct MiddlewareAsyncTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<S> middleware::Middleware<S> for MiddlewareAsyncTest {
|
impl<S> middleware::Middleware<S> for MiddlewareAsyncTest {
|
||||||
fn start(&mut self, _: &mut HttpRequest<S>) -> Result<middleware::Started> {
|
fn start(&self, _: &mut HttpRequest<S>) -> Result<middleware::Started> {
|
||||||
let to = Delay::new(Instant::now() + Duration::from_millis(10));
|
let to = Delay::new(Instant::now() + Duration::from_millis(10));
|
||||||
|
|
||||||
let start = Arc::clone(&self.start);
|
let start = Arc::clone(&self.start);
|
||||||
@ -447,7 +445,7 @@ impl<S> middleware::Middleware<S> for MiddlewareAsyncTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn response(
|
fn response(
|
||||||
&mut self, _: &mut HttpRequest<S>, resp: HttpResponse,
|
&self, _: &mut HttpRequest<S>, resp: HttpResponse,
|
||||||
) -> Result<middleware::Response> {
|
) -> Result<middleware::Response> {
|
||||||
let to = Delay::new(Instant::now() + Duration::from_millis(10));
|
let to = Delay::new(Instant::now() + Duration::from_millis(10));
|
||||||
|
|
||||||
@ -460,9 +458,7 @@ impl<S> middleware::Middleware<S> for MiddlewareAsyncTest {
|
|||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(
|
fn finish(&self, _: &mut HttpRequest<S>, _: &HttpResponse) -> middleware::Finished {
|
||||||
&mut self, _: &mut HttpRequest<S>, _: &HttpResponse,
|
|
||||||
) -> middleware::Finished {
|
|
||||||
let to = Delay::new(Instant::now() + Duration::from_millis(10));
|
let to = Delay::new(Instant::now() + Duration::from_millis(10));
|
||||||
|
|
||||||
let finish = Arc::clone(&self.finish);
|
let finish = Arc::clone(&self.finish);
|
||||||
@ -797,9 +793,7 @@ fn test_async_sync_resource_middleware_multiple() {
|
|||||||
struct MiddlewareWithErr;
|
struct MiddlewareWithErr;
|
||||||
|
|
||||||
impl<S> middleware::Middleware<S> for MiddlewareWithErr {
|
impl<S> middleware::Middleware<S> for MiddlewareWithErr {
|
||||||
fn start(
|
fn start(&self, _req: &mut HttpRequest<S>) -> Result<middleware::Started, Error> {
|
||||||
&mut self, _req: &mut HttpRequest<S>,
|
|
||||||
) -> Result<middleware::Started, Error> {
|
|
||||||
Err(ErrorInternalServerError("middleware error"))
|
Err(ErrorInternalServerError("middleware error"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -807,9 +801,7 @@ impl<S> middleware::Middleware<S> for MiddlewareWithErr {
|
|||||||
struct MiddlewareAsyncWithErr;
|
struct MiddlewareAsyncWithErr;
|
||||||
|
|
||||||
impl<S> middleware::Middleware<S> for MiddlewareAsyncWithErr {
|
impl<S> middleware::Middleware<S> for MiddlewareAsyncWithErr {
|
||||||
fn start(
|
fn start(&self, _req: &mut HttpRequest<S>) -> Result<middleware::Started, Error> {
|
||||||
&mut self, _req: &mut HttpRequest<S>,
|
|
||||||
) -> Result<middleware::Started, Error> {
|
|
||||||
Ok(middleware::Started::Future(Box::new(future::err(
|
Ok(middleware::Started::Future(Box::new(future::err(
|
||||||
ErrorInternalServerError("middleware error"),
|
ErrorInternalServerError("middleware error"),
|
||||||
))))
|
))))
|
||||||
|
Loading…
Reference in New Issue
Block a user