1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-27 17:52:56 +01:00

allow middlware error result

This commit is contained in:
Nikolay Kim 2017-11-25 10:24:45 -08:00
parent 54bbc98343
commit 45ecb87eab
5 changed files with 37 additions and 23 deletions

View File

@ -13,6 +13,8 @@ pub use self::session::{RequestSession, Session, SessionImpl,
/// Middleware start result /// Middleware start result
pub enum Started { pub enum Started {
/// Moddleware error
Err(Error),
/// Execution completed /// Execution completed
Done(HttpRequest), Done(HttpRequest),
/// New http response got generated. If middleware generates response /// New http response got generated. If middleware generates response
@ -24,8 +26,10 @@ pub enum Started {
/// Middleware execution result /// Middleware execution result
pub enum Response { pub enum Response {
/// Moddleware error
Err(Error),
/// New http response got generated /// New http response got generated
Response(HttpResponse), Done(HttpResponse),
/// Result is a future that resolves to a new http response /// Result is a future that resolves to a new http response
Future(Box<Future<Item=HttpResponse, Error=Error>>), Future(Box<Future<Item=HttpResponse, Error=Error>>),
} }
@ -49,12 +53,12 @@ pub trait Middleware {
} }
/// Method is called when handler returns response, /// Method is called when handler returns response,
/// but before sending body stream to peer. /// but before sending http message to peer.
fn response(&self, req: &mut HttpRequest, resp: HttpResponse) -> Response { fn response(&self, req: &mut HttpRequest, resp: HttpResponse) -> Response {
Response::Response(resp) Response::Done(resp)
} }
/// Method is called after http response get sent to peer. /// Method is called after body stream get sent to peer.
fn finish(&self, req: &mut HttpRequest, resp: &HttpResponse) -> Finished { fn finish(&self, req: &mut HttpRequest, resp: &HttpResponse) -> Finished {
Finished::Done Finished::Done
} }

View File

@ -106,7 +106,7 @@ impl<T: SessionBackend> Middleware for SessionStorage<T> {
if let Some(s_box) = req.extensions().remove::<Arc<SessionImplBox>>() { if let Some(s_box) = req.extensions().remove::<Arc<SessionImplBox>>() {
s_box.0.write(resp) s_box.0.write(resp)
} else { } else {
Response::Response(resp) Response::Done(resp)
} }
} }
} }
@ -151,7 +151,7 @@ impl SessionImpl for DummySessionImpl {
fn remove(&mut self, key: &str) {} fn remove(&mut self, key: &str) {}
fn clear(&mut self) {} fn clear(&mut self) {}
fn write(&self, resp: HttpResponse) -> Response { fn write(&self, resp: HttpResponse) -> Response {
Response::Response(resp) Response::Done(resp)
} }
} }
@ -176,7 +176,7 @@ impl SessionImpl for CookieSession {
} }
fn clear(&mut self) { fn clear(&mut self) {
let cookies: Vec<_> = self.jar.iter().map(|c| c.clone()).collect(); let cookies: Vec<_> = self.jar.iter().cloned().collect();
for cookie in cookies { for cookie in cookies {
self.jar.remove(cookie); self.jar.remove(cookie);
} }
@ -185,11 +185,11 @@ impl SessionImpl for CookieSession {
fn write(&self, mut resp: HttpResponse) -> Response { fn write(&self, mut resp: HttpResponse) -> Response {
for cookie in self.jar.delta() { for cookie in self.jar.delta() {
match HeaderValue::from_str(&cookie.to_string()) { match HeaderValue::from_str(&cookie.to_string()) {
Err(err) => return Response::Response(err.error_response()), Err(err) => return Response::Err(err.into()),
Ok(val) => resp.headers.append(header::SET_COOKIE, val), Ok(val) => resp.headers.append(header::SET_COOKIE, val),
}; };
} }
Response::Response(resp) Response::Done(resp)
} }
} }

View File

@ -309,6 +309,7 @@ impl Start {
Err(err) => return Err(err) Err(err) => return Err(err)
} }
}, },
Started::Err(err) => return Err(err),
} }
} }
} }
@ -348,6 +349,7 @@ impl Start {
self.fut = Some(fut); self.fut = Some(fut);
continue 'outer continue 'outer
}, },
Started::Err(err) => return Err(err),
} }
} }
} }
@ -375,13 +377,15 @@ impl MiddlewaresResponse {
} }
pub fn response(&mut self, req: &mut HttpRequest, mut resp: HttpResponse) pub fn response(&mut self, req: &mut HttpRequest, mut resp: HttpResponse)
-> Option<HttpResponse> -> Result<Option<HttpResponse>, Error>
{ {
loop { loop {
resp = match self.middlewares[self.idx].response(req, resp) { resp = match self.middlewares[self.idx].response(req, resp) {
Response::Response(r) => { Response::Err(err) =>
return Err(err),
Response::Done(r) => {
if self.idx == 0 { if self.idx == 0 {
return Some(r) return Ok(Some(r))
} else { } else {
self.idx -= 1; self.idx -= 1;
r r
@ -389,7 +393,7 @@ impl MiddlewaresResponse {
}, },
Response::Future(fut) => { Response::Future(fut) => {
self.fut = Some(fut); self.fut = Some(fut);
return None return Ok(None)
}, },
}; };
} }
@ -417,7 +421,9 @@ impl MiddlewaresResponse {
return Ok(Async::Ready(Some(resp))) return Ok(Async::Ready(Some(resp)))
} else { } else {
match self.middlewares[self.idx].response(req, resp) { match self.middlewares[self.idx].response(req, resp) {
Response::Response(r) => { Response::Err(err) =>
return Err(err),
Response::Done(r) => {
self.idx -= 1; self.idx -= 1;
resp = r resp = r
}, },

View File

@ -218,15 +218,19 @@ impl Task {
Frame::Message(mut resp) => { Frame::Message(mut resp) => {
// run middlewares // run middlewares
if let Some(mut middlewares) = self.middlewares.take() { if let Some(mut middlewares) = self.middlewares.take() {
if let Some(mut resp) = middlewares.response(req, resp) { match middlewares.response(req, resp) {
Ok(Some(mut resp)) => {
let result = io.start(req, &mut resp)?; let result = io.start(req, &mut resp)?;
self.prepared = Some(resp); self.prepared = Some(resp);
result result
} else { }
Ok(None) => {
// middlewares need to run some futures // middlewares need to run some futures
self.middlewares = Some(middlewares); self.middlewares = Some(middlewares);
return self.poll_io(io, req) return self.poll_io(io, req)
} }
Err(err) => return Err(err),
}
} else { } else {
let result = io.start(req, &mut resp)?; let result = io.start(req, &mut resp)?;
self.prepared = Some(resp); self.prepared = Some(resp);

View File

@ -68,7 +68,7 @@ impl middlewares::Middleware for MiddlewareTest {
fn response(&self, _: &mut HttpRequest, resp: HttpResponse) -> middlewares::Response { fn response(&self, _: &mut HttpRequest, resp: HttpResponse) -> middlewares::Response {
self.response.store(self.response.load(Ordering::Relaxed) + 1, Ordering::Relaxed); self.response.store(self.response.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
middlewares::Response::Response(resp) middlewares::Response::Done(resp)
} }
fn finish(&self, _: &mut HttpRequest, _: &HttpResponse) -> middlewares::Finished { fn finish(&self, _: &mut HttpRequest, _: &HttpResponse) -> middlewares::Finished {