use std::marker::PhantomData; use std::time::Duration; use actix_net::service::{NewService, Service}; use futures::future::{ok, FutureResult}; use futures::{Async, Poll}; use super::channel::{H1Channel, HttpChannel}; use super::error::HttpDispatchError; use super::handler::HttpHandler; use super::settings::ServiceConfig; use super::IoStream; /// `NewService` implementation for HTTP1/HTTP2 transports pub struct HttpService where H: HttpHandler, Io: IoStream, { settings: ServiceConfig, _t: PhantomData, } impl HttpService where H: HttpHandler, Io: IoStream, { /// Create new `HttpService` instance. pub fn new(settings: ServiceConfig) -> Self { HttpService { settings, _t: PhantomData, } } } impl NewService for HttpService where H: HttpHandler, Io: IoStream, { type Request = Io; type Response = (); type Error = HttpDispatchError; type InitError = (); type Service = HttpServiceHandler; type Future = FutureResult; fn new_service(&self) -> Self::Future { ok(HttpServiceHandler::new(self.settings.clone())) } } pub struct HttpServiceHandler where H: HttpHandler, Io: IoStream, { settings: ServiceConfig, _t: PhantomData, } impl HttpServiceHandler where H: HttpHandler, Io: IoStream, { fn new(settings: ServiceConfig) -> HttpServiceHandler { HttpServiceHandler { settings, _t: PhantomData, } } } impl Service for HttpServiceHandler where H: HttpHandler, Io: IoStream, { type Request = Io; type Response = (); type Error = HttpDispatchError; type Future = HttpChannel; fn poll_ready(&mut self) -> Poll<(), Self::Error> { Ok(Async::Ready(())) } fn call(&mut self, mut req: Self::Request) -> Self::Future { HttpChannel::new(self.settings.clone(), req) } } /// `NewService` implementation for HTTP1 transport pub struct H1Service where H: HttpHandler, Io: IoStream, { settings: ServiceConfig, _t: PhantomData, } impl H1Service where H: HttpHandler, Io: IoStream, { /// Create new `HttpService` instance. pub fn new(settings: ServiceConfig) -> Self { H1Service { settings, _t: PhantomData, } } } impl NewService for H1Service where H: HttpHandler, Io: IoStream, { type Request = Io; type Response = (); type Error = HttpDispatchError; type InitError = (); type Service = H1ServiceHandler; type Future = FutureResult; fn new_service(&self) -> Self::Future { ok(H1ServiceHandler::new(self.settings.clone())) } } /// `Service` implementation for HTTP1 transport pub struct H1ServiceHandler where H: HttpHandler, Io: IoStream, { settings: ServiceConfig, _t: PhantomData, } impl H1ServiceHandler where H: HttpHandler, Io: IoStream, { fn new(settings: ServiceConfig) -> H1ServiceHandler { H1ServiceHandler { settings, _t: PhantomData, } } } impl Service for H1ServiceHandler where H: HttpHandler, Io: IoStream, { type Request = Io; type Response = (); type Error = HttpDispatchError; type Future = H1Channel; fn poll_ready(&mut self) -> Poll<(), Self::Error> { Ok(Async::Ready(())) } fn call(&mut self, req: Self::Request) -> Self::Future { H1Channel::new(self.settings.clone(), req) } } /// `NewService` implementation for stream configuration service /// /// Stream configuration service allows to change some socket level /// parameters. for example `tcp nodelay` or `tcp keep-alive`. pub struct StreamConfiguration { no_delay: Option, tcp_ka: Option>, _t: PhantomData<(T, E)>, } impl Default for StreamConfiguration { fn default() -> Self { Self::new() } } impl StreamConfiguration { /// Create new `StreamConfigurationService` instance. pub fn new() -> Self { Self { no_delay: None, tcp_ka: None, _t: PhantomData, } } /// Sets the value of the `TCP_NODELAY` option on this socket. pub fn nodelay(mut self, nodelay: bool) -> Self { self.no_delay = Some(nodelay); self } /// Sets whether keepalive messages are enabled to be sent on this socket. pub fn tcp_keepalive(mut self, keepalive: Option) -> Self { self.tcp_ka = Some(keepalive); self } } impl NewService for StreamConfiguration { type Request = T; type Response = T; type Error = E; type InitError = (); type Service = StreamConfigurationService; type Future = FutureResult; fn new_service(&self) -> Self::Future { ok(StreamConfigurationService { no_delay: self.no_delay, tcp_ka: self.tcp_ka, _t: PhantomData, }) } } /// Stream configuration service /// /// Stream configuration service allows to change some socket level /// parameters. for example `tcp nodelay` or `tcp keep-alive`. pub struct StreamConfigurationService { no_delay: Option, tcp_ka: Option>, _t: PhantomData<(T, E)>, } impl Service for StreamConfigurationService where T: IoStream, { type Request = T; type Response = T; type Error = E; type Future = FutureResult; fn poll_ready(&mut self) -> Poll<(), Self::Error> { Ok(Async::Ready(())) } fn call(&mut self, mut req: Self::Request) -> Self::Future { if let Some(no_delay) = self.no_delay { if req.set_nodelay(no_delay).is_err() { error!("Can not set socket no-delay option"); } } if let Some(keepalive) = self.tcp_ka { if req.set_keepalive(keepalive).is_err() { error!("Can not set socket keep-alive option"); } } ok(req) } }