diff --git a/Cargo.toml b/Cargo.toml index 1bc3af3b2..0b4ad38a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,8 +56,8 @@ ssl = ["openssl", "actix-server/ssl"] [dependencies] actix-codec = "0.1.0" -actix-service = "0.3.0" -actix-utils = "0.3.0" +actix-service = "0.3.2" +actix-utils = "0.3.1" actix-rt = "0.1.0" actix-http = { git = "https://github.com/actix/actix-http.git" } @@ -99,3 +99,6 @@ serde_derive = "1.0" lto = true opt-level = 3 codegen-units = 1 + +[patch.crates-io] +actix-service = { git = "https://github.com/actix/actix-net.git" } diff --git a/src/app.rs b/src/app.rs index e1479080a..8336fcca3 100644 --- a/src/app.rs +++ b/src/app.rs @@ -7,8 +7,8 @@ use actix_http::{Extensions, PayloadStream, Request, Response}; use actix_router::{Path, ResourceDef, ResourceInfo, Router, Url}; use actix_service::boxed::{self, BoxedNewService, BoxedService}; use actix_service::{ - AndThenNewService, ApplyNewService, IntoNewService, IntoNewTransform, NewService, - NewTransform, Service, + AndThenNewService, ApplyTransform, IntoNewService, IntoTransform, NewService, + Service, Transform, }; use futures::future::{ok, Either, FutureResult}; use futures::{Async, Future, IntoFuture, Poll}; @@ -237,17 +237,17 @@ where >, > where - M: NewTransform< + M: Transform< AppRouting

, Request = ServiceRequest

