1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-02-07 22:04:24 +01:00
actix-web/actix-http/src/builder.rs

245 lines
8.1 KiB
Rust
Raw Normal View History

2021-12-04 19:40:47 +00:00
use std::{fmt, marker::PhantomData, net, rc::Rc};
2019-03-09 10:39:06 -08:00
2019-04-08 14:51:16 -07:00
use actix_codec::Framed;
use actix_service::{IntoServiceFactory, Service, ServiceFactory};
2019-03-09 10:39:06 -08:00
2021-06-17 17:57:58 +01:00
use crate::{
2021-12-04 19:40:47 +00:00
body::{BoxBody, MessageBody},
2021-06-17 17:57:58 +01:00
config::{KeepAlive, ServiceConfig},
h1::{self, ExpectHandler, H1Service, UpgradeHandler},
h2::H2Service,
service::HttpService,
ConnectCallback, Extensions, Request, Response,
};
2019-03-09 10:39:06 -08:00
/// A HTTP service builder
2019-03-09 10:39:06 -08:00
///
/// This type can be used to construct an instance of [`HttpService`] through a
2019-03-09 10:39:06 -08:00
/// builder-like pattern.
pub struct HttpServiceBuilder<T, S, X = ExpectHandler, U = UpgradeHandler> {
2019-03-09 10:39:06 -08:00
keep_alive: KeepAlive,
client_timeout: u64,
client_disconnect: u64,
2019-12-02 17:33:11 +06:00
secure: bool,
local_addr: Option<net::SocketAddr>,
2019-04-05 16:46:44 -07:00
expect: X,
2019-04-08 14:51:16 -07:00
upgrade: Option<U>,
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
2021-01-04 00:49:02 +00:00
_phantom: PhantomData<S>,
2019-03-09 10:39:06 -08:00
}
impl<T, S> HttpServiceBuilder<T, S, ExpectHandler, UpgradeHandler>
2019-03-09 10:39:06 -08:00
where
S: ServiceFactory<Request, Config = ()>,
2021-12-04 19:40:47 +00:00
S::Error: Into<Response<BoxBody>> + 'static,
2019-04-05 16:46:44 -07:00
S::InitError: fmt::Debug,
<S::Service as Service<Request>>::Future: 'static,
2019-03-09 10:39:06 -08:00
{
/// Create instance of `ServiceConfigBuilder`
2021-12-22 07:16:07 +00:00
#[allow(clippy::new_without_default)]
2019-04-05 16:46:44 -07:00
pub fn new() -> Self {
2019-03-09 10:39:06 -08:00
HttpServiceBuilder {
keep_alive: KeepAlive::Timeout(5),
client_timeout: 5000,
client_disconnect: 0,
2019-12-02 17:33:11 +06:00
secure: false,
local_addr: None,
2019-04-05 16:46:44 -07:00
expect: ExpectHandler,
2019-04-08 14:51:16 -07:00
upgrade: None,
on_connect_ext: None,
2021-01-04 00:49:02 +00:00
_phantom: PhantomData,
2019-03-09 10:39:06 -08:00
}
}
2019-04-05 16:46:44 -07:00
}
2019-03-09 10:39:06 -08:00
2019-04-08 14:51:16 -07:00
impl<T, S, X, U> HttpServiceBuilder<T, S, X, U>
2019-04-05 16:46:44 -07:00
where
S: ServiceFactory<Request, Config = ()>,
2021-12-04 19:40:47 +00:00
S::Error: Into<Response<BoxBody>> + 'static,
2019-04-05 16:46:44 -07:00
S::InitError: fmt::Debug,
<S::Service as Service<Request>>::Future: 'static,
X: ServiceFactory<Request, Config = (), Response = Request>,
2021-12-04 19:40:47 +00:00
X::Error: Into<Response<BoxBody>>,
2019-04-05 16:46:44 -07:00
X::InitError: fmt::Debug,
2021-06-17 17:57:58 +01:00
U: ServiceFactory<(Request, Framed<T, h1::Codec>), Config = (), Response = ()>,
2019-04-08 14:51:16 -07:00
U::Error: fmt::Display,
U::InitError: fmt::Debug,
2019-04-05 16:46:44 -07:00
{
2019-03-09 10:39:06 -08:00
/// Set server keep-alive setting.
///
/// By default keep alive is set to a 5 seconds.
2019-04-08 14:51:16 -07:00
pub fn keep_alive<W: Into<KeepAlive>>(mut self, val: W) -> Self {
2019-03-09 10:39:06 -08:00
self.keep_alive = val.into();
self
}
2019-12-02 17:33:11 +06:00
/// Set connection secure state
pub fn secure(mut self) -> Self {
self.secure = true;
self
}
/// Set the local address that this service is bound to.
pub fn local_addr(mut self, addr: net::SocketAddr) -> Self {
self.local_addr = Some(addr);
self
}
2019-03-09 10:39:06 -08:00
/// 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 13:38:56 -08:00
/// By default disconnect timeout is set to 0.
2019-03-09 10:39:06 -08: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 14:51:16 -07:00
pub fn expect<F, X1>(self, expect: F) -> HttpServiceBuilder<T, S, X1, U>
where
F: IntoServiceFactory<X1, Request>,
X1: ServiceFactory<Request, Config = (), Response = Request>,
2021-12-04 19:40:47 +00:00
X1::Error: Into<Response<BoxBody>>,
2019-04-08 14:51:16 -07:00
X1::InitError: fmt::Debug,
{
HttpServiceBuilder {
keep_alive: self.keep_alive,
client_timeout: self.client_timeout,
client_disconnect: self.client_disconnect,
2019-12-02 17:33:11 +06:00
secure: self.secure,
local_addr: self.local_addr,
expect: expect.into_factory(),
2019-04-08 14:51:16 -07:00
upgrade: self.upgrade,
on_connect_ext: self.on_connect_ext,
2021-01-04 00:49:02 +00:00
_phantom: 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
2021-06-17 17:57:58 +01:00
F: IntoServiceFactory<U1, (Request, Framed<T, h1::Codec>)>,
U1: ServiceFactory<(Request, Framed<T, h1::Codec>), Config = (), 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,
2019-12-02 17:33:11 +06:00
secure: self.secure,
local_addr: self.local_addr,
expect: self.expect,
upgrade: Some(upgrade.into_factory()),
on_connect_ext: self.on_connect_ext,
2021-01-04 00:49:02 +00:00
_phantom: PhantomData,
}
}
/// Sets the callback to be run on connection establishment.
///
/// Has mutable access to a data container that will be merged into request extensions.
/// This enables transport layer data (like client certificates) to be accessed in middleware
/// and handlers.
pub fn on_connect_ext<F>(mut self, f: F) -> Self
where
F: Fn(&T, &mut Extensions) + 'static,
{
self.on_connect_ext = Some(Rc::new(f));
self
}
/// Finish service configuration and create a HTTP Service for HTTP/1 protocol.
2019-12-02 17:33:11 +06:00
pub fn h1<F, B>(self, service: F) -> H1Service<T, S, B, X, U>
2019-03-09 10:39:06 -08:00
where
2019-11-20 23:33:22 +06:00
B: MessageBody,
F: IntoServiceFactory<S, Request>,
2021-12-04 19:40:47 +00:00
S::Error: Into<Response<BoxBody>>,
2019-04-05 16:46:44 -07:00
S::InitError: fmt::Debug,
2019-11-20 23:33:22 +06:00
S::Response: Into<Response<B>>,
2019-03-09 10:39:06 -08:00
{
let cfg = ServiceConfig::new(
self.keep_alive,
self.client_timeout,
self.client_disconnect,
2019-12-02 17:33:11 +06:00
self.secure,
self.local_addr,
2019-03-09 10:39:06 -08:00
);
H1Service::with_config(cfg, service.into_factory())
2019-04-08 14:51:16 -07:00
.expect(self.expect)
.upgrade(self.upgrade)
.on_connect_ext(self.on_connect_ext)
2019-03-09 10:39:06 -08:00
}
/// Finish service configuration and create a HTTP service for HTTP/2 protocol.
2019-12-02 17:33:11 +06:00
pub fn h2<F, B>(self, service: F) -> H2Service<T, S, B>
2019-03-09 10:39:06 -08:00
where
F: IntoServiceFactory<S, Request>,
2021-12-04 19:40:47 +00:00
S::Error: Into<Response<BoxBody>> + 'static,
2019-04-05 16:46:44 -07:00
S::InitError: fmt::Debug,
2019-11-19 18:54:19 +06:00
S::Response: Into<Response<B>> + 'static,
B: MessageBody + 'static,
2019-03-09 10:39:06 -08:00
{
let cfg = ServiceConfig::new(
self.keep_alive,
self.client_timeout,
self.client_disconnect,
2019-12-02 17:33:11 +06:00
self.secure,
self.local_addr,
2019-03-09 10:39:06 -08:00
);
2021-12-08 06:01:11 +00:00
H2Service::with_config(cfg, service.into_factory()).on_connect_ext(self.on_connect_ext)
2019-03-09 10:39:06 -08:00
}
/// Finish service configuration and create `HttpService` instance.
2019-12-02 17:33:11 +06:00
pub fn finish<F, B>(self, service: F) -> HttpService<T, S, B, X, U>
2019-03-09 10:39:06 -08:00
where
F: IntoServiceFactory<S, Request>,
2021-12-04 19:40:47 +00:00
S::Error: Into<Response<BoxBody>> + 'static,
2019-04-05 16:46:44 -07:00
S::InitError: fmt::Debug,
2019-11-19 18:54:19 +06:00
S::Response: Into<Response<B>> + 'static,
B: MessageBody + 'static,
2019-03-09 10:39:06 -08:00
{
let cfg = ServiceConfig::new(
self.keep_alive,
self.client_timeout,
self.client_disconnect,
2019-12-02 17:33:11 +06:00
self.secure,
self.local_addr,
2019-03-09 10:39:06 -08:00
);
HttpService::with_config(cfg, service.into_factory())
2019-04-08 14:51:16 -07:00
.expect(self.expect)
.upgrade(self.upgrade)
.on_connect_ext(self.on_connect_ext)
2019-03-09 10:39:06 -08:00
}
}