use std::fmt::Debug; use std::marker::PhantomData; use actix_server_config::ServerConfig as SrvConfig; use actix_service::{IntoNewService, NewService}; use crate::body::MessageBody; use crate::config::{KeepAlive, ServiceConfig}; use crate::request::Request; use crate::response::Response; use crate::h1::H1Service; use crate::h2::H2Service; 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. pub struct HttpServiceBuilder { keep_alive: KeepAlive, client_timeout: u64, client_disconnect: u64, _t: PhantomData<(T, S)>, } impl HttpServiceBuilder where S: NewService, S::Error: Debug + 'static, S::Service: 'static, { /// Create instance of `ServiceConfigBuilder` pub fn new() -> HttpServiceBuilder { HttpServiceBuilder { keep_alive: KeepAlive::Timeout(5), client_timeout: 5000, client_disconnect: 0, _t: PhantomData, } } /// Set server keep-alive setting. /// /// By default keep alive is set to a 5 seconds. pub fn keep_alive>(mut self, val: U) -> Self { 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. /// /// By default disconnect timeout is set to 3000 milliseconds. pub fn client_disconnect(mut self, val: u64) -> Self { self.client_disconnect = val; self } // #[cfg(feature = "ssl")] // /// Configure alpn protocols for SslAcceptorBuilder. // pub fn configure_openssl( // builder: &mut openssl::ssl::SslAcceptorBuilder, // ) -> io::Result<()> { // let protos: &[u8] = b"\x02h2"; // builder.set_alpn_select_callback(|_, protos| { // const H2: &[u8] = b"\x02h2"; // if protos.windows(3).any(|window| window == H2) { // Ok(b"h2") // } else { // Err(openssl::ssl::AlpnError::NOACK) // } // }); // builder.set_alpn_protos(&protos)?; // Ok(()) // } /// Finish service configuration and create *http service* for HTTP/1 protocol. pub fn h1(self, service: F) -> H1Service where B: MessageBody + 'static, F: IntoNewService, S::Response: Into>, { let cfg = ServiceConfig::new( self.keep_alive, self.client_timeout, self.client_disconnect, ); H1Service::with_config(cfg, service.into_new_service()) } /// Finish service configuration and create *http service* for HTTP/2 protocol. pub fn h2(self, service: F) -> H2Service where B: MessageBody + 'static, F: IntoNewService, S::Response: Into>, { 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. pub fn finish(self, service: F) -> HttpService where B: MessageBody + 'static, F: IntoNewService, S::Response: Into>, { let cfg = ServiceConfig::new( self.keep_alive, self.client_timeout, self.client_disconnect, ); HttpService::with_config(cfg, service.into_new_service()) } }