, Response = ServiceResponse, Error = (), InitError = (), >, - F: IntoNewTransform>, + F: IntoTransform>, { let fref = Rc::new(RefCell::new(None)); - let endpoint = ApplyNewService::new(mw, AppEntry::new(fref.clone())); + let endpoint = ApplyTransform::new(mw, AppEntry::new(fref.clone())); AppRouter { endpoint, chain: self.chain, @@ -480,7 +480,7 @@ where >, > where - M: NewTransform< + M: Transform< T::Service, Request = ServiceRequest

, Response = ServiceResponse, @@ -488,9 +488,9 @@ where InitError = (), >, B1: MessageBody, - F: IntoNewTransform, + F: IntoTransform, { - let endpoint = ApplyNewService::new(mw, self.endpoint); + let endpoint = ApplyTransform::new(mw, self.endpoint); AppRouter { endpoint, chain: self.chain, diff --git a/src/middleware/compress.rs b/src/middleware/compress.rs index 5d5586cf7..b95553cb5 100644 --- a/src/middleware/compress.rs +++ b/src/middleware/compress.rs @@ -8,8 +8,9 @@ use actix_http::http::header::{ }; use actix_http::http::{HttpTryFrom, StatusCode}; use actix_http::{Error, Head, ResponseHead}; -use actix_service::{IntoNewTransform, Service, Transform}; +use actix_service::{Service, Transform}; use bytes::{Bytes, BytesMut}; +use futures::future::{ok, FutureResult}; use futures::{Async, Future, Poll}; use log::trace; @@ -18,7 +19,6 @@ use brotli2::write::BrotliEncoder; #[cfg(feature = "flate2")] use flate2::write::{GzEncoder, ZlibEncoder}; -use crate::middleware::MiddlewareFactory; use crate::service::{ServiceRequest, ServiceResponse}; #[derive(Debug, Clone)] @@ -37,6 +37,33 @@ impl Default for Compress { } impl Transform for Compress +where + P: 'static, + B: MessageBody, + S: Service, Response = ServiceResponse>, + S::Future: 'static, +{ + type Request = ServiceRequest

; + type Response = ServiceResponse>; + type Error = S::Error; + type InitError = (); + type Transform = CompressMiddleware; + type Future = FutureResult; + + fn new_transform(&self, service: S) -> Self::Future { + ok(CompressMiddleware { + service, + encoding: self.0, + }) + } +} + +pub struct CompressMiddleware { + service: S, + encoding: ContentEncoding, +} + +impl Service for CompressMiddleware where P: 'static, B: MessageBody, @@ -49,14 +76,14 @@ where type Future = CompressResponse; fn poll_ready(&mut self) -> Poll<(), Self::Error> { - Ok(Async::Ready(())) + self.service.poll_ready() } - fn call(&mut self, req: ServiceRequest

, srv: &mut S) -> Self::Future { + fn call(&mut self, req: ServiceRequest

) -> Self::Future { // negotiate content-encoding let encoding = if let Some(val) = req.headers.get(ACCEPT_ENCODING) { if let Ok(enc) = val.to_str() { - AcceptEncoding::parse(enc, self.0) + AcceptEncoding::parse(enc, self.encoding) } else { ContentEncoding::Identity } @@ -66,7 +93,7 @@ where CompressResponse { encoding, - fut: srv.call(req), + fut: self.service.call(req), } } } @@ -102,18 +129,6 @@ where } } -impl IntoNewTransform, S> for Compress -where - P: 'static, - B: MessageBody, - S: Service, Response = ServiceResponse>, - S::Future: 'static, -{ - fn into_new_transform(self) -> MiddlewareFactory { - MiddlewareFactory::new(self) - } -} - enum EncoderBody { Body(B), Other(Box), diff --git a/src/middleware/defaultheaders.rs b/src/middleware/defaultheaders.rs index 40bf9f1cc..2bd1d5d46 100644 --- a/src/middleware/defaultheaders.rs +++ b/src/middleware/defaultheaders.rs @@ -3,10 +3,10 @@ use std::rc::Rc; use actix_http::http::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use actix_http::http::{HeaderMap, HttpTryFrom}; -use actix_service::{IntoNewTransform, Service, Transform}; -use futures::{Async, Future, Poll}; +use actix_service::{Service, Transform}; +use futures::future::{ok, FutureResult}; +use futures::{Future, Poll}; -use crate::middleware::MiddlewareFactory; use crate::service::{ServiceRequest, ServiceResponse}; /// `Middleware` for setting default response headers. @@ -84,35 +84,49 @@ impl DefaultHeaders { } } -impl IntoNewTransform, S> - for DefaultHeaders +impl Transform for DefaultHeaders where - S: Service, Response = ServiceResponse>, + S: Service, Response = ServiceResponse>, S::Future: 'static, { - fn into_new_transform(self) -> MiddlewareFactory { - MiddlewareFactory::new(self) + type Request = ServiceRequest

; + type Response = ServiceResponse; + type Error = S::Error; + type InitError = (); + type Transform = DefaultHeadersMiddleware; + type Future = FutureResult; + + fn new_transform(&self, service: S) -> Self::Future { + ok(DefaultHeadersMiddleware { + service, + inner: self.inner.clone(), + }) } } -impl Transform for DefaultHeaders +pub struct DefaultHeadersMiddleware { + service: S, + inner: Rc, +} + +impl Service for DefaultHeadersMiddleware where - S: Service, Response = ServiceResponse>, + S: Service, Response = ServiceResponse>, S::Future: 'static, { - type Request = ServiceRequest; + type Request = ServiceRequest

; type Response = ServiceResponse; type Error = S::Error; type Future = Box>; fn poll_ready(&mut self) -> Poll<(), Self::Error> { - Ok(Async::Ready(())) + self.service.poll_ready() } - fn call(&mut self, req: ServiceRequest, srv: &mut S) -> Self::Future { + fn call(&mut self, req: ServiceRequest

) -> Self::Future { let inner = self.inner.clone(); - Box::new(srv.call(req).map(move |mut res| { + Box::new(self.service.call(req).map(move |mut res| { // set response headers for (key, value) in inner.headers.iter() { if !res.headers().contains_key(key) { @@ -143,32 +157,44 @@ mod tests { #[test] fn test_default_headers() { - let mut mw = DefaultHeaders::new().header(CONTENT_TYPE, "0001"); - let mut srv = FnService::new(|req: ServiceRequest<_>| { + let srv = FnService::new(|req: ServiceRequest<_>| { req.into_response(HttpResponse::Ok().finish()) }); + let mut mw = block_on( + DefaultHeaders::new() + .header(CONTENT_TYPE, "0001") + .new_transform(srv), + ) + .unwrap(); let req = TestRequest::default().to_service(); - let resp = block_on(mw.call(req, &mut srv)).unwrap(); + let resp = block_on(mw.call(req)).unwrap(); assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); let req = TestRequest::default().to_service(); - let mut srv = FnService::new(|req: ServiceRequest<_>| { + let srv = FnService::new(|req: ServiceRequest<_>| { req.into_response(HttpResponse::Ok().header(CONTENT_TYPE, "0002").finish()) }); - let resp = block_on(mw.call(req, &mut srv)).unwrap(); + let mut mw = block_on( + DefaultHeaders::new() + .header(CONTENT_TYPE, "0001") + .new_transform(srv), + ) + .unwrap(); + let resp = block_on(mw.call(req)).unwrap(); assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0002"); } #[test] fn test_content_type() { - let mut mw = DefaultHeaders::new().content_type(); - let mut srv = FnService::new(|req: ServiceRequest<_>| { + let srv = FnService::new(|req: ServiceRequest<_>| { req.into_response(HttpResponse::Ok().finish()) }); + let mut mw = + block_on(DefaultHeaders::new().content_type().new_transform(srv)).unwrap(); let req = TestRequest::default().to_service(); - let resp = block_on(mw.call(req, &mut srv)).unwrap(); + let resp = block_on(mw.call(req)).unwrap(); assert_eq!( resp.headers().get(CONTENT_TYPE).unwrap(), "application/octet-stream" diff --git a/src/middleware/mod.rs b/src/middleware/mod.rs index 85127ee28..fc9923029 100644 --- a/src/middleware/mod.rs +++ b/src/middleware/mod.rs @@ -1,8 +1,3 @@ -use std::marker::PhantomData; - -use actix_service::{NewTransform, Service, Transform}; -use futures::future::{ok, FutureResult}; - #[cfg(any(feature = "brotli", feature = "flate2"))] mod compress; #[cfg(any(feature = "brotli", feature = "flate2"))] @@ -10,43 +5,3 @@ pub use self::compress::Compress; mod defaultheaders; pub use self::defaultheaders::DefaultHeaders; - -/// Helper for middleware service factory -pub struct MiddlewareFactory -where - T: Transform + Clone, - S: Service, -{ - tr: T, - _t: PhantomData, -} - -impl MiddlewareFactory -where - T: Transform + Clone, - S: Service, -{ - pub fn new(tr: T) -> Self { - MiddlewareFactory { - tr, - _t: PhantomData, - } - } -} - -impl NewTransform for MiddlewareFactory -where - T: Transform + Clone, - S: Service, -{ - type Request = T::Request; - type Response = T::Response; - type Error = T::Error; - type Transform = T; - type InitError = (); - type Future = FutureResult; - - fn new_transform(&self, _: &C) -> Self::Future { - ok(self.tr.clone()) - } -} diff --git a/src/resource.rs b/src/resource.rs index 342d801d4..755b8d075 100644 --- a/src/resource.rs +++ b/src/resource.rs @@ -4,7 +4,7 @@ use std::rc::Rc; use actix_http::{Error, Response}; use actix_service::boxed::{self, BoxedNewService, BoxedService}; use actix_service::{ - ApplyNewService, IntoNewService, IntoNewTransform, NewService, NewTransform, Service, + ApplyTransform, IntoNewService, IntoTransform, NewService, Service, Transform, }; use futures::future::{ok, Either, FutureResult}; use futures::{Async, Future, IntoFuture, Poll}; @@ -194,16 +194,16 @@ where >, > where - M: NewTransform< + M: Transform< T::Service, Request = ServiceRequest

, Response = ServiceResponse, Error = (), InitError = (), >, - F: IntoNewTransform, + F: IntoTransform, { - let endpoint = ApplyNewService::new(mw, self.endpoint); + let endpoint = ApplyTransform::new(mw, self.endpoint); Resource { endpoint, routes: self.routes, diff --git a/src/scope.rs b/src/scope.rs index 7aeb50412..b255ac14b 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -5,7 +5,7 @@ use actix_http::Response; use actix_router::{ResourceDef, ResourceInfo, Router}; use actix_service::boxed::{self, BoxedNewService, BoxedService}; use actix_service::{ - ApplyNewService, IntoNewService, IntoNewTransform, NewService, NewTransform, Service, + ApplyTransform, IntoNewService, IntoTransform, NewService, Service, Transform, }; use futures::future::{ok, Either, Future, FutureResult}; use futures::{Async, Poll}; @@ -251,16 +251,16 @@ where >, > where - M: NewTransform< + M: Transform< T::Service, Request = ServiceRequest

, Response = ServiceResponse, Error = (), InitError = (), >, - F: IntoNewTransform, + F: IntoTransform, { - let endpoint = ApplyNewService::new(mw, self.endpoint); + let endpoint = ApplyTransform::new(mw, self.endpoint); Scope { endpoint, rdef: self.rdef,