2017-12-09 14:54:04 +01:00
|
|
|
use std::marker::PhantomData;
|
2018-04-14 01:02:01 +02:00
|
|
|
use std::rc::Rc;
|
|
|
|
use std::{io, mem};
|
2017-11-25 07:15:52 +01:00
|
|
|
|
2018-05-30 01:32:39 +02:00
|
|
|
use futures::sync::oneshot;
|
2018-04-14 01:02:01 +02:00
|
|
|
use futures::{Async, Future, Poll, Stream};
|
|
|
|
use log::Level::Debug;
|
2017-11-25 07:15:52 +01:00
|
|
|
|
2017-12-02 00:45:15 +01:00
|
|
|
use body::{Body, BodyStream};
|
2018-04-14 01:02:01 +02:00
|
|
|
use context::{ActorHttpContext, Frame};
|
2018-01-01 02:26:32 +01:00
|
|
|
use error::Error;
|
2018-05-04 01:22:08 +02:00
|
|
|
use handler::{AsyncResult, AsyncResultItem};
|
2018-04-14 01:02:01 +02:00
|
|
|
use header::ContentEncoding;
|
2017-11-25 07:15:52 +01:00
|
|
|
use httprequest::HttpRequest;
|
2018-06-25 06:10:02 +02:00
|
|
|
use httpresponse::HttpResponse;
|
2018-04-14 01:02:01 +02:00
|
|
|
use middleware::{Finished, Middleware, Response, Started};
|
2018-07-04 17:01:27 +02:00
|
|
|
use server::{HttpHandlerTask, Writer, WriterState};
|
2017-11-25 07:15:52 +01:00
|
|
|
|
2018-06-18 01:45:54 +02:00
|
|
|
#[doc(hidden)]
|
|
|
|
pub trait PipelineHandler<S> {
|
2018-02-19 07:23:17 +01:00
|
|
|
fn encoding(&self) -> ContentEncoding;
|
|
|
|
|
2018-07-15 11:12:21 +02:00
|
|
|
fn handle(&self, &HttpRequest<S>) -> AsyncResult<HttpResponse>;
|
2017-12-29 10:01:31 +01:00
|
|
|
}
|
2017-11-25 07:15:52 +01:00
|
|
|
|
2018-06-18 01:45:54 +02:00
|
|
|
#[doc(hidden)]
|
2018-06-25 06:58:04 +02:00
|
|
|
pub struct Pipeline<S: 'static, H>(
|
2018-06-21 19:51:25 +02:00
|
|
|
PipelineInfo<S>,
|
|
|
|
PipelineState<S, H>,
|
|
|
|
Rc<Vec<Box<Middleware<S>>>>,
|
|
|
|
);
|
2017-11-25 07:15:52 +01:00
|
|
|
|
2017-12-29 10:01:31 +01:00
|
|
|
enum PipelineState<S, H> {
|
2017-11-25 07:15:52 +01:00
|
|
|
None,
|
2017-12-02 00:45:15 +01:00
|
|
|
Error,
|
2017-12-29 10:01:31 +01:00
|
|
|
Starting(StartMiddlewares<S, H>),
|
|
|
|
Handler(WaitingResponse<S, H>),
|
|
|
|
RunMiddlewares(RunMiddlewares<S, H>),
|
|
|
|
Response(ProcessResponse<S, H>),
|
|
|
|
Finishing(FinishingMiddlewares<S, H>),
|
|
|
|
Completed(Completed<S, H>),
|
2017-11-25 07:15:52 +01:00
|
|
|
}
|
|
|
|
|
2018-01-11 01:45:57 +01:00
|
|
|
impl<S: 'static, H: PipelineHandler<S>> PipelineState<S, H> {
|
2018-06-21 19:51:25 +02:00
|
|
|
fn poll(
|
|
|
|
&mut self, info: &mut PipelineInfo<S>, mws: &[Box<Middleware<S>>],
|
|
|
|
) -> Option<PipelineState<S, H>> {
|
2018-01-11 01:45:57 +01:00
|
|
|
match *self {
|
2018-06-21 19:51:25 +02:00
|
|
|
PipelineState::Starting(ref mut state) => state.poll(info, mws),
|
|
|
|
PipelineState::Handler(ref mut state) => state.poll(info, mws),
|
|
|
|
PipelineState::RunMiddlewares(ref mut state) => state.poll(info, mws),
|
|
|
|
PipelineState::Finishing(ref mut state) => state.poll(info, mws),
|
2018-01-11 01:45:57 +01:00
|
|
|
PipelineState::Completed(ref mut state) => state.poll(info),
|
2018-08-08 05:48:25 +02:00
|
|
|
PipelineState::Response(ref mut state) => state.poll(info, mws),
|
|
|
|
PipelineState::None | PipelineState::Error => {
|
2018-04-14 01:02:01 +02:00
|
|
|
None
|
|
|
|
}
|
2018-01-11 01:45:57 +01:00
|
|
|
}
|
|
|
|
}
|
2018-04-14 01:02:01 +02:00
|
|
|
}
|
2018-01-11 01:45:57 +01:00
|
|
|
|
2018-06-25 06:58:04 +02:00
|
|
|
struct PipelineInfo<S: 'static> {
|
2018-06-21 19:51:25 +02:00
|
|
|
req: HttpRequest<S>,
|
2018-01-21 05:12:24 +01:00
|
|
|
count: u16,
|
2018-01-01 02:26:32 +01:00
|
|
|
context: Option<Box<ActorHttpContext>>,
|
2017-12-02 00:45:15 +01:00
|
|
|
error: Option<Error>,
|
2018-01-03 08:43:17 +01:00
|
|
|
disconnected: Option<bool>,
|
2018-02-19 07:23:17 +01:00
|
|
|
encoding: ContentEncoding,
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
|
2018-06-25 06:58:04 +02:00
|
|
|
impl<S: 'static> PipelineInfo<S> {
|
2017-12-02 00:45:15 +01:00
|
|
|
fn poll_context(&mut self) -> Poll<(), Error> {
|
|
|
|
if let Some(ref mut context) = self.context {
|
|
|
|
match context.poll() {
|
|
|
|
Err(err) => Err(err),
|
|
|
|
Ok(Async::NotReady) => Ok(Async::NotReady),
|
|
|
|
Ok(Async::Ready(_)) => Ok(Async::Ready(())),
|
2017-11-25 07:15:52 +01:00
|
|
|
}
|
2017-12-02 00:45:15 +01:00
|
|
|
} else {
|
|
|
|
Ok(Async::Ready(()))
|
2017-11-25 07:15:52 +01:00
|
|
|
}
|
|
|
|
}
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
2017-11-25 07:15:52 +01:00
|
|
|
|
2018-01-10 05:00:18 +01:00
|
|
|
impl<S: 'static, H: PipelineHandler<S>> Pipeline<S, H> {
|
2018-08-16 15:11:15 +02:00
|
|
|
pub(crate) fn new(
|
2018-06-21 19:06:23 +02:00
|
|
|
req: HttpRequest<S>, mws: Rc<Vec<Box<Middleware<S>>>>, handler: Rc<H>,
|
2018-04-14 01:02:01 +02:00
|
|
|
) -> Pipeline<S, H> {
|
2017-12-09 14:54:04 +01:00
|
|
|
let mut info = PipelineInfo {
|
2018-06-21 19:51:25 +02:00
|
|
|
req,
|
2017-12-09 14:54:04 +01:00
|
|
|
count: 0,
|
|
|
|
error: None,
|
|
|
|
context: None,
|
2018-01-03 08:43:17 +01:00
|
|
|
disconnected: None,
|
2018-06-21 19:06:23 +02:00
|
|
|
encoding: handler.encoding(),
|
2017-12-09 14:54:04 +01:00
|
|
|
};
|
2018-07-15 11:12:21 +02:00
|
|
|
let state = StartMiddlewares::init(&mut info, &mws, handler);
|
2017-12-09 14:54:04 +01:00
|
|
|
|
2018-06-21 19:51:25 +02:00
|
|
|
Pipeline(info, state, mws)
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
2017-12-09 13:33:40 +01:00
|
|
|
}
|
2017-12-02 00:45:15 +01:00
|
|
|
|
2018-01-10 05:00:18 +01:00
|
|
|
impl<S: 'static, H> Pipeline<S, H> {
|
2018-05-16 01:41:46 +02:00
|
|
|
#[inline]
|
2017-12-09 14:54:04 +01:00
|
|
|
fn is_done(&self) -> bool {
|
|
|
|
match self.1 {
|
2018-04-14 01:02:01 +02:00
|
|
|
PipelineState::None
|
|
|
|
| PipelineState::Error
|
|
|
|
| PipelineState::Starting(_)
|
|
|
|
| PipelineState::Handler(_)
|
|
|
|
| PipelineState::RunMiddlewares(_)
|
|
|
|
| PipelineState::Response(_) => true,
|
2018-01-11 01:45:57 +01:00
|
|
|
PipelineState::Finishing(_) | PipelineState::Completed(_) => false,
|
2017-12-09 14:54:04 +01:00
|
|
|
}
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
2017-12-09 13:33:40 +01:00
|
|
|
}
|
|
|
|
|
2018-01-10 05:00:18 +01:00
|
|
|
impl<S: 'static, H: PipelineHandler<S>> HttpHandlerTask for Pipeline<S, H> {
|
2017-12-09 13:33:40 +01:00
|
|
|
fn disconnected(&mut self) {
|
2018-01-03 08:43:17 +01:00
|
|
|
self.0.disconnected = Some(true);
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
2017-11-25 07:15:52 +01:00
|
|
|
|
2017-12-09 13:33:40 +01:00
|
|
|
fn poll_io(&mut self, io: &mut Writer) -> Poll<bool, Error> {
|
2018-06-19 21:27:41 +02:00
|
|
|
let mut state = mem::replace(&mut self.1, PipelineState::None);
|
2018-01-11 01:45:57 +01:00
|
|
|
|
2017-11-25 07:15:52 +01:00
|
|
|
loop {
|
2018-08-08 05:48:25 +02:00
|
|
|
if let PipelineState::Response(st) = state {
|
|
|
|
match st.poll_io(io, &mut self.0, &self.2) {
|
|
|
|
Ok(state) => {
|
|
|
|
self.1 = state;
|
|
|
|
if let Some(error) = self.0.error.take() {
|
|
|
|
return Err(error);
|
|
|
|
} else {
|
|
|
|
return Ok(Async::Ready(self.is_done()));
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
}
|
2018-08-08 05:48:25 +02:00
|
|
|
Err(state) => {
|
|
|
|
self.1 = state;
|
|
|
|
return Ok(Async::NotReady);
|
|
|
|
}
|
2017-11-25 07:15:52 +01:00
|
|
|
}
|
|
|
|
}
|
2018-06-19 21:27:41 +02:00
|
|
|
match state {
|
2018-04-14 01:02:01 +02:00
|
|
|
PipelineState::None => return Ok(Async::Ready(true)),
|
|
|
|
PipelineState::Error => {
|
2018-05-16 01:41:46 +02:00
|
|
|
return Err(
|
|
|
|
io::Error::new(io::ErrorKind::Other, "Internal error").into()
|
|
|
|
)
|
2018-04-14 01:02:01 +02:00
|
|
|
}
|
2018-01-11 01:45:57 +01:00
|
|
|
_ => (),
|
|
|
|
}
|
|
|
|
|
2018-06-21 19:51:25 +02:00
|
|
|
match state.poll(&mut self.0, &self.2) {
|
2018-06-19 21:27:41 +02:00
|
|
|
Some(st) => state = st,
|
|
|
|
None => {
|
|
|
|
return {
|
|
|
|
self.1 = state;
|
|
|
|
Ok(Async::NotReady)
|
|
|
|
}
|
|
|
|
}
|
2018-01-11 01:45:57 +01:00
|
|
|
}
|
2017-11-25 07:15:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-18 01:45:54 +02:00
|
|
|
fn poll_completed(&mut self) -> Poll<(), Error> {
|
2018-06-19 21:27:41 +02:00
|
|
|
let mut state = mem::replace(&mut self.1, PipelineState::None);
|
2017-11-25 07:15:52 +01:00
|
|
|
loop {
|
2018-06-19 21:27:41 +02:00
|
|
|
match state {
|
2017-12-02 00:45:15 +01:00
|
|
|
PipelineState::None | PipelineState::Error => {
|
|
|
|
return Ok(Async::Ready(()))
|
|
|
|
}
|
2018-01-11 01:45:57 +01:00
|
|
|
_ => (),
|
|
|
|
}
|
|
|
|
|
2018-06-21 19:51:25 +02:00
|
|
|
if let Some(st) = state.poll(&mut self.0, &self.2) {
|
2018-06-19 21:27:41 +02:00
|
|
|
state = st;
|
2018-01-11 01:45:57 +01:00
|
|
|
} else {
|
2018-06-19 21:27:41 +02:00
|
|
|
self.1 = state;
|
2018-01-11 01:45:57 +01:00
|
|
|
return Ok(Async::NotReady);
|
2017-11-25 07:15:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-14 01:02:01 +02:00
|
|
|
type Fut = Box<Future<Item = Option<HttpResponse>, Error = Error>>;
|
2017-11-25 07:15:52 +01:00
|
|
|
|
|
|
|
/// Middlewares start executor
|
2017-12-29 10:01:31 +01:00
|
|
|
struct StartMiddlewares<S, H> {
|
2018-06-21 19:06:23 +02:00
|
|
|
hnd: Rc<H>,
|
2017-11-25 07:15:52 +01:00
|
|
|
fut: Option<Fut>,
|
2017-12-29 10:01:31 +01:00
|
|
|
_s: PhantomData<S>,
|
2017-11-25 07:15:52 +01:00
|
|
|
}
|
|
|
|
|
2018-01-10 05:00:18 +01:00
|
|
|
impl<S: 'static, H: PipelineHandler<S>> StartMiddlewares<S, H> {
|
2018-04-14 01:02:01 +02:00
|
|
|
fn init(
|
2018-06-21 19:51:25 +02:00
|
|
|
info: &mut PipelineInfo<S>, mws: &[Box<Middleware<S>>], hnd: Rc<H>,
|
2018-04-14 01:02:01 +02:00
|
|
|
) -> PipelineState<S, H> {
|
|
|
|
// execute middlewares, we need this stage because middlewares could be
|
|
|
|
// non-async and we can move to next state immediately
|
2018-06-21 19:51:25 +02:00
|
|
|
let len = mws.len() as u16;
|
2018-06-25 06:58:04 +02:00
|
|
|
|
2017-11-25 07:15:52 +01:00
|
|
|
loop {
|
2017-12-02 00:45:15 +01:00
|
|
|
if info.count == len {
|
2018-07-15 11:12:21 +02:00
|
|
|
let reply = hnd.handle(&info.req);
|
2018-06-21 19:51:25 +02:00
|
|
|
return WaitingResponse::init(info, mws, reply);
|
2017-11-25 07:15:52 +01:00
|
|
|
} else {
|
2018-06-25 06:58:04 +02:00
|
|
|
match mws[info.count as usize].start(&info.req) {
|
2018-04-14 01:02:01 +02:00
|
|
|
Ok(Started::Done) => info.count += 1,
|
|
|
|
Ok(Started::Response(resp)) => {
|
2018-06-25 06:58:04 +02:00
|
|
|
return RunMiddlewares::init(info, mws, resp);
|
2018-04-14 01:02:01 +02:00
|
|
|
}
|
2018-05-08 01:09:41 +02:00
|
|
|
Ok(Started::Future(fut)) => {
|
|
|
|
return PipelineState::Starting(StartMiddlewares {
|
|
|
|
hnd,
|
|
|
|
fut: Some(fut),
|
|
|
|
_s: PhantomData,
|
|
|
|
})
|
|
|
|
}
|
2018-06-25 06:58:04 +02:00
|
|
|
Err(err) => {
|
|
|
|
return RunMiddlewares::init(info, mws, err.into());
|
|
|
|
}
|
2017-11-25 07:15:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-21 19:51:25 +02:00
|
|
|
fn poll(
|
|
|
|
&mut self, info: &mut PipelineInfo<S>, mws: &[Box<Middleware<S>>],
|
|
|
|
) -> Option<PipelineState<S, H>> {
|
|
|
|
let len = mws.len() as u16;
|
2018-06-25 06:58:04 +02:00
|
|
|
|
2017-11-25 07:15:52 +01:00
|
|
|
'outer: loop {
|
|
|
|
match self.fut.as_mut().unwrap().poll() {
|
2018-06-25 06:58:04 +02:00
|
|
|
Ok(Async::NotReady) => {
|
|
|
|
return None;
|
|
|
|
}
|
2017-11-27 06:47:33 +01:00
|
|
|
Ok(Async::Ready(resp)) => {
|
2017-12-09 14:54:04 +01:00
|
|
|
info.count += 1;
|
2017-11-25 07:15:52 +01:00
|
|
|
if let Some(resp) = resp {
|
2018-06-21 19:51:25 +02:00
|
|
|
return Some(RunMiddlewares::init(info, mws, resp));
|
2017-11-25 07:15:52 +01:00
|
|
|
}
|
2018-05-16 20:00:29 +02:00
|
|
|
loop {
|
|
|
|
if info.count == len {
|
2018-07-15 11:12:21 +02:00
|
|
|
let reply = self.hnd.handle(&info.req);
|
2018-06-21 19:51:25 +02:00
|
|
|
return Some(WaitingResponse::init(info, mws, reply));
|
2018-05-16 20:00:29 +02:00
|
|
|
} else {
|
2018-06-25 06:58:04 +02:00
|
|
|
let res = mws[info.count as usize].start(&info.req);
|
|
|
|
match res {
|
2018-04-14 01:02:01 +02:00
|
|
|
Ok(Started::Done) => info.count += 1,
|
2018-01-10 07:48:35 +01:00
|
|
|
Ok(Started::Response(resp)) => {
|
2018-06-21 19:51:25 +02:00
|
|
|
return Some(RunMiddlewares::init(info, mws, resp));
|
2018-04-14 01:02:01 +02:00
|
|
|
}
|
2018-01-10 07:48:35 +01:00
|
|
|
Ok(Started::Future(fut)) => {
|
2017-11-25 07:15:52 +01:00
|
|
|
self.fut = Some(fut);
|
2018-04-14 01:02:01 +02:00
|
|
|
continue 'outer;
|
|
|
|
}
|
|
|
|
Err(err) => {
|
2018-06-21 19:51:25 +02:00
|
|
|
return Some(RunMiddlewares::init(
|
|
|
|
info,
|
|
|
|
mws,
|
|
|
|
err.into(),
|
2018-06-25 06:58:04 +02:00
|
|
|
));
|
2018-04-14 01:02:01 +02:00
|
|
|
}
|
2017-11-25 07:15:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-06-25 06:58:04 +02:00
|
|
|
Err(err) => {
|
|
|
|
return Some(RunMiddlewares::init(info, mws, err.into()));
|
|
|
|
}
|
2017-11-25 07:15:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-02 00:45:15 +01:00
|
|
|
// waiting for response
|
2017-12-29 10:01:31 +01:00
|
|
|
struct WaitingResponse<S, H> {
|
2018-04-14 01:02:01 +02:00
|
|
|
fut: Box<Future<Item = HttpResponse, Error = Error>>,
|
2017-12-09 14:54:04 +01:00
|
|
|
_s: PhantomData<S>,
|
2017-12-29 10:01:31 +01:00
|
|
|
_h: PhantomData<H>,
|
2017-11-25 21:05:27 +01:00
|
|
|
}
|
|
|
|
|
2018-01-10 05:00:18 +01:00
|
|
|
impl<S: 'static, H> WaitingResponse<S, H> {
|
2017-12-16 05:00:12 +01:00
|
|
|
#[inline]
|
2018-05-02 02:19:15 +02:00
|
|
|
fn init(
|
2018-06-21 19:51:25 +02:00
|
|
|
info: &mut PipelineInfo<S>, mws: &[Box<Middleware<S>>],
|
|
|
|
reply: AsyncResult<HttpResponse>,
|
2018-05-02 02:19:15 +02:00
|
|
|
) -> PipelineState<S, H> {
|
2017-12-16 05:00:12 +01:00
|
|
|
match reply.into() {
|
2018-06-21 19:51:25 +02:00
|
|
|
AsyncResultItem::Ok(resp) => RunMiddlewares::init(info, mws, resp),
|
2018-06-25 06:58:04 +02:00
|
|
|
AsyncResultItem::Err(err) => RunMiddlewares::init(info, mws, err.into()),
|
2018-05-04 01:22:08 +02:00
|
|
|
AsyncResultItem::Future(fut) => PipelineState::Handler(WaitingResponse {
|
2018-04-14 01:02:01 +02:00
|
|
|
fut,
|
|
|
|
_s: PhantomData,
|
|
|
|
_h: PhantomData,
|
|
|
|
}),
|
2017-12-16 05:00:12 +01:00
|
|
|
}
|
2017-11-25 21:05:27 +01:00
|
|
|
}
|
|
|
|
|
2018-06-21 19:51:25 +02:00
|
|
|
fn poll(
|
|
|
|
&mut self, info: &mut PipelineInfo<S>, mws: &[Box<Middleware<S>>],
|
|
|
|
) -> Option<PipelineState<S, H>> {
|
2018-01-01 02:26:32 +01:00
|
|
|
match self.fut.poll() {
|
2018-01-11 01:45:57 +01:00
|
|
|
Ok(Async::NotReady) => None,
|
2018-06-25 06:58:04 +02:00
|
|
|
Ok(Async::Ready(resp)) => Some(RunMiddlewares::init(info, mws, resp)),
|
2018-06-21 19:51:25 +02:00
|
|
|
Err(err) => Some(RunMiddlewares::init(info, mws, err.into())),
|
2017-11-25 21:05:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-25 07:15:52 +01:00
|
|
|
/// Middlewares response executor
|
2017-12-29 10:01:31 +01:00
|
|
|
struct RunMiddlewares<S, H> {
|
2017-12-02 00:45:15 +01:00
|
|
|
curr: usize,
|
2018-04-14 01:02:01 +02:00
|
|
|
fut: Option<Box<Future<Item = HttpResponse, Error = Error>>>,
|
2017-12-09 14:54:04 +01:00
|
|
|
_s: PhantomData<S>,
|
2017-12-29 10:01:31 +01:00
|
|
|
_h: PhantomData<H>,
|
2017-11-25 07:15:52 +01:00
|
|
|
}
|
|
|
|
|
2018-01-10 05:00:18 +01:00
|
|
|
impl<S: 'static, H> RunMiddlewares<S, H> {
|
2018-05-16 01:41:46 +02:00
|
|
|
#[inline]
|
2018-06-21 19:51:25 +02:00
|
|
|
fn init(
|
|
|
|
info: &mut PipelineInfo<S>, mws: &[Box<Middleware<S>>], mut resp: HttpResponse,
|
|
|
|
) -> PipelineState<S, H> {
|
2017-12-02 00:45:15 +01:00
|
|
|
if info.count == 0 {
|
2017-12-09 14:54:04 +01:00
|
|
|
return ProcessResponse::init(resp);
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
let mut curr = 0;
|
2018-06-21 19:51:25 +02:00
|
|
|
let len = mws.len();
|
2017-12-02 00:45:15 +01:00
|
|
|
|
2017-11-25 07:15:52 +01:00
|
|
|
loop {
|
2018-06-25 06:58:04 +02:00
|
|
|
let state = mws[curr].response(&info.req, resp);
|
2018-06-02 05:37:29 +02:00
|
|
|
resp = match state {
|
2018-01-10 07:48:35 +01:00
|
|
|
Err(err) => {
|
2018-01-21 05:12:24 +01:00
|
|
|
info.count = (curr + 1) as u16;
|
2018-04-14 01:02:01 +02:00
|
|
|
return ProcessResponse::init(err.into());
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
2018-01-10 07:48:35 +01:00
|
|
|
Ok(Response::Done(r)) => {
|
2017-12-02 00:45:15 +01:00
|
|
|
curr += 1;
|
|
|
|
if curr == len {
|
2018-04-14 01:02:01 +02:00
|
|
|
return ProcessResponse::init(r);
|
2017-11-25 07:15:52 +01:00
|
|
|
} else {
|
|
|
|
r
|
|
|
|
}
|
2018-04-14 01:02:01 +02:00
|
|
|
}
|
2018-01-10 07:48:35 +01:00
|
|
|
Ok(Response::Future(fut)) => {
|
2018-04-14 01:02:01 +02:00
|
|
|
return PipelineState::RunMiddlewares(RunMiddlewares {
|
|
|
|
curr,
|
|
|
|
fut: Some(fut),
|
|
|
|
_s: PhantomData,
|
|
|
|
_h: PhantomData,
|
2018-06-25 06:58:04 +02:00
|
|
|
});
|
2018-04-14 01:02:01 +02:00
|
|
|
}
|
2017-11-25 07:15:52 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-21 19:51:25 +02:00
|
|
|
fn poll(
|
|
|
|
&mut self, info: &mut PipelineInfo<S>, mws: &[Box<Middleware<S>>],
|
|
|
|
) -> Option<PipelineState<S, H>> {
|
|
|
|
let len = mws.len();
|
2017-12-02 00:45:15 +01:00
|
|
|
|
2017-11-25 07:15:52 +01:00
|
|
|
loop {
|
|
|
|
// poll latest fut
|
|
|
|
let mut resp = match self.fut.as_mut().unwrap().poll() {
|
2018-04-14 01:02:01 +02:00
|
|
|
Ok(Async::NotReady) => return None,
|
2017-11-25 18:28:25 +01:00
|
|
|
Ok(Async::Ready(resp)) => {
|
2017-12-02 00:45:15 +01:00
|
|
|
self.curr += 1;
|
2017-12-16 01:24:15 +01:00
|
|
|
resp
|
2017-11-25 07:15:52 +01:00
|
|
|
}
|
2018-04-14 01:02:01 +02:00
|
|
|
Err(err) => return Some(ProcessResponse::init(err.into())),
|
2017-11-25 07:15:52 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
loop {
|
2017-12-02 00:45:15 +01:00
|
|
|
if self.curr == len {
|
2018-01-11 01:45:57 +01:00
|
|
|
return Some(ProcessResponse::init(resp));
|
2017-11-25 07:15:52 +01:00
|
|
|
} else {
|
2018-06-25 06:58:04 +02:00
|
|
|
let state = mws[self.curr].response(&info.req, resp);
|
2018-06-02 05:37:29 +02:00
|
|
|
match state {
|
2018-04-14 01:02:01 +02:00
|
|
|
Err(err) => return Some(ProcessResponse::init(err.into())),
|
2018-01-10 07:48:35 +01:00
|
|
|
Ok(Response::Done(r)) => {
|
2017-12-02 00:45:15 +01:00
|
|
|
self.curr += 1;
|
2017-11-25 07:15:52 +01:00
|
|
|
resp = r
|
2018-04-14 01:02:01 +02:00
|
|
|
}
|
2018-01-10 07:48:35 +01:00
|
|
|
Ok(Response::Future(fut)) => {
|
2017-11-25 07:15:52 +01:00
|
|
|
self.fut = Some(fut);
|
2018-04-14 01:02:01 +02:00
|
|
|
break;
|
|
|
|
}
|
2017-11-25 07:15:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-12-02 00:45:15 +01:00
|
|
|
|
2017-12-29 10:01:31 +01:00
|
|
|
struct ProcessResponse<S, H> {
|
2018-08-08 05:48:25 +02:00
|
|
|
resp: Option<HttpResponse>,
|
2017-12-02 00:45:15 +01:00
|
|
|
iostate: IOState,
|
|
|
|
running: RunningState,
|
2017-12-24 20:58:09 +01:00
|
|
|
drain: Option<oneshot::Sender<()>>,
|
2017-12-09 14:54:04 +01:00
|
|
|
_s: PhantomData<S>,
|
2017-12-29 10:01:31 +01:00
|
|
|
_h: PhantomData<H>,
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
|
2018-07-26 00:38:02 +02:00
|
|
|
#[derive(PartialEq, Debug)]
|
2017-12-02 00:45:15 +01:00
|
|
|
enum RunningState {
|
|
|
|
Running,
|
|
|
|
Paused,
|
|
|
|
Done,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl RunningState {
|
|
|
|
#[inline]
|
|
|
|
fn pause(&mut self) {
|
|
|
|
if *self != RunningState::Done {
|
|
|
|
*self = RunningState::Paused
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
fn resume(&mut self) {
|
|
|
|
if *self != RunningState::Done {
|
|
|
|
*self = RunningState::Running
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
enum IOState {
|
|
|
|
Response,
|
|
|
|
Payload(BodyStream),
|
2018-01-01 02:26:32 +01:00
|
|
|
Actor(Box<ActorHttpContext>),
|
2017-12-02 00:45:15 +01:00
|
|
|
Done,
|
|
|
|
}
|
|
|
|
|
2018-01-10 05:00:18 +01:00
|
|
|
impl<S: 'static, H> ProcessResponse<S, H> {
|
2017-12-16 05:00:12 +01:00
|
|
|
#[inline]
|
2018-01-11 05:08:13 +01:00
|
|
|
fn init(resp: HttpResponse) -> PipelineState<S, H> {
|
2018-04-14 01:02:01 +02:00
|
|
|
PipelineState::Response(ProcessResponse {
|
2018-08-08 05:48:25 +02:00
|
|
|
resp: Some(resp),
|
2018-04-14 01:02:01 +02:00
|
|
|
iostate: IOState::Response,
|
|
|
|
running: RunningState::Running,
|
|
|
|
drain: None,
|
|
|
|
_s: PhantomData,
|
|
|
|
_h: PhantomData,
|
|
|
|
})
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
|
2018-08-08 05:48:25 +02:00
|
|
|
fn poll(
|
|
|
|
&mut self, info: &mut PipelineInfo<S>, mws: &[Box<Middleware<S>>],
|
|
|
|
) -> Option<PipelineState<S, H>> {
|
|
|
|
// connection is dead at this point
|
|
|
|
match mem::replace(&mut self.iostate, IOState::Done) {
|
|
|
|
IOState::Response =>
|
|
|
|
Some(FinishingMiddlewares::init(info, mws, self.resp.take().unwrap())),
|
|
|
|
IOState::Payload(_) =>
|
|
|
|
Some(FinishingMiddlewares::init(info, mws, self.resp.take().unwrap())),
|
|
|
|
IOState::Actor(mut ctx) => {
|
|
|
|
if info.disconnected.take().is_some() {
|
|
|
|
ctx.disconnected();
|
|
|
|
}
|
|
|
|
loop {
|
|
|
|
match ctx.poll() {
|
|
|
|
Ok(Async::Ready(Some(vec))) => {
|
|
|
|
if vec.is_empty() {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
for frame in vec {
|
|
|
|
match frame {
|
|
|
|
Frame::Chunk(None) => {
|
|
|
|
info.context = Some(ctx);
|
|
|
|
return Some(FinishingMiddlewares::init(
|
|
|
|
info, mws, self.resp.take().unwrap(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
Frame::Chunk(Some(_)) => (),
|
|
|
|
Frame::Drain(fut) => {let _ = fut.send(());},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-08-16 15:11:15 +02:00
|
|
|
Ok(Async::Ready(None)) =>
|
2018-08-08 05:48:25 +02:00
|
|
|
return Some(FinishingMiddlewares::init(
|
|
|
|
info, mws, self.resp.take().unwrap(),
|
|
|
|
)),
|
|
|
|
Ok(Async::NotReady) => {
|
|
|
|
self.iostate = IOState::Actor(ctx);
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
Err(err) => {
|
|
|
|
info.context = Some(ctx);
|
|
|
|
info.error = Some(err);
|
|
|
|
return Some(FinishingMiddlewares::init(info, mws, self.resp.take().unwrap()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
IOState::Done => Some(FinishingMiddlewares::init(info, mws, self.resp.take().unwrap()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-14 01:02:01 +02:00
|
|
|
fn poll_io(
|
2018-05-17 21:20:20 +02:00
|
|
|
mut self, io: &mut Writer, info: &mut PipelineInfo<S>,
|
2018-06-21 19:51:25 +02:00
|
|
|
mws: &[Box<Middleware<S>>],
|
2018-04-14 01:02:01 +02:00
|
|
|
) -> Result<PipelineState<S, H>, PipelineState<S, H>> {
|
2018-03-20 01:27:03 +01:00
|
|
|
loop {
|
|
|
|
if self.drain.is_none() && self.running != RunningState::Paused {
|
|
|
|
// if task is paused, write buffer is probably full
|
|
|
|
'inner: loop {
|
|
|
|
let result = match mem::replace(&mut self.iostate, IOState::Done) {
|
|
|
|
IOState::Response => {
|
2018-04-14 01:02:01 +02:00
|
|
|
let encoding =
|
2018-08-08 05:48:25 +02:00
|
|
|
self.resp.as_ref().unwrap().content_encoding().unwrap_or(info.encoding);
|
2018-04-14 01:02:01 +02:00
|
|
|
|
2018-06-25 06:58:04 +02:00
|
|
|
let result =
|
2018-08-08 05:48:25 +02:00
|
|
|
match io.start(&info.req, self.resp.as_mut().unwrap(), encoding) {
|
2018-06-25 06:58:04 +02:00
|
|
|
Ok(res) => res,
|
|
|
|
Err(err) => {
|
|
|
|
info.error = Some(err.into());
|
|
|
|
return Ok(FinishingMiddlewares::init(
|
2018-08-08 05:48:25 +02:00
|
|
|
info, mws, self.resp.take().unwrap(),
|
2018-06-25 06:58:04 +02:00
|
|
|
));
|
|
|
|
}
|
|
|
|
};
|
2017-12-02 00:45:15 +01:00
|
|
|
|
2018-08-08 05:48:25 +02:00
|
|
|
if let Some(err) = self.resp.as_ref().unwrap().error() {
|
|
|
|
if self.resp.as_ref().unwrap().status().is_server_error() {
|
2018-04-14 01:02:01 +02:00
|
|
|
error!(
|
2018-05-09 00:44:50 +02:00
|
|
|
"Error occured during request handling, status: {} {}",
|
2018-08-08 05:48:25 +02:00
|
|
|
self.resp.as_ref().unwrap().status(), err
|
2018-04-14 01:02:01 +02:00
|
|
|
);
|
2018-03-20 01:27:03 +01:00
|
|
|
} else {
|
2018-04-14 01:02:01 +02:00
|
|
|
warn!(
|
|
|
|
"Error occured during request handling: {}",
|
|
|
|
err
|
|
|
|
);
|
2018-03-20 01:27:03 +01:00
|
|
|
}
|
|
|
|
if log_enabled!(Debug) {
|
|
|
|
debug!("{:?}", err);
|
|
|
|
}
|
2018-01-21 05:12:24 +01:00
|
|
|
}
|
|
|
|
|
2018-03-20 01:27:03 +01:00
|
|
|
// always poll stream or actor for the first time
|
2018-08-08 05:48:25 +02:00
|
|
|
match self.resp.as_mut().unwrap().replace_body(Body::Empty) {
|
2018-03-20 01:27:03 +01:00
|
|
|
Body::Streaming(stream) => {
|
|
|
|
self.iostate = IOState::Payload(stream);
|
2018-04-14 01:02:01 +02:00
|
|
|
continue 'inner;
|
|
|
|
}
|
|
|
|
Body::Actor(ctx) => {
|
|
|
|
self.iostate = IOState::Actor(ctx);
|
|
|
|
continue 'inner;
|
|
|
|
}
|
2018-03-20 01:27:03 +01:00
|
|
|
_ => (),
|
|
|
|
}
|
2017-12-02 00:45:15 +01:00
|
|
|
|
2018-03-20 01:27:03 +01:00
|
|
|
result
|
2018-04-14 01:02:01 +02:00
|
|
|
}
|
|
|
|
IOState::Payload(mut body) => match body.poll() {
|
|
|
|
Ok(Async::Ready(None)) => {
|
|
|
|
if let Err(err) = io.write_eof() {
|
|
|
|
info.error = Some(err.into());
|
|
|
|
return Ok(FinishingMiddlewares::init(
|
2018-08-08 05:48:25 +02:00
|
|
|
info, mws, self.resp.take().unwrap(),
|
2018-04-14 01:02:01 +02:00
|
|
|
));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
Ok(Async::Ready(Some(chunk))) => {
|
|
|
|
self.iostate = IOState::Payload(body);
|
2018-06-19 03:44:01 +02:00
|
|
|
match io.write(&chunk.into()) {
|
2018-04-14 01:02:01 +02:00
|
|
|
Err(err) => {
|
2017-12-09 14:54:04 +01:00
|
|
|
info.error = Some(err.into());
|
2018-04-14 01:02:01 +02:00
|
|
|
return Ok(FinishingMiddlewares::init(
|
2018-08-08 05:48:25 +02:00
|
|
|
info, mws, self.resp.take().unwrap(),
|
2018-04-14 01:02:01 +02:00
|
|
|
));
|
2018-03-20 01:27:03 +01:00
|
|
|
}
|
2018-04-14 01:02:01 +02:00
|
|
|
Ok(result) => result,
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
2018-04-14 01:02:01 +02:00
|
|
|
}
|
|
|
|
Ok(Async::NotReady) => {
|
|
|
|
self.iostate = IOState::Payload(body);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
Err(err) => {
|
|
|
|
info.error = Some(err);
|
2018-06-21 19:51:25 +02:00
|
|
|
return Ok(FinishingMiddlewares::init(
|
2018-08-08 05:48:25 +02:00
|
|
|
info, mws, self.resp.take().unwrap(),
|
2018-06-21 19:51:25 +02:00
|
|
|
));
|
2018-03-20 01:27:03 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
IOState::Actor(mut ctx) => {
|
|
|
|
if info.disconnected.take().is_some() {
|
|
|
|
ctx.disconnected();
|
|
|
|
}
|
|
|
|
match ctx.poll() {
|
|
|
|
Ok(Async::Ready(Some(vec))) => {
|
|
|
|
if vec.is_empty() {
|
|
|
|
self.iostate = IOState::Actor(ctx);
|
2018-04-14 01:02:01 +02:00
|
|
|
break;
|
2018-03-20 01:27:03 +01:00
|
|
|
}
|
|
|
|
let mut res = None;
|
|
|
|
for frame in vec {
|
|
|
|
match frame {
|
|
|
|
Frame::Chunk(None) => {
|
|
|
|
info.context = Some(ctx);
|
|
|
|
if let Err(err) = io.write_eof() {
|
2018-01-14 01:17:33 +01:00
|
|
|
info.error = Some(err.into());
|
|
|
|
return Ok(
|
2018-04-14 01:02:01 +02:00
|
|
|
FinishingMiddlewares::init(
|
2018-08-08 05:48:25 +02:00
|
|
|
info, mws, self.resp.take().unwrap(),
|
2018-04-14 01:02:01 +02:00
|
|
|
),
|
|
|
|
);
|
2018-03-20 01:27:03 +01:00
|
|
|
}
|
2018-04-14 01:02:01 +02:00
|
|
|
break 'inner;
|
|
|
|
}
|
2018-03-20 01:27:03 +01:00
|
|
|
Frame::Chunk(Some(chunk)) => {
|
2018-06-19 03:44:01 +02:00
|
|
|
match io.write(&chunk) {
|
2018-03-20 01:27:03 +01:00
|
|
|
Err(err) => {
|
2018-07-08 05:41:55 +02:00
|
|
|
info.context = Some(ctx);
|
2018-03-20 01:27:03 +01:00
|
|
|
info.error = Some(err.into());
|
|
|
|
return Ok(
|
2018-04-14 01:02:01 +02:00
|
|
|
FinishingMiddlewares::init(
|
2018-08-08 05:48:25 +02:00
|
|
|
info, mws, self.resp.take().unwrap(),
|
2018-04-14 01:02:01 +02:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
2018-03-20 01:27:03 +01:00
|
|
|
Ok(result) => res = Some(result),
|
|
|
|
}
|
2018-04-14 01:02:01 +02:00
|
|
|
}
|
2018-03-20 01:27:03 +01:00
|
|
|
Frame::Drain(fut) => self.drain = Some(fut),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.iostate = IOState::Actor(ctx);
|
|
|
|
if self.drain.is_some() {
|
|
|
|
self.running.resume();
|
2018-04-14 01:02:01 +02:00
|
|
|
break 'inner;
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
2018-03-20 01:27:03 +01:00
|
|
|
res.unwrap()
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
2018-04-14 01:02:01 +02:00
|
|
|
Ok(Async::Ready(None)) => break,
|
2018-03-20 01:27:03 +01:00
|
|
|
Ok(Async::NotReady) => {
|
|
|
|
self.iostate = IOState::Actor(ctx);
|
2018-04-14 01:02:01 +02:00
|
|
|
break;
|
2018-03-20 01:27:03 +01:00
|
|
|
}
|
|
|
|
Err(err) => {
|
2018-07-08 05:41:55 +02:00
|
|
|
info.context = Some(ctx);
|
2018-03-20 01:27:03 +01:00
|
|
|
info.error = Some(err);
|
2018-04-14 01:02:01 +02:00
|
|
|
return Ok(FinishingMiddlewares::init(
|
2018-08-08 05:48:25 +02:00
|
|
|
info, mws, self.resp.take().unwrap(),
|
2018-04-14 01:02:01 +02:00
|
|
|
));
|
2018-01-14 01:17:33 +01:00
|
|
|
}
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
}
|
2018-03-20 01:27:03 +01:00
|
|
|
IOState::Done => break,
|
|
|
|
};
|
2017-12-02 00:45:15 +01:00
|
|
|
|
2018-03-20 01:27:03 +01:00
|
|
|
match result {
|
|
|
|
WriterState::Pause => {
|
|
|
|
self.running.pause();
|
2018-04-14 01:02:01 +02:00
|
|
|
break;
|
2018-03-20 01:27:03 +01:00
|
|
|
}
|
2018-04-14 01:02:01 +02:00
|
|
|
WriterState::Done => self.running.resume(),
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-20 01:27:03 +01:00
|
|
|
// flush io but only if we need to
|
|
|
|
if self.running == RunningState::Paused || self.drain.is_some() {
|
|
|
|
match io.poll_completed(false) {
|
|
|
|
Ok(Async::Ready(_)) => {
|
|
|
|
self.running.resume();
|
2017-12-29 20:45:56 +01:00
|
|
|
|
2018-03-20 01:27:03 +01:00
|
|
|
// resolve drain futures
|
|
|
|
if let Some(tx) = self.drain.take() {
|
|
|
|
let _ = tx.send(());
|
|
|
|
}
|
|
|
|
// restart io processing
|
2018-04-14 01:02:01 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
Ok(Async::NotReady) => return Err(PipelineState::Response(self)),
|
2018-03-20 01:27:03 +01:00
|
|
|
Err(err) => {
|
2018-07-08 05:41:55 +02:00
|
|
|
if let IOState::Actor(mut ctx) =
|
|
|
|
mem::replace(&mut self.iostate, IOState::Done)
|
|
|
|
{
|
|
|
|
ctx.disconnected();
|
|
|
|
info.context = Some(ctx);
|
|
|
|
}
|
2018-03-20 01:27:03 +01:00
|
|
|
info.error = Some(err.into());
|
2018-08-08 05:48:25 +02:00
|
|
|
return Ok(FinishingMiddlewares::init(info, mws, self.resp.take().unwrap()));
|
2017-12-29 20:45:56 +01:00
|
|
|
}
|
2017-12-15 04:34:31 +01:00
|
|
|
}
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
2018-04-14 01:02:01 +02:00
|
|
|
break;
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// response is completed
|
2017-12-16 05:00:12 +01:00
|
|
|
match self.iostate {
|
|
|
|
IOState::Done => {
|
2018-01-03 00:23:31 +01:00
|
|
|
match io.write_eof() {
|
|
|
|
Ok(_) => (),
|
|
|
|
Err(err) => {
|
|
|
|
info.error = Some(err.into());
|
2018-08-08 05:48:25 +02:00
|
|
|
return Ok(FinishingMiddlewares::init(info, mws, self.resp.take().unwrap()));
|
2018-01-03 00:23:31 +01:00
|
|
|
}
|
|
|
|
}
|
2018-08-08 05:48:25 +02:00
|
|
|
self.resp.as_mut().unwrap().set_response_size(io.written());
|
|
|
|
Ok(FinishingMiddlewares::init(info, mws, self.resp.take().unwrap()))
|
2017-12-16 05:00:12 +01:00
|
|
|
}
|
2018-01-11 01:45:57 +01:00
|
|
|
_ => Err(PipelineState::Response(self)),
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Middlewares start executor
|
2017-12-29 10:01:31 +01:00
|
|
|
struct FinishingMiddlewares<S, H> {
|
2018-06-25 05:08:28 +02:00
|
|
|
resp: Option<HttpResponse>,
|
2018-04-14 01:02:01 +02:00
|
|
|
fut: Option<Box<Future<Item = (), Error = Error>>>,
|
2017-12-09 14:54:04 +01:00
|
|
|
_s: PhantomData<S>,
|
2017-12-29 10:01:31 +01:00
|
|
|
_h: PhantomData<H>,
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
|
2018-01-10 05:00:18 +01:00
|
|
|
impl<S: 'static, H> FinishingMiddlewares<S, H> {
|
2018-05-16 01:41:46 +02:00
|
|
|
#[inline]
|
2018-06-21 19:51:25 +02:00
|
|
|
fn init(
|
|
|
|
info: &mut PipelineInfo<S>, mws: &[Box<Middleware<S>>], resp: HttpResponse,
|
|
|
|
) -> PipelineState<S, H> {
|
2017-12-02 00:45:15 +01:00
|
|
|
if info.count == 0 {
|
2018-06-25 06:10:02 +02:00
|
|
|
resp.release();
|
|
|
|
Completed::init(info)
|
2017-12-02 00:45:15 +01:00
|
|
|
} else {
|
2018-04-14 01:02:01 +02:00
|
|
|
let mut state = FinishingMiddlewares {
|
2018-06-25 05:08:28 +02:00
|
|
|
resp: Some(resp),
|
2018-04-14 01:02:01 +02:00
|
|
|
fut: None,
|
|
|
|
_s: PhantomData,
|
|
|
|
_h: PhantomData,
|
|
|
|
};
|
2018-06-21 19:51:25 +02:00
|
|
|
if let Some(st) = state.poll(info, mws) {
|
2018-01-11 01:45:57 +01:00
|
|
|
st
|
|
|
|
} else {
|
|
|
|
PipelineState::Finishing(state)
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-21 19:51:25 +02:00
|
|
|
fn poll(
|
|
|
|
&mut self, info: &mut PipelineInfo<S>, mws: &[Box<Middleware<S>>],
|
|
|
|
) -> Option<PipelineState<S, H>> {
|
2017-12-02 00:45:15 +01:00
|
|
|
loop {
|
|
|
|
// poll latest fut
|
|
|
|
let not_ready = if let Some(ref mut fut) = self.fut {
|
|
|
|
match fut.poll() {
|
2018-04-14 01:02:01 +02:00
|
|
|
Ok(Async::NotReady) => true,
|
|
|
|
Ok(Async::Ready(())) => false,
|
2017-12-02 00:45:15 +01:00
|
|
|
Err(err) => {
|
|
|
|
error!("Middleware finish error: {}", err);
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
};
|
|
|
|
if not_ready {
|
2018-01-11 01:45:57 +01:00
|
|
|
return None;
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
self.fut = None;
|
2018-05-05 21:18:43 +02:00
|
|
|
if info.count == 0 {
|
2018-06-25 06:10:02 +02:00
|
|
|
self.resp.take().unwrap().release();
|
|
|
|
return Some(Completed::init(info));
|
2018-05-05 21:18:43 +02:00
|
|
|
}
|
2017-12-02 00:45:15 +01:00
|
|
|
|
2018-05-05 21:18:43 +02:00
|
|
|
info.count -= 1;
|
2018-06-25 06:58:04 +02:00
|
|
|
let state =
|
|
|
|
mws[info.count as usize].finish(&info.req, self.resp.as_ref().unwrap());
|
2018-06-02 05:37:29 +02:00
|
|
|
match state {
|
2017-12-02 00:45:15 +01:00
|
|
|
Finished::Done => {
|
2017-12-09 14:54:04 +01:00
|
|
|
if info.count == 0 {
|
2018-06-25 06:10:02 +02:00
|
|
|
self.resp.take().unwrap().release();
|
|
|
|
return Some(Completed::init(info));
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Finished::Future(fut) => {
|
|
|
|
self.fut = Some(fut);
|
2018-04-14 01:02:01 +02:00
|
|
|
}
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-14 01:17:33 +01:00
|
|
|
#[derive(Debug)]
|
2018-06-25 06:10:02 +02:00
|
|
|
struct Completed<S, H>(PhantomData<S>, PhantomData<H>);
|
2017-12-02 00:45:15 +01:00
|
|
|
|
2017-12-29 10:01:31 +01:00
|
|
|
impl<S, H> Completed<S, H> {
|
2017-12-16 05:00:12 +01:00
|
|
|
#[inline]
|
2018-06-25 06:10:02 +02:00
|
|
|
fn init(info: &mut PipelineInfo<S>) -> PipelineState<S, H> {
|
2018-01-21 05:12:24 +01:00
|
|
|
if let Some(ref err) = info.error {
|
2018-01-31 18:28:53 +01:00
|
|
|
error!("Error occurred during request handling: {}", err);
|
2018-01-21 05:12:24 +01:00
|
|
|
}
|
|
|
|
|
2017-12-02 00:45:15 +01:00
|
|
|
if info.context.is_none() {
|
|
|
|
PipelineState::None
|
|
|
|
} else {
|
2018-07-08 05:41:55 +02:00
|
|
|
match info.poll_context() {
|
|
|
|
Ok(Async::NotReady) => {
|
|
|
|
PipelineState::Completed(Completed(PhantomData, PhantomData))
|
|
|
|
}
|
|
|
|
Ok(Async::Ready(())) => PipelineState::None,
|
|
|
|
Err(_) => PipelineState::Error,
|
|
|
|
}
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-16 05:00:12 +01:00
|
|
|
#[inline]
|
2018-01-11 01:45:57 +01:00
|
|
|
fn poll(&mut self, info: &mut PipelineInfo<S>) -> Option<PipelineState<S, H>> {
|
2017-12-09 14:54:04 +01:00
|
|
|
match info.poll_context() {
|
2018-01-11 01:45:57 +01:00
|
|
|
Ok(Async::NotReady) => None,
|
2018-06-25 06:10:02 +02:00
|
|
|
Ok(Async::Ready(())) => Some(PipelineState::None),
|
|
|
|
Err(_) => Some(PipelineState::Error),
|
2017-12-02 00:45:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|