diff --git a/CHANGES.md b/CHANGES.md
index bf60787f..f7693e66 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,15 @@
# 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
### Added
diff --git a/actix-files/src/lib.rs b/actix-files/src/lib.rs
index 6ebf4336..fd7ac3f6 100644
--- a/actix-files/src/lib.rs
+++ b/actix-files/src/lib.rs
@@ -32,9 +32,8 @@ use self::error::{FilesError, UriSegmentError};
pub use crate::named::NamedFile;
pub use crate::range::HttpRange;
-type HttpService
= BoxedService, ServiceResponse, Error>;
-type HttpNewService =
- BoxedNewService<(), ServiceRequest
, ServiceResponse, Error, ()>;
+type HttpService = BoxedService;
+type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
/// 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
@@ -225,18 +224,18 @@ type MimeOverride = Fn(&mime::Name) -> DispositionType;
/// .service(fs::Files::new("/static", "."));
/// }
/// ```
-pub struct Files {
+pub struct Files {
path: String,
directory: PathBuf,
index: Option,
show_index: bool,
- default: Rc>>>>,
+ default: Rc>>>,
renderer: Rc,
mime_override: Option>,
file_flags: named::Flags,
}
-impl Clone for Files {
+impl Clone for Files {
fn clone(&self) -> Self {
Self {
directory: self.directory.clone(),
@@ -251,13 +250,13 @@ impl Clone for Files {
}
}
-impl Files {
+impl Files {
/// Create new `Files` instance for specified base directory.
///
/// `File` uses `ThreadPool` for blocking filesystem operations.
/// By default pool with 5x threads of available cpus is used.
/// Pool size can be changed by setting ACTIX_CPU_POOL environment variable.
- pub fn new>(path: &str, dir: T) -> Files {
+ pub fn new>(path: &str, dir: T) -> Files {
let dir = dir.into().canonicalize().unwrap_or_else(|_| PathBuf::new());
if !dir.is_dir() {
log::error!("Specified path is not a directory");
@@ -335,7 +334,7 @@ impl Files {
where
F: IntoNewService,
U: NewService<
- Request = ServiceRequest,
+ Request = ServiceRequest,
Response = ServiceResponse,
Error = Error,
> + 'static,
@@ -349,11 +348,8 @@ impl Files {
}
}
-impl HttpServiceFactory
for Files
-where
- P: 'static,
-{
- fn register(self, config: &mut ServiceConfig
) {
+impl HttpServiceFactory for Files {
+ fn register(self, config: &mut ServiceConfig) {
if self.default.borrow().is_none() {
*self.default.borrow_mut() = Some(config.default_service());
}
@@ -366,11 +362,11 @@ where
}
}
-impl NewService for Files {
- type Request = ServiceRequest
;
+impl NewService for Files {
+ type Request = ServiceRequest;
type Response = ServiceResponse;
type Error = Error;
- type Service = FilesService
;
+ type Service = FilesService;
type InitError = ();
type Future = Box>;
@@ -401,22 +397,22 @@ impl NewService for Files {
}
}
-pub struct FilesService
{
+pub struct FilesService {
directory: PathBuf,
index: Option,
show_index: bool,
- default: Option>,
+ default: Option,
renderer: Rc,
mime_override: Option>,
file_flags: named::Flags,
}
-impl FilesService
{
+impl FilesService {
fn handle_err(
&mut self,
e: io::Error,
req: HttpRequest,
- payload: Payload
,
+ payload: Payload,
) -> Either<
FutureResult,
Box>,
@@ -430,8 +426,8 @@ impl FilesService
{
}
}
-impl
Service for FilesService
{
- type Request = ServiceRequest
;
+impl Service for FilesService {
+ type Request = ServiceRequest;
type Response = ServiceResponse;
type Error = Error;
type Future = Either<
@@ -443,7 +439,7 @@ impl
Service for FilesService
{
Ok(Async::Ready(()))
}
- fn call(&mut self, req: ServiceRequest
) -> Self::Future {
+ fn call(&mut self, req: ServiceRequest) -> Self::Future {
let (req, pl) = req.into_parts();
let real_path = match PathBufWrp::get_pathbuf(req.match_info().path()) {
@@ -547,11 +543,11 @@ impl PathBufWrp {
}
}
-impl
FromRequest
for PathBufWrp {
+impl FromRequest for PathBufWrp {
type Error = UriSegmentError;
type Future = Result;
- fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
+ fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
PathBufWrp::get_pathbuf(req.match_info().path())
}
}
@@ -570,6 +566,7 @@ mod tests {
self, ContentDisposition, DispositionParam, DispositionType,
};
use actix_web::http::{Method, StatusCode};
+ use actix_web::middleware::Compress;
use actix_web::test::{self, TestRequest};
use actix_web::App;
@@ -965,7 +962,7 @@ mod tests {
#[test]
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(|| {
NamedFile::open("Cargo.toml")
.unwrap()
@@ -984,7 +981,7 @@ mod tests {
#[test]
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(|| {
NamedFile::open("Cargo.toml")
.unwrap()
@@ -1053,15 +1050,15 @@ mod tests {
#[test]
fn test_static_files_bad_directory() {
- let _st: Files<()> = Files::new("/", "missing");
- let _st: Files<()> = Files::new("/", "Cargo.toml");
+ let _st: Files = Files::new("/", "missing");
+ let _st: Files = Files::new("/", "Cargo.toml");
}
#[test]
fn test_default_handler_file_missing() {
let mut st = test::block_on(
Files::new("/", ".")
- .default_handler(|req: ServiceRequest<_>| {
+ .default_handler(|req: ServiceRequest| {
Ok(req.into_response(HttpResponse::Ok().body("default content")))
})
.new_service(&()),
diff --git a/actix-files/src/named.rs b/actix-files/src/named.rs
index 1f54c828..c506c02f 100644
--- a/actix-files/src/named.rs
+++ b/actix-files/src/named.rs
@@ -15,7 +15,7 @@ use actix_web::http::header::{
self, ContentDisposition, DispositionParam, DispositionType,
};
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 crate::range::HttpRange;
diff --git a/actix-http/src/payload.rs b/actix-http/src/payload.rs
index 91e6b5c9..0ce20970 100644
--- a/actix-http/src/payload.rs
+++ b/actix-http/src/payload.rs
@@ -53,6 +53,7 @@ where
type Item = Bytes;
type Error = PayloadError;
+ #[inline]
fn poll(&mut self) -> Poll, Self::Error> {
match self {
Payload::None => Ok(Async::Ready(None)),
diff --git a/actix-multipart/src/extractor.rs b/actix-multipart/src/extractor.rs
index 52290b60..1f2f15c6 100644
--- a/actix-multipart/src/extractor.rs
+++ b/actix-multipart/src/extractor.rs
@@ -1,9 +1,5 @@
//! Multipart payload support
-use bytes::Bytes;
-use futures::Stream;
-
-use actix_web::error::{Error, PayloadError};
-use actix_web::{dev::Payload, FromRequest, HttpRequest};
+use actix_web::{dev::Payload, Error, FromRequest, HttpRequest};
use crate::server::Multipart;
@@ -34,15 +30,12 @@ use crate::server::Multipart;
/// }
/// # fn main() {}
/// ```
-impl FromRequest
for Multipart
-where
- P: Stream- + 'static,
-{
+impl FromRequest for Multipart {
type Error = Error;
type Future = Result
;
#[inline]
- fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
+ fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
Ok(Multipart::new(req.headers(), payload.take()))
}
}
diff --git a/actix-session/src/cookie.rs b/actix-session/src/cookie.rs
index b44c87e0..634288b4 100644
--- a/actix-session/src/cookie.rs
+++ b/actix-session/src/cookie.rs
@@ -120,7 +120,7 @@ impl CookieSessionInner {
Ok(())
}
- fn load
(&self, req: &ServiceRequest
) -> HashMap {
+ fn load(&self, req: &ServiceRequest) -> HashMap {
if let Ok(cookies) = req.cookies() {
for cookie in cookies.iter() {
if cookie.name() == self.name {
@@ -256,13 +256,13 @@ impl CookieSession {
}
}
-impl Transform for CookieSession
+impl Transform for CookieSession
where
- S: Service, Response = ServiceResponse>,
+ S: Service>,
S::Future: 'static,
S::Error: 'static,
{
- type Request = ServiceRequest;
+ type Request = ServiceRequest;
type Response = ServiceResponse;
type Error = S::Error;
type InitError = ();
@@ -283,13 +283,13 @@ pub struct CookieSessionMiddleware {
inner: Rc,
}
-impl Service for CookieSessionMiddleware
+impl Service for CookieSessionMiddleware
where
- S: Service, Response = ServiceResponse>,
+ S: Service>,
S::Future: 'static,
S::Error: 'static,
{
- type Request = ServiceRequest;
+ type Request = ServiceRequest;
type Response = ServiceResponse;
type Error = S::Error;
type Future = Box>;
@@ -298,7 +298,7 @@ where
self.service.poll_ready()
}
- fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
+ fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
let inner = self.inner.clone();
let state = self.inner.load(&req);
Session::set_session(state.into_iter(), &mut req);
diff --git a/actix-session/src/lib.rs b/actix-session/src/lib.rs
index 4b7ae2fd..8db87523 100644
--- a/actix-session/src/lib.rs
+++ b/actix-session/src/lib.rs
@@ -119,9 +119,9 @@ impl Session {
inner.state.clear()
}
- pub fn set_session
(
+ pub fn set_session(
data: impl Iterator- ,
- req: &mut ServiceRequest
,
+ req: &mut ServiceRequest,
) {
let session = Session::get_session(&mut *req.extensions_mut());
let mut inner = session.0.borrow_mut();
@@ -172,12 +172,12 @@ impl Session {
/// }
/// # fn main() {}
/// ```
-impl
FromRequest
for Session {
+impl FromRequest for Session {
type Error = Error;
type Future = Result;
#[inline]
- fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
+ fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
Ok(Session::get_session(&mut *req.extensions_mut()))
}
}
diff --git a/actix-web-codegen/src/route.rs b/actix-web-codegen/src/route.rs
index e1a870db..348ce86a 100644
--- a/actix-web-codegen/src/route.rs
+++ b/actix-web-codegen/src/route.rs
@@ -61,8 +61,8 @@ impl fmt::Display for Args {
#[allow(non_camel_case_types)]
pub struct {name};
-impl actix_web::dev::HttpServiceFactory for {name} {{
- fn register(self, config: &mut actix_web::dev::ServiceConfig
) {{
+impl actix_web::dev::HttpServiceFactory for {name} {{
+ fn register(self, config: &mut actix_web::dev::ServiceConfig) {{
{ast}
let resource = actix_web::Resource::new(\"{path}\"){guards}.{to}({name});
diff --git a/actix-web-codegen/tests/test_macro.rs b/actix-web-codegen/tests/test_macro.rs
index c27eefde..dd105785 100644
--- a/actix-web-codegen/tests/test_macro.rs
+++ b/actix-web-codegen/tests/test_macro.rs
@@ -4,11 +4,6 @@ use actix_web::{http, App, HttpResponse, Responder};
use actix_web_codegen::get;
use futures::{future, Future};
-//fn guard_head(head: &actix_web::dev::RequestHead) -> bool {
-// true
-//}
-
-//#[get("/test", guard="guard_head")]
#[get("/test")]
fn test() -> impl Responder {
HttpResponse::Ok()
diff --git a/examples/basic.rs b/examples/basic.rs
index 1191b371..91119657 100644
--- a/examples/basic.rs
+++ b/examples/basic.rs
@@ -27,7 +27,7 @@ fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.wrap(middleware::DefaultHeaders::new().header("X-Version", "0.2"))
- .wrap(middleware::encoding::Compress::default())
+ .wrap(middleware::Compress::default())
.wrap(middleware::Logger::default())
.service(index)
.service(no_params)
diff --git a/src/app.rs b/src/app.rs
index f378572b..39c96cd9 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -3,22 +3,18 @@ use std::marker::PhantomData;
use std::rc::Rc;
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_service::boxed::{self, BoxedNewService};
use actix_service::{
apply_transform, IntoNewService, IntoTransform, NewService, Transform,
};
-#[cfg(any(feature = "brotli", feature = "flate2-zlib", feature = "flate2-rust"))]
-use bytes::Bytes;
-use futures::{IntoFuture, Stream};
+use futures::IntoFuture;
-use crate::app_service::{AppChain, AppEntry, AppInit, AppRouting, AppRoutingFactory};
+use crate::app_service::{AppEntry, AppInit, AppRoutingFactory};
use crate::config::{AppConfig, AppConfigInner, RouterConfig};
use crate::data::{Data, DataFactory};
-use crate::dev::{Payload, PayloadStream, ResourceDef};
-use crate::error::{Error, PayloadError};
+use crate::dev::ResourceDef;
+use crate::error::Error;
use crate::resource::Resource;
use crate::route::Route;
use crate::service::{
@@ -26,40 +22,44 @@ use crate::service::{
ServiceResponse,
};
-type HttpNewService
=
- BoxedNewService<(), ServiceRequest
, ServiceResponse, Error, ()>;
+type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
/// Application builder - structure that follows the builder pattern
/// for building application instances.
-pub struct App
-where
- T: NewService, Response = ServiceRequest>,
-{
- chain: T,
+pub struct App {
+ endpoint: T,
+ services: Vec>,
+ default: Option>,
+ factory_ref: Rc>>,
data: Vec>,
config: AppConfigInner,
- _t: PhantomData<(In, Out)>,
+ external: Vec,
+ _t: PhantomData<(B)>,
}
-impl App {
+impl App {
/// Create application builder. Application can be configured with a builder-like pattern.
pub fn new() -> Self {
+ let fref = Rc::new(RefCell::new(None));
App {
- chain: AppChain,
+ endpoint: AppEntry::new(fref.clone()),
data: Vec::new(),
+ services: Vec::new(),
+ default: None,
+ factory_ref: fref,
config: AppConfigInner::default(),
+ external: Vec::new(),
_t: PhantomData,
}
}
}
-impl App
+impl App
where
- In: 'static,
- Out: 'static,
+ B: MessageBody,
T: NewService<
- Request = ServiceRequest,
- Response = ServiceRequest,
+ Request = ServiceRequest,
+ Response = ServiceResponse,
Error = Error,
InitError = (),
>,
@@ -112,151 +112,6 @@ where
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(
- self,
- mw: F,
- ) -> AppRouter<
- T,
- Out,
- B,
- impl NewService<
- Request = ServiceRequest,
- Response = ServiceResponse,
- Error = Error,
- InitError = (),
- >,
- >
- where
- M: Transform<
- AppRouting,
- Request = ServiceRequest,
- Response = ServiceResponse,
- Error = Error,
- InitError = (),
- >,
- F: IntoTransform>,
- {
- 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(
- self,
- mw: F,
- ) -> AppRouter<
- T,
- Out,
- B,
- impl NewService<
- Request = ServiceRequest,
- Response = ServiceResponse,
- Error = Error,
- InitError = (),
- >,
- >
- where
- F: FnMut(ServiceRequest, &mut AppRouting) -> R + Clone,
- R: IntoFuture- , Error = Error>,
- {
- self.wrap(mw)
- }
-
- /// Register a request modifier. It can modify any request parameters
- /// including request payload type.
- pub fn chain
(
- self,
- chain: F,
- ) -> App<
- In,
- P,
- impl NewService<
- Request = ServiceRequest,
- Response = ServiceRequest,
- Error = Error,
- InitError = (),
- >,
- >
- where
- C: NewService<
- Request = ServiceRequest,
- Response = ServiceRequest,
- Error = Error,
- InitError = (),
- >,
- F: IntoNewService,
- {
- 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
/// process
///
@@ -269,7 +124,7 @@ where
/// use actix_web::{web, middleware, App, HttpResponse};
///
/// // this function could be located in different module
- /// fn config(cfg: &mut web::RouterConfig
) {
+ /// fn config(cfg: &mut web::RouterConfig) {
/// cfg.service(web::resource("/test")
/// .route(web::get().to(|| HttpResponse::Ok()))
/// .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
@@ -283,27 +138,16 @@ where
/// .route("/index.html", web::get().to(|| HttpResponse::Ok()));
/// }
/// ```
- pub fn configure(mut self, f: F) -> AppRouter>
+ pub fn configure(mut self, f: F) -> Self
where
- F: Fn(&mut RouterConfig),
+ F: Fn(&mut RouterConfig),
{
let mut cfg = RouterConfig::new();
f(&mut cfg);
self.data.extend(cfg.data);
-
- 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: cfg.services,
- external: cfg.external,
- _t: PhantomData,
- }
+ self.services.extend(cfg.services);
+ self.external.extend(cfg.external);
+ self
}
/// Configure route for a specific path.
@@ -325,171 +169,7 @@ where
/// .route("/test2", web::post().to(|| HttpResponse::MethodNotAllowed()));
/// }
/// ```
- pub fn route(
- self,
- path: &str,
- mut route: Route,
- ) -> AppRouter> {
- 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(self, service: F) -> AppRouter>
- where
- F: HttpServiceFactory + '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,
- Response = ServiceRequest>>,
- Error = Error,
- InitError = (),
- >,
- Decoder>,
- Encoder,
- impl NewService<
- Request = ServiceRequest>>,
- Response = ServiceResponse>,
- Error = Error,
- InitError = (),
- >,
- >
- where
- Out: Stream- ,
- {
- 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
{
- chain: C,
- endpoint: T,
- services: Vec>>,
- default: Option>>,
- factory_ref: Rc>>>,
- data: Vec>,
- config: AppConfigInner,
- external: Vec,
- _t: PhantomData<(P, B)>,
-}
-
-impl AppRouter
-where
- P: 'static,
- B: MessageBody,
- T: NewService<
- Request = ServiceRequest,
- Response = ServiceResponse,
- 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
(cfg: &mut web::RouterConfig
) {
- /// 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(mut self, f: F) -> Self
- where
- F: Fn(&mut RouterConfig),
- {
- 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
) -> Self {
+ pub fn route(self, path: &str, mut route: Route) -> Self {
self.service(
Resource::new(path)
.add_guards(route.take_guards())
@@ -508,94 +188,31 @@ where
/// * "StaticFiles" is a service for static files support
pub fn service(mut self, factory: F) -> Self
where
- F: HttpServiceFactory + 'static,
+ F: HttpServiceFactory + 'static,
{
self.services
.push(Box::new(ServiceFactoryWrapper::new(factory)));
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 *Route*.
+ /// Set server host name.
///
- /// 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(
- self,
- mw: F,
- ) -> AppRouter<
- C,
- P,
- B1,
- impl NewService<
- Request = ServiceRequest,
- Response = ServiceResponse,
- Error = Error,
- InitError = (),
- >,
- >
- where
- M: Transform<
- T::Service,
- Request = ServiceRequest,
- Response = ServiceResponse,
- Error = Error,
- InitError = (),
- >,
- B1: MessageBody,
- F: IntoTransform,
- {
- 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(
- self,
- mw: F,
- ) -> AppRouter<
- C,
- P,
- B1,
- impl NewService<
- Request = ServiceRequest,
- Response = ServiceResponse,
- Error = Error,
- InitError = (),
- >,
- >
- where
- B1: MessageBody,
- F: FnMut(ServiceRequest, &mut T::Service) -> R + Clone,
- R: IntoFuture- , Error = Error>,
- {
- self.wrap(mw)
+ /// 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
}
/// Default resource to be used if no matching resource could be found.
pub fn default_resource
(mut self, f: F) -> Self
where
- F: FnOnce(Resource) -> Resource
,
+ F: FnOnce(Resource) -> Resource,
U: NewService<
- Request = ServiceRequest
,
+ Request = ServiceRequest,
Response = ServiceResponse,
Error = Error,
InitError = (),
@@ -641,27 +258,128 @@ where
self.external.push(rdef);
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(
+ self,
+ mw: F,
+ ) -> App<
+ impl NewService<
+ Request = ServiceRequest,
+ Response = ServiceResponse,
+ Error = Error,
+ InitError = (),
+ >,
+ B1,
+ >
+ where
+ M: Transform<
+ T::Service,
+ Request = ServiceRequest,
+ Response = ServiceResponse,
+ Error = Error,
+ InitError = (),
+ >,
+ B1: MessageBody,
+ F: IntoTransform,
+ {
+ 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,
+ }
+ }
+
+ /// 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(
+ self,
+ mw: F,
+ ) -> App<
+ impl NewService<
+ Request = ServiceRequest,
+ Response = ServiceResponse,
+ Error = Error,
+ InitError = (),
+ >,
+ B1,
+ >
+ where
+ B1: MessageBody,
+ F: FnMut(ServiceRequest, &mut T::Service) -> R + Clone,
+ R: IntoFuture- , Error = Error>,
+ {
+ self.wrap(mw)
+ }
}
-impl
IntoNewService, ServerConfig>
- for AppRouter
+impl IntoNewService, ServerConfig> for App
where
+ B: MessageBody,
T: NewService<
- Request = ServiceRequest,
+ Request = ServiceRequest,
Response = ServiceResponse,
Error = Error,
InitError = (),
>,
- C: NewService<
- Request = ServiceRequest,
- Response = ServiceRequest
,
- Error = Error,
- InitError = (),
- >,
{
- fn into_new_service(self) -> AppInit {
+ fn into_new_service(self) -> AppInit {
AppInit {
- chain: self.chain,
data: self.data,
endpoint: self.endpoint,
services: RefCell::new(self.services),
@@ -742,13 +460,13 @@ mod tests {
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
}
- fn md(
- req: ServiceRequest ,
+ fn md(
+ req: ServiceRequest,
srv: &mut S,
) -> impl IntoFuture- , Error = Error>
where
S: Service<
- Request = ServiceRequest
,
+ Request = ServiceRequest,
Response = ServiceResponse,
Error = Error,
>,
diff --git a/src/app_service.rs b/src/app_service.rs
index 593fbe67..a5d90636 100644
--- a/src/app_service.rs
+++ b/src/app_service.rs
@@ -6,7 +6,7 @@ use actix_http::{Request, Response};
use actix_router::{Path, ResourceDef, ResourceInfo, Router, Url};
use actix_server_config::ServerConfig;
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::{Async, Future, Poll};
@@ -19,9 +19,8 @@ use crate::rmap::ResourceMap;
use crate::service::{ServiceFactory, ServiceRequest, ServiceResponse};
type Guards = Vec>;
-type HttpService = BoxedService, ServiceResponse, Error>;
-type HttpNewService =
- BoxedNewService<(), ServiceRequest
, ServiceResponse, Error, ()>;
+type HttpService = BoxedService;
+type HttpNewService = BoxedNewService<(), ServiceRequest, ServiceResponse, Error, ()>;
type BoxedResponse = Either<
FutureResult,
Box>,
@@ -29,36 +28,28 @@ type BoxedResponse = Either<
/// Service factory to convert `Request` to a `ServiceRequest`.
/// It also executes data factories.
-pub struct AppInit
+pub struct AppInit
where
- C: NewService>,
T: NewService<
- Request = ServiceRequest,
+ Request = ServiceRequest,
Response = ServiceResponse,
Error = Error,
InitError = (),
>,
{
- pub(crate) chain: C,
pub(crate) endpoint: T,
pub(crate) data: Vec>,
pub(crate) config: RefCell,
- pub(crate) services: RefCell>>>,
- pub(crate) default: Option>>,
- pub(crate) factory_ref: Rc>>>,
+ pub(crate) services: RefCell>>,
+ pub(crate) default: Option>,
+ pub(crate) factory_ref: Rc>>,
pub(crate) external: RefCell>,
}
-impl NewService for AppInit
+impl NewService for AppInit
where
- C: NewService<
- Request = ServiceRequest,
- Response = ServiceRequest,
- Error = Error,
- InitError = (),
- >,
T: NewService<
- Request = ServiceRequest
,
+ Request = ServiceRequest,
Response = ServiceResponse,
Error = Error,
InitError = (),
@@ -66,15 +57,15 @@ where
{
type Request = Request;
type Response = ServiceResponse;
- type Error = C::Error;
- type InitError = C::InitError;
- type Service = AndThen, T::Service>;
- type Future = AppInitResult;
+ type Error = T::Error;
+ type InitError = T::InitError;
+ type Service = AppInitService;
+ type Future = AppInitResult;
fn new_service(&self, cfg: &ServerConfig) -> Self::Future {
// update resource default service
let default = self.default.clone().unwrap_or_else(|| {
- Rc::new(boxed::new_service(fn_service(|req: ServiceRequest| {
+ Rc::new(boxed::new_service(fn_service(|req: ServiceRequest| {
Ok(req.into_response(Response::NotFound().finish()))
})))
});
@@ -121,8 +112,6 @@ where
rmap.finish(rmap.clone());
AppInitResult {
- chain: None,
- chain_fut: self.chain.new_service(&()),
endpoint: None,
endpoint_fut: self.endpoint.new_service(&()),
data: self.data.iter().map(|s| s.construct()).collect(),
@@ -133,38 +122,29 @@ where
}
}
-pub struct AppInitResult
+pub struct AppInitResult
where
- C: NewService,
T: NewService,
{
- chain: Option,
endpoint: Option,
- chain_fut: C::Future,
endpoint_fut: T::Future,
rmap: Rc,
data: Vec>,
config: AppConfig,
- _t: PhantomData<(P, B)>,
+ _t: PhantomData,
}
-impl Future for AppInitResult
+impl Future for AppInitResult
where
- C: NewService<
- Request = ServiceRequest,
- Response = ServiceRequest,
- Error = Error,
- InitError = (),
- >,
T: NewService<
- Request = ServiceRequest
,
+ Request = ServiceRequest,
Response = ServiceResponse,
Error = Error,
InitError = (),
>,
{
- type Item = AndThen, T::Service>;
- type Error = C::InitError;
+ type Item = AppInitService;
+ type Error = T::InitError;
fn poll(&mut self) -> Poll {
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 let Async::Ready(srv) = self.endpoint_fut.poll()? {
self.endpoint = Some(srv);
}
}
- if self.chain.is_some() && self.endpoint.is_some() {
- Ok(Async::Ready(
- AppInitService {
- chain: self.chain.take().unwrap(),
- rmap: self.rmap.clone(),
- config: self.config.clone(),
- pool: HttpRequestPool::create(),
- }
- .and_then(self.endpoint.take().unwrap()),
- ))
+ if self.endpoint.is_some() {
+ Ok(Async::Ready(AppInitService {
+ service: self.endpoint.take().unwrap(),
+ rmap: self.rmap.clone(),
+ config: self.config.clone(),
+ pool: HttpRequestPool::create(),
+ }))
} else {
Ok(Async::NotReady)
}
@@ -206,27 +177,27 @@ where
}
/// Service to convert `Request` to a `ServiceRequest`
-pub struct AppInitService
+pub struct AppInitService
where
- C: Service, Error = Error>,
+ T: Service, Error = Error>,
{
- chain: C,
+ service: T,
rmap: Rc,
config: AppConfig,
pool: &'static HttpRequestPool,
}
-impl Service for AppInitService
+impl Service for AppInitService
where
- C: Service, Error = Error>,
+ T: Service, Error = Error>,
{
type Request = Request;
- type Response = ServiceRequest;
- type Error = C::Error;
- type Future = C::Future;
+ type Response = ServiceResponse;
+ type Error = T::Error;
+ type Future = T::Future;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
- self.chain.poll_ready()
+ self.service.poll_ready()
}
fn call(&mut self, req: Request) -> Self::Future {
@@ -247,22 +218,22 @@ where
self.pool,
)
};
- self.chain.call(ServiceRequest::from_parts(req, payload))
+ self.service.call(ServiceRequest::from_parts(req, payload))
}
}
-pub struct AppRoutingFactory
{
- services: Rc, RefCell>)>>,
- default: Rc>,
+pub struct AppRoutingFactory {
+ services: Rc>)>>,
+ default: Rc,
}
-impl NewService for AppRoutingFactory {
- type Request = ServiceRequest
;
+impl NewService for AppRoutingFactory {
+ type Request = ServiceRequest;
type Response = ServiceResponse;
type Error = Error;
type InitError = ();
- type Service = AppRouting
;
- type Future = AppRoutingFactoryResponse
;
+ type Service = AppRouting;
+ type Future = AppRoutingFactoryResponse;
fn new_service(&self, _: &()) -> Self::Future {
AppRoutingFactoryResponse {
@@ -283,23 +254,23 @@ impl NewService for AppRoutingFactory {
}
}
-type HttpServiceFut
= Box, Error = ()>>;
+type HttpServiceFut = Box>;
/// Create app service
#[doc(hidden)]
-pub struct AppRoutingFactoryResponse {
- fut: Vec