diff --git a/Cargo.toml b/Cargo.toml index 9d55b85c5..594ab88db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,7 @@ actix-codec = "0.1.1" actix-connector = { git="https://github.com/actix/actix-net.git" } actix-service = { git="https://github.com/actix/actix-net.git" } actix-utils = { git="https://github.com/actix/actix-net.git" } +actix-server-config = { git="https://github.com/actix/actix-net.git" } base64 = "0.10" backtrace = "0.3" @@ -92,6 +93,7 @@ actix-server = { git="https://github.com/actix/actix-net.git", features=["ssl"] #actix-connector = { version = "0.3.0", features=["ssl"] } actix-connector = { git="https://github.com/actix/actix-net.git", features=["ssl"] } actix-http-test = { path="test-server", features=["ssl"] } + env_logger = "0.6" serde_derive = "1.0" openssl = { version="0.10" } diff --git a/examples/echo.rs b/examples/echo.rs index 03d5b4706..eb4aaa657 100644 --- a/examples/echo.rs +++ b/examples/echo.rs @@ -1,3 +1,5 @@ +use std::{env, io}; + use actix_http::HttpMessage; use actix_http::{h1, Request, Response}; use actix_server::Server; @@ -6,9 +8,8 @@ use bytes::Bytes; use futures::Future; use http::header::HeaderValue; use log::info; -use std::env; -fn main() { +fn main() -> io::Result<()> { env::set_var("RUST_LOG", "echo=info"); env_logger::init(); @@ -27,7 +28,6 @@ fn main() { }) }) .map(|_| ()) - }) - .unwrap() - .run(); + })? + .run() } diff --git a/examples/echo2.rs b/examples/echo2.rs index 2fd9cbcff..3bb8d83d5 100644 --- a/examples/echo2.rs +++ b/examples/echo2.rs @@ -1,3 +1,5 @@ +use std::{env, io}; + use actix_http::http::HeaderValue; use actix_http::HttpMessage; use actix_http::{h1, Error, Request, Response}; @@ -6,7 +8,6 @@ use actix_service::NewService; use bytes::Bytes; use futures::Future; use log::info; -use std::env; fn handle_request(mut req: Request) -> impl Future { req.body().limit(512).from_err().and_then(|bytes: Bytes| { @@ -17,7 +18,7 @@ fn handle_request(mut req: Request) -> impl Future io::Result<()> { env::set_var("RUST_LOG", "echo=info"); env_logger::init(); @@ -29,7 +30,6 @@ fn main() { .server_hostname("localhost") .finish(|_req: Request| handle_request(_req)) .map(|_| ()) - }) - .unwrap() - .run(); + })? + .run() } diff --git a/examples/framed_hello.rs b/examples/framed_hello.rs index 5bbc3be9b..ff3977854 100644 --- a/examples/framed_hello.rs +++ b/examples/framed_hello.rs @@ -1,3 +1,5 @@ +use std::{env, io}; + use actix_codec::Framed; use actix_http::{h1, Response, SendResponse, ServiceConfig}; use actix_server::Server; @@ -5,9 +7,8 @@ use actix_service::NewService; use actix_utils::framed::IntoFramed; use actix_utils::stream::TakeItem; use futures::Future; -use std::env; -fn main() { +fn main() -> io::Result<()> { env::set_var("RUST_LOG", "framed_hello=info"); env_logger::init(); @@ -20,7 +21,6 @@ fn main() { .map_err(|_| ()) .map(|_| ()) }) - }) - .unwrap() - .run(); + })? + .run() } diff --git a/examples/hello-world.rs b/examples/hello-world.rs index e0c322a22..05d69fed8 100644 --- a/examples/hello-world.rs +++ b/examples/hello-world.rs @@ -1,12 +1,13 @@ +use std::{env, io}; + use actix_http::{h1, Response}; use actix_server::Server; use actix_service::NewService; use futures::future; use http::header::HeaderValue; use log::info; -use std::env; -fn main() { +fn main() -> io::Result<()> { env::set_var("RUST_LOG", "hello_world=info"); env_logger::init(); @@ -23,7 +24,6 @@ fn main() { future::ok::<_, ()>(res.body("Hello world!")) }) .map(|_| ()) - }) - .unwrap() - .run(); + })? + .run() } diff --git a/src/client/connector.rs b/src/client/connector.rs index d1fd802e9..5eb85ba61 100644 --- a/src/client/connector.rs +++ b/src/client/connector.rs @@ -133,8 +133,11 @@ impl Connector { /// Finish configuration process and create connector service. pub fn service( self, - ) -> impl Service + Clone - { + ) -> impl Service< + Request = Connect, + Response = impl Connection, + Error = ConnectorError, + > + Clone { #[cfg(not(feature = "ssl"))] { let connector = TimeoutService::new( @@ -238,7 +241,11 @@ mod connect_impl { pub(crate) struct InnerConnector where Io: AsyncRead + AsyncWrite + 'static, - T: Service, + T: Service< + Request = Connect, + Response = (Connect, Io, Protocol), + Error = ConnectorError, + >, { pub(crate) tcp_pool: ConnectionPool, } @@ -246,8 +253,11 @@ mod connect_impl { impl Clone for InnerConnector where Io: AsyncRead + AsyncWrite + 'static, - T: Service - + Clone, + T: Service< + Request = Connect, + Response = (Connect, Io, Protocol), + Error = ConnectorError, + > + Clone, { fn clone(&self) -> Self { InnerConnector { @@ -256,15 +266,16 @@ mod connect_impl { } } - impl Service for InnerConnector + impl Service for InnerConnector where Io: AsyncRead + AsyncWrite + 'static, T: Service, { + type Request = Connect; type Response = IoConnection; type Error = ConnectorError; type Future = Either< - as Service>::Future, + as Service>::Future, FutureResult, ConnectorError>, >; @@ -299,12 +310,12 @@ mod connect_impl { Io1: AsyncRead + AsyncWrite + 'static, Io2: AsyncRead + AsyncWrite + 'static, T1: Service< - Connect, + Request = Connect, Response = (Connect, Io1, Protocol), Error = ConnectorError, >, T2: Service< - Connect, + Request = Connect, Response = (Connect, Io2, Protocol), Error = ConnectorError, >, @@ -318,12 +329,12 @@ mod connect_impl { Io1: AsyncRead + AsyncWrite + 'static, Io2: AsyncRead + AsyncWrite + 'static, T1: Service< - Connect, + Request = Connect, Response = (Connect, Io1, Protocol), Error = ConnectorError, > + Clone, T2: Service< - Connect, + Request = Connect, Response = (Connect, Io2, Protocol), Error = ConnectorError, > + Clone, @@ -336,21 +347,22 @@ mod connect_impl { } } - impl Service for InnerConnector + impl Service for InnerConnector where Io1: AsyncRead + AsyncWrite + 'static, Io2: AsyncRead + AsyncWrite + 'static, T1: Service< - Connect, + Request = Connect, Response = (Connect, Io1, Protocol), Error = ConnectorError, >, T2: Service< - Connect, + Request = Connect, Response = (Connect, Io2, Protocol), Error = ConnectorError, >, { + type Request = Connect; type Response = EitherConnection; type Error = ConnectorError; type Future = Either< @@ -385,15 +397,23 @@ mod connect_impl { pub(crate) struct InnerConnectorResponseA where Io1: AsyncRead + AsyncWrite + 'static, - T: Service, + T: Service< + Request = Connect, + Response = (Connect, Io1, Protocol), + Error = ConnectorError, + >, { - fut: as Service>::Future, + fut: as Service>::Future, _t: PhantomData, } impl Future for InnerConnectorResponseA where - T: Service, + T: Service< + Request = Connect, + Response = (Connect, Io1, Protocol), + Error = ConnectorError, + >, Io1: AsyncRead + AsyncWrite + 'static, Io2: AsyncRead + AsyncWrite + 'static, { @@ -411,15 +431,23 @@ mod connect_impl { pub(crate) struct InnerConnectorResponseB where Io2: AsyncRead + AsyncWrite + 'static, - T: Service, + T: Service< + Request = Connect, + Response = (Connect, Io2, Protocol), + Error = ConnectorError, + >, { - fut: as Service>::Future, + fut: as Service>::Future, _t: PhantomData, } impl Future for InnerConnectorResponseB where - T: Service, + T: Service< + Request = Connect, + Response = (Connect, Io2, Protocol), + Error = ConnectorError, + >, Io1: AsyncRead + AsyncWrite + 'static, Io2: AsyncRead + AsyncWrite + 'static, { diff --git a/src/client/pool.rs b/src/client/pool.rs index 425e89395..188980cb3 100644 --- a/src/client/pool.rs +++ b/src/client/pool.rs @@ -48,7 +48,11 @@ pub(crate) struct ConnectionPool( impl ConnectionPool where Io: AsyncRead + AsyncWrite + 'static, - T: Service, + T: Service< + Request = Connect, + Response = (Connect, Io, Protocol), + Error = ConnectorError, + >, { pub(crate) fn new( connector: T, @@ -84,11 +88,16 @@ where } } -impl Service for ConnectionPool +impl Service for ConnectionPool where Io: AsyncRead + AsyncWrite + 'static, - T: Service, + T: Service< + Request = Connect, + Response = (Connect, Io, Protocol), + Error = ConnectorError, + >, { + type Request = Connect; type Response = IoConnection; type Error = ConnectorError; type Future = Either< diff --git a/src/client/request.rs b/src/client/request.rs index 637635d0f..7e971756d 100644 --- a/src/client/request.rs +++ b/src/client/request.rs @@ -176,7 +176,7 @@ where ) -> impl Future where B: 'static, - T: Service, + T: Service, I: Connection, { let Self { head, body } = self; diff --git a/src/h1/dispatcher.rs b/src/h1/dispatcher.rs index 42ab33e79..a7eb96c3f 100644 --- a/src/h1/dispatcher.rs +++ b/src/h1/dispatcher.rs @@ -36,14 +36,14 @@ bitflags! { } /// Dispatcher for HTTP/1.1 protocol -pub struct Dispatcher + 'static, B: MessageBody> +pub struct Dispatcher + 'static, B: MessageBody> where S::Error: Debug, { inner: Option>, } -struct InnerDispatcher + 'static, B: MessageBody> +struct InnerDispatcher + 'static, B: MessageBody> where S::Error: Debug, { @@ -67,13 +67,13 @@ enum DispatcherMessage { Error(Response<()>), } -enum State, B: MessageBody> { +enum State, B: MessageBody> { None, ServiceCall(S::Future), SendPayload(ResponseBody), } -impl, B: MessageBody> State { +impl, B: MessageBody> State { fn is_empty(&self) -> bool { if let State::None = self { true @@ -86,7 +86,7 @@ impl, B: MessageBody> State { impl Dispatcher where T: AsyncRead + AsyncWrite, - S: Service + 'static, + S: Service + 'static, S::Error: Debug, S::Response: Into>, B: MessageBody, @@ -145,7 +145,7 @@ where impl InnerDispatcher where T: AsyncRead + AsyncWrite, - S: Service + 'static, + S: Service + 'static, S::Error: Debug, S::Response: Into>, B: MessageBody, @@ -465,7 +465,7 @@ where impl Future for Dispatcher where T: AsyncRead + AsyncWrite, - S: Service, + S: Service, S::Error: Debug, S::Response: Into>, B: MessageBody, diff --git a/src/h1/service.rs b/src/h1/service.rs index 229229e69..6a36678b3 100644 --- a/src/h1/service.rs +++ b/src/h1/service.rs @@ -3,6 +3,7 @@ use std::marker::PhantomData; use std::net; use actix_codec::{AsyncRead, AsyncWrite, Framed}; +use actix_server_config::ServerConfig as SrvConfig; use actix_service::{IntoNewService, NewService, Service}; use actix_utils::cloneable::CloneableService; use futures::future::{ok, FutureResult}; @@ -28,14 +29,14 @@ pub struct H1Service { impl H1Service where - S: NewService, + S: NewService, S::Error: Debug, S::Response: Into>, S::Service: 'static, B: MessageBody, { /// Create new `HttpService` instance with default config. - pub fn new>(service: F) -> Self { + pub fn new>(service: F) -> Self { let cfg = ServiceConfig::new(KeepAlive::Timeout(5), 5000, 0); H1Service { @@ -46,7 +47,7 @@ where } /// Create new `HttpService` instance with config. - pub fn with_config>( + pub fn with_config>( cfg: ServiceConfig, service: F, ) -> Self { @@ -63,24 +64,25 @@ where } } -impl NewService for H1Service +impl NewService for H1Service where T: AsyncRead + AsyncWrite, - S: NewService, + S: NewService, S::Error: Debug, S::Response: Into>, S::Service: 'static, B: MessageBody, { + type Request = T; type Response = (); type Error = DispatchError; type InitError = S::InitError; type Service = H1ServiceHandler; type Future = H1ServiceResponse; - fn new_service(&self, _: &()) -> Self::Future { + fn new_service(&self, cfg: &SrvConfig) -> Self::Future { H1ServiceResponse { - fut: self.srv.new_service(&()).into_future(), + fut: self.srv.new_service(cfg).into_future(), cfg: Some(self.cfg.clone()), _t: PhantomData, } @@ -103,7 +105,7 @@ pub struct H1ServiceBuilder { impl H1ServiceBuilder where - S: NewService, + S: NewService, S::Error: Debug, { /// Create instance of `ServiceConfigBuilder` @@ -201,7 +203,7 @@ where pub fn finish(self, service: F) -> H1Service where B: MessageBody, - F: IntoNewService, + F: IntoNewService, { let cfg = ServiceConfig::new( self.keep_alive, @@ -217,7 +219,7 @@ where } #[doc(hidden)] -pub struct H1ServiceResponse, B> { +pub struct H1ServiceResponse, B> { fut: ::Future, cfg: Option, _t: PhantomData<(T, B)>, @@ -226,7 +228,7 @@ pub struct H1ServiceResponse, B> { impl Future for H1ServiceResponse where T: AsyncRead + AsyncWrite, - S: NewService, + S: NewService, S::Service: 'static, S::Error: Debug, S::Response: Into>, @@ -253,7 +255,7 @@ pub struct H1ServiceHandler { impl H1ServiceHandler where - S: Service, + S: Service, S::Error: Debug, S::Response: Into>, B: MessageBody, @@ -267,14 +269,15 @@ where } } -impl Service for H1ServiceHandler +impl Service for H1ServiceHandler where T: AsyncRead + AsyncWrite, - S: Service, + S: Service, S::Error: Debug, S::Response: Into>, B: MessageBody, { + type Request = T; type Response = (); type Error = DispatchError; type Future = Dispatcher; @@ -311,17 +314,18 @@ where } } -impl NewService for OneRequest +impl NewService for OneRequest where T: AsyncRead + AsyncWrite, { + type Request = T; type Response = (Request, Framed); type Error = ParseError; type InitError = (); type Service = OneRequestService; type Future = FutureResult; - fn new_service(&self, _: &()) -> Self::Future { + fn new_service(&self, _: &SrvConfig) -> Self::Future { ok(OneRequestService { config: self.config.clone(), _t: PhantomData, @@ -336,10 +340,11 @@ pub struct OneRequestService { _t: PhantomData, } -impl Service for OneRequestService +impl Service for OneRequestService where T: AsyncRead + AsyncWrite, { + type Request = T; type Response = (Request, Framed); type Error = ParseError; type Future = OneRequestServiceResponse; diff --git a/src/h2/dispatcher.rs b/src/h2/dispatcher.rs index be813bd57..a3c731ebb 100644 --- a/src/h2/dispatcher.rs +++ b/src/h2/dispatcher.rs @@ -38,7 +38,7 @@ bitflags! { /// Dispatcher for HTTP/2 protocol pub struct Dispatcher< T: AsyncRead + AsyncWrite, - S: Service + 'static, + S: Service + 'static, B: MessageBody, > { flags: Flags, @@ -53,7 +53,7 @@ pub struct Dispatcher< impl Dispatcher where T: AsyncRead + AsyncWrite, - S: Service + 'static, + S: Service + 'static, S::Error: fmt::Debug, S::Response: Into>, B: MessageBody + 'static, @@ -95,7 +95,7 @@ where impl Future for Dispatcher where T: AsyncRead + AsyncWrite, - S: Service + 'static, + S: Service + 'static, S::Error: fmt::Debug, S::Response: Into>, B: MessageBody + 'static, @@ -141,20 +141,20 @@ where } } -struct ServiceResponse, B> { +struct ServiceResponse { state: ServiceResponseState, config: ServiceConfig, buffer: Option, } -enum ServiceResponseState, B> { +enum ServiceResponseState { ServiceCall(S::Future, Option>), SendPayload(SendStream, ResponseBody), } impl ServiceResponse where - S: Service + 'static, + S: Service + 'static, S::Error: fmt::Debug, S::Response: Into>, B: MessageBody + 'static, @@ -222,7 +222,7 @@ where impl Future for ServiceResponse where - S: Service + 'static, + S: Service + 'static, S::Error: fmt::Debug, S::Response: Into>, B: MessageBody + 'static, diff --git a/src/h2/service.rs b/src/h2/service.rs index 530629947..57515d4e8 100644 --- a/src/h2/service.rs +++ b/src/h2/service.rs @@ -3,6 +3,7 @@ use std::marker::PhantomData; use std::{io, net}; use actix_codec::{AsyncRead, AsyncWrite, Framed}; +use actix_server_config::ServerConfig as SrvConfig; use actix_service::{IntoNewService, NewService, Service}; use actix_utils::cloneable::CloneableService; use bytes::Bytes; @@ -30,14 +31,14 @@ pub struct H2Service { impl H2Service where - S: NewService, + S: NewService, S::Service: 'static, S::Error: Debug + 'static, S::Response: Into>, B: MessageBody + 'static, { /// Create new `HttpService` instance. - pub fn new>(service: F) -> Self { + pub fn new>(service: F) -> Self { let cfg = ServiceConfig::new(KeepAlive::Timeout(5), 5000, 0); H2Service { @@ -48,7 +49,7 @@ where } /// Create new `HttpService` instance with config. - pub fn with_config>( + pub fn with_config>( cfg: ServiceConfig, service: F, ) -> Self { @@ -65,24 +66,25 @@ where } } -impl NewService for H2Service +impl NewService for H2Service where T: AsyncRead + AsyncWrite, - S: NewService, + S: NewService, S::Service: 'static, S::Error: Debug, S::Response: Into>, B: MessageBody + 'static, { + type Request = T; type Response = (); type Error = DispatchError; type InitError = S::InitError; type Service = H2ServiceHandler; type Future = H2ServiceResponse; - fn new_service(&self, _: &()) -> Self::Future { + fn new_service(&self, cfg: &SrvConfig) -> Self::Future { H2ServiceResponse { - fut: self.srv.new_service(&()).into_future(), + fut: self.srv.new_service(cfg).into_future(), cfg: Some(self.cfg.clone()), _t: PhantomData, } @@ -105,7 +107,7 @@ pub struct H2ServiceBuilder { impl H2ServiceBuilder where - S: NewService, + S: NewService, S::Service: 'static, S::Error: Debug + 'static, { @@ -204,7 +206,7 @@ where pub fn finish(self, service: F) -> H2Service where B: MessageBody, - F: IntoNewService, + F: IntoNewService, { let cfg = ServiceConfig::new( self.keep_alive, @@ -220,7 +222,7 @@ where } #[doc(hidden)] -pub struct H2ServiceResponse, B> { +pub struct H2ServiceResponse, B> { fut: ::Future, cfg: Option, _t: PhantomData<(T, B)>, @@ -229,7 +231,7 @@ pub struct H2ServiceResponse, B> { impl Future for H2ServiceResponse where T: AsyncRead + AsyncWrite, - S: NewService, + S: NewService, S::Service: 'static, S::Response: Into>, S::Error: Debug, @@ -256,7 +258,7 @@ pub struct H2ServiceHandler { impl H2ServiceHandler where - S: Service + 'static, + S: Service + 'static, S::Error: Debug, S::Response: Into>, B: MessageBody + 'static, @@ -270,14 +272,15 @@ where } } -impl Service for H2ServiceHandler +impl Service for H2ServiceHandler where T: AsyncRead + AsyncWrite, - S: Service + 'static, + S: Service + 'static, S::Error: Debug, S::Response: Into>, B: MessageBody + 'static, { + type Request = T; type Response = (); type Error = DispatchError; type Future = H2ServiceHandlerResponse; @@ -300,7 +303,11 @@ where } } -enum State + 'static, B: MessageBody> { +enum State< + T: AsyncRead + AsyncWrite, + S: Service + 'static, + B: MessageBody, +> { Incoming(Dispatcher), Handshake( Option>, @@ -312,7 +319,7 @@ enum State + 'static, B: MessageB pub struct H2ServiceHandlerResponse where T: AsyncRead + AsyncWrite, - S: Service + 'static, + S: Service + 'static, S::Error: Debug, S::Response: Into>, B: MessageBody + 'static, @@ -323,7 +330,7 @@ where impl Future for H2ServiceHandlerResponse where T: AsyncRead + AsyncWrite, - S: Service + 'static, + S: Service + 'static, S::Error: Debug, S::Response: Into>, B: MessageBody, diff --git a/src/lib.rs b/src/lib.rs index 74a46fd17..9d8bc50f1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -97,8 +97,7 @@ pub use self::message::{Head, Message, RequestHead, ResponseHead}; pub use self::payload::{Payload, PayloadStream}; pub use self::request::Request; pub use self::response::Response; -pub use self::service::HttpService; -pub use self::service::{SendError, SendResponse}; +pub use self::service::{HttpService, SendError, SendResponse}; pub mod dev { //! The `actix-web` prelude for library developers diff --git a/src/service/senderror.rs b/src/service/senderror.rs index 8268c6660..44d362593 100644 --- a/src/service/senderror.rs +++ b/src/service/senderror.rs @@ -22,11 +22,12 @@ where } } -impl NewService)>> for SendError +impl NewService for SendError where T: AsyncRead + AsyncWrite, E: ResponseError, { + type Request = Result)>; type Response = R; type Error = (E, Framed); type InitError = (); @@ -38,11 +39,12 @@ where } } -impl Service)>> for SendError +impl Service for SendError where T: AsyncRead + AsyncWrite, E: ResponseError, { + type Request = Result)>; type Response = R; type Error = (E, Framed); type Future = Either)>, SendErrorFut>; @@ -128,11 +130,12 @@ where } } -impl NewService<(Response, Framed)> for SendResponse +impl NewService for SendResponse where T: AsyncRead + AsyncWrite, B: MessageBody, { + type Request = (Response, Framed); type Response = Framed; type Error = Error; type InitError = (); @@ -144,11 +147,12 @@ where } } -impl Service<(Response, Framed)> for SendResponse +impl Service for SendResponse where T: AsyncRead + AsyncWrite, B: MessageBody, { + type Request = (Response, Framed); type Response = Framed; type Error = Error; type Future = SendResponseFut; diff --git a/src/service/service.rs b/src/service/service.rs index 3d0009ed0..0fa5d6653 100644 --- a/src/service/service.rs +++ b/src/service/service.rs @@ -3,6 +3,7 @@ use std::marker::PhantomData; use std::{fmt, io, net}; use actix_codec::{AsyncRead, AsyncWrite, Framed, FramedParts}; +use actix_server_config::ServerConfig as SrvConfig; use actix_service::{IntoNewService, NewService, Service}; use actix_utils::cloneable::CloneableService; use bytes::{Buf, BufMut, Bytes, BytesMut}; @@ -27,14 +28,14 @@ pub struct HttpService { impl HttpService where - S: NewService, + S: NewService, S::Service: 'static, S::Error: Debug + 'static, S::Response: Into>, B: MessageBody + 'static, { /// Create new `HttpService` instance. - pub fn new>(service: F) -> Self { + pub fn new>(service: F) -> Self { let cfg = ServiceConfig::new(KeepAlive::Timeout(5), 5000, 0); HttpService { @@ -45,7 +46,7 @@ where } /// Create new `HttpService` instance with config. - pub fn with_config>( + pub fn with_config>( cfg: ServiceConfig, service: F, ) -> Self { @@ -62,24 +63,25 @@ where } } -impl NewService for HttpService +impl NewService for HttpService where T: AsyncRead + AsyncWrite + 'static, - S: NewService, + S: NewService, S::Service: 'static, S::Error: Debug, S::Response: Into>, B: MessageBody + 'static, { + type Request = T; type Response = (); type Error = DispatchError; type InitError = S::InitError; type Service = HttpServiceHandler; type Future = HttpServiceResponse; - fn new_service(&self, _: &()) -> Self::Future { + fn new_service(&self, cfg: &SrvConfig) -> Self::Future { HttpServiceResponse { - fut: self.srv.new_service(&()).into_future(), + fut: self.srv.new_service(cfg).into_future(), cfg: Some(self.cfg.clone()), _t: PhantomData, } @@ -102,7 +104,7 @@ pub struct HttpServiceBuilder { impl HttpServiceBuilder where - S: NewService, + S: NewService, S::Service: 'static, S::Error: Debug + 'static, { @@ -220,7 +222,7 @@ where pub fn finish(self, service: F) -> HttpService where B: MessageBody, - F: IntoNewService, + F: IntoNewService, { let cfg = ServiceConfig::new( self.keep_alive, @@ -236,7 +238,7 @@ where } #[doc(hidden)] -pub struct HttpServiceResponse, B> { +pub struct HttpServiceResponse, B> { fut: ::Future, cfg: Option, _t: PhantomData<(T, B)>, @@ -245,7 +247,7 @@ pub struct HttpServiceResponse, B> { impl Future for HttpServiceResponse where T: AsyncRead + AsyncWrite, - S: NewService, + S: NewService, S::Service: 'static, S::Response: Into>, S::Error: Debug, @@ -272,7 +274,7 @@ pub struct HttpServiceHandler { impl HttpServiceHandler where - S: Service + 'static, + S: Service + 'static, S::Error: Debug, S::Response: Into>, B: MessageBody + 'static, @@ -286,14 +288,15 @@ where } } -impl Service for HttpServiceHandler +impl Service for HttpServiceHandler where T: AsyncRead + AsyncWrite + 'static, - S: Service + 'static, + S: Service + 'static, S::Error: Debug, S::Response: Into>, B: MessageBody + 'static, { + type Request = T; type Response = (); type Error = DispatchError; type Future = HttpServiceHandlerResponse; @@ -317,7 +320,7 @@ where } } -enum State + 'static, B: MessageBody> +enum State + 'static, B: MessageBody> where S::Error: fmt::Debug, T: AsyncRead + AsyncWrite + 'static, @@ -331,7 +334,7 @@ where pub struct HttpServiceHandlerResponse where T: AsyncRead + AsyncWrite + 'static, - S: Service + 'static, + S: Service + 'static, S::Error: Debug, S::Response: Into>, B: MessageBody + 'static, @@ -344,7 +347,7 @@ const HTTP2_PREFACE: [u8; 14] = *b"PRI * HTTP/2.0"; impl Future for HttpServiceHandlerResponse where T: AsyncRead + AsyncWrite, - S: Service + 'static, + S: Service + 'static, S::Error: Debug, S::Response: Into>, B: MessageBody, diff --git a/src/ws/client/mod.rs b/src/ws/client/mod.rs index 8e59e846d..12c7229b9 100644 --- a/src/ws/client/mod.rs +++ b/src/ws/client/mod.rs @@ -25,6 +25,20 @@ impl Protocol { } } + fn is_http(self) -> bool { + match self { + Protocol::Https | Protocol::Http => true, + _ => false, + } + } + + fn is_secure(self) -> bool { + match self { + Protocol::Https | Protocol::Wss => true, + _ => false, + } + } + fn port(self) -> u16 { match self { Protocol::Http | Protocol::Ws => 80, diff --git a/src/ws/client/service.rs b/src/ws/client/service.rs index c48b6e0c1..586873d19 100644 --- a/src/ws/client/service.rs +++ b/src/ws/client/service.rs @@ -26,7 +26,7 @@ pub type DefaultClient = Client; /// WebSocket's client pub struct Client where - T: Service, + T: Service, T::Response: AsyncRead + AsyncWrite, { connector: T, @@ -34,7 +34,7 @@ where impl Client where - T: Service, + T: Service, T::Response: AsyncRead + AsyncWrite, { /// Create new websocket's client factory @@ -51,7 +51,7 @@ impl Default for Client { impl Clone for Client where - T: Service + Clone, + T: Service + Clone, T::Response: AsyncRead + AsyncWrite, { fn clone(&self) -> Self { @@ -61,12 +61,13 @@ where } } -impl Service for Client +impl Service for Client where - T: Service, + T: Service, T::Response: AsyncRead + AsyncWrite + 'static, T::Future: 'static, { + type Request = Connect; type Response = Framed; type Error = ClientError; type Future = Either< diff --git a/src/ws/service.rs b/src/ws/service.rs index bbd9f7826..f3b066053 100644 --- a/src/ws/service.rs +++ b/src/ws/service.rs @@ -20,7 +20,8 @@ impl Default for VerifyWebSockets { } } -impl NewService<(Request, Framed)> for VerifyWebSockets { +impl NewService for VerifyWebSockets { + type Request = (Request, Framed); type Response = (Request, Framed); type Error = (HandshakeError, Framed); type InitError = (); @@ -32,7 +33,8 @@ impl NewService<(Request, Framed)> for VerifyWebSockets { } } -impl Service<(Request, Framed)> for VerifyWebSockets { +impl Service for VerifyWebSockets { + type Request = (Request, Framed); type Response = (Request, Framed); type Error = (HandshakeError, Framed); type Future = FutureResult; diff --git a/src/ws/transport.rs b/src/ws/transport.rs index 6a4f4d227..da7782be5 100644 --- a/src/ws/transport.rs +++ b/src/ws/transport.rs @@ -7,7 +7,7 @@ use super::{Codec, Frame, Message}; pub struct Transport where - S: Service + 'static, + S: Service + 'static, T: AsyncRead + AsyncWrite, { inner: FramedTransport, @@ -16,17 +16,17 @@ where impl Transport where T: AsyncRead + AsyncWrite, - S: Service, + S: Service, S::Future: 'static, S::Error: 'static, { - pub fn new>(io: T, service: F) -> Self { + pub fn new>(io: T, service: F) -> Self { Transport { inner: FramedTransport::new(Framed::new(io, Codec::new()), service), } } - pub fn with>(framed: Framed, service: F) -> Self { + pub fn with>(framed: Framed, service: F) -> Self { Transport { inner: FramedTransport::new(framed, service), } @@ -36,7 +36,7 @@ where impl Future for Transport where T: AsyncRead + AsyncWrite, - S: Service, + S: Service, S::Future: 'static, S::Error: 'static, { diff --git a/test-server/src/lib.rs b/test-server/src/lib.rs index dd7bc362a..6b70fbc10 100644 --- a/test-server/src/lib.rs +++ b/test-server/src/lib.rs @@ -56,7 +56,8 @@ impl TestServer { pub fn new( factory: F, ) -> TestServerRuntime< - impl Service + Clone, + impl Service + + Clone, > { let (tx, rx) = mpsc::channel(); @@ -88,8 +89,11 @@ impl TestServer { } fn new_connector( - ) -> impl Service + Clone - { + ) -> impl Service< + Request = Connect, + Response = impl Connection, + Error = ConnectorError, + > + Clone { #[cfg(feature = "ssl")] { use openssl::ssl::{SslConnector, SslMethod, SslVerifyMode}; @@ -202,7 +206,7 @@ impl TestServerRuntime { impl TestServerRuntime where - T: Service + Clone, + T: Service + Clone, T::Response: Connection, { /// Connect to websocket server at a given path diff --git a/tests/test_server.rs b/tests/test_server.rs index 4cffdd096..b7cd5557b 100644 --- a/tests/test_server.rs +++ b/tests/test_server.rs @@ -565,17 +565,22 @@ fn test_body_chunked_implicit() { assert_eq!(bytes, Bytes::from_static(STR.as_ref())); } +use actix_server_config::ServerConfig; +use actix_service::fn_cfg_factory; + #[test] fn test_response_http_error_handling() { let mut srv = TestServer::new(|| { - h1::H1Service::new(|_| { - let broken_header = Bytes::from_static(b"\0\0\0"); - ok::<_, ()>( - Response::Ok() - .header(http::header::CONTENT_TYPE, broken_header) - .body(STR), - ) - }) + h1::H1Service::new(fn_cfg_factory(|_: &ServerConfig| { + Ok::<_, ()>(|_| { + let broken_header = Bytes::from_static(b"\0\0\0"); + ok::<_, ()>( + Response::Ok() + .header(http::header::CONTENT_TYPE, broken_header) + .body(STR), + ) + }) + })) }); let req = srv.get().finish().unwrap();