mirror of
https://github.com/actix/actix-extras.git
synced 2025-06-25 18:09:22 +02:00
fix panic during middleware execution #226
This commit is contained in:
@ -284,12 +284,12 @@ impl<S: 'static, H: PipelineHandler<S>> StartMiddlewares<S, H> {
|
||||
if let Some(resp) = resp {
|
||||
return Some(RunMiddlewares::init(info, resp));
|
||||
}
|
||||
if info.count == len {
|
||||
let reply = unsafe { &mut *self.hnd.get() }
|
||||
.handle(info.req().clone(), self.htype);
|
||||
return Some(WaitingResponse::init(info, reply));
|
||||
} else {
|
||||
loop {
|
||||
loop {
|
||||
if info.count == len {
|
||||
let reply = unsafe { &mut *self.hnd.get() }
|
||||
.handle(info.req().clone(), self.htype);
|
||||
return Some(WaitingResponse::init(info, reply));
|
||||
} else {
|
||||
match info.mws[info.count as usize].start(info.req_mut()) {
|
||||
Ok(Started::Done) => info.count += 1,
|
||||
Ok(Started::Response(resp)) => {
|
||||
|
47
src/route.rs
47
src/route.rs
@ -5,13 +5,17 @@ use std::rc::Rc;
|
||||
use futures::{Async, Future, Poll};
|
||||
|
||||
use error::Error;
|
||||
use handler::{AsyncHandler, AsyncResult, AsyncResultItem, FromRequest, Handler,
|
||||
Responder, RouteHandler, WrapHandler};
|
||||
use handler::{
|
||||
AsyncHandler, AsyncResult, AsyncResultItem, FromRequest, Handler, Responder,
|
||||
RouteHandler, WrapHandler,
|
||||
};
|
||||
use http::StatusCode;
|
||||
use httprequest::HttpRequest;
|
||||
use httpresponse::HttpResponse;
|
||||
use middleware::{Finished as MiddlewareFinished, Middleware,
|
||||
Response as MiddlewareResponse, Started as MiddlewareStarted};
|
||||
use middleware::{
|
||||
Finished as MiddlewareFinished, Middleware, Response as MiddlewareResponse,
|
||||
Started as MiddlewareStarted,
|
||||
};
|
||||
use pred::Predicate;
|
||||
use with::{ExtractorConfig, With, With2, With3, WithAsync};
|
||||
|
||||
@ -51,7 +55,9 @@ impl<S: 'static> Route<S> {
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn compose(
|
||||
&mut self, req: HttpRequest<S>, mws: Rc<Vec<Box<Middleware<S>>>>,
|
||||
&mut self,
|
||||
req: HttpRequest<S>,
|
||||
mws: Rc<Vec<Box<Middleware<S>>>>,
|
||||
) -> AsyncResult<HttpResponse> {
|
||||
AsyncResult::async(Box::new(Compose::new(req, mws, self.handler.clone())))
|
||||
}
|
||||
@ -242,7 +248,8 @@ impl<S: 'static> Route<S> {
|
||||
/// }
|
||||
/// ```
|
||||
pub fn with2<T1, T2, F, R>(
|
||||
&mut self, handler: F,
|
||||
&mut self,
|
||||
handler: F,
|
||||
) -> (ExtractorConfig<S, T1>, ExtractorConfig<S, T2>)
|
||||
where
|
||||
F: Fn(T1, T2) -> R + 'static,
|
||||
@ -263,7 +270,8 @@ impl<S: 'static> Route<S> {
|
||||
#[doc(hidden)]
|
||||
/// Set handler function, use request extractor for all parameters.
|
||||
pub fn with3<T1, T2, T3, F, R>(
|
||||
&mut self, handler: F,
|
||||
&mut self,
|
||||
handler: F,
|
||||
) -> (
|
||||
ExtractorConfig<S, T1>,
|
||||
ExtractorConfig<S, T2>,
|
||||
@ -296,9 +304,7 @@ struct InnerHandler<S>(Rc<UnsafeCell<Box<RouteHandler<S>>>>);
|
||||
impl<S: 'static> InnerHandler<S> {
|
||||
#[inline]
|
||||
fn new<H: Handler<S>>(h: H) -> Self {
|
||||
InnerHandler(Rc::new(UnsafeCell::new(Box::new(WrapHandler::new(
|
||||
h,
|
||||
)))))
|
||||
InnerHandler(Rc::new(UnsafeCell::new(Box::new(WrapHandler::new(h)))))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -309,9 +315,7 @@ impl<S: 'static> InnerHandler<S> {
|
||||
R: Responder + 'static,
|
||||
E: Into<Error> + 'static,
|
||||
{
|
||||
InnerHandler(Rc::new(UnsafeCell::new(Box::new(AsyncHandler::new(
|
||||
h,
|
||||
)))))
|
||||
InnerHandler(Rc::new(UnsafeCell::new(Box::new(AsyncHandler::new(h)))))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -364,7 +368,9 @@ impl<S: 'static> ComposeState<S> {
|
||||
|
||||
impl<S: 'static> Compose<S> {
|
||||
fn new(
|
||||
req: HttpRequest<S>, mws: Rc<Vec<Box<Middleware<S>>>>, handler: InnerHandler<S>,
|
||||
req: HttpRequest<S>,
|
||||
mws: Rc<Vec<Box<Middleware<S>>>>,
|
||||
handler: InnerHandler<S>,
|
||||
) -> Self {
|
||||
let mut info = ComposeInfo {
|
||||
count: 0,
|
||||
@ -440,11 +446,11 @@ impl<S: 'static> StartMiddlewares<S> {
|
||||
if let Some(resp) = resp {
|
||||
return Some(RunMiddlewares::init(info, resp));
|
||||
}
|
||||
if info.count == len {
|
||||
let reply = info.handler.handle(info.req.clone());
|
||||
return Some(WaitingResponse::init(info, reply));
|
||||
} else {
|
||||
loop {
|
||||
loop {
|
||||
if info.count == len {
|
||||
let reply = info.handler.handle(info.req.clone());
|
||||
return Some(WaitingResponse::init(info, reply));
|
||||
} else {
|
||||
match info.mws[info.count].start(&mut info.req) {
|
||||
Ok(MiddlewareStarted::Done) => info.count += 1,
|
||||
Ok(MiddlewareStarted::Response(resp)) => {
|
||||
@ -479,7 +485,8 @@ struct WaitingResponse<S> {
|
||||
impl<S: 'static> WaitingResponse<S> {
|
||||
#[inline]
|
||||
fn init(
|
||||
info: &mut ComposeInfo<S>, reply: AsyncResult<HttpResponse>,
|
||||
info: &mut ComposeInfo<S>,
|
||||
reply: AsyncResult<HttpResponse>,
|
||||
) -> ComposeState<S> {
|
||||
match reply.into() {
|
||||
AsyncResultItem::Err(err) => RunMiddlewares::init(info, err.into()),
|
||||
|
35
src/scope.rs
35
src/scope.rs
@ -10,8 +10,10 @@ use handler::{AsyncResult, AsyncResultItem, FromRequest, Responder, RouteHandler
|
||||
use http::Method;
|
||||
use httprequest::HttpRequest;
|
||||
use httpresponse::HttpResponse;
|
||||
use middleware::{Finished as MiddlewareFinished, Middleware,
|
||||
Response as MiddlewareResponse, Started as MiddlewareStarted};
|
||||
use middleware::{
|
||||
Finished as MiddlewareFinished, Middleware, Response as MiddlewareResponse,
|
||||
Started as MiddlewareStarted,
|
||||
};
|
||||
use pred::Predicate;
|
||||
use resource::ResourceHandler;
|
||||
use router::Resource;
|
||||
@ -400,8 +402,7 @@ struct Wrapper<S: 'static> {
|
||||
|
||||
impl<S: 'static, S2: 'static> RouteHandler<S2> for Wrapper<S> {
|
||||
fn handle(&mut self, req: HttpRequest<S2>) -> AsyncResult<HttpResponse> {
|
||||
self.scope
|
||||
.handle(req.change_state(Rc::clone(&self.state)))
|
||||
self.scope.handle(req.change_state(Rc::clone(&self.state)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -458,7 +459,8 @@ impl<S: 'static> ComposeState<S> {
|
||||
|
||||
impl<S: 'static> Compose<S> {
|
||||
fn new(
|
||||
req: HttpRequest<S>, mws: Rc<Vec<Box<Middleware<S>>>>,
|
||||
req: HttpRequest<S>,
|
||||
mws: Rc<Vec<Box<Middleware<S>>>>,
|
||||
resource: Rc<UnsafeCell<ResourceHandler<S>>>,
|
||||
default: Option<Rc<UnsafeCell<ResourceHandler<S>>>>,
|
||||
) -> Self {
|
||||
@ -543,17 +545,17 @@ impl<S: 'static> StartMiddlewares<S> {
|
||||
if let Some(resp) = resp {
|
||||
return Some(RunMiddlewares::init(info, resp));
|
||||
}
|
||||
if info.count == len {
|
||||
let resource = unsafe { &mut *info.resource.get() };
|
||||
let reply = if let Some(ref default) = info.default {
|
||||
let d = unsafe { &mut *default.as_ref().get() };
|
||||
resource.handle(info.req.clone(), Some(d))
|
||||
loop {
|
||||
if info.count == len {
|
||||
let resource = unsafe { &mut *info.resource.get() };
|
||||
let reply = if let Some(ref default) = info.default {
|
||||
let d = unsafe { &mut *default.as_ref().get() };
|
||||
resource.handle(info.req.clone(), Some(d))
|
||||
} else {
|
||||
resource.handle(info.req.clone(), None)
|
||||
};
|
||||
return Some(WaitingResponse::init(info, reply));
|
||||
} else {
|
||||
resource.handle(info.req.clone(), None)
|
||||
};
|
||||
return Some(WaitingResponse::init(info, reply));
|
||||
} else {
|
||||
loop {
|
||||
match info.mws[info.count].start(&mut info.req) {
|
||||
Ok(MiddlewareStarted::Done) => info.count += 1,
|
||||
Ok(MiddlewareStarted::Response(resp)) => {
|
||||
@ -583,7 +585,8 @@ struct WaitingResponse<S> {
|
||||
impl<S: 'static> WaitingResponse<S> {
|
||||
#[inline]
|
||||
fn init(
|
||||
info: &mut ComposeInfo<S>, reply: AsyncResult<HttpResponse>,
|
||||
info: &mut ComposeInfo<S>,
|
||||
reply: AsyncResult<HttpResponse>,
|
||||
) -> ComposeState<S> {
|
||||
match reply.into() {
|
||||
AsyncResultItem::Ok(resp) => RunMiddlewares::init(info, resp),
|
||||
|
Reference in New Issue
Block a user