use std::marker::PhantomData; use actix_net::codec::Framed; use actix_net::service::{IntoNewService, NewService, Service}; use futures::{future, Async, Future, Poll, Stream}; use tokio_io::{AsyncRead, AsyncWrite}; use config::ServiceConfig; use error::{DispatchError, Error, ParseError}; use request::Request; use response::Response; use super::codec::{Codec, InMessage}; use super::dispatcher::Dispatcher; /// `NewService` implementation for HTTP1 transport pub struct H1Service { srv: S, cfg: ServiceConfig, _t: PhantomData, } impl H1Service where S: NewService, S::Service: Clone, S::Error: Into, { /// Create new `HttpService` instance. pub fn new>(cfg: ServiceConfig, service: F) -> Self { H1Service { cfg, srv: service.into_new_service(), _t: PhantomData, } } } impl NewService for H1Service where T: AsyncRead + AsyncWrite, S: NewService + Clone, S::Service: Clone, S::Error: Into, { type Request = T; type Response = (); type Error = DispatchError; type InitError = S::InitError; type Service = H1ServiceHandler; type Future = H1ServiceResponse; fn new_service(&self) -> Self::Future { H1ServiceResponse { fut: self.srv.new_service(), cfg: Some(self.cfg.clone()), _t: PhantomData, } } } pub struct H1ServiceResponse { fut: S::Future, cfg: Option, _t: PhantomData, } impl Future for H1ServiceResponse where T: AsyncRead + AsyncWrite, S: NewService, S::Service: Clone, S::Error: Into, { type Item = H1ServiceHandler; type Error = S::InitError; fn poll(&mut self) -> Poll { let service = try_ready!(self.fut.poll()); Ok(Async::Ready(H1ServiceHandler::new( self.cfg.take().unwrap(), service, ))) } } /// `Service` implementation for HTTP1 transport pub struct H1ServiceHandler { srv: S, cfg: ServiceConfig, _t: PhantomData, } impl H1ServiceHandler where S: Service + Clone, S::Error: Into, { fn new(cfg: ServiceConfig, srv: S) -> H1ServiceHandler { H1ServiceHandler { srv, cfg, _t: PhantomData, } } } impl Service for H1ServiceHandler where T: AsyncRead + AsyncWrite, S: Service + Clone, S::Error: Into, { type Request = T; type Response = (); type Error = DispatchError; type Future = Dispatcher; fn poll_ready(&mut self) -> Poll<(), Self::Error> { self.srv.poll_ready().map_err(|e| DispatchError::Service(e)) } fn call(&mut self, req: Self::Request) -> Self::Future { Dispatcher::new(req, self.cfg.clone(), self.srv.clone()) } } /// `NewService` that implements, read one request from framed object feature. pub struct TakeRequest { _t: PhantomData, } impl TakeRequest { /// Create new `TakeRequest` instance. pub fn new() -> Self { TakeRequest { _t: PhantomData } } } impl NewService for TakeRequest where T: AsyncRead + AsyncWrite, { type Request = Framed; type Response = (Option, Framed); type Error = ParseError; type InitError = (); type Service = TakeRequestService; type Future = future::FutureResult; fn new_service(&self) -> Self::Future { future::ok(TakeRequestService { _t: PhantomData }) } } /// `NewService` that implements, read one request from framed object feature. pub struct TakeRequestService { _t: PhantomData, } impl Service for TakeRequestService where T: AsyncRead + AsyncWrite, { type Request = Framed; type Response = (Option, Framed); type Error = ParseError; type Future = TakeRequestServiceResponse; fn poll_ready(&mut self) -> Poll<(), Self::Error> { Ok(Async::Ready(())) } fn call(&mut self, framed: Self::Request) -> Self::Future { TakeRequestServiceResponse { framed: Some(framed), } } } pub struct TakeRequestServiceResponse where T: AsyncRead + AsyncWrite, { framed: Option>, } impl Future for TakeRequestServiceResponse where T: AsyncRead + AsyncWrite, { type Item = (Option, Framed); type Error = ParseError; fn poll(&mut self) -> Poll { match self.framed.as_mut().unwrap().poll()? { Async::Ready(item) => Ok(Async::Ready((item, self.framed.take().unwrap()))), Async::NotReady => Ok(Async::NotReady), } } }