1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-12-04 12:21:56 +01:00
actix-web/actix-http/src/builder.rs

225 lines
7.2 KiB
Rust
Raw Normal View History

2019-04-06 01:46:44 +02:00
use std::fmt;
2019-03-09 19:39:06 +01:00
use std::marker::PhantomData;
2019-06-28 10:34:26 +02:00
use std::rc::Rc;
2019-03-09 19:39:06 +01:00
2019-04-08 23:51:16 +02:00
use actix_codec::Framed;
2019-03-09 19:39:06 +01:00
use actix_server_config::ServerConfig as SrvConfig;
2019-04-04 19:59:34 +02:00
use actix_service::{IntoNewService, NewService, Service};
2019-03-09 19:39:06 +01:00
use crate::body::MessageBody;
use crate::config::{KeepAlive, ServiceConfig};
2019-04-06 01:46:44 +02:00
use crate::error::Error;
2019-04-08 23:51:16 +02:00
use crate::h1::{Codec, ExpectHandler, H1Service, UpgradeHandler};
2019-04-06 01:46:44 +02:00
use crate::h2::H2Service;
2019-06-28 10:34:26 +02:00
use crate::helpers::{Data, DataFactory};
2019-03-09 19:39:06 +01:00
use crate::request::Request;
use crate::response::Response;
use crate::service::HttpService;
/// A http service builder
///
/// This type can be used to construct an instance of `http service` through a
/// builder-like pattern.
2019-04-08 23:51:16 +02:00
pub struct HttpServiceBuilder<T, S, X = ExpectHandler, U = UpgradeHandler<T>> {
2019-03-09 19:39:06 +01:00
keep_alive: KeepAlive,
client_timeout: u64,
client_disconnect: u64,
2019-04-06 01:46:44 +02:00
expect: X,
2019-04-08 23:51:16 +02:00
upgrade: Option<U>,
2019-07-17 11:48:37 +02:00
on_connect: Option<Rc<dyn Fn(&T) -> Box<dyn DataFactory>>>,
2019-03-09 19:39:06 +01:00
_t: PhantomData<(T, S)>,
}
2019-04-08 23:51:16 +02:00
impl<T, S> HttpServiceBuilder<T, S, ExpectHandler, UpgradeHandler<T>>
2019-03-09 19:39:06 +01:00
where
2019-05-12 17:34:51 +02:00
S: NewService<Config = SrvConfig, Request = Request>,
2019-04-06 01:46:44 +02:00
S::Error: Into<Error>,
S::InitError: fmt::Debug,
2019-03-09 19:39:06 +01:00
{
/// Create instance of `ServiceConfigBuilder`
2019-04-06 01:46:44 +02:00
pub fn new() -> Self {
2019-03-09 19:39:06 +01:00
HttpServiceBuilder {
keep_alive: KeepAlive::Timeout(5),
client_timeout: 5000,
client_disconnect: 0,
2019-04-06 01:46:44 +02:00
expect: ExpectHandler,
2019-04-08 23:51:16 +02:00
upgrade: None,
2019-06-28 10:34:26 +02:00
on_connect: None,
2019-03-09 19:39:06 +01:00
_t: PhantomData,
}
}
2019-04-06 01:46:44 +02:00
}
2019-03-09 19:39:06 +01:00
2019-04-08 23:51:16 +02:00
impl<T, S, X, U> HttpServiceBuilder<T, S, X, U>
2019-04-06 01:46:44 +02:00
where
2019-05-12 17:34:51 +02:00
S: NewService<Config = SrvConfig, Request = Request>,
2019-04-06 01:46:44 +02:00
S::Error: Into<Error>,
S::InitError: fmt::Debug,
2019-05-12 17:34:51 +02:00
X: NewService<Config = SrvConfig, Request = Request, Response = Request>,
2019-04-06 01:46:44 +02:00
X::Error: Into<Error>,
X::InitError: fmt::Debug,
2019-05-12 17:34:51 +02:00
U: NewService<
Config = SrvConfig,
Request = (Request, Framed<T, Codec>),
Response = (),
>,
2019-04-08 23:51:16 +02:00
U::Error: fmt::Display,
U::InitError: fmt::Debug,
2019-04-06 01:46:44 +02:00
{
2019-03-09 19:39:06 +01:00
/// Set server keep-alive setting.
///
/// By default keep alive is set to a 5 seconds.
2019-04-08 23:51:16 +02:00
pub fn keep_alive<W: Into<KeepAlive>>(mut self, val: W) -> Self {
2019-03-09 19:39:06 +01:00
self.keep_alive = val.into();
self
}
/// Set server client timeout in milliseconds for first request.
///
/// Defines a timeout for reading client request header. If a client does not transmit
/// the entire set headers within this time, the request is terminated with
/// the 408 (Request Time-out) error.
///
/// To disable timeout set value to 0.
///
/// By default client timeout is set to 5000 milliseconds.
pub fn client_timeout(mut self, val: u64) -> Self {
self.client_timeout = val;
self
}
/// Set server connection disconnect timeout in milliseconds.
///
/// Defines a timeout for disconnect connection. If a disconnect procedure does not complete
/// within this time, the request get dropped. This timeout affects secure connections.
///
/// To disable timeout set value to 0.
///
2019-03-09 22:38:56 +01:00
/// By default disconnect timeout is set to 0.
2019-03-09 19:39:06 +01:00
pub fn client_disconnect(mut self, val: u64) -> Self {
self.client_disconnect = val;
self
}
/// Provide service for `EXPECT: 100-Continue` support.
///
/// Service get called with request that contains `EXPECT` header.
/// Service must return request in case of success, in that case
/// request will be forwarded to main service.
2019-04-08 23:51:16 +02:00
pub fn expect<F, X1>(self, expect: F) -> HttpServiceBuilder<T, S, X1, U>
where
2019-04-08 23:51:16 +02:00
F: IntoNewService<X1>,
2019-05-12 17:34:51 +02:00
X1: NewService<Config = SrvConfig, Request = Request, Response = Request>,
2019-04-08 23:51:16 +02:00
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(),
2019-04-08 23:51:16 +02:00
upgrade: self.upgrade,
2019-06-28 10:34:26 +02:00
on_connect: self.on_connect,
_t: PhantomData,
}
}
/// Provide service for custom `Connection: UPGRADE` support.
///
/// If service is provided then normal requests handling get halted
/// and this service get called with original request and framed object.
pub fn upgrade<F, U1>(self, upgrade: F) -> HttpServiceBuilder<T, S, X, U1>
where
F: IntoNewService<U1>,
2019-05-12 17:34:51 +02:00
U1: NewService<
Config = SrvConfig,
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()),
2019-06-28 10:34:26 +02:00
on_connect: self.on_connect,
_t: PhantomData,
}
}
2019-06-28 10:34:26 +02:00
/// Set on-connect callback.
///
/// It get called once per connection and result of the call
/// get stored to the request's extensions.
pub fn on_connect<F, I>(mut self, f: F) -> Self
where
F: Fn(&T) -> I + 'static,
I: Clone + 'static,
{
self.on_connect = Some(Rc::new(move |io| Box::new(Data(f(io)))));
self
}
2019-03-09 19:39:06 +01:00
/// Finish service configuration and create *http service* for HTTP/1 protocol.
2019-04-08 23:51:16 +02:00
pub fn h1<F, P, B>(self, service: F) -> H1Service<T, P, S, B, X, U>
2019-03-09 19:39:06 +01:00
where
B: MessageBody + 'static,
2019-05-12 17:34:51 +02:00
F: IntoNewService<S>,
2019-04-06 01:46:44 +02:00
S::Error: Into<Error>,
S::InitError: fmt::Debug,
2019-03-09 19:39:06 +01:00
S::Response: Into<Response<B>>,
{
let cfg = ServiceConfig::new(
self.keep_alive,
self.client_timeout,
self.client_disconnect,
);
2019-04-08 23:51:16 +02:00
H1Service::with_config(cfg, service.into_new_service())
.expect(self.expect)
.upgrade(self.upgrade)
2019-06-28 10:34:26 +02:00
.on_connect(self.on_connect)
2019-03-09 19:39:06 +01:00
}
/// Finish service configuration and create *http service* for HTTP/2 protocol.
2019-03-11 23:09:42 +01:00
pub fn h2<F, P, B>(self, service: F) -> H2Service<T, P, S, B>
2019-03-09 19:39:06 +01:00
where
B: MessageBody + 'static,
2019-05-12 17:34:51 +02:00
F: IntoNewService<S>,
2019-04-06 01:46:44 +02:00
S::Error: Into<Error>,
S::InitError: fmt::Debug,
2019-03-09 19:39:06 +01:00
S::Response: Into<Response<B>>,
2019-04-04 19:59:34 +02:00
<S::Service as Service>::Future: 'static,
2019-03-09 19:39:06 +01:00
{
let cfg = ServiceConfig::new(
self.keep_alive,
self.client_timeout,
self.client_disconnect,
);
H2Service::with_config(cfg, service.into_new_service())
}
/// Finish service configuration and create `HttpService` instance.
2019-04-08 23:51:16 +02:00
pub fn finish<F, P, B>(self, service: F) -> HttpService<T, P, S, B, X, U>
2019-03-09 19:39:06 +01:00
where
B: MessageBody + 'static,
2019-05-12 17:34:51 +02:00
F: IntoNewService<S>,
2019-04-06 01:46:44 +02:00
S::Error: Into<Error>,
S::InitError: fmt::Debug,
2019-03-09 19:39:06 +01:00
S::Response: Into<Response<B>>,
2019-04-04 19:59:34 +02:00
<S::Service as Service>::Future: 'static,
2019-03-09 19:39:06 +01:00
{
let cfg = ServiceConfig::new(
self.keep_alive,
self.client_timeout,
self.client_disconnect,
);
2019-04-08 23:51:16 +02:00
HttpService::with_config(cfg, service.into_new_service())
.expect(self.expect)
.upgrade(self.upgrade)
2019-06-28 10:34:26 +02:00
.on_connect(self.on_connect)
2019-03-09 19:39:06 +01:00
}
}