use std::fmt;
use std::marker::PhantomData;
use actix_codec::Framed;
use actix_server_config::ServerConfig as SrvConfig;
use actix_service::{IntoNewService, NewService, Service};
use crate::body::MessageBody;
use crate::config::{KeepAlive, ServiceConfig};
use crate::error::Error;
use crate::h1::{Codec, ExpectHandler, H1Service, UpgradeHandler};
use crate::h2::H2Service;
use crate::request::Request;
use crate::response::Response;
use crate::service::HttpService;
pub struct HttpServiceBuilder<T, S, X = ExpectHandler, U = UpgradeHandler<T>> {
keep_alive: KeepAlive,
client_timeout: u64,
client_disconnect: u64,
expect: X,
upgrade: Option<U>,
_t: PhantomData<(T, S)>,
}
impl<T, S> HttpServiceBuilder<T, S, ExpectHandler, UpgradeHandler<T>>
where
S: NewService<SrvConfig, Request = Request>,
S::Error: Into<Error>,
S::InitError: fmt::Debug,
{
pub fn new() -> Self {
HttpServiceBuilder {
keep_alive: KeepAlive::Timeout(5),
client_timeout: 5000,
client_disconnect: 0,
expect: ExpectHandler,
upgrade: None,
_t: PhantomData,
}
}
}
impl<T, S, X, U> HttpServiceBuilder<T, S, X, U>
where
S: NewService<SrvConfig, Request = Request>,
S::Error: Into<Error>,
S::InitError: fmt::Debug,
X: NewService<Request = Request, Response = Request>,
X::Error: Into<Error>,
X::InitError: fmt::Debug,
U: NewService<Request = (Request, Framed<T, Codec>), Response = ()>,
U::Error: fmt::Display,
U::InitError: fmt::Debug,
{
pub fn keep_alive<W: Into<KeepAlive>>(mut self, val: W) -> Self {
self.keep_alive = val.into();
self
}
pub fn client_timeout(mut self, val: u64) -> Self {
self.client_timeout = val;
self
}
pub fn client_disconnect(mut self, val: u64) -> Self {
self.client_disconnect = val;
self
}
pub fn expect<F, X1>(self, expect: F) -> HttpServiceBuilder<T, S, X1, U>
where
F: IntoNewService<X1>,
X1: NewService<Request = Request, Response = Request>,
X1::Error: Into<Error>,
X1::InitError: fmt::Debug,
{
HttpServiceBuilder {
keep_alive: self.keep_alive,
client_timeout: self.client_timeout,
client_disconnect: self.client_disconnect,
expect: expect.into_new_service(),
upgrade: self.upgrade,
_t: PhantomData,
}
}
pub fn upgrade<F, U1>(self, upgrade: F) -> HttpServiceBuilder<T, S, X, U1>
where
F: IntoNewService<U1>,
U1: NewService<Request = (Request, Framed<T, Codec>), Response = ()>,
U1::Error: fmt::Display,
U1::InitError: fmt::Debug,
{
HttpServiceBuilder {
keep_alive: self.keep_alive,
client_timeout: self.client_timeout,
client_disconnect: self.client_disconnect,
expect: self.expect,
upgrade: Some(upgrade.into_new_service()),
_t: PhantomData,
}
}
pub fn h1<F, P, B>(self, service: F) -> H1Service<T, P, S, B, X, U>
where
B: MessageBody + 'static,
F: IntoNewService<S, SrvConfig>,
S::Error: Into<Error>,
S::InitError: fmt::Debug,
S::Response: Into<Response<B>>,
{
let cfg = ServiceConfig::new(
self.keep_alive,
self.client_timeout,
self.client_disconnect,
);
H1Service::with_config(cfg, service.into_new_service())
.expect(self.expect)
.upgrade(self.upgrade)
}
pub fn h2<F, P, B>(self, service: F) -> H2Service<T, P, S, B>
where
B: MessageBody + 'static,
F: IntoNewService<S, SrvConfig>,
S::Error: Into<Error>,
S::InitError: fmt::Debug,
S::Response: Into<Response<B>>,
<S::Service as Service>::Future: 'static,
{
let cfg = ServiceConfig::new(
self.keep_alive,
self.client_timeout,
self.client_disconnect,
);
H2Service::with_config(cfg, service.into_new_service())
}
pub fn finish<F, P, B>(self, service: F) -> HttpService<T, P, S, B, X, U>
where
B: MessageBody + 'static,
F: IntoNewService<S, SrvConfig>,
S::Error: Into<Error>,
S::InitError: fmt::Debug,
S::Response: Into<Response<B>>,
<S::Service as Service>::Future: 'static,
{
let cfg = ServiceConfig::new(
self.keep_alive,
self.client_timeout,
self.client_disconnect,
);
HttpService::with_config(cfg, service.into_new_service())
.expect(self.expect)
.upgrade(self.upgrade)
}
}