1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-24 00:21:08 +01:00

Remove generic type for request payload, always use default

This commit is contained in:
Nikolay Kim 2019-04-13 14:50:54 -07:00
parent 043f6e77ae
commit 4f30fa9d46
38 changed files with 704 additions and 1207 deletions

View File

@ -1,5 +1,15 @@
# Changes # Changes
## [1.0.0-alpha.6] - 2019-04-xx
### Changed
* Remove generic type for request payload, always use default.
* Removed `Decompress` middleware. Bytes, String, Json, Form extractors
automatically decompress payload.
## [1.0.0-alpha.5] - 2019-04-12 ## [1.0.0-alpha.5] - 2019-04-12
### Added ### Added

View File

@ -32,9 +32,8 @@ use self::error::{FilesError, UriSegmentError};
pub use crate::named::NamedFile; pub use crate::named::NamedFile;
pub use crate::range::HttpRange; pub use crate::range::HttpRange;
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, Error>; type HttpService = BoxedService<ServiceRequest, ServiceResponse, Error>;
type HttpNewService<P> = type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
/// Return the MIME type associated with a filename extension (case-insensitive). /// Return the MIME type associated with a filename extension (case-insensitive).
/// If `ext` is empty or no associated type for the extension was found, returns /// If `ext` is empty or no associated type for the extension was found, returns
@ -225,18 +224,18 @@ type MimeOverride = Fn(&mime::Name) -> DispositionType;
/// .service(fs::Files::new("/static", ".")); /// .service(fs::Files::new("/static", "."));
/// } /// }
/// ``` /// ```
pub struct Files<S> { pub struct Files {
path: String, path: String,
directory: PathBuf, directory: PathBuf,
index: Option<String>, index: Option<String>,
show_index: bool, show_index: bool,
default: Rc<RefCell<Option<Rc<HttpNewService<S>>>>>, default: Rc<RefCell<Option<Rc<HttpNewService>>>>,
renderer: Rc<DirectoryRenderer>, renderer: Rc<DirectoryRenderer>,
mime_override: Option<Rc<MimeOverride>>, mime_override: Option<Rc<MimeOverride>>,
file_flags: named::Flags, file_flags: named::Flags,
} }
impl<S> Clone for Files<S> { impl Clone for Files {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
directory: self.directory.clone(), directory: self.directory.clone(),
@ -251,13 +250,13 @@ impl<S> Clone for Files<S> {
} }
} }
impl<S: 'static> Files<S> { impl Files {
/// Create new `Files` instance for specified base directory. /// Create new `Files` instance for specified base directory.
/// ///
/// `File` uses `ThreadPool` for blocking filesystem operations. /// `File` uses `ThreadPool` for blocking filesystem operations.
/// By default pool with 5x threads of available cpus is used. /// By default pool with 5x threads of available cpus is used.
/// Pool size can be changed by setting ACTIX_CPU_POOL environment variable. /// Pool size can be changed by setting ACTIX_CPU_POOL environment variable.
pub fn new<T: Into<PathBuf>>(path: &str, dir: T) -> Files<S> { pub fn new<T: Into<PathBuf>>(path: &str, dir: T) -> Files {
let dir = dir.into().canonicalize().unwrap_or_else(|_| PathBuf::new()); let dir = dir.into().canonicalize().unwrap_or_else(|_| PathBuf::new());
if !dir.is_dir() { if !dir.is_dir() {
log::error!("Specified path is not a directory"); log::error!("Specified path is not a directory");
@ -335,7 +334,7 @@ impl<S: 'static> Files<S> {
where where
F: IntoNewService<U>, F: IntoNewService<U>,
U: NewService< U: NewService<
Request = ServiceRequest<S>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
> + 'static, > + 'static,
@ -349,11 +348,8 @@ impl<S: 'static> Files<S> {
} }
} }
impl<P> HttpServiceFactory<P> for Files<P> impl HttpServiceFactory for Files {
where fn register(self, config: &mut ServiceConfig) {
P: 'static,
{
fn register(self, config: &mut ServiceConfig<P>) {
if self.default.borrow().is_none() { if self.default.borrow().is_none() {
*self.default.borrow_mut() = Some(config.default_service()); *self.default.borrow_mut() = Some(config.default_service());
} }
@ -366,11 +362,11 @@ where
} }
} }
impl<P: 'static> NewService for Files<P> { impl NewService for Files {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type Service = FilesService<P>; type Service = FilesService;
type InitError = (); type InitError = ();
type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>; type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>;
@ -401,22 +397,22 @@ impl<P: 'static> NewService for Files<P> {
} }
} }
pub struct FilesService<P> { pub struct FilesService {
directory: PathBuf, directory: PathBuf,
index: Option<String>, index: Option<String>,
show_index: bool, show_index: bool,
default: Option<HttpService<P>>, default: Option<HttpService>,
renderer: Rc<DirectoryRenderer>, renderer: Rc<DirectoryRenderer>,
mime_override: Option<Rc<MimeOverride>>, mime_override: Option<Rc<MimeOverride>>,
file_flags: named::Flags, file_flags: named::Flags,
} }
impl<P> FilesService<P> { impl FilesService {
fn handle_err( fn handle_err(
&mut self, &mut self,
e: io::Error, e: io::Error,
req: HttpRequest, req: HttpRequest,
payload: Payload<P>, payload: Payload,
) -> Either< ) -> Either<
FutureResult<ServiceResponse, Error>, FutureResult<ServiceResponse, Error>,
Box<Future<Item = ServiceResponse, Error = Error>>, Box<Future<Item = ServiceResponse, Error = Error>>,
@ -430,8 +426,8 @@ impl<P> FilesService<P> {
} }
} }
impl<P> Service for FilesService<P> { impl Service for FilesService {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type Future = Either< type Future = Either<
@ -443,7 +439,7 @@ impl<P> Service for FilesService<P> {
Ok(Async::Ready(())) Ok(Async::Ready(()))
} }
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future { fn call(&mut self, req: ServiceRequest) -> Self::Future {
let (req, pl) = req.into_parts(); let (req, pl) = req.into_parts();
let real_path = match PathBufWrp::get_pathbuf(req.match_info().path()) { let real_path = match PathBufWrp::get_pathbuf(req.match_info().path()) {
@ -547,11 +543,11 @@ impl PathBufWrp {
} }
} }
impl<P> FromRequest<P> for PathBufWrp { impl FromRequest for PathBufWrp {
type Error = UriSegmentError; type Error = UriSegmentError;
type Future = Result<Self, Self::Error>; type Future = Result<Self, Self::Error>;
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
PathBufWrp::get_pathbuf(req.match_info().path()) PathBufWrp::get_pathbuf(req.match_info().path())
} }
} }
@ -570,6 +566,7 @@ mod tests {
self, ContentDisposition, DispositionParam, DispositionType, self, ContentDisposition, DispositionParam, DispositionType,
}; };
use actix_web::http::{Method, StatusCode}; use actix_web::http::{Method, StatusCode};
use actix_web::middleware::Compress;
use actix_web::test::{self, TestRequest}; use actix_web::test::{self, TestRequest};
use actix_web::App; use actix_web::App;
@ -965,7 +962,7 @@ mod tests {
#[test] #[test]
fn test_named_file_content_encoding() { fn test_named_file_content_encoding() {
let mut srv = test::init_service(App::new().enable_encoding().service( let mut srv = test::init_service(App::new().wrap(Compress::default()).service(
web::resource("/").to(|| { web::resource("/").to(|| {
NamedFile::open("Cargo.toml") NamedFile::open("Cargo.toml")
.unwrap() .unwrap()
@ -984,7 +981,7 @@ mod tests {
#[test] #[test]
fn test_named_file_content_encoding_gzip() { fn test_named_file_content_encoding_gzip() {
let mut srv = test::init_service(App::new().enable_encoding().service( let mut srv = test::init_service(App::new().wrap(Compress::default()).service(
web::resource("/").to(|| { web::resource("/").to(|| {
NamedFile::open("Cargo.toml") NamedFile::open("Cargo.toml")
.unwrap() .unwrap()
@ -1053,15 +1050,15 @@ mod tests {
#[test] #[test]
fn test_static_files_bad_directory() { fn test_static_files_bad_directory() {
let _st: Files<()> = Files::new("/", "missing"); let _st: Files = Files::new("/", "missing");
let _st: Files<()> = Files::new("/", "Cargo.toml"); let _st: Files = Files::new("/", "Cargo.toml");
} }
#[test] #[test]
fn test_default_handler_file_missing() { fn test_default_handler_file_missing() {
let mut st = test::block_on( let mut st = test::block_on(
Files::new("/", ".") Files::new("/", ".")
.default_handler(|req: ServiceRequest<_>| { .default_handler(|req: ServiceRequest| {
Ok(req.into_response(HttpResponse::Ok().body("default content"))) Ok(req.into_response(HttpResponse::Ok().body("default content")))
}) })
.new_service(&()), .new_service(&()),

View File

@ -15,7 +15,7 @@ use actix_web::http::header::{
self, ContentDisposition, DispositionParam, DispositionType, self, ContentDisposition, DispositionParam, DispositionType,
}; };
use actix_web::http::{ContentEncoding, Method, StatusCode}; use actix_web::http::{ContentEncoding, Method, StatusCode};
use actix_web::middleware::encoding::BodyEncoding; use actix_web::middleware::BodyEncoding;
use actix_web::{Error, HttpMessage, HttpRequest, HttpResponse, Responder}; use actix_web::{Error, HttpMessage, HttpRequest, HttpResponse, Responder};
use crate::range::HttpRange; use crate::range::HttpRange;

View File

@ -53,6 +53,7 @@ where
type Item = Bytes; type Item = Bytes;
type Error = PayloadError; type Error = PayloadError;
#[inline]
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> { fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
match self { match self {
Payload::None => Ok(Async::Ready(None)), Payload::None => Ok(Async::Ready(None)),

View File

@ -1,9 +1,5 @@
//! Multipart payload support //! Multipart payload support
use bytes::Bytes; use actix_web::{dev::Payload, Error, FromRequest, HttpRequest};
use futures::Stream;
use actix_web::error::{Error, PayloadError};
use actix_web::{dev::Payload, FromRequest, HttpRequest};
use crate::server::Multipart; use crate::server::Multipart;
@ -34,15 +30,12 @@ use crate::server::Multipart;
/// } /// }
/// # fn main() {} /// # fn main() {}
/// ``` /// ```
impl<P> FromRequest<P> for Multipart impl FromRequest for Multipart {
where
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
{
type Error = Error; type Error = Error;
type Future = Result<Multipart, Error>; type Future = Result<Multipart, Error>;
#[inline] #[inline]
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
Ok(Multipart::new(req.headers(), payload.take())) Ok(Multipart::new(req.headers(), payload.take()))
} }
} }

View File

@ -120,7 +120,7 @@ impl CookieSessionInner {
Ok(()) Ok(())
} }
fn load<P>(&self, req: &ServiceRequest<P>) -> HashMap<String, String> { fn load(&self, req: &ServiceRequest) -> HashMap<String, String> {
if let Ok(cookies) = req.cookies() { if let Ok(cookies) = req.cookies() {
for cookie in cookies.iter() { for cookie in cookies.iter() {
if cookie.name() == self.name { if cookie.name() == self.name {
@ -256,13 +256,13 @@ impl CookieSession {
} }
} }
impl<S, P, B: 'static> Transform<S> for CookieSession impl<S, B: 'static> Transform<S> for CookieSession
where where
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>, S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
S::Future: 'static, S::Future: 'static,
S::Error: 'static, S::Error: 'static,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse<B>; type Response = ServiceResponse<B>;
type Error = S::Error; type Error = S::Error;
type InitError = (); type InitError = ();
@ -283,13 +283,13 @@ pub struct CookieSessionMiddleware<S> {
inner: Rc<CookieSessionInner>, inner: Rc<CookieSessionInner>,
} }
impl<S, P, B: 'static> Service for CookieSessionMiddleware<S> impl<S, B: 'static> Service for CookieSessionMiddleware<S>
where where
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>, S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
S::Future: 'static, S::Future: 'static,
S::Error: 'static, S::Error: 'static,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse<B>; type Response = ServiceResponse<B>;
type Error = S::Error; type Error = S::Error;
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>; type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
@ -298,7 +298,7 @@ where
self.service.poll_ready() self.service.poll_ready()
} }
fn call(&mut self, mut req: ServiceRequest<P>) -> Self::Future { fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
let inner = self.inner.clone(); let inner = self.inner.clone();
let state = self.inner.load(&req); let state = self.inner.load(&req);
Session::set_session(state.into_iter(), &mut req); Session::set_session(state.into_iter(), &mut req);

View File

@ -119,9 +119,9 @@ impl Session {
inner.state.clear() inner.state.clear()
} }
pub fn set_session<P>( pub fn set_session(
data: impl Iterator<Item = (String, String)>, data: impl Iterator<Item = (String, String)>,
req: &mut ServiceRequest<P>, req: &mut ServiceRequest,
) { ) {
let session = Session::get_session(&mut *req.extensions_mut()); let session = Session::get_session(&mut *req.extensions_mut());
let mut inner = session.0.borrow_mut(); let mut inner = session.0.borrow_mut();
@ -172,12 +172,12 @@ impl Session {
/// } /// }
/// # fn main() {} /// # fn main() {}
/// ``` /// ```
impl<P> FromRequest<P> for Session { impl FromRequest for Session {
type Error = Error; type Error = Error;
type Future = Result<Session, Error>; type Future = Result<Session, Error>;
#[inline] #[inline]
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
Ok(Session::get_session(&mut *req.extensions_mut())) Ok(Session::get_session(&mut *req.extensions_mut()))
} }
} }

View File

@ -61,8 +61,8 @@ impl fmt::Display for Args {
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub struct {name}; pub struct {name};
impl<P: 'static> actix_web::dev::HttpServiceFactory<P> for {name} {{ impl actix_web::dev::HttpServiceFactory for {name} {{
fn register(self, config: &mut actix_web::dev::ServiceConfig<P>) {{ fn register(self, config: &mut actix_web::dev::ServiceConfig) {{
{ast} {ast}
let resource = actix_web::Resource::new(\"{path}\"){guards}.{to}({name}); let resource = actix_web::Resource::new(\"{path}\"){guards}.{to}({name});

View File

@ -4,11 +4,6 @@ use actix_web::{http, App, HttpResponse, Responder};
use actix_web_codegen::get; use actix_web_codegen::get;
use futures::{future, Future}; use futures::{future, Future};
//fn guard_head(head: &actix_web::dev::RequestHead) -> bool {
// true
//}
//#[get("/test", guard="guard_head")]
#[get("/test")] #[get("/test")]
fn test() -> impl Responder { fn test() -> impl Responder {
HttpResponse::Ok() HttpResponse::Ok()

View File

@ -27,7 +27,7 @@ fn main() -> std::io::Result<()> {
HttpServer::new(|| { HttpServer::new(|| {
App::new() App::new()
.wrap(middleware::DefaultHeaders::new().header("X-Version", "0.2")) .wrap(middleware::DefaultHeaders::new().header("X-Version", "0.2"))
.wrap(middleware::encoding::Compress::default()) .wrap(middleware::Compress::default())
.wrap(middleware::Logger::default()) .wrap(middleware::Logger::default())
.service(index) .service(index)
.service(no_params) .service(no_params)

View File

@ -3,22 +3,18 @@ use std::marker::PhantomData;
use std::rc::Rc; use std::rc::Rc;
use actix_http::body::{Body, MessageBody}; use actix_http::body::{Body, MessageBody};
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
use actix_http::encoding::{Decoder, Encoder};
use actix_server_config::ServerConfig; use actix_server_config::ServerConfig;
use actix_service::boxed::{self, BoxedNewService}; use actix_service::boxed::{self, BoxedNewService};
use actix_service::{ use actix_service::{
apply_transform, IntoNewService, IntoTransform, NewService, Transform, apply_transform, IntoNewService, IntoTransform, NewService, Transform,
}; };
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))] use futures::IntoFuture;
use bytes::Bytes;
use futures::{IntoFuture, Stream};
use crate::app_service::{AppChain, AppEntry, AppInit, AppRouting, AppRoutingFactory}; use crate::app_service::{AppEntry, AppInit, AppRoutingFactory};
use crate::config::{AppConfig, AppConfigInner, RouterConfig}; use crate::config::{AppConfig, AppConfigInner, RouterConfig};
use crate::data::{Data, DataFactory}; use crate::data::{Data, DataFactory};
use crate::dev::{Payload, PayloadStream, ResourceDef}; use crate::dev::ResourceDef;
use crate::error::{Error, PayloadError}; use crate::error::Error;
use crate::resource::Resource; use crate::resource::Resource;
use crate::route::Route; use crate::route::Route;
use crate::service::{ use crate::service::{
@ -26,40 +22,44 @@ use crate::service::{
ServiceResponse, ServiceResponse,
}; };
type HttpNewService<P> = type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
/// Application builder - structure that follows the builder pattern /// Application builder - structure that follows the builder pattern
/// for building application instances. /// for building application instances.
pub struct App<In, Out, T> pub struct App<T, B> {
where endpoint: T,
T: NewService<Request = ServiceRequest<In>, Response = ServiceRequest<Out>>, services: Vec<Box<ServiceFactory>>,
{ default: Option<Rc<HttpNewService>>,
chain: T, factory_ref: Rc<RefCell<Option<AppRoutingFactory>>>,
data: Vec<Box<DataFactory>>, data: Vec<Box<DataFactory>>,
config: AppConfigInner, config: AppConfigInner,
_t: PhantomData<(In, Out)>, external: Vec<ResourceDef>,
_t: PhantomData<(B)>,
} }
impl App<PayloadStream, PayloadStream, AppChain> { impl App<AppEntry, Body> {
/// Create application builder. Application can be configured with a builder-like pattern. /// Create application builder. Application can be configured with a builder-like pattern.
pub fn new() -> Self { pub fn new() -> Self {
let fref = Rc::new(RefCell::new(None));
App { App {
chain: AppChain, endpoint: AppEntry::new(fref.clone()),
data: Vec::new(), data: Vec::new(),
services: Vec::new(),
default: None,
factory_ref: fref,
config: AppConfigInner::default(), config: AppConfigInner::default(),
external: Vec::new(),
_t: PhantomData, _t: PhantomData,
} }
} }
} }
impl<In, Out, T> App<In, Out, T> impl<T, B> App<T, B>
where where
In: 'static, B: MessageBody,
Out: 'static,
T: NewService< T: NewService<
Request = ServiceRequest<In>, Request = ServiceRequest,
Response = ServiceRequest<Out>, Response = ServiceResponse<B>,
Error = Error, Error = Error,
InitError = (), InitError = (),
>, >,
@ -112,151 +112,6 @@ where
self self
} }
/// Registers middleware, in the form of a middleware component (type),
/// that runs during inbound and/or outbound processing in the request
/// lifecycle (request -> response), modifying request/response as
/// necessary, across all requests managed by the *Application*.
///
/// Use middleware when you need to read or modify *every* request or response in some way.
///
/// ```rust
/// use actix_service::Service;
/// # use futures::Future;
/// use actix_web::{middleware, web, App};
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
///
/// fn index() -> &'static str {
/// "Welcome!"
/// }
///
/// fn main() {
/// let app = App::new()
/// .wrap(middleware::Logger::default())
/// .route("/index.html", web::get().to(index));
/// }
/// ```
pub fn wrap<M, B, F>(
self,
mw: F,
) -> AppRouter<
T,
Out,
B,
impl NewService<
Request = ServiceRequest<Out>,
Response = ServiceResponse<B>,
Error = Error,
InitError = (),
>,
>
where
M: Transform<
AppRouting<Out>,
Request = ServiceRequest<Out>,
Response = ServiceResponse<B>,
Error = Error,
InitError = (),
>,
F: IntoTransform<M, AppRouting<Out>>,
{
let fref = Rc::new(RefCell::new(None));
let endpoint = apply_transform(mw, AppEntry::new(fref.clone()));
AppRouter {
endpoint,
chain: self.chain,
data: self.data,
services: Vec::new(),
default: None,
factory_ref: fref,
config: self.config,
external: Vec::new(),
_t: PhantomData,
}
}
/// Registers middleware, in the form of a closure, that runs during inbound
/// and/or outbound processing in the request lifecycle (request -> response),
/// modifying request/response as necessary, across all requests managed by
/// the *Application*.
///
/// Use middleware when you need to read or modify *every* request or response in some way.
///
/// ```rust
/// use actix_service::Service;
/// # use futures::Future;
/// use actix_web::{web, App};
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
///
/// fn index() -> &'static str {
/// "Welcome!"
/// }
///
/// fn main() {
/// let app = App::new()
/// .wrap_fn(|req, srv|
/// srv.call(req).map(|mut res| {
/// res.headers_mut().insert(
/// CONTENT_TYPE, HeaderValue::from_static("text/plain"),
/// );
/// res
/// }))
/// .route("/index.html", web::get().to(index));
/// }
/// ```
pub fn wrap_fn<F, R, B>(
self,
mw: F,
) -> AppRouter<
T,
Out,
B,
impl NewService<
Request = ServiceRequest<Out>,
Response = ServiceResponse<B>,
Error = Error,
InitError = (),
>,
>
where
F: FnMut(ServiceRequest<Out>, &mut AppRouting<Out>) -> R + Clone,
R: IntoFuture<Item = ServiceResponse<B>, Error = Error>,
{
self.wrap(mw)
}
/// Register a request modifier. It can modify any request parameters
/// including request payload type.
pub fn chain<C, F, P>(
self,
chain: F,
) -> App<
In,
P,
impl NewService<
Request = ServiceRequest<In>,
Response = ServiceRequest<P>,
Error = Error,
InitError = (),
>,
>
where
C: NewService<
Request = ServiceRequest<Out>,
Response = ServiceRequest<P>,
Error = Error,
InitError = (),
>,
F: IntoNewService<C>,
{
let chain = self.chain.and_then(chain.into_new_service());
App {
chain,
data: self.data,
config: self.config,
_t: PhantomData,
}
}
/// Run external configuration as part of the application building /// Run external configuration as part of the application building
/// process /// process
/// ///
@ -269,7 +124,7 @@ where
/// use actix_web::{web, middleware, App, HttpResponse}; /// use actix_web::{web, middleware, App, HttpResponse};
/// ///
/// // this function could be located in different module /// // this function could be located in different module
/// fn config<P>(cfg: &mut web::RouterConfig<P>) { /// fn config(cfg: &mut web::RouterConfig) {
/// cfg.service(web::resource("/test") /// cfg.service(web::resource("/test")
/// .route(web::get().to(|| HttpResponse::Ok())) /// .route(web::get().to(|| HttpResponse::Ok()))
/// .route(web::head().to(|| HttpResponse::MethodNotAllowed())) /// .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
@ -283,27 +138,16 @@ where
/// .route("/index.html", web::get().to(|| HttpResponse::Ok())); /// .route("/index.html", web::get().to(|| HttpResponse::Ok()));
/// } /// }
/// ``` /// ```
pub fn configure<F>(mut self, f: F) -> AppRouter<T, Out, Body, AppEntry<Out>> pub fn configure<F>(mut self, f: F) -> Self
where where
F: Fn(&mut RouterConfig<Out>), F: Fn(&mut RouterConfig),
{ {
let mut cfg = RouterConfig::new(); let mut cfg = RouterConfig::new();
f(&mut cfg); f(&mut cfg);
self.data.extend(cfg.data); self.data.extend(cfg.data);
self.services.extend(cfg.services);
let fref = Rc::new(RefCell::new(None)); self.external.extend(cfg.external);
self
AppRouter {
chain: self.chain,
default: None,
endpoint: AppEntry::new(fref.clone()),
factory_ref: fref,
data: self.data,
config: self.config,
services: cfg.services,
external: cfg.external,
_t: PhantomData,
}
} }
/// Configure route for a specific path. /// Configure route for a specific path.
@ -325,171 +169,7 @@ where
/// .route("/test2", web::post().to(|| HttpResponse::MethodNotAllowed())); /// .route("/test2", web::post().to(|| HttpResponse::MethodNotAllowed()));
/// } /// }
/// ``` /// ```
pub fn route( pub fn route(self, path: &str, mut route: Route) -> Self {
self,
path: &str,
mut route: Route<Out>,
) -> AppRouter<T, Out, Body, AppEntry<Out>> {
self.service(
Resource::new(path)
.add_guards(route.take_guards())
.route(route),
)
}
/// Register http service.
///
/// Http service is any type that implements `HttpServiceFactory` trait.
///
/// Actix web provides several services implementations:
///
/// * *Resource* is an entry in resource table which corresponds to requested URL.
/// * *Scope* is a set of resources with common root path.
/// * "StaticFiles" is a service for static files support
pub fn service<F>(self, service: F) -> AppRouter<T, Out, Body, AppEntry<Out>>
where
F: HttpServiceFactory<Out> + 'static,
{
let fref = Rc::new(RefCell::new(None));
AppRouter {
chain: self.chain,
default: None,
endpoint: AppEntry::new(fref.clone()),
factory_ref: fref,
data: self.data,
config: self.config,
services: vec![Box::new(ServiceFactoryWrapper::new(service))],
external: Vec::new(),
_t: PhantomData,
}
}
/// Set server host name.
///
/// Host name is used by application router as a hostname for url
/// generation. Check [ConnectionInfo](./dev/struct.ConnectionInfo.
/// html#method.host) documentation for more information.
///
/// By default host name is set to a "localhost" value.
pub fn hostname(mut self, val: &str) -> Self {
self.config.host = val.to_owned();
self
}
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
/// Enable content compression and decompression.
pub fn enable_encoding(
self,
) -> AppRouter<
impl NewService<
Request = ServiceRequest<In>,
Response = ServiceRequest<Decoder<Payload<Out>>>,
Error = Error,
InitError = (),
>,
Decoder<Payload<Out>>,
Encoder<Body>,
impl NewService<
Request = ServiceRequest<Decoder<Payload<Out>>>,
Response = ServiceResponse<Encoder<Body>>,
Error = Error,
InitError = (),
>,
>
where
Out: Stream<Item = Bytes, Error = PayloadError>,
{
use crate::middleware::encoding::{Compress, Decompress};
self.chain(Decompress::new()).wrap(Compress::default())
}
}
/// Application router builder - Structure that follows the builder pattern
/// for building application instances.
pub struct AppRouter<C, P, B, T> {
chain: C,
endpoint: T,
services: Vec<Box<ServiceFactory<P>>>,
default: Option<Rc<HttpNewService<P>>>,
factory_ref: Rc<RefCell<Option<AppRoutingFactory<P>>>>,
data: Vec<Box<DataFactory>>,
config: AppConfigInner,
external: Vec<ResourceDef>,
_t: PhantomData<(P, B)>,
}
impl<C, P, B, T> AppRouter<C, P, B, T>
where
P: 'static,
B: MessageBody,
T: NewService<
Request = ServiceRequest<P>,
Response = ServiceResponse<B>,
Error = Error,
InitError = (),
>,
{
/// Run external configuration as part of the application building
/// process
///
/// This function is useful for moving parts of configuration to a
/// different module or even library. For example,
/// some of the resource's configuration could be moved to different module.
///
/// ```rust
/// # extern crate actix_web;
/// use actix_web::{web, middleware, App, HttpResponse};
///
/// // this function could be located in different module
/// fn config<P>(cfg: &mut web::RouterConfig<P>) {
/// cfg.service(web::resource("/test")
/// .route(web::get().to(|| HttpResponse::Ok()))
/// .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
/// );
/// }
///
/// fn main() {
/// let app = App::new()
/// .wrap(middleware::Logger::default())
/// .configure(config) // <- register resources
/// .route("/index.html", web::get().to(|| HttpResponse::Ok()));
/// }
/// ```
pub fn configure<F>(mut self, f: F) -> Self
where
F: Fn(&mut RouterConfig<P>),
{
let mut cfg = RouterConfig::new();
f(&mut cfg);
self.data.extend(cfg.data);
self.services.extend(cfg.services);
self.external.extend(cfg.external);
self
}
/// Configure route for a specific path.
///
/// This is a simplified version of the `App::service()` method.
/// This method can not be could multiple times, in that case
/// multiple resources with one route would be registered for same resource path.
///
/// ```rust
/// use actix_web::{web, App, HttpResponse};
///
/// fn index(data: web::Path<(String, String)>) -> &'static str {
/// "Welcome!"
/// }
///
/// fn main() {
/// let app = App::new()
/// .route("/test1", web::get().to(index))
/// .route("/test2", web::post().to(|| HttpResponse::MethodNotAllowed()));
/// }
/// ```
pub fn route(self, path: &str, mut route: Route<P>) -> Self {
self.service( self.service(
Resource::new(path) Resource::new(path)
.add_guards(route.take_guards()) .add_guards(route.take_guards())
@ -508,94 +188,31 @@ where
/// * "StaticFiles" is a service for static files support /// * "StaticFiles" is a service for static files support
pub fn service<F>(mut self, factory: F) -> Self pub fn service<F>(mut self, factory: F) -> Self
where where
F: HttpServiceFactory<P> + 'static, F: HttpServiceFactory + 'static,
{ {
self.services self.services
.push(Box::new(ServiceFactoryWrapper::new(factory))); .push(Box::new(ServiceFactoryWrapper::new(factory)));
self self
} }
/// Registers middleware, in the form of a middleware component (type), /// Set server host name.
/// that runs during inbound and/or outbound processing in the request
/// lifecycle (request -> response), modifying request/response as
/// necessary, across all requests managed by the *Route*.
/// ///
/// Use middleware when you need to read or modify *every* request or response in some way. /// Host name is used by application router as a hostname for url
/// generation. Check [ConnectionInfo](./dev/struct.ConnectionInfo.
/// html#method.host) documentation for more information.
/// ///
pub fn wrap<M, B1, F>( /// By default host name is set to a "localhost" value.
self, pub fn hostname(mut self, val: &str) -> Self {
mw: F, self.config.host = val.to_owned();
) -> AppRouter< self
C,
P,
B1,
impl NewService<
Request = ServiceRequest<P>,
Response = ServiceResponse<B1>,
Error = Error,
InitError = (),
>,
>
where
M: Transform<
T::Service,
Request = ServiceRequest<P>,
Response = ServiceResponse<B1>,
Error = Error,
InitError = (),
>,
B1: MessageBody,
F: IntoTransform<M, T::Service>,
{
let endpoint = apply_transform(mw, self.endpoint);
AppRouter {
endpoint,
chain: self.chain,
data: self.data,
services: self.services,
default: self.default,
factory_ref: self.factory_ref,
config: self.config,
external: self.external,
_t: PhantomData,
}
}
/// Registers middleware, in the form of a closure, that runs during inbound
/// and/or outbound processing in the request lifecycle (request -> response),
/// modifying request/response as necessary, across all requests managed by
/// the *Route*.
///
/// Use middleware when you need to read or modify *every* request or response in some way.
///
pub fn wrap_fn<B1, F, R>(
self,
mw: F,
) -> AppRouter<
C,
P,
B1,
impl NewService<
Request = ServiceRequest<P>,
Response = ServiceResponse<B1>,
Error = Error,
InitError = (),
>,
>
where
B1: MessageBody,
F: FnMut(ServiceRequest<P>, &mut T::Service) -> R + Clone,
R: IntoFuture<Item = ServiceResponse<B1>, Error = Error>,
{
self.wrap(mw)
} }
/// Default resource to be used if no matching resource could be found. /// Default resource to be used if no matching resource could be found.
pub fn default_resource<F, U>(mut self, f: F) -> Self pub fn default_resource<F, U>(mut self, f: F) -> Self
where where
F: FnOnce(Resource<P>) -> Resource<P, U>, F: FnOnce(Resource) -> Resource<U>,
U: NewService< U: NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
@ -641,27 +258,128 @@ where
self.external.push(rdef); self.external.push(rdef);
self self
} }
/// Registers middleware, in the form of a middleware component (type),
/// that runs during inbound and/or outbound processing in the request
/// lifecycle (request -> response), modifying request/response as
/// necessary, across all requests managed by the *Application*.
///
/// Use middleware when you need to read or modify *every* request or response in some way.
///
/// ```rust
/// use actix_service::Service;
/// # use futures::Future;
/// use actix_web::{middleware, web, App};
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
///
/// fn index() -> &'static str {
/// "Welcome!"
/// }
///
/// fn main() {
/// let app = App::new()
/// .wrap(middleware::Logger::default())
/// .route("/index.html", web::get().to(index));
/// }
/// ```
pub fn wrap<M, B1, F>(
self,
mw: F,
) -> App<
impl NewService<
Request = ServiceRequest,
Response = ServiceResponse<B1>,
Error = Error,
InitError = (),
>,
B1,
>
where
M: Transform<
T::Service,
Request = ServiceRequest,
Response = ServiceResponse<B1>,
Error = Error,
InitError = (),
>,
B1: MessageBody,
F: IntoTransform<M, T::Service>,
{
let endpoint = apply_transform(mw, self.endpoint);
App {
endpoint,
data: self.data,
services: self.services,
default: self.default,
factory_ref: self.factory_ref,
config: self.config,
external: self.external,
_t: PhantomData,
}
} }
impl<C, T, P: 'static, B: MessageBody> IntoNewService<AppInit<C, T, P, B>, ServerConfig> /// Registers middleware, in the form of a closure, that runs during inbound
for AppRouter<C, P, B, T> /// and/or outbound processing in the request lifecycle (request -> response),
/// modifying request/response as necessary, across all requests managed by
/// the *Application*.
///
/// Use middleware when you need to read or modify *every* request or response in some way.
///
/// ```rust
/// use actix_service::Service;
/// # use futures::Future;
/// use actix_web::{web, App};
/// use actix_web::http::{header::CONTENT_TYPE, HeaderValue};
///
/// fn index() -> &'static str {
/// "Welcome!"
/// }
///
/// fn main() {
/// let app = App::new()
/// .wrap_fn(|req, srv|
/// srv.call(req).map(|mut res| {
/// res.headers_mut().insert(
/// CONTENT_TYPE, HeaderValue::from_static("text/plain"),
/// );
/// res
/// }))
/// .route("/index.html", web::get().to(index));
/// }
/// ```
pub fn wrap_fn<B1, F, R>(
self,
mw: F,
) -> App<
impl NewService<
Request = ServiceRequest,
Response = ServiceResponse<B1>,
Error = Error,
InitError = (),
>,
B1,
>
where where
B1: MessageBody,
F: FnMut(ServiceRequest, &mut T::Service) -> R + Clone,
R: IntoFuture<Item = ServiceResponse<B1>, Error = Error>,
{
self.wrap(mw)
}
}
impl<T, B> IntoNewService<AppInit<T, B>, ServerConfig> for App<T, B>
where
B: MessageBody,
T: NewService< T: NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse<B>, Response = ServiceResponse<B>,
Error = Error, Error = Error,
InitError = (), InitError = (),
>, >,
C: NewService<
Request = ServiceRequest,
Response = ServiceRequest<P>,
Error = Error,
InitError = (),
>,
{ {
fn into_new_service(self) -> AppInit<C, T, P, B> { fn into_new_service(self) -> AppInit<T, B> {
AppInit { AppInit {
chain: self.chain,
data: self.data, data: self.data,
endpoint: self.endpoint, endpoint: self.endpoint,
services: RefCell::new(self.services), services: RefCell::new(self.services),
@ -742,13 +460,13 @@ mod tests {
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR); assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
} }
fn md<S, P, B>( fn md<S, B>(
req: ServiceRequest<P>, req: ServiceRequest,
srv: &mut S, srv: &mut S,
) -> impl IntoFuture<Item = ServiceResponse<B>, Error = Error> ) -> impl IntoFuture<Item = ServiceResponse<B>, Error = Error>
where where
S: Service< S: Service<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse<B>, Response = ServiceResponse<B>,
Error = Error, Error = Error,
>, >,

View File

@ -6,7 +6,7 @@ use actix_http::{Request, Response};
use actix_router::{Path, ResourceDef, ResourceInfo, Router, Url}; use actix_router::{Path, ResourceDef, ResourceInfo, Router, Url};
use actix_server_config::ServerConfig; use actix_server_config::ServerConfig;
use actix_service::boxed::{self, BoxedNewService, BoxedService}; use actix_service::boxed::{self, BoxedNewService, BoxedService};
use actix_service::{fn_service, AndThen, NewService, Service, ServiceExt}; use actix_service::{fn_service, NewService, Service};
use futures::future::{ok, Either, FutureResult}; use futures::future::{ok, Either, FutureResult};
use futures::{Async, Future, Poll}; use futures::{Async, Future, Poll};
@ -19,9 +19,8 @@ use crate::rmap::ResourceMap;
use crate::service::{ServiceFactory, ServiceRequest, ServiceResponse}; use crate::service::{ServiceFactory, ServiceRequest, ServiceResponse};
type Guards = Vec<Box<Guard>>; type Guards = Vec<Box<Guard>>;
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, Error>; type HttpService = BoxedService<ServiceRequest, ServiceResponse, Error>;
type HttpNewService<P> = type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
type BoxedResponse = Either< type BoxedResponse = Either<
FutureResult<ServiceResponse, Error>, FutureResult<ServiceResponse, Error>,
Box<Future<Item = ServiceResponse, Error = Error>>, Box<Future<Item = ServiceResponse, Error = Error>>,
@ -29,36 +28,28 @@ type BoxedResponse = Either<
/// Service factory to convert `Request` to a `ServiceRequest<S>`. /// Service factory to convert `Request` to a `ServiceRequest<S>`.
/// It also executes data factories. /// It also executes data factories.
pub struct AppInit<C, T, P, B> pub struct AppInit<T, B>
where where
C: NewService<Request = ServiceRequest, Response = ServiceRequest<P>>,
T: NewService< T: NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse<B>, Response = ServiceResponse<B>,
Error = Error, Error = Error,
InitError = (), InitError = (),
>, >,
{ {
pub(crate) chain: C,
pub(crate) endpoint: T, pub(crate) endpoint: T,
pub(crate) data: Vec<Box<DataFactory>>, pub(crate) data: Vec<Box<DataFactory>>,
pub(crate) config: RefCell<AppConfig>, pub(crate) config: RefCell<AppConfig>,
pub(crate) services: RefCell<Vec<Box<ServiceFactory<P>>>>, pub(crate) services: RefCell<Vec<Box<ServiceFactory>>>,
pub(crate) default: Option<Rc<HttpNewService<P>>>, pub(crate) default: Option<Rc<HttpNewService>>,
pub(crate) factory_ref: Rc<RefCell<Option<AppRoutingFactory<P>>>>, pub(crate) factory_ref: Rc<RefCell<Option<AppRoutingFactory>>>,
pub(crate) external: RefCell<Vec<ResourceDef>>, pub(crate) external: RefCell<Vec<ResourceDef>>,
} }
impl<C, T, P: 'static, B> NewService<ServerConfig> for AppInit<C, T, P, B> impl<T, B> NewService<ServerConfig> for AppInit<T, B>
where where
C: NewService<
Request = ServiceRequest,
Response = ServiceRequest<P>,
Error = Error,
InitError = (),
>,
T: NewService< T: NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse<B>, Response = ServiceResponse<B>,
Error = Error, Error = Error,
InitError = (), InitError = (),
@ -66,15 +57,15 @@ where
{ {
type Request = Request; type Request = Request;
type Response = ServiceResponse<B>; type Response = ServiceResponse<B>;
type Error = C::Error; type Error = T::Error;
type InitError = C::InitError; type InitError = T::InitError;
type Service = AndThen<AppInitService<C::Service, P>, T::Service>; type Service = AppInitService<T::Service, B>;
type Future = AppInitResult<C, T, P, B>; type Future = AppInitResult<T, B>;
fn new_service(&self, cfg: &ServerConfig) -> Self::Future { fn new_service(&self, cfg: &ServerConfig) -> Self::Future {
// update resource default service // update resource default service
let default = self.default.clone().unwrap_or_else(|| { let default = self.default.clone().unwrap_or_else(|| {
Rc::new(boxed::new_service(fn_service(|req: ServiceRequest<P>| { Rc::new(boxed::new_service(fn_service(|req: ServiceRequest| {
Ok(req.into_response(Response::NotFound().finish())) Ok(req.into_response(Response::NotFound().finish()))
}))) })))
}); });
@ -121,8 +112,6 @@ where
rmap.finish(rmap.clone()); rmap.finish(rmap.clone());
AppInitResult { AppInitResult {
chain: None,
chain_fut: self.chain.new_service(&()),
endpoint: None, endpoint: None,
endpoint_fut: self.endpoint.new_service(&()), endpoint_fut: self.endpoint.new_service(&()),
data: self.data.iter().map(|s| s.construct()).collect(), data: self.data.iter().map(|s| s.construct()).collect(),
@ -133,38 +122,29 @@ where
} }
} }
pub struct AppInitResult<C, T, P, B> pub struct AppInitResult<T, B>
where where
C: NewService,
T: NewService, T: NewService,
{ {
chain: Option<C::Service>,
endpoint: Option<T::Service>, endpoint: Option<T::Service>,
chain_fut: C::Future,
endpoint_fut: T::Future, endpoint_fut: T::Future,
rmap: Rc<ResourceMap>, rmap: Rc<ResourceMap>,
data: Vec<Box<DataFactoryResult>>, data: Vec<Box<DataFactoryResult>>,
config: AppConfig, config: AppConfig,
_t: PhantomData<(P, B)>, _t: PhantomData<B>,
} }
impl<C, T, P, B> Future for AppInitResult<C, T, P, B> impl<T, B> Future for AppInitResult<T, B>
where where
C: NewService<
Request = ServiceRequest,
Response = ServiceRequest<P>,
Error = Error,
InitError = (),
>,
T: NewService< T: NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse<B>, Response = ServiceResponse<B>,
Error = Error, Error = Error,
InitError = (), InitError = (),
>, >,
{ {
type Item = AndThen<AppInitService<C::Service, P>, T::Service>; type Item = AppInitService<T::Service, B>;
type Error = C::InitError; type Error = T::InitError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let mut idx = 0; let mut idx = 0;
@ -177,28 +157,19 @@ where
} }
} }
if self.chain.is_none() {
if let Async::Ready(srv) = self.chain_fut.poll()? {
self.chain = Some(srv);
}
}
if self.endpoint.is_none() { if self.endpoint.is_none() {
if let Async::Ready(srv) = self.endpoint_fut.poll()? { if let Async::Ready(srv) = self.endpoint_fut.poll()? {
self.endpoint = Some(srv); self.endpoint = Some(srv);
} }
} }
if self.chain.is_some() && self.endpoint.is_some() { if self.endpoint.is_some() {
Ok(Async::Ready( Ok(Async::Ready(AppInitService {
AppInitService { service: self.endpoint.take().unwrap(),
chain: self.chain.take().unwrap(),
rmap: self.rmap.clone(), rmap: self.rmap.clone(),
config: self.config.clone(), config: self.config.clone(),
pool: HttpRequestPool::create(), pool: HttpRequestPool::create(),
} }))
.and_then(self.endpoint.take().unwrap()),
))
} else { } else {
Ok(Async::NotReady) Ok(Async::NotReady)
} }
@ -206,27 +177,27 @@ where
} }
/// Service to convert `Request` to a `ServiceRequest<S>` /// Service to convert `Request` to a `ServiceRequest<S>`
pub struct AppInitService<C, P> pub struct AppInitService<T: Service, B>
where where
C: Service<Request = ServiceRequest, Response = ServiceRequest<P>, Error = Error>, T: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
{ {
chain: C, service: T,
rmap: Rc<ResourceMap>, rmap: Rc<ResourceMap>,
config: AppConfig, config: AppConfig,
pool: &'static HttpRequestPool, pool: &'static HttpRequestPool,
} }
impl<C, P> Service for AppInitService<C, P> impl<T, B> Service for AppInitService<T, B>
where where
C: Service<Request = ServiceRequest, Response = ServiceRequest<P>, Error = Error>, T: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
{ {
type Request = Request; type Request = Request;
type Response = ServiceRequest<P>; type Response = ServiceResponse<B>;
type Error = C::Error; type Error = T::Error;
type Future = C::Future; type Future = T::Future;
fn poll_ready(&mut self) -> Poll<(), Self::Error> { fn poll_ready(&mut self) -> Poll<(), Self::Error> {
self.chain.poll_ready() self.service.poll_ready()
} }
fn call(&mut self, req: Request) -> Self::Future { fn call(&mut self, req: Request) -> Self::Future {
@ -247,22 +218,22 @@ where
self.pool, self.pool,
) )
}; };
self.chain.call(ServiceRequest::from_parts(req, payload)) self.service.call(ServiceRequest::from_parts(req, payload))
} }
} }
pub struct AppRoutingFactory<P> { pub struct AppRoutingFactory {
services: Rc<Vec<(ResourceDef, HttpNewService<P>, RefCell<Option<Guards>>)>>, services: Rc<Vec<(ResourceDef, HttpNewService, RefCell<Option<Guards>>)>>,
default: Rc<HttpNewService<P>>, default: Rc<HttpNewService>,
} }
impl<P: 'static> NewService for AppRoutingFactory<P> { impl NewService for AppRoutingFactory {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type InitError = (); type InitError = ();
type Service = AppRouting<P>; type Service = AppRouting;
type Future = AppRoutingFactoryResponse<P>; type Future = AppRoutingFactoryResponse;
fn new_service(&self, _: &()) -> Self::Future { fn new_service(&self, _: &()) -> Self::Future {
AppRoutingFactoryResponse { AppRoutingFactoryResponse {
@ -283,23 +254,23 @@ impl<P: 'static> NewService for AppRoutingFactory<P> {
} }
} }
type HttpServiceFut<P> = Box<Future<Item = HttpService<P>, Error = ()>>; type HttpServiceFut = Box<Future<Item = HttpService, Error = ()>>;
/// Create app service /// Create app service
#[doc(hidden)] #[doc(hidden)]
pub struct AppRoutingFactoryResponse<P> { pub struct AppRoutingFactoryResponse {
fut: Vec<CreateAppRoutingItem<P>>, fut: Vec<CreateAppRoutingItem>,
default: Option<HttpService<P>>, default: Option<HttpService>,
default_fut: Option<Box<Future<Item = HttpService<P>, Error = ()>>>, default_fut: Option<Box<Future<Item = HttpService, Error = ()>>>,
} }
enum CreateAppRoutingItem<P> { enum CreateAppRoutingItem {
Future(Option<ResourceDef>, Option<Guards>, HttpServiceFut<P>), Future(Option<ResourceDef>, Option<Guards>, HttpServiceFut),
Service(ResourceDef, Option<Guards>, HttpService<P>), Service(ResourceDef, Option<Guards>, HttpService),
} }
impl<P> Future for AppRoutingFactoryResponse<P> { impl Future for AppRoutingFactoryResponse {
type Item = AppRouting<P>; type Item = AppRouting;
type Error = (); type Error = ();
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
@ -360,14 +331,14 @@ impl<P> Future for AppRoutingFactoryResponse<P> {
} }
} }
pub struct AppRouting<P> { pub struct AppRouting {
router: Router<HttpService<P>, Guards>, router: Router<HttpService, Guards>,
ready: Option<(ServiceRequest<P>, ResourceInfo)>, ready: Option<(ServiceRequest, ResourceInfo)>,
default: Option<HttpService<P>>, default: Option<HttpService>,
} }
impl<P> Service for AppRouting<P> { impl Service for AppRouting {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type Future = BoxedResponse; type Future = BoxedResponse;
@ -380,7 +351,7 @@ impl<P> Service for AppRouting<P> {
} }
} }
fn call(&mut self, mut req: ServiceRequest<P>) -> Self::Future { fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
let res = self.router.recognize_mut_checked(&mut req, |req, guards| { let res = self.router.recognize_mut_checked(&mut req, |req, guards| {
if let Some(ref guards) = guards { if let Some(ref guards) = guards {
for f in guards { for f in guards {
@ -404,58 +375,25 @@ impl<P> Service for AppRouting<P> {
} }
/// Wrapper service for routing /// Wrapper service for routing
pub struct AppEntry<P> { pub struct AppEntry {
factory: Rc<RefCell<Option<AppRoutingFactory<P>>>>, factory: Rc<RefCell<Option<AppRoutingFactory>>>,
} }
impl<P> AppEntry<P> { impl AppEntry {
pub fn new(factory: Rc<RefCell<Option<AppRoutingFactory<P>>>>) -> Self { pub fn new(factory: Rc<RefCell<Option<AppRoutingFactory>>>) -> Self {
AppEntry { factory } AppEntry { factory }
} }
} }
impl<P: 'static> NewService for AppEntry<P> { impl NewService for AppEntry {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type InitError = (); type InitError = ();
type Service = AppRouting<P>; type Service = AppRouting;
type Future = AppRoutingFactoryResponse<P>; type Future = AppRoutingFactoryResponse;
fn new_service(&self, _: &()) -> Self::Future { fn new_service(&self, _: &()) -> Self::Future {
self.factory.borrow_mut().as_mut().unwrap().new_service(&()) self.factory.borrow_mut().as_mut().unwrap().new_service(&())
} }
} }
#[doc(hidden)]
pub struct AppChain;
impl NewService for AppChain {
type Request = ServiceRequest;
type Response = ServiceRequest;
type Error = Error;
type InitError = ();
type Service = AppChain;
type Future = FutureResult<Self::Service, Self::InitError>;
fn new_service(&self, _: &()) -> Self::Future {
ok(AppChain)
}
}
impl Service for AppChain {
type Request = ServiceRequest;
type Response = ServiceRequest;
type Error = Error;
type Future = FutureResult<Self::Response, Self::Error>;
#[inline]
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
Ok(Async::Ready(()))
}
#[inline]
fn call(&mut self, req: ServiceRequest) -> Self::Future {
ok(req)
}
}

View File

@ -19,25 +19,25 @@ use crate::service::{
}; };
type Guards = Vec<Box<Guard>>; type Guards = Vec<Box<Guard>>;
type HttpNewService<P> = type HttpNewService =
boxed::BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>; boxed::BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
/// Application configuration /// Application configuration
pub struct ServiceConfig<P> { pub struct ServiceConfig {
config: AppConfig, config: AppConfig,
root: bool, root: bool,
default: Rc<HttpNewService<P>>, default: Rc<HttpNewService>,
services: Vec<( services: Vec<(
ResourceDef, ResourceDef,
HttpNewService<P>, HttpNewService,
Option<Guards>, Option<Guards>,
Option<Rc<ResourceMap>>, Option<Rc<ResourceMap>>,
)>, )>,
} }
impl<P: 'static> ServiceConfig<P> { impl ServiceConfig {
/// Crate server settings instance /// Crate server settings instance
pub(crate) fn new(config: AppConfig, default: Rc<HttpNewService<P>>) -> Self { pub(crate) fn new(config: AppConfig, default: Rc<HttpNewService>) -> Self {
ServiceConfig { ServiceConfig {
config, config,
default, default,
@ -55,7 +55,7 @@ impl<P: 'static> ServiceConfig<P> {
self, self,
) -> Vec<( ) -> Vec<(
ResourceDef, ResourceDef,
HttpNewService<P>, HttpNewService,
Option<Guards>, Option<Guards>,
Option<Rc<ResourceMap>>, Option<Rc<ResourceMap>>,
)> { )> {
@ -77,7 +77,7 @@ impl<P: 'static> ServiceConfig<P> {
} }
/// Default resource /// Default resource
pub fn default_service(&self) -> Rc<HttpNewService<P>> { pub fn default_service(&self) -> Rc<HttpNewService> {
self.default.clone() self.default.clone()
} }
@ -90,7 +90,7 @@ impl<P: 'static> ServiceConfig<P> {
) where ) where
F: IntoNewService<S>, F: IntoNewService<S>,
S: NewService< S: NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
@ -169,13 +169,13 @@ impl Default for AppConfigInner {
/// Part of application configuration could be offloaded /// Part of application configuration could be offloaded
/// to set of external methods. This could help with /// to set of external methods. This could help with
/// modularization of big application configuration. /// modularization of big application configuration.
pub struct RouterConfig<P: 'static> { pub struct RouterConfig {
pub(crate) services: Vec<Box<ServiceFactory<P>>>, pub(crate) services: Vec<Box<ServiceFactory>>,
pub(crate) data: Vec<Box<DataFactory>>, pub(crate) data: Vec<Box<DataFactory>>,
pub(crate) external: Vec<ResourceDef>, pub(crate) external: Vec<ResourceDef>,
} }
impl<P: 'static> RouterConfig<P> { impl RouterConfig {
pub(crate) fn new() -> Self { pub(crate) fn new() -> Self {
Self { Self {
services: Vec::new(), services: Vec::new(),
@ -211,7 +211,7 @@ impl<P: 'static> RouterConfig<P> {
/// Configure route for a specific path. /// Configure route for a specific path.
/// ///
/// This is same as `App::route()` method. /// This is same as `App::route()` method.
pub fn route(&mut self, path: &str, mut route: Route<P>) -> &mut Self { pub fn route(&mut self, path: &str, mut route: Route) -> &mut Self {
self.service( self.service(
Resource::new(path) Resource::new(path)
.add_guards(route.take_guards()) .add_guards(route.take_guards())
@ -224,7 +224,7 @@ impl<P: 'static> RouterConfig<P> {
/// This is same as `App::service()` method. /// This is same as `App::service()` method.
pub fn service<F>(&mut self, factory: F) -> &mut Self pub fn service<F>(&mut self, factory: F) -> &mut Self
where where
F: HttpServiceFactory<P> + 'static, F: HttpServiceFactory + 'static,
{ {
self.services self.services
.push(Box::new(ServiceFactoryWrapper::new(factory))); .push(Box::new(ServiceFactoryWrapper::new(factory)));
@ -261,7 +261,7 @@ mod tests {
#[test] #[test]
fn test_data() { fn test_data() {
let cfg = |cfg: &mut RouterConfig<_>| { let cfg = |cfg: &mut RouterConfig| {
cfg.data(10usize); cfg.data(10usize);
}; };
@ -276,7 +276,7 @@ mod tests {
#[test] #[test]
fn test_data_factory() { fn test_data_factory() {
let cfg = |cfg: &mut RouterConfig<_>| { let cfg = |cfg: &mut RouterConfig| {
cfg.data_factory(|| Ok::<_, ()>(10usize)); cfg.data_factory(|| Ok::<_, ()>(10usize));
}; };
@ -288,7 +288,7 @@ mod tests {
let resp = block_on(srv.call(req)).unwrap(); let resp = block_on(srv.call(req)).unwrap();
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
let cfg2 = |cfg: &mut RouterConfig<_>| { let cfg2 = |cfg: &mut RouterConfig| {
cfg.data_factory(|| Ok::<_, ()>(10u32)); cfg.data_factory(|| Ok::<_, ()>(10u32));
}; };
let mut srv = init_service( let mut srv = init_service(

View File

@ -88,12 +88,12 @@ impl<T> Clone for Data<T> {
} }
} }
impl<T: 'static, P> FromRequest<P> for Data<T> { impl<T: 'static> FromRequest for Data<T> {
type Error = Error; type Error = Error;
type Future = Result<Self, Error>; type Future = Result<Self, Error>;
#[inline] #[inline]
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
if let Some(st) = req.app_config().extensions().get::<Data<T>>() { if let Some(st) = req.app_config().extensions().get::<Data<T>>() {
Ok(st.clone()) Ok(st.clone())
} else { } else {
@ -232,12 +232,12 @@ impl<T> Clone for RouteData<T> {
} }
} }
impl<T: 'static, P> FromRequest<P> for RouteData<T> { impl<T: 'static> FromRequest for RouteData<T> {
type Error = Error; type Error = Error;
type Future = Result<Self, Error>; type Future = Result<Self, Error>;
#[inline] #[inline]
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
if let Some(st) = req.route_data::<T>() { if let Some(st) = req.route_data::<T>() {
Ok(st.clone()) Ok(st.clone())
} else { } else {

View File

@ -10,7 +10,7 @@ use crate::request::HttpRequest;
/// Trait implemented by types that can be extracted from request. /// Trait implemented by types that can be extracted from request.
/// ///
/// Types that implement this trait can be used with `Route` handlers. /// Types that implement this trait can be used with `Route` handlers.
pub trait FromRequest<P>: Sized { pub trait FromRequest: Sized {
/// The associated error which can be returned. /// The associated error which can be returned.
type Error: Into<Error>; type Error: Into<Error>;
@ -18,7 +18,7 @@ pub trait FromRequest<P>: Sized {
type Future: IntoFuture<Item = Self, Error = Self::Error>; type Future: IntoFuture<Item = Self, Error = Self::Error>;
/// Convert request to a Self /// Convert request to a Self
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future; fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future;
/// Convert request to a Self /// Convert request to a Self
/// ///
@ -45,11 +45,11 @@ pub trait FromRequest<P>: Sized {
/// name: String /// name: String
/// } /// }
/// ///
/// impl<P> FromRequest<P> for Thing { /// impl FromRequest for Thing {
/// type Error = Error; /// type Error = Error;
/// type Future = Result<Self, Self::Error>; /// type Future = Result<Self, Self::Error>;
/// ///
/// fn from_request(req: &HttpRequest, payload: &mut dev::Payload<P>) -> Self::Future { /// fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
/// if rand::random() { /// if rand::random() {
/// Ok(Thing { name: "thingy".into() }) /// Ok(Thing { name: "thingy".into() })
/// } else { /// } else {
@ -75,16 +75,16 @@ pub trait FromRequest<P>: Sized {
/// ); /// );
/// } /// }
/// ``` /// ```
impl<T: 'static, P> FromRequest<P> for Option<T> impl<T: 'static> FromRequest for Option<T>
where where
T: FromRequest<P>, T: FromRequest,
T::Future: 'static, T::Future: 'static,
{ {
type Error = Error; type Error = Error;
type Future = Box<Future<Item = Option<T>, Error = Error>>; type Future = Box<Future<Item = Option<T>, Error = Error>>;
#[inline] #[inline]
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
Box::new( Box::new(
T::from_request(req, payload) T::from_request(req, payload)
.into_future() .into_future()
@ -116,11 +116,11 @@ where
/// name: String /// name: String
/// } /// }
/// ///
/// impl<P> FromRequest<P> for Thing { /// impl FromRequest for Thing {
/// type Error = Error; /// type Error = Error;
/// type Future = Result<Thing, Error>; /// type Future = Result<Thing, Error>;
/// ///
/// fn from_request(req: &HttpRequest, payload: &mut dev::Payload<P>) -> Self::Future { /// fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
/// if rand::random() { /// if rand::random() {
/// Ok(Thing { name: "thingy".into() }) /// Ok(Thing { name: "thingy".into() })
/// } else { /// } else {
@ -143,9 +143,9 @@ where
/// ); /// );
/// } /// }
/// ``` /// ```
impl<T: 'static, P> FromRequest<P> for Result<T, T::Error> impl<T: 'static> FromRequest for Result<T, T::Error>
where where
T: FromRequest<P>, T: FromRequest,
T::Future: 'static, T::Future: 'static,
T::Error: 'static, T::Error: 'static,
{ {
@ -153,7 +153,7 @@ where
type Future = Box<Future<Item = Result<T, T::Error>, Error = Error>>; type Future = Box<Future<Item = Result<T, T::Error>, Error = Error>>;
#[inline] #[inline]
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
Box::new( Box::new(
T::from_request(req, payload) T::from_request(req, payload)
.into_future() .into_future()
@ -166,11 +166,11 @@ where
} }
#[doc(hidden)] #[doc(hidden)]
impl<P> FromRequest<P> for () { impl FromRequest for () {
type Error = Error; type Error = Error;
type Future = Result<(), Error>; type Future = Result<(), Error>;
fn from_request(_: &HttpRequest, _: &mut Payload<P>) -> Self::Future { fn from_request(_: &HttpRequest, _: &mut Payload) -> Self::Future {
Ok(()) Ok(())
} }
} }
@ -179,12 +179,12 @@ macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
/// FromRequest implementation for tuple /// FromRequest implementation for tuple
#[doc(hidden)] #[doc(hidden)]
impl<P, $($T: FromRequest<P> + 'static),+> FromRequest<P> for ($($T,)+) impl<$($T: FromRequest + 'static),+> FromRequest for ($($T,)+)
{ {
type Error = Error; type Error = Error;
type Future = $fut_type<P, $($T),+>; type Future = $fut_type<$($T),+>;
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
$fut_type { $fut_type {
items: <($(Option<$T>,)+)>::default(), items: <($(Option<$T>,)+)>::default(),
futs: ($($T::from_request(req, payload).into_future(),)+), futs: ($($T::from_request(req, payload).into_future(),)+),
@ -193,12 +193,12 @@ macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
} }
#[doc(hidden)] #[doc(hidden)]
pub struct $fut_type<P, $($T: FromRequest<P>),+> { pub struct $fut_type<$($T: FromRequest),+> {
items: ($(Option<$T>,)+), items: ($(Option<$T>,)+),
futs: ($(<$T::Future as futures::IntoFuture>::Future,)+), futs: ($(<$T::Future as futures::IntoFuture>::Future,)+),
} }
impl<P, $($T: FromRequest<P>),+> Future for $fut_type<P, $($T),+> impl<$($T: FromRequest),+> Future for $fut_type<$($T),+>
{ {
type Item = ($($T,)+); type Item = ($($T,)+);
type Error = Error; type Error = Error;

View File

@ -242,13 +242,13 @@ where
} }
/// Extract arguments from request /// Extract arguments from request
pub struct Extract<P, T: FromRequest<P>, S> { pub struct Extract<T: FromRequest, S> {
config: Rc<RefCell<Option<Rc<Extensions>>>>, config: Rc<RefCell<Option<Rc<Extensions>>>>,
service: S, service: S,
_t: PhantomData<(P, T)>, _t: PhantomData<T>,
} }
impl<P, T: FromRequest<P>, S> Extract<P, T, S> { impl<T: FromRequest, S> Extract<T, S> {
pub fn new(config: Rc<RefCell<Option<Rc<Extensions>>>>, service: S) -> Self { pub fn new(config: Rc<RefCell<Option<Rc<Extensions>>>>, service: S) -> Self {
Extract { Extract {
config, config,
@ -258,16 +258,16 @@ impl<P, T: FromRequest<P>, S> Extract<P, T, S> {
} }
} }
impl<P, T: FromRequest<P>, S> NewService for Extract<P, T, S> impl<T: FromRequest, S> NewService for Extract<T, S>
where where
S: Service<Request = (T, HttpRequest), Response = ServiceResponse, Error = Void> S: Service<Request = (T, HttpRequest), Response = ServiceResponse, Error = Void>
+ Clone, + Clone,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = (Error, ServiceRequest<P>); type Error = (Error, ServiceRequest);
type InitError = (); type InitError = ();
type Service = ExtractService<P, T, S>; type Service = ExtractService<T, S>;
type Future = FutureResult<Self::Service, ()>; type Future = FutureResult<Self::Service, ()>;
fn new_service(&self, _: &()) -> Self::Future { fn new_service(&self, _: &()) -> Self::Future {
@ -279,27 +279,27 @@ where
} }
} }
pub struct ExtractService<P, T: FromRequest<P>, S> { pub struct ExtractService<T: FromRequest, S> {
config: Option<Rc<Extensions>>, config: Option<Rc<Extensions>>,
service: S, service: S,
_t: PhantomData<(P, T)>, _t: PhantomData<T>,
} }
impl<P, T: FromRequest<P>, S> Service for ExtractService<P, T, S> impl<T: FromRequest, S> Service for ExtractService<T, S>
where where
S: Service<Request = (T, HttpRequest), Response = ServiceResponse, Error = Void> S: Service<Request = (T, HttpRequest), Response = ServiceResponse, Error = Void>
+ Clone, + Clone,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = (Error, ServiceRequest<P>); type Error = (Error, ServiceRequest);
type Future = ExtractResponse<P, T, S>; type Future = ExtractResponse<T, S>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> { fn poll_ready(&mut self) -> Poll<(), Self::Error> {
Ok(Async::Ready(())) Ok(Async::Ready(()))
} }
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future { fn call(&mut self, req: ServiceRequest) -> Self::Future {
let (mut req, mut payload) = req.into_parts(); let (mut req, mut payload) = req.into_parts();
req.set_route_data(self.config.clone()); req.set_route_data(self.config.clone());
let fut = T::from_request(&req, &mut payload).into_future(); let fut = T::from_request(&req, &mut payload).into_future();
@ -313,19 +313,19 @@ where
} }
} }
pub struct ExtractResponse<P, T: FromRequest<P>, S: Service> { pub struct ExtractResponse<T: FromRequest, S: Service> {
req: Option<(HttpRequest, Payload<P>)>, req: Option<(HttpRequest, Payload)>,
service: S, service: S,
fut: <T::Future as IntoFuture>::Future, fut: <T::Future as IntoFuture>::Future,
fut_s: Option<S::Future>, fut_s: Option<S::Future>,
} }
impl<P, T: FromRequest<P>, S> Future for ExtractResponse<P, T, S> impl<T: FromRequest, S> Future for ExtractResponse<T, S>
where where
S: Service<Request = (T, HttpRequest), Response = ServiceResponse, Error = Void>, S: Service<Request = (T, HttpRequest), Response = ServiceResponse, Error = Void>,
{ {
type Item = ServiceResponse; type Item = ServiceResponse;
type Error = (Error, ServiceRequest<P>); type Error = (Error, ServiceRequest);
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
if let Some(ref mut fut) = self.fut_s { if let Some(ref mut fut) = self.fut_s {

View File

@ -133,7 +133,6 @@ pub mod dev {
//! use actix_web::dev::*; //! use actix_web::dev::*;
//! ``` //! ```
pub use crate::app::AppRouter;
pub use crate::config::{AppConfig, ServiceConfig}; pub use crate::config::{AppConfig, ServiceConfig};
pub use crate::info::ConnectionInfo; pub use crate::info::ConnectionInfo;
pub use crate::rmap::ResourceMap; pub use crate::rmap::ResourceMap;
@ -143,6 +142,7 @@ pub mod dev {
pub use crate::types::readlines::Readlines; pub use crate::types::readlines::Readlines;
pub use actix_http::body::{Body, BodySize, MessageBody, ResponseBody}; pub use actix_http::body::{Body, BodySize, MessageBody, ResponseBody};
pub use actix_http::encoding::Decoder as Decompress;
pub use actix_http::ResponseBuilder as HttpResponseBuilder; pub use actix_http::ResponseBuilder as HttpResponseBuilder;
pub use actix_http::{ pub use actix_http::{
Extensions, Payload, PayloadStream, RequestHead, ResponseHead, Extensions, Payload, PayloadStream, RequestHead, ResponseHead,

View File

@ -41,11 +41,11 @@ impl<B> BodyEncoding for Response<B> {
/// To disable compression set encoding to `ContentEncoding::Identity` value. /// To disable compression set encoding to `ContentEncoding::Identity` value.
/// ///
/// ```rust /// ```rust
/// use actix_web::{web, middleware::encoding, App, HttpResponse}; /// use actix_web::{web, middleware, App, HttpResponse};
/// ///
/// fn main() { /// fn main() {
/// let app = App::new() /// let app = App::new()
/// .wrap(encoding::Compress::default()) /// .wrap(middleware::Compress::default())
/// .service( /// .service(
/// web::resource("/test") /// web::resource("/test")
/// .route(web::get().to(|| HttpResponse::Ok())) /// .route(web::get().to(|| HttpResponse::Ok()))
@ -68,12 +68,12 @@ impl Default for Compress {
} }
} }
impl<S, P, B> Transform<S> for Compress impl<S, B> Transform<S> for Compress
where where
B: MessageBody, B: MessageBody,
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>, S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse<Encoder<B>>; type Response = ServiceResponse<Encoder<B>>;
type Error = S::Error; type Error = S::Error;
type InitError = (); type InitError = ();
@ -93,21 +93,21 @@ pub struct CompressMiddleware<S> {
encoding: ContentEncoding, encoding: ContentEncoding,
} }
impl<S, P, B> Service for CompressMiddleware<S> impl<S, B> Service for CompressMiddleware<S>
where where
B: MessageBody, B: MessageBody,
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>, S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse<Encoder<B>>; type Response = ServiceResponse<Encoder<B>>;
type Error = S::Error; type Error = S::Error;
type Future = CompressResponse<S, P, B>; type Future = CompressResponse<S, B>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> { fn poll_ready(&mut self) -> Poll<(), Self::Error> {
self.service.poll_ready() self.service.poll_ready()
} }
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future { fn call(&mut self, req: ServiceRequest) -> Self::Future {
// negotiate content-encoding // negotiate content-encoding
let encoding = if let Some(val) = req.headers().get(&ACCEPT_ENCODING) { let encoding = if let Some(val) = req.headers().get(&ACCEPT_ENCODING) {
if let Ok(enc) = val.to_str() { if let Ok(enc) = val.to_str() {
@ -128,20 +128,20 @@ where
} }
#[doc(hidden)] #[doc(hidden)]
pub struct CompressResponse<S, P, B> pub struct CompressResponse<S, B>
where where
S: Service, S: Service,
B: MessageBody, B: MessageBody,
{ {
fut: S::Future, fut: S::Future,
encoding: ContentEncoding, encoding: ContentEncoding,
_t: PhantomData<(P, B)>, _t: PhantomData<(B)>,
} }
impl<S, P, B> Future for CompressResponse<S, P, B> impl<S, B> Future for CompressResponse<S, B>
where where
B: MessageBody, B: MessageBody,
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>, S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
{ {
type Item = ServiceResponse<Encoder<B>>; type Item = ServiceResponse<Encoder<B>>;
type Error = S::Error; type Error = S::Error;

View File

@ -475,9 +475,9 @@ fn cors<'a>(
parts.as_mut() parts.as_mut()
} }
impl<S, P, B> IntoTransform<CorsFactory, S> for Cors impl<S, B> IntoTransform<CorsFactory, S> for Cors
where where
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>, S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
S::Future: 'static, S::Future: 'static,
S::Error: 'static, S::Error: 'static,
B: 'static, B: 'static,
@ -537,14 +537,14 @@ pub struct CorsFactory {
inner: Rc<Inner>, inner: Rc<Inner>,
} }
impl<S, P, B> Transform<S> for CorsFactory impl<S, B> Transform<S> for CorsFactory
where where
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>, S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
S::Future: 'static, S::Future: 'static,
S::Error: 'static, S::Error: 'static,
B: 'static, B: 'static,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse<B>; type Response = ServiceResponse<B>;
type Error = S::Error; type Error = S::Error;
type InitError = (); type InitError = ();
@ -678,14 +678,14 @@ impl Inner {
} }
} }
impl<S, P, B> Service for CorsMiddleware<S> impl<S, B> Service for CorsMiddleware<S>
where where
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>, S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
S::Future: 'static, S::Future: 'static,
S::Error: 'static, S::Error: 'static,
B: 'static, B: 'static,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse<B>; type Response = ServiceResponse<B>;
type Error = S::Error; type Error = S::Error;
type Future = Either< type Future = Either<
@ -697,7 +697,7 @@ where
self.service.poll_ready() self.service.poll_ready()
} }
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future { fn call(&mut self, req: ServiceRequest) -> Self::Future {
if self.inner.preflight && Method::OPTIONS == *req.method() { if self.inner.preflight && Method::OPTIONS == *req.method() {
if let Err(e) = self if let Err(e) = self
.inner .inner
@ -815,13 +815,12 @@ mod tests {
use actix_service::{FnService, Transform}; use actix_service::{FnService, Transform};
use super::*; use super::*;
use crate::dev::PayloadStream;
use crate::test::{self, block_on, TestRequest}; use crate::test::{self, block_on, TestRequest};
impl Cors { impl Cors {
fn finish<S, P, B>(self, srv: S) -> CorsMiddleware<S> fn finish<S, B>(self, srv: S) -> CorsMiddleware<S>
where where
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>> S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>
+ 'static, + 'static,
S::Future: 'static, S::Future: 'static,
S::Error: 'static, S::Error: 'static,
@ -1057,7 +1056,7 @@ mod tests {
.allowed_headers(exposed_headers.clone()) .allowed_headers(exposed_headers.clone())
.expose_headers(exposed_headers.clone()) .expose_headers(exposed_headers.clone())
.allowed_header(header::CONTENT_TYPE) .allowed_header(header::CONTENT_TYPE)
.finish(FnService::new(move |req: ServiceRequest<PayloadStream>| { .finish(FnService::new(move |req: ServiceRequest| {
req.into_response( req.into_response(
HttpResponse::Ok().header(header::VARY, "Accept").finish(), HttpResponse::Ok().header(header::VARY, "Accept").finish(),
) )

View File

@ -1,75 +0,0 @@
//! Chain service for decompressing request payload.
use std::marker::PhantomData;
use actix_http::encoding::Decoder;
use actix_service::{NewService, Service};
use bytes::Bytes;
use futures::future::{ok, FutureResult};
use futures::{Async, Poll, Stream};
use crate::dev::Payload;
use crate::error::{Error, PayloadError};
use crate::service::ServiceRequest;
/// `Middleware` for decompressing request's payload.
/// `Decompress` middleware must be added with `App::chain()` method.
///
/// ```rust
/// use actix_web::{web, middleware::encoding, App, HttpResponse};
///
/// fn main() {
/// let app = App::new()
/// .chain(encoding::Decompress::new())
/// .service(
/// web::resource("/test")
/// .route(web::get().to(|| HttpResponse::Ok()))
/// .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
/// );
/// }
/// ```
pub struct Decompress<P>(PhantomData<P>);
impl<P> Decompress<P>
where
P: Stream<Item = Bytes, Error = PayloadError>,
{
pub fn new() -> Self {
Decompress(PhantomData)
}
}
impl<P> NewService for Decompress<P>
where
P: Stream<Item = Bytes, Error = PayloadError>,
{
type Request = ServiceRequest<P>;
type Response = ServiceRequest<Decoder<Payload<P>>>;
type Error = Error;
type InitError = ();
type Service = Decompress<P>;
type Future = FutureResult<Self::Service, Self::InitError>;
fn new_service(&self, _: &()) -> Self::Future {
ok(Decompress(PhantomData))
}
}
impl<P> Service for Decompress<P>
where
P: Stream<Item = Bytes, Error = PayloadError>,
{
type Request = ServiceRequest<P>;
type Response = ServiceRequest<Decoder<Payload<P>>>;
type Error = Error;
type Future = FutureResult<Self::Response, Self::Error>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
Ok(Async::Ready(()))
}
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future {
let (req, payload) = req.into_parts();
let payload = Decoder::from_headers(payload, req.headers());
ok(ServiceRequest::from_parts(req, Payload::Stream(payload)))
}
}

View File

@ -85,12 +85,12 @@ impl DefaultHeaders {
} }
} }
impl<S, P, B> Transform<S> for DefaultHeaders impl<S, B> Transform<S> for DefaultHeaders
where where
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>, S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
S::Future: 'static, S::Future: 'static,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse<B>; type Response = ServiceResponse<B>;
type Error = S::Error; type Error = S::Error;
type InitError = (); type InitError = ();
@ -110,12 +110,12 @@ pub struct DefaultHeadersMiddleware<S> {
inner: Rc<Inner>, inner: Rc<Inner>,
} }
impl<S, P, B> Service for DefaultHeadersMiddleware<S> impl<S, B> Service for DefaultHeadersMiddleware<S>
where where
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>, S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
S::Future: 'static, S::Future: 'static,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse<B>; type Response = ServiceResponse<B>;
type Error = S::Error; type Error = S::Error;
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>; type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
@ -124,7 +124,7 @@ where
self.service.poll_ready() self.service.poll_ready()
} }
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future { fn call(&mut self, req: ServiceRequest) -> Self::Future {
let inner = self.inner.clone(); let inner = self.inner.clone();
Box::new(self.service.call(req).map(move |mut res| { Box::new(self.service.call(req).map(move |mut res| {
@ -171,7 +171,7 @@ mod tests {
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
let req = TestRequest::default().to_srv_request(); let req = TestRequest::default().to_srv_request();
let srv = FnService::new(|req: ServiceRequest<_>| { let srv = FnService::new(|req: ServiceRequest| {
req.into_response(HttpResponse::Ok().header(CONTENT_TYPE, "0002").finish()) req.into_response(HttpResponse::Ok().header(CONTENT_TYPE, "0002").finish())
}); });
let mut mw = block_on( let mut mw = block_on(
@ -186,7 +186,7 @@ mod tests {
#[test] #[test]
fn test_content_type() { fn test_content_type() {
let srv = FnService::new(|req: ServiceRequest<_>| { let srv = FnService::new(|req: ServiceRequest| {
req.into_response(HttpResponse::Ok().finish()) req.into_response(HttpResponse::Ok().finish())
}); });
let mut mw = let mut mw =

View File

@ -81,18 +81,14 @@ impl<B> ErrorHandlers<B> {
} }
} }
impl<S, P, B> Transform<S> for ErrorHandlers<B> impl<S, B> Transform<S> for ErrorHandlers<B>
where where
S: Service< S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
Request = ServiceRequest<P>,
Response = ServiceResponse<B>,
Error = Error,
>,
S::Future: 'static, S::Future: 'static,
S::Error: 'static, S::Error: 'static,
B: 'static, B: 'static,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse<B>; type Response = ServiceResponse<B>;
type Error = Error; type Error = Error;
type InitError = (); type InitError = ();
@ -113,18 +109,14 @@ pub struct ErrorHandlersMiddleware<S, B> {
handlers: Rc<HashMap<StatusCode, Box<ErrorHandler<B>>>>, handlers: Rc<HashMap<StatusCode, Box<ErrorHandler<B>>>>,
} }
impl<S, P, B> Service for ErrorHandlersMiddleware<S, B> impl<S, B> Service for ErrorHandlersMiddleware<S, B>
where where
S: Service< S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
Request = ServiceRequest<P>,
Response = ServiceResponse<B>,
Error = Error,
>,
S::Future: 'static, S::Future: 'static,
S::Error: 'static, S::Error: 'static,
B: 'static, B: 'static,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse<B>; type Response = ServiceResponse<B>;
type Error = Error; type Error = Error;
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>; type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
@ -133,7 +125,7 @@ where
self.service.poll_ready() self.service.poll_ready()
} }
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future { fn call(&mut self, req: ServiceRequest) -> Self::Future {
let handlers = self.handlers.clone(); let handlers = self.handlers.clone();
Box::new(self.service.call(req).and_then(move |res| { Box::new(self.service.call(req).and_then(move |res| {
@ -169,7 +161,7 @@ mod tests {
#[test] #[test]
fn test_handler() { fn test_handler() {
let srv = FnService::new(|req: ServiceRequest<_>| { let srv = FnService::new(|req: ServiceRequest| {
req.into_response(HttpResponse::InternalServerError().finish()) req.into_response(HttpResponse::InternalServerError().finish())
}); });
@ -195,7 +187,7 @@ mod tests {
#[test] #[test]
fn test_handler_async() { fn test_handler_async() {
let srv = FnService::new(|req: ServiceRequest<_>| { let srv = FnService::new(|req: ServiceRequest| {
req.into_response(HttpResponse::InternalServerError().finish()) req.into_response(HttpResponse::InternalServerError().finish())
}); });

View File

@ -140,12 +140,12 @@ struct IdentityItem {
/// } /// }
/// # fn main() {} /// # fn main() {}
/// ``` /// ```
impl<P> FromRequest<P> for Identity { impl FromRequest for Identity {
type Error = Error; type Error = Error;
type Future = Result<Identity, Error>; type Future = Result<Identity, Error>;
#[inline] #[inline]
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
Ok(Identity(req.clone())) Ok(Identity(req.clone()))
} }
} }
@ -159,7 +159,7 @@ pub trait IdentityPolicy: Sized + 'static {
type ResponseFuture: IntoFuture<Item = (), Error = Error>; type ResponseFuture: IntoFuture<Item = (), Error = Error>;
/// Parse the session from request and load data from a service identity. /// Parse the session from request and load data from a service identity.
fn from_request<P>(&self, request: &mut ServiceRequest<P>) -> Self::Future; fn from_request(&self, request: &mut ServiceRequest) -> Self::Future;
/// Write changes to response /// Write changes to response
fn to_response<B>( fn to_response<B>(
@ -198,16 +198,15 @@ impl<T> IdentityService<T> {
} }
} }
impl<S, T, P, B> Transform<S> for IdentityService<T> impl<S, T, B> Transform<S> for IdentityService<T>
where where
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>> + 'static, S: Service<Request = ServiceRequest, Response = ServiceResponse<B>> + 'static,
S::Future: 'static, S::Future: 'static,
S::Error: 'static, S::Error: 'static,
T: IdentityPolicy, T: IdentityPolicy,
P: 'static,
B: 'static, B: 'static,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse<B>; type Response = ServiceResponse<B>;
type Error = S::Error; type Error = S::Error;
type InitError = (); type InitError = ();
@ -228,16 +227,15 @@ pub struct IdentityServiceMiddleware<S, T> {
service: Rc<RefCell<S>>, service: Rc<RefCell<S>>,
} }
impl<S, T, P, B> Service for IdentityServiceMiddleware<S, T> impl<S, T, B> Service for IdentityServiceMiddleware<S, T>
where where
P: 'static,
B: 'static, B: 'static,
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>> + 'static, S: Service<Request = ServiceRequest, Response = ServiceResponse<B>> + 'static,
S::Future: 'static, S::Future: 'static,
S::Error: 'static, S::Error: 'static,
T: IdentityPolicy, T: IdentityPolicy,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse<B>; type Response = ServiceResponse<B>;
type Error = S::Error; type Error = S::Error;
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>; type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
@ -246,7 +244,7 @@ where
self.service.borrow_mut().poll_ready() self.service.borrow_mut().poll_ready()
} }
fn call(&mut self, mut req: ServiceRequest<P>) -> Self::Future { fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
let srv = self.service.clone(); let srv = self.service.clone();
let backend = self.backend.clone(); let backend = self.backend.clone();
@ -348,7 +346,7 @@ impl CookieIdentityInner {
Ok(()) Ok(())
} }
fn load<T>(&self, req: &ServiceRequest<T>) -> Option<String> { fn load(&self, req: &ServiceRequest) -> Option<String> {
if let Ok(cookies) = req.cookies() { if let Ok(cookies) = req.cookies() {
for cookie in cookies.iter() { for cookie in cookies.iter() {
if cookie.name() == self.name { if cookie.name() == self.name {
@ -445,7 +443,7 @@ impl IdentityPolicy for CookieIdentityPolicy {
type Future = Result<Option<String>, Error>; type Future = Result<Option<String>, Error>;
type ResponseFuture = Result<(), Error>; type ResponseFuture = Result<(), Error>;
fn from_request<P>(&self, req: &mut ServiceRequest<P>) -> Self::Future { fn from_request(&self, req: &mut ServiceRequest) -> Self::Future {
Ok(self.0.load(req)) Ok(self.0.load(req))
} }

View File

@ -114,12 +114,12 @@ impl Default for Logger {
} }
} }
impl<S, P, B> Transform<S> for Logger impl<S, B> Transform<S> for Logger
where where
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>, S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
B: MessageBody, B: MessageBody,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse<StreamLog<B>>; type Response = ServiceResponse<StreamLog<B>>;
type Error = S::Error; type Error = S::Error;
type InitError = (); type InitError = ();
@ -140,21 +140,21 @@ pub struct LoggerMiddleware<S> {
service: S, service: S,
} }
impl<S, P, B> Service for LoggerMiddleware<S> impl<S, B> Service for LoggerMiddleware<S>
where where
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>, S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
B: MessageBody, B: MessageBody,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse<StreamLog<B>>; type Response = ServiceResponse<StreamLog<B>>;
type Error = S::Error; type Error = S::Error;
type Future = LoggerResponse<S, P, B>; type Future = LoggerResponse<S, B>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> { fn poll_ready(&mut self) -> Poll<(), Self::Error> {
self.service.poll_ready() self.service.poll_ready()
} }
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future { fn call(&mut self, req: ServiceRequest) -> Self::Future {
if self.inner.exclude.contains(req.path()) { if self.inner.exclude.contains(req.path()) {
LoggerResponse { LoggerResponse {
fut: self.service.call(req), fut: self.service.call(req),
@ -180,7 +180,7 @@ where
} }
#[doc(hidden)] #[doc(hidden)]
pub struct LoggerResponse<S, P, B> pub struct LoggerResponse<S, B>
where where
B: MessageBody, B: MessageBody,
S: Service, S: Service,
@ -188,13 +188,13 @@ where
fut: S::Future, fut: S::Future,
time: time::Tm, time: time::Tm,
format: Option<Format>, format: Option<Format>,
_t: PhantomData<(P, B)>, _t: PhantomData<(B,)>,
} }
impl<S, P, B> Future for LoggerResponse<S, P, B> impl<S, B> Future for LoggerResponse<S, B>
where where
B: MessageBody, B: MessageBody,
S: Service<Request = ServiceRequest<P>, Response = ServiceResponse<B>>, S: Service<Request = ServiceRequest, Response = ServiceResponse<B>>,
{ {
type Item = ServiceResponse<StreamLog<B>>; type Item = ServiceResponse<StreamLog<B>>;
type Error = S::Error; type Error = S::Error;
@ -402,7 +402,7 @@ impl FormatText {
} }
} }
fn render_request<P>(&mut self, now: time::Tm, req: &ServiceRequest<P>) { fn render_request(&mut self, now: time::Tm, req: &ServiceRequest) {
match *self { match *self {
FormatText::RequestLine => { FormatText::RequestLine => {
*self = if req.query_string().is_empty() { *self = if req.query_string().is_empty() {
@ -464,7 +464,7 @@ mod tests {
#[test] #[test]
fn test_logger() { fn test_logger() {
let srv = FnService::new(|req: ServiceRequest<_>| { let srv = FnService::new(|req: ServiceRequest| {
req.into_response( req.into_response(
HttpResponse::build(StatusCode::OK) HttpResponse::build(StatusCode::OK)
.header("X-Test", "ttt") .header("X-Test", "ttt")

View File

@ -1,14 +1,6 @@
//! Middlewares //! Middlewares
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
mod compress; mod compress;
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))] pub use self::compress::{BodyEncoding, Compress};
mod decompress;
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
pub mod encoding {
//! Middlewares for compressing/decompressing payloads.
pub use super::compress::{BodyEncoding, Compress};
pub use super::decompress::Decompress;
}
pub mod cors; pub mod cors;
mod defaultheaders; mod defaultheaders;

View File

@ -265,12 +265,12 @@ impl Drop for HttpRequest {
/// ); /// );
/// } /// }
/// ``` /// ```
impl<P> FromRequest<P> for HttpRequest { impl FromRequest for HttpRequest {
type Error = Error; type Error = Error;
type Future = Result<Self, Error>; type Future = Result<Self, Error>;
#[inline] #[inline]
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
Ok(req.clone()) Ok(req.clone())
} }
} }

View File

@ -17,9 +17,8 @@ use crate::responder::Responder;
use crate::route::{CreateRouteService, Route, RouteService}; use crate::route::{CreateRouteService, Route, RouteService};
use crate::service::{ServiceRequest, ServiceResponse}; use crate::service::{ServiceRequest, ServiceResponse};
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, Error>; type HttpService = BoxedService<ServiceRequest, ServiceResponse, Error>;
type HttpNewService<P> = type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
/// *Resource* is an entry in resources table which corresponds to requested URL. /// *Resource* is an entry in resources table which corresponds to requested URL.
/// ///
@ -43,18 +42,18 @@ type HttpNewService<P> =
/// ///
/// If no matching route could be found, *405* response code get returned. /// If no matching route could be found, *405* response code get returned.
/// Default behavior could be overriden with `default_resource()` method. /// Default behavior could be overriden with `default_resource()` method.
pub struct Resource<P, T = ResourceEndpoint<P>> { pub struct Resource<T = ResourceEndpoint> {
endpoint: T, endpoint: T,
rdef: String, rdef: String,
name: Option<String>, name: Option<String>,
routes: Vec<Route<P>>, routes: Vec<Route>,
guards: Vec<Box<Guard>>, guards: Vec<Box<Guard>>,
default: Rc<RefCell<Option<Rc<HttpNewService<P>>>>>, default: Rc<RefCell<Option<Rc<HttpNewService>>>>,
factory_ref: Rc<RefCell<Option<ResourceFactory<P>>>>, factory_ref: Rc<RefCell<Option<ResourceFactory>>>,
} }
impl<P> Resource<P> { impl Resource {
pub fn new(path: &str) -> Resource<P> { pub fn new(path: &str) -> Resource {
let fref = Rc::new(RefCell::new(None)); let fref = Rc::new(RefCell::new(None));
Resource { Resource {
@ -69,11 +68,10 @@ impl<P> Resource<P> {
} }
} }
impl<P, T> Resource<P, T> impl<T> Resource<T>
where where
P: 'static,
T: NewService< T: NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
@ -154,7 +152,7 @@ where
/// # fn post_handler() {} /// # fn post_handler() {}
/// # fn delete_handler() {} /// # fn delete_handler() {}
/// ``` /// ```
pub fn route(mut self, route: Route<P>) -> Self { pub fn route(mut self, route: Route) -> Self {
self.routes.push(route.finish()); self.routes.push(route.finish());
self self
} }
@ -182,7 +180,7 @@ where
pub fn to<F, I, R>(mut self, handler: F) -> Self pub fn to<F, I, R>(mut self, handler: F) -> Self
where where
F: Factory<I, R> + 'static, F: Factory<I, R> + 'static,
I: FromRequest<P> + 'static, I: FromRequest + 'static,
R: Responder + 'static, R: Responder + 'static,
{ {
self.routes.push(Route::new().to(handler)); self.routes.push(Route::new().to(handler));
@ -216,7 +214,7 @@ where
pub fn to_async<F, I, R>(mut self, handler: F) -> Self pub fn to_async<F, I, R>(mut self, handler: F) -> Self
where where
F: AsyncFactory<I, R>, F: AsyncFactory<I, R>,
I: FromRequest<P> + 'static, I: FromRequest + 'static,
R: IntoFuture + 'static, R: IntoFuture + 'static,
R::Item: Into<Response>, R::Item: Into<Response>,
R::Error: Into<Error>, R::Error: Into<Error>,
@ -236,9 +234,8 @@ where
self, self,
mw: F, mw: F,
) -> Resource< ) -> Resource<
P,
impl NewService< impl NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
@ -247,7 +244,7 @@ where
where where
M: Transform< M: Transform<
T::Service, T::Service,
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
@ -302,16 +299,15 @@ where
self, self,
mw: F, mw: F,
) -> Resource< ) -> Resource<
P,
impl NewService< impl NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
>, >,
> >
where where
F: FnMut(ServiceRequest<P>, &mut T::Service) -> R + Clone, F: FnMut(ServiceRequest, &mut T::Service) -> R + Clone,
R: IntoFuture<Item = ServiceResponse, Error = Error>, R: IntoFuture<Item = ServiceResponse, Error = Error>,
{ {
self.wrap(mw) self.wrap(mw)
@ -322,10 +318,10 @@ where
/// default handler from `App` or `Scope`. /// default handler from `App` or `Scope`.
pub fn default_resource<F, R, U>(mut self, f: F) -> Self pub fn default_resource<F, R, U>(mut self, f: F) -> Self
where where
F: FnOnce(Resource<P>) -> R, F: FnOnce(Resource) -> R,
R: IntoNewService<U>, R: IntoNewService<U>,
U: NewService< U: NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
> + 'static, > + 'static,
@ -339,17 +335,16 @@ where
} }
} }
impl<P, T> HttpServiceFactory<P> for Resource<P, T> impl<T> HttpServiceFactory for Resource<T>
where where
P: 'static,
T: NewService< T: NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
> + 'static, > + 'static,
{ {
fn register(mut self, config: &mut ServiceConfig<P>) { fn register(mut self, config: &mut ServiceConfig) {
let guards = if self.guards.is_empty() { let guards = if self.guards.is_empty() {
None None
} else { } else {
@ -367,10 +362,10 @@ where
} }
} }
impl<P, T> IntoNewService<T> for Resource<P, T> impl<T> IntoNewService<T> for Resource<T>
where where
T: NewService< T: NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
@ -386,18 +381,18 @@ where
} }
} }
pub struct ResourceFactory<P> { pub struct ResourceFactory {
routes: Vec<Route<P>>, routes: Vec<Route>,
default: Rc<RefCell<Option<Rc<HttpNewService<P>>>>>, default: Rc<RefCell<Option<Rc<HttpNewService>>>>,
} }
impl<P: 'static> NewService for ResourceFactory<P> { impl NewService for ResourceFactory {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type InitError = (); type InitError = ();
type Service = ResourceService<P>; type Service = ResourceService;
type Future = CreateResourceService<P>; type Future = CreateResourceService;
fn new_service(&self, _: &()) -> Self::Future { fn new_service(&self, _: &()) -> Self::Future {
let default_fut = if let Some(ref default) = *self.default.borrow() { let default_fut = if let Some(ref default) = *self.default.borrow() {
@ -418,19 +413,19 @@ impl<P: 'static> NewService for ResourceFactory<P> {
} }
} }
enum CreateRouteServiceItem<P> { enum CreateRouteServiceItem {
Future(CreateRouteService<P>), Future(CreateRouteService),
Service(RouteService<P>), Service(RouteService),
} }
pub struct CreateResourceService<P> { pub struct CreateResourceService {
fut: Vec<CreateRouteServiceItem<P>>, fut: Vec<CreateRouteServiceItem>,
default: Option<HttpService<P>>, default: Option<HttpService>,
default_fut: Option<Box<Future<Item = HttpService<P>, Error = ()>>>, default_fut: Option<Box<Future<Item = HttpService, Error = ()>>>,
} }
impl<P> Future for CreateResourceService<P> { impl Future for CreateResourceService {
type Item = ResourceService<P>; type Item = ResourceService;
type Error = (); type Error = ();
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
@ -477,13 +472,13 @@ impl<P> Future for CreateResourceService<P> {
} }
} }
pub struct ResourceService<P> { pub struct ResourceService {
routes: Vec<RouteService<P>>, routes: Vec<RouteService>,
default: Option<HttpService<P>>, default: Option<HttpService>,
} }
impl<P> Service for ResourceService<P> { impl Service for ResourceService {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type Future = Either< type Future = Either<
@ -495,7 +490,7 @@ impl<P> Service for ResourceService<P> {
Ok(Async::Ready(())) Ok(Async::Ready(()))
} }
fn call(&mut self, mut req: ServiceRequest<P>) -> Self::Future { fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
for route in self.routes.iter_mut() { for route in self.routes.iter_mut() {
if route.check(&mut req) { if route.check(&mut req) {
return route.call(req); return route.call(req);
@ -514,23 +509,23 @@ impl<P> Service for ResourceService<P> {
} }
#[doc(hidden)] #[doc(hidden)]
pub struct ResourceEndpoint<P> { pub struct ResourceEndpoint {
factory: Rc<RefCell<Option<ResourceFactory<P>>>>, factory: Rc<RefCell<Option<ResourceFactory>>>,
} }
impl<P> ResourceEndpoint<P> { impl ResourceEndpoint {
fn new(factory: Rc<RefCell<Option<ResourceFactory<P>>>>) -> Self { fn new(factory: Rc<RefCell<Option<ResourceFactory>>>) -> Self {
ResourceEndpoint { factory } ResourceEndpoint { factory }
} }
} }
impl<P: 'static> NewService for ResourceEndpoint<P> { impl NewService for ResourceEndpoint {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type InitError = (); type InitError = ();
type Service = ResourceService<P>; type Service = ResourceService;
type Future = CreateResourceService<P>; type Future = CreateResourceService;
fn new_service(&self, _: &()) -> Self::Future { fn new_service(&self, _: &()) -> Self::Future {
self.factory.borrow_mut().as_mut().unwrap().new_service(&()) self.factory.borrow_mut().as_mut().unwrap().new_service(&())
@ -550,13 +545,13 @@ mod tests {
use crate::test::{call_success, init_service, TestRequest}; use crate::test::{call_success, init_service, TestRequest};
use crate::{web, App, Error, HttpResponse}; use crate::{web, App, Error, HttpResponse};
fn md<S, P, B>( fn md<S, B>(
req: ServiceRequest<P>, req: ServiceRequest,
srv: &mut S, srv: &mut S,
) -> impl IntoFuture<Item = ServiceResponse<B>, Error = Error> ) -> impl IntoFuture<Item = ServiceResponse<B>, Error = Error>
where where
S: Service< S: Service<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse<B>, Response = ServiceResponse<B>,
Error = Error, Error = Error,
>, >,

View File

@ -1,5 +1,4 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::marker::PhantomData;
use std::rc::Rc; use std::rc::Rc;
use actix_http::{http::Method, Error, Extensions, Response}; use actix_http::{http::Method, Error, Extensions, Response};
@ -42,16 +41,16 @@ type BoxedRouteNewService<Req, Res> = Box<
/// ///
/// Route uses builder-like pattern for configuration. /// Route uses builder-like pattern for configuration.
/// If handler is not explicitly set, default *404 Not Found* handler is used. /// If handler is not explicitly set, default *404 Not Found* handler is used.
pub struct Route<P> { pub struct Route {
service: BoxedRouteNewService<ServiceRequest<P>, ServiceResponse>, service: BoxedRouteNewService<ServiceRequest, ServiceResponse>,
guards: Rc<Vec<Box<Guard>>>, guards: Rc<Vec<Box<Guard>>>,
data: Option<Extensions>, data: Option<Extensions>,
data_ref: Rc<RefCell<Option<Rc<Extensions>>>>, data_ref: Rc<RefCell<Option<Rc<Extensions>>>>,
} }
impl<P: 'static> Route<P> { impl Route {
/// Create new route which matches any request. /// Create new route which matches any request.
pub fn new() -> Route<P> { pub fn new() -> Route {
let data_ref = Rc::new(RefCell::new(None)); let data_ref = Rc::new(RefCell::new(None));
Route { Route {
service: Box::new(RouteNewService::new(Extract::new( service: Box::new(RouteNewService::new(Extract::new(
@ -74,13 +73,13 @@ impl<P: 'static> Route<P> {
} }
} }
impl<P> NewService for Route<P> { impl NewService for Route {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type InitError = (); type InitError = ();
type Service = RouteService<P>; type Service = RouteService;
type Future = CreateRouteService<P>; type Future = CreateRouteService;
fn new_service(&self, _: &()) -> Self::Future { fn new_service(&self, _: &()) -> Self::Future {
CreateRouteService { CreateRouteService {
@ -90,17 +89,16 @@ impl<P> NewService for Route<P> {
} }
} }
type RouteFuture<P> = Box< type RouteFuture =
Future<Item = BoxedRouteService<ServiceRequest<P>, ServiceResponse>, Error = ()>, Box<Future<Item = BoxedRouteService<ServiceRequest, ServiceResponse>, Error = ()>>;
>;
pub struct CreateRouteService<P> { pub struct CreateRouteService {
fut: RouteFuture<P>, fut: RouteFuture,
guards: Rc<Vec<Box<Guard>>>, guards: Rc<Vec<Box<Guard>>>,
} }
impl<P> Future for CreateRouteService<P> { impl Future for CreateRouteService {
type Item = RouteService<P>; type Item = RouteService;
type Error = (); type Error = ();
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
@ -114,13 +112,13 @@ impl<P> Future for CreateRouteService<P> {
} }
} }
pub struct RouteService<P> { pub struct RouteService {
service: BoxedRouteService<ServiceRequest<P>, ServiceResponse>, service: BoxedRouteService<ServiceRequest, ServiceResponse>,
guards: Rc<Vec<Box<Guard>>>, guards: Rc<Vec<Box<Guard>>>,
} }
impl<P> RouteService<P> { impl RouteService {
pub fn check(&self, req: &mut ServiceRequest<P>) -> bool { pub fn check(&self, req: &mut ServiceRequest) -> bool {
for f in self.guards.iter() { for f in self.guards.iter() {
if !f.check(req.head()) { if !f.check(req.head()) {
return false; return false;
@ -130,8 +128,8 @@ impl<P> RouteService<P> {
} }
} }
impl<P> Service for RouteService<P> { impl Service for RouteService {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type Future = Either< type Future = Either<
@ -143,12 +141,12 @@ impl<P> Service for RouteService<P> {
self.service.poll_ready() self.service.poll_ready()
} }
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future { fn call(&mut self, req: ServiceRequest) -> Self::Future {
self.service.call(req) self.service.call(req)
} }
} }
impl<P: 'static> Route<P> { impl Route {
/// Add method guard to the route. /// Add method guard to the route.
/// ///
/// ```rust /// ```rust
@ -235,10 +233,10 @@ impl<P: 'static> Route<P> {
/// ); /// );
/// } /// }
/// ``` /// ```
pub fn to<F, T, R>(mut self, handler: F) -> Route<P> pub fn to<F, T, R>(mut self, handler: F) -> Route
where where
F: Factory<T, R> + 'static, F: Factory<T, R> + 'static,
T: FromRequest<P> + 'static, T: FromRequest + 'static,
R: Responder + 'static, R: Responder + 'static,
{ {
self.service = Box::new(RouteNewService::new(Extract::new( self.service = Box::new(RouteNewService::new(Extract::new(
@ -278,7 +276,7 @@ impl<P: 'static> Route<P> {
pub fn to_async<F, T, R>(mut self, handler: F) -> Self pub fn to_async<F, T, R>(mut self, handler: F) -> Self
where where
F: AsyncFactory<T, R>, F: AsyncFactory<T, R>,
T: FromRequest<P> + 'static, T: FromRequest + 'static,
R: IntoFuture + 'static, R: IntoFuture + 'static,
R::Item: Into<Response>, R::Item: Into<Response>,
R::Error: Into<Error>, R::Error: Into<Error>,
@ -321,49 +319,45 @@ impl<P: 'static> Route<P> {
} }
} }
struct RouteNewService<P, T> struct RouteNewService<T>
where where
T: NewService<Request = ServiceRequest<P>, Error = (Error, ServiceRequest<P>)>, T: NewService<Request = ServiceRequest, Error = (Error, ServiceRequest)>,
{ {
service: T, service: T,
_t: PhantomData<P>,
} }
impl<P: 'static, T> RouteNewService<P, T> impl<T> RouteNewService<T>
where where
T: NewService< T: NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = (Error, ServiceRequest<P>), Error = (Error, ServiceRequest),
>, >,
T::Future: 'static, T::Future: 'static,
T::Service: 'static, T::Service: 'static,
<T::Service as Service>::Future: 'static, <T::Service as Service>::Future: 'static,
{ {
pub fn new(service: T) -> Self { pub fn new(service: T) -> Self {
RouteNewService { RouteNewService { service }
service,
_t: PhantomData,
}
} }
} }
impl<P: 'static, T> NewService for RouteNewService<P, T> impl<T> NewService for RouteNewService<T>
where where
T: NewService< T: NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = (Error, ServiceRequest<P>), Error = (Error, ServiceRequest),
>, >,
T::Future: 'static, T::Future: 'static,
T::Service: 'static, T::Service: 'static,
<T::Service as Service>::Future: 'static, <T::Service as Service>::Future: 'static,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type InitError = (); type InitError = ();
type Service = BoxedRouteService<ServiceRequest<P>, Self::Response>; type Service = BoxedRouteService<ServiceRequest, Self::Response>;
type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>; type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>;
fn new_service(&self, _: &()) -> Self::Future { fn new_service(&self, _: &()) -> Self::Future {
@ -373,31 +367,27 @@ where
.map_err(|_| ()) .map_err(|_| ())
.and_then(|service| { .and_then(|service| {
let service: BoxedRouteService<_, _> = let service: BoxedRouteService<_, _> =
Box::new(RouteServiceWrapper { Box::new(RouteServiceWrapper { service });
service,
_t: PhantomData,
});
Ok(service) Ok(service)
}), }),
) )
} }
} }
struct RouteServiceWrapper<P, T: Service> { struct RouteServiceWrapper<T: Service> {
service: T, service: T,
_t: PhantomData<P>,
} }
impl<P, T> Service for RouteServiceWrapper<P, T> impl<T> Service for RouteServiceWrapper<T>
where where
T::Future: 'static, T::Future: 'static,
T: Service< T: Service<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = (Error, ServiceRequest<P>), Error = (Error, ServiceRequest),
>, >,
{ {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type Future = Either< type Future = Either<
@ -409,7 +399,7 @@ where
self.service.poll_ready().map_err(|(e, _)| e) self.service.poll_ready().map_err(|(e, _)| e)
} }
fn call(&mut self, req: ServiceRequest<P>) -> Self::Future { fn call(&mut self, req: ServiceRequest) -> Self::Future {
let mut fut = self.service.call(req); let mut fut = self.service.call(req);
match fut.poll() { match fut.poll() {
Ok(Async::Ready(res)) => Either::A(ok(res)), Ok(Async::Ready(res)) => Either::A(ok(res)),

View File

@ -21,9 +21,8 @@ use crate::service::{
}; };
type Guards = Vec<Box<Guard>>; type Guards = Vec<Box<Guard>>;
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, Error>; type HttpService = BoxedService<ServiceRequest, ServiceResponse, Error>;
type HttpNewService<P> = type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
type BoxedResponse = Either< type BoxedResponse = Either<
FutureResult<ServiceResponse, Error>, FutureResult<ServiceResponse, Error>,
Box<Future<Item = ServiceResponse, Error = Error>>, Box<Future<Item = ServiceResponse, Error = Error>>,
@ -58,18 +57,18 @@ type BoxedResponse = Either<
/// * /{project_id}/path2 - `GET` requests /// * /{project_id}/path2 - `GET` requests
/// * /{project_id}/path3 - `HEAD` requests /// * /{project_id}/path3 - `HEAD` requests
/// ///
pub struct Scope<P, T = ScopeEndpoint<P>> { pub struct Scope<T = ScopeEndpoint> {
endpoint: T, endpoint: T,
rdef: String, rdef: String,
services: Vec<Box<ServiceFactory<P>>>, services: Vec<Box<ServiceFactory>>,
guards: Vec<Box<Guard>>, guards: Vec<Box<Guard>>,
default: Rc<RefCell<Option<Rc<HttpNewService<P>>>>>, default: Rc<RefCell<Option<Rc<HttpNewService>>>>,
factory_ref: Rc<RefCell<Option<ScopeFactory<P>>>>, factory_ref: Rc<RefCell<Option<ScopeFactory>>>,
} }
impl<P: 'static> Scope<P> { impl Scope {
/// Create a new scope /// Create a new scope
pub fn new(path: &str) -> Scope<P> { pub fn new(path: &str) -> Scope {
let fref = Rc::new(RefCell::new(None)); let fref = Rc::new(RefCell::new(None));
Scope { Scope {
endpoint: ScopeEndpoint::new(fref.clone()), endpoint: ScopeEndpoint::new(fref.clone()),
@ -82,11 +81,10 @@ impl<P: 'static> Scope<P> {
} }
} }
impl<P, T> Scope<P, T> impl<T> Scope<T>
where where
P: 'static,
T: NewService< T: NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
@ -146,7 +144,7 @@ where
/// ``` /// ```
pub fn service<F>(mut self, factory: F) -> Self pub fn service<F>(mut self, factory: F) -> Self
where where
F: HttpServiceFactory<P> + 'static, F: HttpServiceFactory + 'static,
{ {
self.services self.services
.push(Box::new(ServiceFactoryWrapper::new(factory))); .push(Box::new(ServiceFactoryWrapper::new(factory)));
@ -174,7 +172,7 @@ where
/// ); /// );
/// } /// }
/// ``` /// ```
pub fn route(self, path: &str, mut route: Route<P>) -> Self { pub fn route(self, path: &str, mut route: Route) -> Self {
self.service( self.service(
Resource::new(path) Resource::new(path)
.add_guards(route.take_guards()) .add_guards(route.take_guards())
@ -187,9 +185,9 @@ where
/// If default resource is not registered, app's default resource is being used. /// If default resource is not registered, app's default resource is being used.
pub fn default_resource<F, U>(mut self, f: F) -> Self pub fn default_resource<F, U>(mut self, f: F) -> Self
where where
F: FnOnce(Resource<P>) -> Resource<P, U>, F: FnOnce(Resource) -> Resource<U>,
U: NewService< U: NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
@ -216,9 +214,8 @@ where
self, self,
mw: F, mw: F,
) -> Scope< ) -> Scope<
P,
impl NewService< impl NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
@ -227,7 +224,7 @@ where
where where
M: Transform< M: Transform<
T::Service, T::Service,
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
@ -279,33 +276,31 @@ where
self, self,
mw: F, mw: F,
) -> Scope< ) -> Scope<
P,
impl NewService< impl NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
>, >,
> >
where where
F: FnMut(ServiceRequest<P>, &mut T::Service) -> R + Clone, F: FnMut(ServiceRequest, &mut T::Service) -> R + Clone,
R: IntoFuture<Item = ServiceResponse, Error = Error>, R: IntoFuture<Item = ServiceResponse, Error = Error>,
{ {
self.wrap(mw) self.wrap(mw)
} }
} }
impl<P, T> HttpServiceFactory<P> for Scope<P, T> impl<T> HttpServiceFactory for Scope<T>
where where
P: 'static,
T: NewService< T: NewService<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
> + 'static, > + 'static,
{ {
fn register(self, config: &mut ServiceConfig<P>) { fn register(self, config: &mut ServiceConfig) {
// update default resource if needed // update default resource if needed
if self.default.borrow().is_none() { if self.default.borrow().is_none() {
*self.default.borrow_mut() = Some(config.default_service()); *self.default.borrow_mut() = Some(config.default_service());
@ -350,18 +345,18 @@ where
} }
} }
pub struct ScopeFactory<P> { pub struct ScopeFactory {
services: Rc<Vec<(ResourceDef, HttpNewService<P>, RefCell<Option<Guards>>)>>, services: Rc<Vec<(ResourceDef, HttpNewService, RefCell<Option<Guards>>)>>,
default: Rc<RefCell<Option<Rc<HttpNewService<P>>>>>, default: Rc<RefCell<Option<Rc<HttpNewService>>>>,
} }
impl<P: 'static> NewService for ScopeFactory<P> { impl NewService for ScopeFactory {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type InitError = (); type InitError = ();
type Service = ScopeService<P>; type Service = ScopeService;
type Future = ScopeFactoryResponse<P>; type Future = ScopeFactoryResponse;
fn new_service(&self, _: &()) -> Self::Future { fn new_service(&self, _: &()) -> Self::Future {
let default_fut = if let Some(ref default) = *self.default.borrow() { let default_fut = if let Some(ref default) = *self.default.borrow() {
@ -390,21 +385,21 @@ impl<P: 'static> NewService for ScopeFactory<P> {
/// Create scope service /// Create scope service
#[doc(hidden)] #[doc(hidden)]
pub struct ScopeFactoryResponse<P> { pub struct ScopeFactoryResponse {
fut: Vec<CreateScopeServiceItem<P>>, fut: Vec<CreateScopeServiceItem>,
default: Option<HttpService<P>>, default: Option<HttpService>,
default_fut: Option<Box<Future<Item = HttpService<P>, Error = ()>>>, default_fut: Option<Box<Future<Item = HttpService, Error = ()>>>,
} }
type HttpServiceFut<P> = Box<Future<Item = HttpService<P>, Error = ()>>; type HttpServiceFut = Box<Future<Item = HttpService, Error = ()>>;
enum CreateScopeServiceItem<P> { enum CreateScopeServiceItem {
Future(Option<ResourceDef>, Option<Guards>, HttpServiceFut<P>), Future(Option<ResourceDef>, Option<Guards>, HttpServiceFut),
Service(ResourceDef, Option<Guards>, HttpService<P>), Service(ResourceDef, Option<Guards>, HttpService),
} }
impl<P> Future for ScopeFactoryResponse<P> { impl Future for ScopeFactoryResponse {
type Item = ScopeService<P>; type Item = ScopeService;
type Error = (); type Error = ();
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
@ -465,14 +460,14 @@ impl<P> Future for ScopeFactoryResponse<P> {
} }
} }
pub struct ScopeService<P> { pub struct ScopeService {
router: Router<HttpService<P>, Vec<Box<Guard>>>, router: Router<HttpService, Vec<Box<Guard>>>,
default: Option<HttpService<P>>, default: Option<HttpService>,
_ready: Option<(ServiceRequest<P>, ResourceInfo)>, _ready: Option<(ServiceRequest, ResourceInfo)>,
} }
impl<P> Service for ScopeService<P> { impl Service for ScopeService {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type Future = Either<BoxedResponse, FutureResult<Self::Response, Self::Error>>; type Future = Either<BoxedResponse, FutureResult<Self::Response, Self::Error>>;
@ -481,7 +476,7 @@ impl<P> Service for ScopeService<P> {
Ok(Async::Ready(())) Ok(Async::Ready(()))
} }
fn call(&mut self, mut req: ServiceRequest<P>) -> Self::Future { fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
let res = self.router.recognize_mut_checked(&mut req, |req, guards| { let res = self.router.recognize_mut_checked(&mut req, |req, guards| {
if let Some(ref guards) = guards { if let Some(ref guards) = guards {
for f in guards { for f in guards {
@ -505,23 +500,23 @@ impl<P> Service for ScopeService<P> {
} }
#[doc(hidden)] #[doc(hidden)]
pub struct ScopeEndpoint<P> { pub struct ScopeEndpoint {
factory: Rc<RefCell<Option<ScopeFactory<P>>>>, factory: Rc<RefCell<Option<ScopeFactory>>>,
} }
impl<P> ScopeEndpoint<P> { impl ScopeEndpoint {
fn new(factory: Rc<RefCell<Option<ScopeFactory<P>>>>) -> Self { fn new(factory: Rc<RefCell<Option<ScopeFactory>>>) -> Self {
ScopeEndpoint { factory } ScopeEndpoint { factory }
} }
} }
impl<P: 'static> NewService for ScopeEndpoint<P> { impl NewService for ScopeEndpoint {
type Request = ServiceRequest<P>; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;
type Error = Error; type Error = Error;
type InitError = (); type InitError = ();
type Service = ScopeService<P>; type Service = ScopeService;
type Future = ScopeFactoryResponse<P>; type Future = ScopeFactoryResponse;
fn new_service(&self, _: &()) -> Self::Future { fn new_service(&self, _: &()) -> Self::Future {
self.factory.borrow_mut().as_mut().unwrap().new_service(&()) self.factory.borrow_mut().as_mut().unwrap().new_service(&())
@ -886,13 +881,13 @@ mod tests {
assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
} }
fn md<S, P, B>( fn md<S, B>(
req: ServiceRequest<P>, req: ServiceRequest,
srv: &mut S, srv: &mut S,
) -> impl IntoFuture<Item = ServiceResponse<B>, Error = Error> ) -> impl IntoFuture<Item = ServiceResponse<B>, Error = Error>
where where
S: Service< S: Service<
Request = ServiceRequest<P>, Request = ServiceRequest,
Response = ServiceResponse<B>, Response = ServiceResponse<B>,
Error = Error, Error = Error,
>, >,

View File

@ -1,6 +1,5 @@
use std::cell::{Ref, RefMut}; use std::cell::{Ref, RefMut};
use std::fmt; use std::fmt;
use std::marker::PhantomData;
use actix_http::body::{Body, MessageBody, ResponseBody}; use actix_http::body::{Body, MessageBody, ResponseBody};
use actix_http::http::{HeaderMap, Method, StatusCode, Uri, Version}; use actix_http::http::{HeaderMap, Method, StatusCode, Uri, Version};
@ -15,52 +14,50 @@ use crate::config::{AppConfig, ServiceConfig};
use crate::data::Data; use crate::data::Data;
use crate::request::HttpRequest; use crate::request::HttpRequest;
pub trait HttpServiceFactory<P> { pub trait HttpServiceFactory {
fn register(self, config: &mut ServiceConfig<P>); fn register(self, config: &mut ServiceConfig);
} }
pub(crate) trait ServiceFactory<P> { pub(crate) trait ServiceFactory {
fn register(&mut self, config: &mut ServiceConfig<P>); fn register(&mut self, config: &mut ServiceConfig);
} }
pub(crate) struct ServiceFactoryWrapper<T, P> { pub(crate) struct ServiceFactoryWrapper<T> {
factory: Option<T>, factory: Option<T>,
_t: PhantomData<P>,
} }
impl<T, P> ServiceFactoryWrapper<T, P> { impl<T> ServiceFactoryWrapper<T> {
pub fn new(factory: T) -> Self { pub fn new(factory: T) -> Self {
Self { Self {
factory: Some(factory), factory: Some(factory),
_t: PhantomData,
} }
} }
} }
impl<T, P> ServiceFactory<P> for ServiceFactoryWrapper<T, P> impl<T> ServiceFactory for ServiceFactoryWrapper<T>
where where
T: HttpServiceFactory<P>, T: HttpServiceFactory,
{ {
fn register(&mut self, config: &mut ServiceConfig<P>) { fn register(&mut self, config: &mut ServiceConfig) {
if let Some(item) = self.factory.take() { if let Some(item) = self.factory.take() {
item.register(config) item.register(config)
} }
} }
} }
pub struct ServiceRequest<P = PayloadStream> { pub struct ServiceRequest {
req: HttpRequest, req: HttpRequest,
payload: Payload<P>, payload: Payload,
} }
impl<P> ServiceRequest<P> { impl ServiceRequest {
/// Construct service request from parts /// Construct service request from parts
pub fn from_parts(req: HttpRequest, payload: Payload<P>) -> Self { pub fn from_parts(req: HttpRequest, payload: Payload) -> Self {
ServiceRequest { req, payload } ServiceRequest { req, payload }
} }
/// Deconstruct request into parts /// Deconstruct request into parts
pub fn into_parts(self) -> (HttpRequest, Payload<P>) { pub fn into_parts(self) -> (HttpRequest, Payload) {
(self.req, self.payload) (self.req, self.payload)
} }
@ -170,14 +167,14 @@ impl<P> ServiceRequest<P> {
} }
} }
impl<P> Resource<Url> for ServiceRequest<P> { impl Resource<Url> for ServiceRequest {
fn resource_path(&mut self) -> &mut Path<Url> { fn resource_path(&mut self) -> &mut Path<Url> {
self.match_info_mut() self.match_info_mut()
} }
} }
impl<P> HttpMessage for ServiceRequest<P> { impl HttpMessage for ServiceRequest {
type Stream = P; type Stream = PayloadStream;
#[inline] #[inline]
/// Returns Request's headers. /// Returns Request's headers.
@ -203,7 +200,7 @@ impl<P> HttpMessage for ServiceRequest<P> {
} }
} }
impl<P> fmt::Debug for ServiceRequest<P> { impl fmt::Debug for ServiceRequest {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!( writeln!(
f, f,

View File

@ -6,7 +6,7 @@ use actix_http::cookie::Cookie;
use actix_http::http::header::{Header, HeaderName, IntoHeaderValue}; use actix_http::http::header::{Header, HeaderName, IntoHeaderValue};
use actix_http::http::{HttpTryFrom, Method, StatusCode, Version}; use actix_http::http::{HttpTryFrom, Method, StatusCode, Version};
use actix_http::test::TestRequest as HttpTestRequest; use actix_http::test::TestRequest as HttpTestRequest;
use actix_http::{Extensions, PayloadStream, Request}; use actix_http::{Extensions, Request};
use actix_router::{Path, ResourceDef, Url}; use actix_router::{Path, ResourceDef, Url};
use actix_rt::Runtime; use actix_rt::Runtime;
use actix_server_config::ServerConfig; use actix_server_config::ServerConfig;
@ -60,23 +60,18 @@ where
} }
/// Create service that always responds with `HttpResponse::Ok()` /// Create service that always responds with `HttpResponse::Ok()`
pub fn ok_service() -> impl Service< pub fn ok_service(
Request = ServiceRequest<PayloadStream>, ) -> impl Service<Request = ServiceRequest, Response = ServiceResponse<Body>, Error = Error>
Response = ServiceResponse<Body>, {
Error = Error,
> {
default_service(StatusCode::OK) default_service(StatusCode::OK)
} }
/// Create service that responds with response with specified status code /// Create service that responds with response with specified status code
pub fn default_service( pub fn default_service(
status_code: StatusCode, status_code: StatusCode,
) -> impl Service< ) -> impl Service<Request = ServiceRequest, Response = ServiceResponse<Body>, Error = Error>
Request = ServiceRequest<PayloadStream>, {
Response = ServiceResponse<Body>, FnService::new(move |req: ServiceRequest| {
Error = Error,
> {
FnService::new(move |req: ServiceRequest<PayloadStream>| {
req.into_response(HttpResponse::build(status_code).finish()) req.into_response(HttpResponse::build(status_code).finish())
}) })
} }
@ -298,12 +293,12 @@ impl TestRequest {
} }
/// Complete request creation and generate `Request` instance /// Complete request creation and generate `Request` instance
pub fn to_request(mut self) -> Request<PayloadStream> { pub fn to_request(mut self) -> Request {
self.req.finish() self.req.finish()
} }
/// Complete request creation and generate `ServiceRequest` instance /// Complete request creation and generate `ServiceRequest` instance
pub fn to_srv_request(mut self) -> ServiceRequest<PayloadStream> { pub fn to_srv_request(mut self) -> ServiceRequest {
let (head, payload) = self.req.finish().into_parts(); let (head, payload) = self.req.finish().into_parts();
let req = HttpRequest::new( let req = HttpRequest::new(

View File

@ -3,15 +3,15 @@
use std::rc::Rc; use std::rc::Rc;
use std::{fmt, ops}; use std::{fmt, ops};
use actix_http::error::{Error, PayloadError}; use actix_http::{Error, HttpMessage, Payload};
use actix_http::{HttpMessage, Payload}; use bytes::BytesMut;
use bytes::{Bytes, BytesMut};
use encoding::all::UTF_8; use encoding::all::UTF_8;
use encoding::types::{DecoderTrap, Encoding}; use encoding::types::{DecoderTrap, Encoding};
use encoding::EncodingRef; use encoding::EncodingRef;
use futures::{Future, Poll, Stream}; use futures::{Future, Poll, Stream};
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use crate::dev::Decompress;
use crate::error::UrlencodedError; use crate::error::UrlencodedError;
use crate::extract::FromRequest; use crate::extract::FromRequest;
use crate::http::header::CONTENT_LENGTH; use crate::http::header::CONTENT_LENGTH;
@ -69,16 +69,15 @@ impl<T> ops::DerefMut for Form<T> {
} }
} }
impl<T, P> FromRequest<P> for Form<T> impl<T> FromRequest for Form<T>
where where
T: DeserializeOwned + 'static, T: DeserializeOwned + 'static,
P: Stream<Item = Bytes, Error = crate::error::PayloadError> + 'static,
{ {
type Error = Error; type Error = Error;
type Future = Box<Future<Item = Self, Error = Error>>; type Future = Box<Future<Item = Self, Error = Error>>;
#[inline] #[inline]
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
let req2 = req.clone(); let req2 = req.clone();
let (limit, err) = req let (limit, err) = req
.route_data::<FormConfig>() .route_data::<FormConfig>()
@ -182,8 +181,8 @@ impl Default for FormConfig {
/// * content type is not `application/x-www-form-urlencoded` /// * content type is not `application/x-www-form-urlencoded`
/// * content-length is greater than 32k /// * content-length is greater than 32k
/// ///
pub struct UrlEncoded<P, U> { pub struct UrlEncoded<U> {
stream: Payload<P>, stream: Option<Decompress<Payload>>,
limit: usize, limit: usize,
length: Option<usize>, length: Option<usize>,
encoding: EncodingRef, encoding: EncodingRef,
@ -191,12 +190,9 @@ pub struct UrlEncoded<P, U> {
fut: Option<Box<Future<Item = U, Error = UrlencodedError>>>, fut: Option<Box<Future<Item = U, Error = UrlencodedError>>>,
} }
impl<P, U> UrlEncoded<P, U> impl<U> UrlEncoded<U> {
where
P: Stream<Item = Bytes, Error = PayloadError>,
{
/// Create a new future to URL encode a request /// Create a new future to URL encode a request
pub fn new(req: &HttpRequest, payload: &mut Payload<P>) -> UrlEncoded<P, U> { pub fn new(req: &HttpRequest, payload: &mut Payload) -> UrlEncoded<U> {
// check content type // check content type
if req.content_type().to_lowercase() != "application/x-www-form-urlencoded" { if req.content_type().to_lowercase() != "application/x-www-form-urlencoded" {
return Self::err(UrlencodedError::ContentType); return Self::err(UrlencodedError::ContentType);
@ -219,9 +215,10 @@ where
} }
}; };
let payload = Decompress::from_headers(payload.take(), req.headers());
UrlEncoded { UrlEncoded {
encoding, encoding,
stream: payload.take(), stream: Some(payload),
limit: 32_768, limit: 32_768,
length: len, length: len,
fut: None, fut: None,
@ -231,7 +228,7 @@ where
fn err(e: UrlencodedError) -> Self { fn err(e: UrlencodedError) -> Self {
UrlEncoded { UrlEncoded {
stream: Payload::None, stream: None,
limit: 32_768, limit: 32_768,
fut: None, fut: None,
err: Some(e), err: Some(e),
@ -247,9 +244,8 @@ where
} }
} }
impl<P, U> Future for UrlEncoded<P, U> impl<U> Future for UrlEncoded<U>
where where
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
U: DeserializeOwned + 'static, U: DeserializeOwned + 'static,
{ {
type Item = U; type Item = U;
@ -274,7 +270,10 @@ where
// future // future
let encoding = self.encoding; let encoding = self.encoding;
let fut = std::mem::replace(&mut self.stream, Payload::None) let fut = self
.stream
.take()
.unwrap()
.from_err() .from_err()
.fold(BytesMut::with_capacity(8192), move |mut body, chunk| { .fold(BytesMut::with_capacity(8192), move |mut body, chunk| {
if (body.len() + chunk.len()) > limit { if (body.len() + chunk.len()) > limit {
@ -355,20 +354,20 @@ mod tests {
TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded") TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
.header(CONTENT_LENGTH, "xxxx") .header(CONTENT_LENGTH, "xxxx")
.to_http_parts(); .to_http_parts();
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl)); let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl));
assert!(eq(info.err().unwrap(), UrlencodedError::UnknownLength)); assert!(eq(info.err().unwrap(), UrlencodedError::UnknownLength));
let (req, mut pl) = let (req, mut pl) =
TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded") TestRequest::with_header(CONTENT_TYPE, "application/x-www-form-urlencoded")
.header(CONTENT_LENGTH, "1000000") .header(CONTENT_LENGTH, "1000000")
.to_http_parts(); .to_http_parts();
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl)); let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl));
assert!(eq(info.err().unwrap(), UrlencodedError::Overflow)); assert!(eq(info.err().unwrap(), UrlencodedError::Overflow));
let (req, mut pl) = TestRequest::with_header(CONTENT_TYPE, "text/plain") let (req, mut pl) = TestRequest::with_header(CONTENT_TYPE, "text/plain")
.header(CONTENT_LENGTH, "10") .header(CONTENT_LENGTH, "10")
.to_http_parts(); .to_http_parts();
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl)); let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl));
assert!(eq(info.err().unwrap(), UrlencodedError::ContentType)); assert!(eq(info.err().unwrap(), UrlencodedError::ContentType));
} }
@ -380,7 +379,7 @@ mod tests {
.set_payload(Bytes::from_static(b"hello=world")) .set_payload(Bytes::from_static(b"hello=world"))
.to_http_parts(); .to_http_parts();
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl)).unwrap(); let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl)).unwrap();
assert_eq!( assert_eq!(
info, info,
Info { Info {
@ -396,7 +395,7 @@ mod tests {
.set_payload(Bytes::from_static(b"hello=world")) .set_payload(Bytes::from_static(b"hello=world"))
.to_http_parts(); .to_http_parts();
let info = block_on(UrlEncoded::<_, Info>::new(&req, &mut pl)).unwrap(); let info = block_on(UrlEncoded::<Info>::new(&req, &mut pl)).unwrap();
assert_eq!( assert_eq!(
info, info,
Info { Info {

View File

@ -3,7 +3,7 @@
use std::rc::Rc; use std::rc::Rc;
use std::{fmt, ops}; use std::{fmt, ops};
use bytes::{Bytes, BytesMut}; use bytes::BytesMut;
use futures::{Future, Poll, Stream}; use futures::{Future, Poll, Stream};
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde::Serialize; use serde::Serialize;
@ -12,7 +12,8 @@ use serde_json;
use actix_http::http::{header::CONTENT_LENGTH, StatusCode}; use actix_http::http::{header::CONTENT_LENGTH, StatusCode};
use actix_http::{HttpMessage, Payload, Response}; use actix_http::{HttpMessage, Payload, Response};
use crate::error::{Error, JsonPayloadError, PayloadError}; use crate::dev::Decompress;
use crate::error::{Error, JsonPayloadError};
use crate::extract::FromRequest; use crate::extract::FromRequest;
use crate::request::HttpRequest; use crate::request::HttpRequest;
use crate::responder::Responder; use crate::responder::Responder;
@ -163,16 +164,15 @@ impl<T: Serialize> Responder for Json<T> {
/// ); /// );
/// } /// }
/// ``` /// ```
impl<T, P> FromRequest<P> for Json<T> impl<T> FromRequest for Json<T>
where where
T: DeserializeOwned + 'static, T: DeserializeOwned + 'static,
P: Stream<Item = Bytes, Error = crate::error::PayloadError> + 'static,
{ {
type Error = Error; type Error = Error;
type Future = Box<Future<Item = Self, Error = Error>>; type Future = Box<Future<Item = Self, Error = Error>>;
#[inline] #[inline]
fn from_request(req: &HttpRequest, payload: &mut Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
let req2 = req.clone(); let req2 = req.clone();
let (limit, err) = req let (limit, err) = req
.route_data::<JsonConfig>() .route_data::<JsonConfig>()
@ -270,21 +270,20 @@ impl Default for JsonConfig {
/// ///
/// * content type is not `application/json` /// * content type is not `application/json`
/// * content length is greater than 256k /// * content length is greater than 256k
pub struct JsonBody<P, U> { pub struct JsonBody<U> {
limit: usize, limit: usize,
length: Option<usize>, length: Option<usize>,
stream: Payload<P>, stream: Option<Decompress<Payload>>,
err: Option<JsonPayloadError>, err: Option<JsonPayloadError>,
fut: Option<Box<Future<Item = U, Error = JsonPayloadError>>>, fut: Option<Box<Future<Item = U, Error = JsonPayloadError>>>,
} }
impl<P, U> JsonBody<P, U> impl<U> JsonBody<U>
where where
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
U: DeserializeOwned + 'static, U: DeserializeOwned + 'static,
{ {
/// Create `JsonBody` for request. /// Create `JsonBody` for request.
pub fn new(req: &HttpRequest, payload: &mut Payload<P>) -> Self { pub fn new(req: &HttpRequest, payload: &mut Payload) -> Self {
// check content-type // check content-type
let json = if let Ok(Some(mime)) = req.mime_type() { let json = if let Ok(Some(mime)) = req.mime_type() {
mime.subtype() == mime::JSON || mime.suffix() == Some(mime::JSON) mime.subtype() == mime::JSON || mime.suffix() == Some(mime::JSON)
@ -295,7 +294,7 @@ where
return JsonBody { return JsonBody {
limit: 262_144, limit: 262_144,
length: None, length: None,
stream: Payload::None, stream: None,
fut: None, fut: None,
err: Some(JsonPayloadError::ContentType), err: Some(JsonPayloadError::ContentType),
}; };
@ -309,11 +308,12 @@ where
} }
} }
} }
let payload = Decompress::from_headers(payload.take(), req.headers());
JsonBody { JsonBody {
limit: 262_144, limit: 262_144,
length: len, length: len,
stream: payload.take(), stream: Some(payload),
fut: None, fut: None,
err: None, err: None,
} }
@ -326,9 +326,8 @@ where
} }
} }
impl<P, U> Future for JsonBody<P, U> impl<U> Future for JsonBody<U>
where where
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
U: DeserializeOwned + 'static, U: DeserializeOwned + 'static,
{ {
type Item = U; type Item = U;
@ -350,7 +349,10 @@ where
} }
} }
let fut = std::mem::replace(&mut self.stream, Payload::None) let fut = self
.stream
.take()
.unwrap()
.from_err() .from_err()
.fold(BytesMut::with_capacity(8192), move |mut body, chunk| { .fold(BytesMut::with_capacity(8192), move |mut body, chunk| {
if (body.len() + chunk.len()) > limit { if (body.len() + chunk.len()) > limit {
@ -508,7 +510,7 @@ mod tests {
#[test] #[test]
fn test_json_body() { fn test_json_body() {
let (req, mut pl) = TestRequest::default().to_http_parts(); let (req, mut pl) = TestRequest::default().to_http_parts();
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl)); let json = block_on(JsonBody::<MyObject>::new(&req, &mut pl));
assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType)); assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
let (req, mut pl) = TestRequest::default() let (req, mut pl) = TestRequest::default()
@ -517,7 +519,7 @@ mod tests {
header::HeaderValue::from_static("application/text"), header::HeaderValue::from_static("application/text"),
) )
.to_http_parts(); .to_http_parts();
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl)); let json = block_on(JsonBody::<MyObject>::new(&req, &mut pl));
assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType)); assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
let (req, mut pl) = TestRequest::default() let (req, mut pl) = TestRequest::default()
@ -531,7 +533,7 @@ mod tests {
) )
.to_http_parts(); .to_http_parts();
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl).limit(100)); let json = block_on(JsonBody::<MyObject>::new(&req, &mut pl).limit(100));
assert!(json_eq(json.err().unwrap(), JsonPayloadError::Overflow)); assert!(json_eq(json.err().unwrap(), JsonPayloadError::Overflow));
let (req, mut pl) = TestRequest::default() let (req, mut pl) = TestRequest::default()
@ -546,7 +548,7 @@ mod tests {
.set_payload(Bytes::from_static(b"{\"name\": \"test\"}")) .set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
.to_http_parts(); .to_http_parts();
let json = block_on(JsonBody::<_, MyObject>::new(&req, &mut pl)); let json = block_on(JsonBody::<MyObject>::new(&req, &mut pl));
assert_eq!( assert_eq!(
json.ok().unwrap(), json.ok().unwrap(),
MyObject { MyObject {

View File

@ -152,7 +152,7 @@ impl<T: fmt::Display> fmt::Display for Path<T> {
/// ); /// );
/// } /// }
/// ``` /// ```
impl<T, P> FromRequest<P> for Path<T> impl<T> FromRequest for Path<T>
where where
T: de::DeserializeOwned, T: de::DeserializeOwned,
{ {
@ -160,7 +160,7 @@ where
type Future = Result<Self, Error>; type Future = Result<Self, Error>;
#[inline] #[inline]
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
de::Deserialize::deserialize(PathDeserializer::new(req.match_info())) de::Deserialize::deserialize(PathDeserializer::new(req.match_info()))
.map(|inner| Path { inner }) .map(|inner| Path { inner })
.map_err(ErrorNotFound) .map_err(ErrorNotFound)

View File

@ -44,7 +44,7 @@ use crate::request::HttpRequest;
/// ); /// );
/// } /// }
/// ``` /// ```
pub struct Payload(crate::dev::Payload<Box<Stream<Item = Bytes, Error = PayloadError>>>); pub struct Payload(crate::dev::Payload);
impl Stream for Payload { impl Stream for Payload {
type Item = Bytes; type Item = Bytes;
@ -85,26 +85,13 @@ impl Stream for Payload {
/// ); /// );
/// } /// }
/// ``` /// ```
impl<P> FromRequest<P> for Payload impl FromRequest for Payload {
where
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
{
type Error = Error; type Error = Error;
type Future = Result<Payload, Error>; type Future = Result<Payload, Error>;
#[inline] #[inline]
fn from_request(_: &HttpRequest, payload: &mut dev::Payload<P>) -> Self::Future { fn from_request(_: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
let pl = match payload.take() { Ok(Payload(payload.take()))
crate::dev::Payload::Stream(s) => {
let pl: Box<dyn Stream<Item = Bytes, Error = PayloadError>> =
Box::new(s);
crate::dev::Payload::Stream(pl)
}
crate::dev::Payload::None => crate::dev::Payload::None,
crate::dev::Payload::H1(pl) => crate::dev::Payload::H1(pl),
crate::dev::Payload::H2(pl) => crate::dev::Payload::H2(pl),
};
Ok(Payload(pl))
} }
} }
@ -133,16 +120,13 @@ where
/// ); /// );
/// } /// }
/// ``` /// ```
impl<P> FromRequest<P> for Bytes impl FromRequest for Bytes {
where
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
{
type Error = Error; type Error = Error;
type Future = type Future =
Either<Box<Future<Item = Bytes, Error = Error>>, FutureResult<Bytes, Error>>; Either<Box<Future<Item = Bytes, Error = Error>>, FutureResult<Bytes, Error>>;
#[inline] #[inline]
fn from_request(req: &HttpRequest, payload: &mut dev::Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
let mut tmp; let mut tmp;
let cfg = if let Some(cfg) = req.route_data::<PayloadConfig>() { let cfg = if let Some(cfg) = req.route_data::<PayloadConfig>() {
cfg cfg
@ -188,16 +172,13 @@ where
/// ); /// );
/// } /// }
/// ``` /// ```
impl<P> FromRequest<P> for String impl FromRequest for String {
where
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
{
type Error = Error; type Error = Error;
type Future = type Future =
Either<Box<Future<Item = String, Error = Error>>, FutureResult<String, Error>>; Either<Box<Future<Item = String, Error = Error>>, FutureResult<String, Error>>;
#[inline] #[inline]
fn from_request(req: &HttpRequest, payload: &mut dev::Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
let mut tmp; let mut tmp;
let cfg = if let Some(cfg) = req.route_data::<PayloadConfig>() { let cfg = if let Some(cfg) = req.route_data::<PayloadConfig>() {
cfg cfg
@ -300,20 +281,17 @@ impl Default for PayloadConfig {
/// By default only 256Kb payload reads to a memory, then /// By default only 256Kb payload reads to a memory, then
/// `PayloadError::Overflow` get returned. Use `MessageBody::limit()` /// `PayloadError::Overflow` get returned. Use `MessageBody::limit()`
/// method to change upper limit. /// method to change upper limit.
pub struct HttpMessageBody<P> { pub struct HttpMessageBody {
limit: usize, limit: usize,
length: Option<usize>, length: Option<usize>,
stream: dev::Payload<P>, stream: Option<dev::Decompress<dev::Payload>>,
err: Option<PayloadError>, err: Option<PayloadError>,
fut: Option<Box<Future<Item = Bytes, Error = PayloadError>>>, fut: Option<Box<Future<Item = Bytes, Error = PayloadError>>>,
} }
impl<P> HttpMessageBody<P> impl HttpMessageBody {
where
P: Stream<Item = Bytes, Error = PayloadError>,
{
/// Create `MessageBody` for request. /// Create `MessageBody` for request.
pub fn new(req: &HttpRequest, payload: &mut dev::Payload<P>) -> HttpMessageBody<P> { pub fn new(req: &HttpRequest, payload: &mut dev::Payload) -> HttpMessageBody {
let mut len = None; let mut len = None;
if let Some(l) = req.headers().get(&header::CONTENT_LENGTH) { if let Some(l) = req.headers().get(&header::CONTENT_LENGTH) {
if let Ok(s) = l.to_str() { if let Ok(s) = l.to_str() {
@ -328,7 +306,7 @@ where
} }
HttpMessageBody { HttpMessageBody {
stream: payload.take(), stream: Some(dev::Decompress::from_headers(payload.take(), req.headers())),
limit: 262_144, limit: 262_144,
length: len, length: len,
fut: None, fut: None,
@ -344,7 +322,7 @@ where
fn err(e: PayloadError) -> Self { fn err(e: PayloadError) -> Self {
HttpMessageBody { HttpMessageBody {
stream: dev::Payload::None, stream: None,
limit: 262_144, limit: 262_144,
fut: None, fut: None,
err: Some(e), err: Some(e),
@ -353,10 +331,7 @@ where
} }
} }
impl<P> Future for HttpMessageBody<P> impl Future for HttpMessageBody {
where
P: Stream<Item = Bytes, Error = PayloadError> + 'static,
{
type Item = Bytes; type Item = Bytes;
type Error = PayloadError; type Error = PayloadError;
@ -378,7 +353,9 @@ where
// future // future
let limit = self.limit; let limit = self.limit;
self.fut = Some(Box::new( self.fut = Some(Box::new(
std::mem::replace(&mut self.stream, actix_http::Payload::None) self.stream
.take()
.unwrap()
.from_err() .from_err()
.fold(BytesMut::with_capacity(8192), move |mut body, chunk| { .fold(BytesMut::with_capacity(8192), move |mut body, chunk| {
if (body.len() + chunk.len()) > limit { if (body.len() + chunk.len()) > limit {

View File

@ -111,7 +111,7 @@ impl<T: fmt::Display> fmt::Display for Query<T> {
/// .route(web::get().to(index))); // <- use `Query` extractor /// .route(web::get().to(index))); // <- use `Query` extractor
/// } /// }
/// ``` /// ```
impl<T, P> FromRequest<P> for Query<T> impl<T> FromRequest for Query<T>
where where
T: de::DeserializeOwned, T: de::DeserializeOwned,
{ {
@ -119,7 +119,7 @@ where
type Future = Result<Self, Error>; type Future = Result<Self, Error>;
#[inline] #[inline]
fn from_request(req: &HttpRequest, _: &mut Payload<P>) -> Self::Future { fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
serde_urlencoded::from_str::<T>(req.query_string()) serde_urlencoded::from_str::<T>(req.query_string())
.map(|val| Ok(Query(val))) .map(|val| Ok(Query(val)))
.unwrap_or_else(|e| { .unwrap_or_else(|e| {

View File

@ -50,7 +50,7 @@ pub use crate::types::*;
/// ); /// );
/// } /// }
/// ``` /// ```
pub fn resource<P: 'static>(path: &str) -> Resource<P> { pub fn resource(path: &str) -> Resource {
Resource::new(path) Resource::new(path)
} }
@ -77,12 +77,12 @@ pub fn resource<P: 'static>(path: &str) -> Resource<P> {
/// * /{project_id}/path2 /// * /{project_id}/path2
/// * /{project_id}/path3 /// * /{project_id}/path3
/// ///
pub fn scope<P: 'static>(path: &str) -> Scope<P> { pub fn scope(path: &str) -> Scope {
Scope::new(path) Scope::new(path)
} }
/// Create *route* without configuration. /// Create *route* without configuration.
pub fn route<P: 'static>() -> Route<P> { pub fn route() -> Route {
Route::new() Route::new()
} }
@ -102,7 +102,7 @@ pub fn route<P: 'static>() -> Route<P> {
/// In the above example, one `GET` route get added: /// In the above example, one `GET` route get added:
/// * /{project_id} /// * /{project_id}
/// ///
pub fn get<P: 'static>() -> Route<P> { pub fn get() -> Route {
Route::new().method(Method::GET) Route::new().method(Method::GET)
} }
@ -122,7 +122,7 @@ pub fn get<P: 'static>() -> Route<P> {
/// In the above example, one `POST` route get added: /// In the above example, one `POST` route get added:
/// * /{project_id} /// * /{project_id}
/// ///
pub fn post<P: 'static>() -> Route<P> { pub fn post() -> Route {
Route::new().method(Method::POST) Route::new().method(Method::POST)
} }
@ -142,7 +142,7 @@ pub fn post<P: 'static>() -> Route<P> {
/// In the above example, one `PUT` route get added: /// In the above example, one `PUT` route get added:
/// * /{project_id} /// * /{project_id}
/// ///
pub fn put<P: 'static>() -> Route<P> { pub fn put() -> Route {
Route::new().method(Method::PUT) Route::new().method(Method::PUT)
} }
@ -162,7 +162,7 @@ pub fn put<P: 'static>() -> Route<P> {
/// In the above example, one `PATCH` route get added: /// In the above example, one `PATCH` route get added:
/// * /{project_id} /// * /{project_id}
/// ///
pub fn patch<P: 'static>() -> Route<P> { pub fn patch() -> Route {
Route::new().method(Method::PATCH) Route::new().method(Method::PATCH)
} }
@ -182,7 +182,7 @@ pub fn patch<P: 'static>() -> Route<P> {
/// In the above example, one `DELETE` route get added: /// In the above example, one `DELETE` route get added:
/// * /{project_id} /// * /{project_id}
/// ///
pub fn delete<P: 'static>() -> Route<P> { pub fn delete() -> Route {
Route::new().method(Method::DELETE) Route::new().method(Method::DELETE)
} }
@ -202,7 +202,7 @@ pub fn delete<P: 'static>() -> Route<P> {
/// In the above example, one `HEAD` route get added: /// In the above example, one `HEAD` route get added:
/// * /{project_id} /// * /{project_id}
/// ///
pub fn head<P: 'static>() -> Route<P> { pub fn head() -> Route {
Route::new().method(Method::HEAD) Route::new().method(Method::HEAD)
} }
@ -222,7 +222,7 @@ pub fn head<P: 'static>() -> Route<P> {
/// In the above example, one `GET` route get added: /// In the above example, one `GET` route get added:
/// * /{project_id} /// * /{project_id}
/// ///
pub fn method<P: 'static>(method: Method) -> Route<P> { pub fn method(method: Method) -> Route {
Route::new().method(method) Route::new().method(method)
} }
@ -240,10 +240,10 @@ pub fn method<P: 'static>(method: Method) -> Route<P> {
/// web::to(index)) /// web::to(index))
/// ); /// );
/// ``` /// ```
pub fn to<F, I, R, P: 'static>(handler: F) -> Route<P> pub fn to<F, I, R>(handler: F) -> Route
where where
F: Factory<I, R> + 'static, F: Factory<I, R> + 'static,
I: FromRequest<P> + 'static, I: FromRequest + 'static,
R: Responder + 'static, R: Responder + 'static,
{ {
Route::new().to(handler) Route::new().to(handler)
@ -263,10 +263,10 @@ where
/// web::to_async(index)) /// web::to_async(index))
/// ); /// );
/// ``` /// ```
pub fn to_async<F, I, R, P: 'static>(handler: F) -> Route<P> pub fn to_async<F, I, R>(handler: F) -> Route
where where
F: AsyncFactory<I, R>, F: AsyncFactory<I, R>,
I: FromRequest<P> + 'static, I: FromRequest + 'static,
R: IntoFuture + 'static, R: IntoFuture + 'static,
R::Item: Into<Response>, R::Item: Into<Response>,
R::Error: Into<Error>, R::Error: Into<Error>,

View File

@ -19,9 +19,7 @@ use rand::{distributions::Alphanumeric, Rng};
use actix_web::{http, test, web, App, HttpResponse, HttpServer}; use actix_web::{http, test, web, App, HttpResponse, HttpServer};
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))] #[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
use actix_web::middleware::encoding; use actix_web::middleware::{BodyEncoding, Compress};
#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
use actix_web::middleware::encoding::BodyEncoding;
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World \
@ -68,7 +66,7 @@ fn test_body_gzip() {
let mut srv = TestServer::new(|| { let mut srv = TestServer::new(|| {
h1::H1Service::new( h1::H1Service::new(
App::new() App::new()
.wrap(encoding::Compress::new(ContentEncoding::Gzip)) .wrap(Compress::new(ContentEncoding::Gzip))
.service(web::resource("/").route(web::to(|| Response::Ok().body(STR)))), .service(web::resource("/").route(web::to(|| Response::Ok().body(STR)))),
) )
}); });
@ -99,13 +97,11 @@ fn test_body_encoding_override() {
let mut srv = TestServer::new(|| { let mut srv = TestServer::new(|| {
h1::H1Service::new( h1::H1Service::new(
App::new() App::new()
.wrap(encoding::Compress::new(ContentEncoding::Gzip)) .wrap(Compress::new(ContentEncoding::Gzip))
.service(web::resource("/").route(web::to(|| { .service(web::resource("/").route(web::to(|| {
use actix_web::middleware::encoding::BodyEncoding;
Response::Ok().encoding(ContentEncoding::Deflate).body(STR) Response::Ok().encoding(ContentEncoding::Deflate).body(STR)
}))) })))
.service(web::resource("/raw").route(web::to(|| { .service(web::resource("/raw").route(web::to(|| {
use actix_web::middleware::encoding::BodyEncoding;
let body = actix_web::dev::Body::Bytes(STR.into()); let body = actix_web::dev::Body::Bytes(STR.into());
let mut response = let mut response =
Response::with_body(actix_web::http::StatusCode::OK, body); Response::with_body(actix_web::http::StatusCode::OK, body);
@ -168,7 +164,7 @@ fn test_body_gzip_large() {
let data = srv_data.clone(); let data = srv_data.clone();
h1::H1Service::new( h1::H1Service::new(
App::new() App::new()
.wrap(encoding::Compress::new(ContentEncoding::Gzip)) .wrap(Compress::new(ContentEncoding::Gzip))
.service( .service(
web::resource("/") web::resource("/")
.route(web::to(move || Response::Ok().body(data.clone()))), .route(web::to(move || Response::Ok().body(data.clone()))),
@ -209,7 +205,7 @@ fn test_body_gzip_large_random() {
let data = srv_data.clone(); let data = srv_data.clone();
h1::H1Service::new( h1::H1Service::new(
App::new() App::new()
.wrap(encoding::Compress::new(ContentEncoding::Gzip)) .wrap(Compress::new(ContentEncoding::Gzip))
.service( .service(
web::resource("/") web::resource("/")
.route(web::to(move || Response::Ok().body(data.clone()))), .route(web::to(move || Response::Ok().body(data.clone()))),
@ -244,7 +240,7 @@ fn test_body_chunked_implicit() {
let mut srv = TestServer::new(move || { let mut srv = TestServer::new(move || {
h1::H1Service::new( h1::H1Service::new(
App::new() App::new()
.wrap(encoding::Compress::new(ContentEncoding::Gzip)) .wrap(Compress::new(ContentEncoding::Gzip))
.service(web::resource("/").route(web::get().to(move || { .service(web::resource("/").route(web::get().to(move || {
Response::Ok().streaming(once(Ok::<_, Error>(Bytes::from_static( Response::Ok().streaming(once(Ok::<_, Error>(Bytes::from_static(
STR.as_ref(), STR.as_ref(),
@ -281,15 +277,12 @@ fn test_body_chunked_implicit() {
#[cfg(feature = "brotli")] #[cfg(feature = "brotli")]
fn test_body_br_streaming() { fn test_body_br_streaming() {
let mut srv = TestServer::new(move || { let mut srv = TestServer::new(move || {
h1::H1Service::new( h1::H1Service::new(App::new().wrap(Compress::new(ContentEncoding::Br)).service(
App::new() web::resource("/").route(web::to(move || {
.wrap(encoding::Compress::new(ContentEncoding::Br)) Response::Ok()
.service(web::resource("/").route(web::to(move || { .streaming(once(Ok::<_, Error>(Bytes::from_static(STR.as_ref()))))
Response::Ok().streaming(once(Ok::<_, Error>(Bytes::from_static( })),
STR.as_ref(), ))
))))
}))),
)
}); });
let mut response = srv let mut response = srv
@ -361,7 +354,7 @@ fn test_body_deflate() {
let mut srv = TestServer::new(move || { let mut srv = TestServer::new(move || {
h1::H1Service::new( h1::H1Service::new(
App::new() App::new()
.wrap(encoding::Compress::new(ContentEncoding::Deflate)) .wrap(Compress::new(ContentEncoding::Deflate))
.service( .service(
web::resource("/").route(web::to(move || Response::Ok().body(STR))), web::resource("/").route(web::to(move || Response::Ok().body(STR))),
), ),
@ -392,13 +385,9 @@ fn test_body_deflate() {
#[cfg(any(feature = "brotli"))] #[cfg(any(feature = "brotli"))]
fn test_body_brotli() { fn test_body_brotli() {
let mut srv = TestServer::new(move || { let mut srv = TestServer::new(move || {
h1::H1Service::new( h1::H1Service::new(App::new().wrap(Compress::new(ContentEncoding::Br)).service(
App::new()
.wrap(encoding::Compress::new(ContentEncoding::Br))
.service(
web::resource("/").route(web::to(move || Response::Ok().body(STR))), web::resource("/").route(web::to(move || Response::Ok().body(STR))),
), ))
)
}); });
// client request // client request
@ -427,7 +416,7 @@ fn test_body_brotli() {
fn test_encoding() { fn test_encoding() {
let mut srv = TestServer::new(move || { let mut srv = TestServer::new(move || {
HttpService::new( HttpService::new(
App::new().enable_encoding().service( App::new().wrap(Compress::default()).service(
web::resource("/") web::resource("/")
.route(web::to(move |body: Bytes| Response::Ok().body(body))), .route(web::to(move |body: Bytes| Response::Ok().body(body))),
), ),
@ -456,7 +445,7 @@ fn test_encoding() {
fn test_gzip_encoding() { fn test_gzip_encoding() {
let mut srv = TestServer::new(move || { let mut srv = TestServer::new(move || {
HttpService::new( HttpService::new(
App::new().chain(encoding::Decompress::new()).service( App::new().service(
web::resource("/") web::resource("/")
.route(web::to(move |body: Bytes| Response::Ok().body(body))), .route(web::to(move |body: Bytes| Response::Ok().body(body))),
), ),
@ -486,7 +475,7 @@ fn test_gzip_encoding_large() {
let data = STR.repeat(10); let data = STR.repeat(10);
let mut srv = TestServer::new(move || { let mut srv = TestServer::new(move || {
h1::H1Service::new( h1::H1Service::new(
App::new().chain(encoding::Decompress::new()).service( App::new().service(
web::resource("/") web::resource("/")
.route(web::to(move |body: Bytes| Response::Ok().body(body))), .route(web::to(move |body: Bytes| Response::Ok().body(body))),
), ),
@ -520,7 +509,7 @@ fn test_reading_gzip_encoding_large_random() {
let mut srv = TestServer::new(move || { let mut srv = TestServer::new(move || {
HttpService::new( HttpService::new(
App::new().chain(encoding::Decompress::new()).service( App::new().service(
web::resource("/") web::resource("/")
.route(web::to(move |body: Bytes| Response::Ok().body(body))), .route(web::to(move |body: Bytes| Response::Ok().body(body))),
), ),
@ -550,7 +539,7 @@ fn test_reading_gzip_encoding_large_random() {
fn test_reading_deflate_encoding() { fn test_reading_deflate_encoding() {
let mut srv = TestServer::new(move || { let mut srv = TestServer::new(move || {
h1::H1Service::new( h1::H1Service::new(
App::new().chain(encoding::Decompress::new()).service( App::new().service(
web::resource("/") web::resource("/")
.route(web::to(move |body: Bytes| Response::Ok().body(body))), .route(web::to(move |body: Bytes| Response::Ok().body(body))),
), ),
@ -580,7 +569,7 @@ fn test_reading_deflate_encoding_large() {
let data = STR.repeat(10); let data = STR.repeat(10);
let mut srv = TestServer::new(move || { let mut srv = TestServer::new(move || {
h1::H1Service::new( h1::H1Service::new(
App::new().chain(encoding::Decompress::new()).service( App::new().service(
web::resource("/") web::resource("/")
.route(web::to(move |body: Bytes| Response::Ok().body(body))), .route(web::to(move |body: Bytes| Response::Ok().body(body))),
), ),
@ -614,7 +603,7 @@ fn test_reading_deflate_encoding_large_random() {
let mut srv = TestServer::new(move || { let mut srv = TestServer::new(move || {
h1::H1Service::new( h1::H1Service::new(
App::new().chain(encoding::Decompress::new()).service( App::new().service(
web::resource("/") web::resource("/")
.route(web::to(move |body: Bytes| Response::Ok().body(body))), .route(web::to(move |body: Bytes| Response::Ok().body(body))),
), ),
@ -644,7 +633,7 @@ fn test_reading_deflate_encoding_large_random() {
fn test_brotli_encoding() { fn test_brotli_encoding() {
let mut srv = TestServer::new(move || { let mut srv = TestServer::new(move || {
h1::H1Service::new( h1::H1Service::new(
App::new().chain(encoding::Decompress::new()).service( App::new().service(
web::resource("/") web::resource("/")
.route(web::to(move |body: Bytes| Response::Ok().body(body))), .route(web::to(move |body: Bytes| Response::Ok().body(body))),
), ),
@ -674,7 +663,7 @@ fn test_brotli_encoding_large() {
let data = STR.repeat(10); let data = STR.repeat(10);
let mut srv = TestServer::new(move || { let mut srv = TestServer::new(move || {
h1::H1Service::new( h1::H1Service::new(
App::new().chain(encoding::Decompress::new()).service( App::new().service(
web::resource("/") web::resource("/")
.route(web::to(move |body: Bytes| Response::Ok().body(body))), .route(web::to(move |body: Bytes| Response::Ok().body(body))),
), ),