2018-09-27 05:43:54 +02:00
|
|
|
use std::marker::PhantomData;
|
2018-10-02 07:23:02 +02:00
|
|
|
use std::time::Duration;
|
2018-09-27 05:43:54 +02:00
|
|
|
|
|
|
|
use actix_net::service::{NewService, Service};
|
|
|
|
use futures::future::{ok, FutureResult};
|
|
|
|
use futures::{Async, Poll};
|
|
|
|
|
2018-10-03 02:30:29 +02:00
|
|
|
use super::channel::{H1Channel, HttpChannel};
|
2018-10-01 23:43:06 +02:00
|
|
|
use super::error::HttpDispatchError;
|
2018-09-28 02:15:38 +02:00
|
|
|
use super::handler::HttpHandler;
|
2018-10-03 00:25:32 +02:00
|
|
|
use super::settings::ServiceConfig;
|
2018-09-28 02:15:38 +02:00
|
|
|
use super::IoStream;
|
2018-09-27 05:43:54 +02:00
|
|
|
|
2018-10-02 07:23:02 +02:00
|
|
|
/// `NewService` implementation for HTTP1/HTTP2 transports
|
2018-10-01 23:43:06 +02:00
|
|
|
pub struct HttpService<H, Io>
|
2018-09-27 05:43:54 +02:00
|
|
|
where
|
2018-09-28 02:15:38 +02:00
|
|
|
H: HttpHandler,
|
2018-09-27 05:43:54 +02:00
|
|
|
Io: IoStream,
|
|
|
|
{
|
2018-10-03 00:25:32 +02:00
|
|
|
settings: ServiceConfig<H>,
|
2018-09-27 05:43:54 +02:00
|
|
|
_t: PhantomData<Io>,
|
|
|
|
}
|
|
|
|
|
2018-09-28 02:15:38 +02:00
|
|
|
impl<H, Io> HttpService<H, Io>
|
2018-09-27 05:43:54 +02:00
|
|
|
where
|
2018-09-28 02:15:38 +02:00
|
|
|
H: HttpHandler,
|
2018-09-27 05:43:54 +02:00
|
|
|
Io: IoStream,
|
|
|
|
{
|
2018-10-01 23:43:06 +02:00
|
|
|
/// Create new `HttpService` instance.
|
2018-10-03 00:25:32 +02:00
|
|
|
pub fn new(settings: ServiceConfig<H>) -> Self {
|
2018-09-27 05:43:54 +02:00
|
|
|
HttpService {
|
2018-09-28 02:15:38 +02:00
|
|
|
settings,
|
2018-09-27 05:43:54 +02:00
|
|
|
_t: PhantomData,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-28 02:15:38 +02:00
|
|
|
impl<H, Io> NewService for HttpService<H, Io>
|
2018-09-27 05:43:54 +02:00
|
|
|
where
|
2018-09-28 02:15:38 +02:00
|
|
|
H: HttpHandler,
|
2018-09-27 05:43:54 +02:00
|
|
|
Io: IoStream,
|
|
|
|
{
|
|
|
|
type Request = Io;
|
|
|
|
type Response = ();
|
2018-10-01 23:43:06 +02:00
|
|
|
type Error = HttpDispatchError;
|
2018-09-27 05:43:54 +02:00
|
|
|
type InitError = ();
|
2018-09-28 02:15:38 +02:00
|
|
|
type Service = HttpServiceHandler<H, Io>;
|
2018-10-01 23:43:06 +02:00
|
|
|
type Future = FutureResult<Self::Service, Self::InitError>;
|
2018-09-27 05:43:54 +02:00
|
|
|
|
|
|
|
fn new_service(&self) -> Self::Future {
|
2018-09-28 02:15:38 +02:00
|
|
|
ok(HttpServiceHandler::new(self.settings.clone()))
|
2018-09-27 05:43:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-01 23:43:06 +02:00
|
|
|
pub struct HttpServiceHandler<H, Io>
|
2018-09-27 05:43:54 +02:00
|
|
|
where
|
|
|
|
H: HttpHandler,
|
|
|
|
Io: IoStream,
|
|
|
|
{
|
2018-10-03 00:25:32 +02:00
|
|
|
settings: ServiceConfig<H>,
|
2018-09-27 05:43:54 +02:00
|
|
|
_t: PhantomData<Io>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<H, Io> HttpServiceHandler<H, Io>
|
|
|
|
where
|
|
|
|
H: HttpHandler,
|
|
|
|
Io: IoStream,
|
|
|
|
{
|
2018-10-03 00:25:32 +02:00
|
|
|
fn new(settings: ServiceConfig<H>) -> HttpServiceHandler<H, Io> {
|
2018-09-27 05:43:54 +02:00
|
|
|
HttpServiceHandler {
|
|
|
|
settings,
|
|
|
|
_t: PhantomData,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<H, Io> Service for HttpServiceHandler<H, Io>
|
|
|
|
where
|
|
|
|
H: HttpHandler,
|
|
|
|
Io: IoStream,
|
|
|
|
{
|
|
|
|
type Request = Io;
|
|
|
|
type Response = ();
|
2018-10-01 23:43:06 +02:00
|
|
|
type Error = HttpDispatchError;
|
2018-09-27 05:43:54 +02:00
|
|
|
type Future = HttpChannel<Io, H>;
|
|
|
|
|
|
|
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
|
|
|
Ok(Async::Ready(()))
|
|
|
|
}
|
|
|
|
|
2018-11-09 01:29:43 +01:00
|
|
|
fn call(&mut self, mut req: Self::Request) -> Self::Future {
|
2018-10-03 02:30:29 +02:00
|
|
|
HttpChannel::new(self.settings.clone(), req)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// `NewService` implementation for HTTP1 transport
|
|
|
|
pub struct H1Service<H, Io>
|
|
|
|
where
|
|
|
|
H: HttpHandler,
|
|
|
|
Io: IoStream,
|
|
|
|
{
|
|
|
|
settings: ServiceConfig<H>,
|
|
|
|
_t: PhantomData<Io>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<H, Io> H1Service<H, Io>
|
|
|
|
where
|
|
|
|
H: HttpHandler,
|
|
|
|
Io: IoStream,
|
|
|
|
{
|
|
|
|
/// Create new `HttpService` instance.
|
|
|
|
pub fn new(settings: ServiceConfig<H>) -> Self {
|
|
|
|
H1Service {
|
|
|
|
settings,
|
|
|
|
_t: PhantomData,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<H, Io> NewService for H1Service<H, Io>
|
|
|
|
where
|
|
|
|
H: HttpHandler,
|
|
|
|
Io: IoStream,
|
|
|
|
{
|
|
|
|
type Request = Io;
|
|
|
|
type Response = ();
|
|
|
|
type Error = HttpDispatchError;
|
|
|
|
type InitError = ();
|
|
|
|
type Service = H1ServiceHandler<H, Io>;
|
|
|
|
type Future = FutureResult<Self::Service, Self::InitError>;
|
|
|
|
|
|
|
|
fn new_service(&self) -> Self::Future {
|
|
|
|
ok(H1ServiceHandler::new(self.settings.clone()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// `Service` implementation for HTTP1 transport
|
|
|
|
pub struct H1ServiceHandler<H, Io>
|
|
|
|
where
|
|
|
|
H: HttpHandler,
|
|
|
|
Io: IoStream,
|
|
|
|
{
|
|
|
|
settings: ServiceConfig<H>,
|
|
|
|
_t: PhantomData<Io>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<H, Io> H1ServiceHandler<H, Io>
|
|
|
|
where
|
|
|
|
H: HttpHandler,
|
|
|
|
Io: IoStream,
|
|
|
|
{
|
|
|
|
fn new(settings: ServiceConfig<H>) -> H1ServiceHandler<H, Io> {
|
|
|
|
H1ServiceHandler {
|
|
|
|
settings,
|
|
|
|
_t: PhantomData,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<H, Io> Service for H1ServiceHandler<H, Io>
|
|
|
|
where
|
|
|
|
H: HttpHandler,
|
|
|
|
Io: IoStream,
|
|
|
|
{
|
|
|
|
type Request = Io;
|
|
|
|
type Response = ();
|
|
|
|
type Error = HttpDispatchError;
|
|
|
|
type Future = H1Channel<Io, H>;
|
|
|
|
|
|
|
|
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)
|
2018-09-27 05:43:54 +02:00
|
|
|
}
|
|
|
|
}
|
2018-10-02 07:23:02 +02:00
|
|
|
|
|
|
|
/// `NewService` implementation for stream configuration service
|
2018-10-02 07:48:11 +02:00
|
|
|
///
|
|
|
|
/// Stream configuration service allows to change some socket level
|
|
|
|
/// parameters. for example `tcp nodelay` or `tcp keep-alive`.
|
2018-10-02 07:23:02 +02:00
|
|
|
pub struct StreamConfiguration<T, E> {
|
|
|
|
no_delay: Option<bool>,
|
|
|
|
tcp_ka: Option<Option<Duration>>,
|
|
|
|
_t: PhantomData<(T, E)>,
|
|
|
|
}
|
|
|
|
|
2018-10-03 00:25:32 +02:00
|
|
|
impl<T, E> Default for StreamConfiguration<T, E> {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self::new()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-02 07:23:02 +02:00
|
|
|
impl<T, E> StreamConfiguration<T, E> {
|
|
|
|
/// 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<Duration>) -> Self {
|
|
|
|
self.tcp_ka = Some(keepalive);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: IoStream, E> NewService for StreamConfiguration<T, E> {
|
|
|
|
type Request = T;
|
|
|
|
type Response = T;
|
|
|
|
type Error = E;
|
|
|
|
type InitError = ();
|
|
|
|
type Service = StreamConfigurationService<T, E>;
|
|
|
|
type Future = FutureResult<Self::Service, Self::InitError>;
|
|
|
|
|
|
|
|
fn new_service(&self) -> Self::Future {
|
|
|
|
ok(StreamConfigurationService {
|
2018-10-03 00:25:32 +02:00
|
|
|
no_delay: self.no_delay,
|
|
|
|
tcp_ka: self.tcp_ka,
|
2018-10-02 07:23:02 +02:00
|
|
|
_t: PhantomData,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Stream configuration service
|
2018-10-02 07:48:11 +02:00
|
|
|
///
|
|
|
|
/// Stream configuration service allows to change some socket level
|
|
|
|
/// parameters. for example `tcp nodelay` or `tcp keep-alive`.
|
2018-10-02 07:23:02 +02:00
|
|
|
pub struct StreamConfigurationService<T, E> {
|
|
|
|
no_delay: Option<bool>,
|
|
|
|
tcp_ka: Option<Option<Duration>>,
|
|
|
|
_t: PhantomData<(T, E)>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T, E> Service for StreamConfigurationService<T, E>
|
|
|
|
where
|
|
|
|
T: IoStream,
|
|
|
|
{
|
|
|
|
type Request = T;
|
|
|
|
type Response = T;
|
|
|
|
type Error = E;
|
|
|
|
type Future = FutureResult<T, E>;
|
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|