mirror of https://github.com/fafhrd91/actix-web
Merge remote-tracking branch 'origin/master' into on-connect-fix-2
This commit is contained in:
commit
d4a04b20c6
|
@ -7,13 +7,15 @@
|
||||||
* `Range` typed header. [#2485]
|
* `Range` typed header. [#2485]
|
||||||
* `HttpResponse::map_into_{left,right}_body` and `HttpResponse::map_into_boxed_body`. [#2468]
|
* `HttpResponse::map_into_{left,right}_body` and `HttpResponse::map_into_boxed_body`. [#2468]
|
||||||
* `ServiceResponse::map_into_{left,right}_body` and `HttpResponse::map_into_boxed_body`. [#2468]
|
* `ServiceResponse::map_into_{left,right}_body` and `HttpResponse::map_into_boxed_body`. [#2468]
|
||||||
* Connection data set through the `HttpServer::on_connect` callback is now accessible only from the new `HttpRequest::conn_data()` method. [#2491]
|
* Connection data set through the `HttpServer::on_connect` callback is now accessible only from the new `HttpRequest::conn_data()` and `ServiceRequest::conn_data()` methods. [#2491]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
* Rename `Accept::{mime_precedence => ranked}`. [#2480]
|
* Rename `Accept::{mime_precedence => ranked}`. [#2480]
|
||||||
* Rename `Accept::{mime_preference => preference}`. [#2480]
|
* Rename `Accept::{mime_preference => preference}`. [#2480]
|
||||||
* Un-deprecate `App::data_factory`. [#2484]
|
* Un-deprecate `App::data_factory`. [#2484]
|
||||||
* `HttpRequest::url_for` no longer constructs URLs with query or fragment components. [#2430]
|
* `HttpRequest::url_for` no longer constructs URLs with query or fragment components. [#2430]
|
||||||
|
* Remove `B` (body) type parameter on `App`. [#2493]
|
||||||
|
* Add `B` (body) type parameter on `Scope`. [#2492]
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
* Accept wildcard `*` items in `AcceptLanguage`. [#2480]
|
* Accept wildcard `*` items in `AcceptLanguage`. [#2480]
|
||||||
|
@ -27,6 +29,8 @@
|
||||||
[#2484]: https://github.com/actix/actix-web/pull/2484
|
[#2484]: https://github.com/actix/actix-web/pull/2484
|
||||||
[#2485]: https://github.com/actix/actix-web/pull/2485
|
[#2485]: https://github.com/actix/actix-web/pull/2485
|
||||||
[#2491]: https://github.com/actix/actix-web/pull/2491
|
[#2491]: https://github.com/actix/actix-web/pull/2491
|
||||||
|
[#2492]: https://github.com/actix/actix-web/pull/2492
|
||||||
|
[#2493]: https://github.com/actix/actix-web/pull/2493
|
||||||
|
|
||||||
|
|
||||||
## 4.0.0-beta.13 - 2021-11-30
|
## 4.0.0-beta.13 - 2021-11-30
|
||||||
|
|
|
@ -84,6 +84,7 @@ zstd = { version = "0.9", optional = true }
|
||||||
actix-server = "2.0.0-rc.1"
|
actix-server = "2.0.0-rc.1"
|
||||||
actix-http-test = { version = "3.0.0-beta.7", features = ["openssl"] }
|
actix-http-test = { version = "3.0.0-beta.7", features = ["openssl"] }
|
||||||
actix-tls = { version = "3.0.0-rc.1", features = ["openssl"] }
|
actix-tls = { version = "3.0.0-rc.1", features = ["openssl"] }
|
||||||
|
actix-web = "4.0.0-beta.13"
|
||||||
async-stream = "0.3"
|
async-stream = "0.3"
|
||||||
criterion = { version = "0.3", features = ["html_reports"] }
|
criterion = { version = "0.3", features = ["html_reports"] }
|
||||||
env_logger = "0.9"
|
env_logger = "0.9"
|
||||||
|
@ -95,7 +96,7 @@ serde_json = "1.0"
|
||||||
static_assertions = "1"
|
static_assertions = "1"
|
||||||
tls-openssl = { package = "openssl", version = "0.10.9" }
|
tls-openssl = { package = "openssl", version = "0.10.9" }
|
||||||
tls-rustls = { package = "rustls", version = "0.20.0" }
|
tls-rustls = { package = "rustls", version = "0.20.0" }
|
||||||
tokio = { version = "1.2", features = ["net", "rt"] }
|
tokio = { version = "1.2", features = ["net", "rt", "macros"] }
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "ws"
|
name = "ws"
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
use actix_http::HttpService;
|
||||||
|
use actix_server::Server;
|
||||||
|
use actix_service::map_config;
|
||||||
|
use actix_web::{dev::AppConfig, get, App};
|
||||||
|
|
||||||
|
#[get("/")]
|
||||||
|
async fn index() -> &'static str {
|
||||||
|
"Hello, world. From Actix Web!"
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main(flavor = "current_thread")]
|
||||||
|
async fn main() -> std::io::Result<()> {
|
||||||
|
Server::build()
|
||||||
|
.bind("hello-world", "127.0.0.1:8080", || {
|
||||||
|
// construct actix-web app
|
||||||
|
let app = App::new().service(index);
|
||||||
|
|
||||||
|
HttpService::build()
|
||||||
|
// pass the app to service builder
|
||||||
|
// map_config is used to map App's configuration to ServiceBuilder
|
||||||
|
.finish(map_config(app, |_| AppConfig::default()))
|
||||||
|
.tcp()
|
||||||
|
})?
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
53
src/app.rs
53
src/app.rs
|
@ -1,9 +1,6 @@
|
||||||
use std::{cell::RefCell, fmt, future::Future, marker::PhantomData, rc::Rc};
|
use std::{cell::RefCell, fmt, future::Future, rc::Rc};
|
||||||
|
|
||||||
use actix_http::{
|
use actix_http::{body::MessageBody, Extensions, Request};
|
||||||
body::{BoxBody, MessageBody},
|
|
||||||
Extensions, Request,
|
|
||||||
};
|
|
||||||
use actix_service::{
|
use actix_service::{
|
||||||
apply, apply_fn_factory, boxed, IntoServiceFactory, ServiceFactory, ServiceFactoryExt,
|
apply, apply_fn_factory, boxed, IntoServiceFactory, ServiceFactory, ServiceFactoryExt,
|
||||||
Transform,
|
Transform,
|
||||||
|
@ -26,7 +23,7 @@ use crate::{
|
||||||
|
|
||||||
/// 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<T, B> {
|
pub struct App<T> {
|
||||||
endpoint: T,
|
endpoint: T,
|
||||||
services: Vec<Box<dyn AppServiceFactory>>,
|
services: Vec<Box<dyn AppServiceFactory>>,
|
||||||
default: Option<Rc<BoxedHttpServiceFactory>>,
|
default: Option<Rc<BoxedHttpServiceFactory>>,
|
||||||
|
@ -34,10 +31,9 @@ pub struct App<T, B> {
|
||||||
data_factories: Vec<FnDataFactory>,
|
data_factories: Vec<FnDataFactory>,
|
||||||
external: Vec<ResourceDef>,
|
external: Vec<ResourceDef>,
|
||||||
extensions: Extensions,
|
extensions: Extensions,
|
||||||
_phantom: PhantomData<B>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App<AppEntry, BoxBody> {
|
impl App<AppEntry> {
|
||||||
/// Create application builder. Application can be configured with a builder-like pattern.
|
/// Create application builder. Application can be configured with a builder-like pattern.
|
||||||
#[allow(clippy::new_without_default)]
|
#[allow(clippy::new_without_default)]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
@ -51,22 +47,11 @@ impl App<AppEntry, BoxBody> {
|
||||||
factory_ref,
|
factory_ref,
|
||||||
external: Vec::new(),
|
external: Vec::new(),
|
||||||
extensions: Extensions::new(),
|
extensions: Extensions::new(),
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, B> App<T, B>
|
impl<T> App<T> {
|
||||||
where
|
|
||||||
B: MessageBody,
|
|
||||||
T: ServiceFactory<
|
|
||||||
ServiceRequest,
|
|
||||||
Config = (),
|
|
||||||
Response = ServiceResponse<B>,
|
|
||||||
Error = Error,
|
|
||||||
InitError = (),
|
|
||||||
>,
|
|
||||||
{
|
|
||||||
/// Set application (root level) data.
|
/// Set application (root level) data.
|
||||||
///
|
///
|
||||||
/// Application data stored with `App::app_data()` method is available through the
|
/// Application data stored with `App::app_data()` method is available through the
|
||||||
|
@ -365,7 +350,7 @@ where
|
||||||
/// .route("/index.html", web::get().to(index));
|
/// .route("/index.html", web::get().to(index));
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn wrap<M, B1>(
|
pub fn wrap<M, B, B1>(
|
||||||
self,
|
self,
|
||||||
mw: M,
|
mw: M,
|
||||||
) -> App<
|
) -> App<
|
||||||
|
@ -376,9 +361,16 @@ where
|
||||||
Error = Error,
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
B1,
|
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
|
T: ServiceFactory<
|
||||||
|
ServiceRequest,
|
||||||
|
Response = ServiceResponse<B>,
|
||||||
|
Error = Error,
|
||||||
|
Config = (),
|
||||||
|
InitError = (),
|
||||||
|
>,
|
||||||
|
B: MessageBody,
|
||||||
M: Transform<
|
M: Transform<
|
||||||
T::Service,
|
T::Service,
|
||||||
ServiceRequest,
|
ServiceRequest,
|
||||||
|
@ -396,7 +388,6 @@ where
|
||||||
factory_ref: self.factory_ref,
|
factory_ref: self.factory_ref,
|
||||||
external: self.external,
|
external: self.external,
|
||||||
extensions: self.extensions,
|
extensions: self.extensions,
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,7 +422,7 @@ where
|
||||||
/// .route("/index.html", web::get().to(index));
|
/// .route("/index.html", web::get().to(index));
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn wrap_fn<B1, F, R>(
|
pub fn wrap_fn<F, R, B, B1>(
|
||||||
self,
|
self,
|
||||||
mw: F,
|
mw: F,
|
||||||
) -> App<
|
) -> App<
|
||||||
|
@ -442,12 +433,19 @@ where
|
||||||
Error = Error,
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
B1,
|
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
B1: MessageBody,
|
T: ServiceFactory<
|
||||||
|
ServiceRequest,
|
||||||
|
Response = ServiceResponse<B>,
|
||||||
|
Error = Error,
|
||||||
|
Config = (),
|
||||||
|
InitError = (),
|
||||||
|
>,
|
||||||
|
B: MessageBody,
|
||||||
F: Fn(ServiceRequest, &T::Service) -> R + Clone,
|
F: Fn(ServiceRequest, &T::Service) -> R + Clone,
|
||||||
R: Future<Output = Result<ServiceResponse<B1>, Error>>,
|
R: Future<Output = Result<ServiceResponse<B1>, Error>>,
|
||||||
|
B1: MessageBody,
|
||||||
{
|
{
|
||||||
App {
|
App {
|
||||||
endpoint: apply_fn_factory(self.endpoint, mw),
|
endpoint: apply_fn_factory(self.endpoint, mw),
|
||||||
|
@ -457,12 +455,11 @@ where
|
||||||
factory_ref: self.factory_ref,
|
factory_ref: self.factory_ref,
|
||||||
external: self.external,
|
external: self.external,
|
||||||
extensions: self.extensions,
|
extensions: self.extensions,
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, B> IntoServiceFactory<AppInit<T, B>, Request> for App<T, B>
|
impl<T, B> IntoServiceFactory<AppInit<T, B>, Request> for App<T>
|
||||||
where
|
where
|
||||||
B: MessageBody,
|
B: MessageBody,
|
||||||
T: ServiceFactory<
|
T: ServiceFactory<
|
||||||
|
|
50
src/data.rs
50
src/data.rs
|
@ -31,41 +31,53 @@ pub(crate) type FnDataFactory =
|
||||||
/// server constructs an application instance for each thread, thus application data must be
|
/// server constructs an application instance for each thread, thus application data must be
|
||||||
/// constructed multiple times. If you want to share data between different threads, a shareable
|
/// constructed multiple times. If you want to share data between different threads, a shareable
|
||||||
/// object should be used, e.g. `Send + Sync`. Application data does not need to be `Send`
|
/// object should be used, e.g. `Send + Sync`. Application data does not need to be `Send`
|
||||||
/// or `Sync`. Internally `Data` uses `Arc`.
|
/// or `Sync`. Internally `Data` contains an `Arc`.
|
||||||
///
|
///
|
||||||
/// If route data is not set for a handler, using `Data<T>` extractor would cause *Internal
|
/// If route data is not set for a handler, using `Data<T>` extractor would cause a `500 Internal
|
||||||
/// Server Error* response.
|
/// Server Error` response.
|
||||||
///
|
///
|
||||||
// TODO: document `dyn T` functionality through converting an Arc
|
/// # Unsized Data
|
||||||
// TODO: note equivalence of req.app_data<Data<T>> and Data<T> extractor
|
/// For types that are unsized, most commonly `dyn T`, `Data` can wrap these types by first
|
||||||
// TODO: note that data must be inserted using Data<T> in order to extract it
|
/// constructing an `Arc<dyn T>` and using the `From` implementation to convert it.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use std::{fmt::Display, sync::Arc};
|
||||||
|
/// # use actix_web::web::Data;
|
||||||
|
/// let displayable_arc: Arc<dyn Display> = Arc::new(42usize);
|
||||||
|
/// let displayable_data: Data<dyn Display> = Data::from(displayable_arc);
|
||||||
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::sync::Mutex;
|
/// use std::sync::Mutex;
|
||||||
/// use actix_web::{web, App, HttpResponse, Responder};
|
/// use actix_web::{App, HttpRequest, HttpResponse, Responder, web::{self, Data}};
|
||||||
///
|
///
|
||||||
/// struct MyData {
|
/// struct MyData {
|
||||||
/// counter: usize,
|
/// counter: usize,
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// /// Use the `Data<T>` extractor to access data in a handler.
|
/// /// Use the `Data<T>` extractor to access data in a handler.
|
||||||
/// async fn index(data: web::Data<Mutex<MyData>>) -> impl Responder {
|
/// async fn index(data: Data<Mutex<MyData>>) -> impl Responder {
|
||||||
/// let mut data = data.lock().unwrap();
|
/// let mut my_data = data.lock().unwrap();
|
||||||
/// data.counter += 1;
|
/// my_data.counter += 1;
|
||||||
/// HttpResponse::Ok()
|
/// HttpResponse::Ok()
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// /// Alteratively, use the `HttpRequest::app_data` method to access data in a handler.
|
||||||
/// let data = web::Data::new(Mutex::new(MyData{ counter: 0 }));
|
/// async fn index_alt(req: HttpRequest) -> impl Responder {
|
||||||
///
|
/// let data = req.app_data::<Data<Mutex<MyData>>>().unwrap();
|
||||||
/// let app = App::new()
|
/// let mut my_data = data.lock().unwrap();
|
||||||
/// // Store `MyData` in application storage.
|
/// my_data.counter += 1;
|
||||||
/// .app_data(data.clone())
|
/// HttpResponse::Ok()
|
||||||
/// .service(
|
|
||||||
/// web::resource("/index.html").route(
|
|
||||||
/// web::get().to(index)));
|
|
||||||
/// }
|
/// }
|
||||||
|
///
|
||||||
|
/// let data = Data::new(Mutex::new(MyData { counter: 0 }));
|
||||||
|
///
|
||||||
|
/// let app = App::new()
|
||||||
|
/// // Store `MyData` in application storage.
|
||||||
|
/// .app_data(Data::clone(&data))
|
||||||
|
/// .route("/index.html", web::get().to(index))
|
||||||
|
/// .route("/index-alt.html", web::get().to(index_alt));
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Data<T: ?Sized>(Arc<T>);
|
pub struct Data<T: ?Sized>(Arc<T>);
|
||||||
|
|
|
@ -154,7 +154,7 @@ mod tests {
|
||||||
let srv = init_service(
|
let srv = init_service(
|
||||||
App::new().service(
|
App::new().service(
|
||||||
web::scope("app")
|
web::scope("app")
|
||||||
.wrap(Compat::new(logger))
|
.wrap(logger)
|
||||||
.wrap(Compat::new(compress))
|
.wrap(Compat::new(compress))
|
||||||
.service(web::resource("/test").route(web::get().to(HttpResponse::Ok))),
|
.service(web::resource("/test").route(web::get().to(HttpResponse::Ok))),
|
||||||
),
|
),
|
||||||
|
|
49
src/scope.rs
49
src/scope.rs
|
@ -1,6 +1,6 @@
|
||||||
use std::{cell::RefCell, fmt, future::Future, mem, rc::Rc};
|
use std::{cell::RefCell, fmt, future::Future, marker::PhantomData, mem, rc::Rc};
|
||||||
|
|
||||||
use actix_http::Extensions;
|
use actix_http::{body::BoxBody, Extensions};
|
||||||
use actix_router::{ResourceDef, Router};
|
use actix_router::{ResourceDef, Router};
|
||||||
use actix_service::{
|
use actix_service::{
|
||||||
apply, apply_fn_factory, boxed, IntoServiceFactory, Service, ServiceFactory,
|
apply, apply_fn_factory, boxed, IntoServiceFactory, Service, ServiceFactory,
|
||||||
|
@ -52,7 +52,7 @@ type Guards = Vec<Box<dyn Guard>>;
|
||||||
/// * /{project_id}/path1 - responds to all http method
|
/// * /{project_id}/path1 - responds to all http method
|
||||||
/// * /{project_id}/path2 - `GET` requests
|
/// * /{project_id}/path2 - `GET` requests
|
||||||
/// * /{project_id}/path3 - `HEAD` requests
|
/// * /{project_id}/path3 - `HEAD` requests
|
||||||
pub struct Scope<T = ScopeEndpoint> {
|
pub struct Scope<T = ScopeEndpoint, B = BoxBody> {
|
||||||
endpoint: T,
|
endpoint: T,
|
||||||
rdef: String,
|
rdef: String,
|
||||||
app_data: Option<Extensions>,
|
app_data: Option<Extensions>,
|
||||||
|
@ -61,6 +61,7 @@ pub struct Scope<T = ScopeEndpoint> {
|
||||||
default: Option<Rc<BoxedHttpServiceFactory>>,
|
default: Option<Rc<BoxedHttpServiceFactory>>,
|
||||||
external: Vec<ResourceDef>,
|
external: Vec<ResourceDef>,
|
||||||
factory_ref: Rc<RefCell<Option<ScopeFactory>>>,
|
factory_ref: Rc<RefCell<Option<ScopeFactory>>>,
|
||||||
|
_phantom: PhantomData<B>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scope {
|
impl Scope {
|
||||||
|
@ -77,19 +78,21 @@ impl Scope {
|
||||||
default: None,
|
default: None,
|
||||||
external: Vec::new(),
|
external: Vec::new(),
|
||||||
factory_ref,
|
factory_ref,
|
||||||
|
_phantom: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Scope<T>
|
impl<T, B> Scope<T, B>
|
||||||
where
|
where
|
||||||
T: ServiceFactory<
|
T: ServiceFactory<
|
||||||
ServiceRequest,
|
ServiceRequest,
|
||||||
Config = (),
|
Config = (),
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse<B>,
|
||||||
Error = Error,
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
|
B: 'static,
|
||||||
{
|
{
|
||||||
/// Add match guard to a scope.
|
/// Add match guard to a scope.
|
||||||
///
|
///
|
||||||
|
@ -295,32 +298,29 @@ where
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registers middleware, in the form of a middleware component (type),
|
/// Registers middleware, in the form of a middleware component (type), that runs during inbound
|
||||||
/// that runs during inbound processing in the request
|
/// processing in the request life-cycle (request -> response), modifying request as necessary,
|
||||||
/// life-cycle (request -> response), modifying request as
|
/// across all requests managed by the *Scope*.
|
||||||
/// necessary, across all requests managed by the *Scope*. Scope-level
|
|
||||||
/// middleware is more limited in what it can modify, relative to Route or
|
|
||||||
/// Application level middleware, in that Scope-level middleware can not modify
|
|
||||||
/// ServiceResponse.
|
|
||||||
///
|
///
|
||||||
/// Use middleware when you need to read or modify *every* request in some way.
|
/// Use middleware when you need to read or modify *every* request in some way.
|
||||||
pub fn wrap<M>(
|
pub fn wrap<M, B1>(
|
||||||
self,
|
self,
|
||||||
mw: M,
|
mw: M,
|
||||||
) -> Scope<
|
) -> Scope<
|
||||||
impl ServiceFactory<
|
impl ServiceFactory<
|
||||||
ServiceRequest,
|
ServiceRequest,
|
||||||
Config = (),
|
Config = (),
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse<B1>,
|
||||||
Error = Error,
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
|
B1,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
M: Transform<
|
M: Transform<
|
||||||
T::Service,
|
T::Service,
|
||||||
ServiceRequest,
|
ServiceRequest,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse<B1>,
|
||||||
Error = Error,
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
|
@ -334,16 +334,15 @@ where
|
||||||
default: self.default,
|
default: self.default,
|
||||||
external: self.external,
|
external: self.external,
|
||||||
factory_ref: self.factory_ref,
|
factory_ref: self.factory_ref,
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registers middleware, in the form of a closure, that runs during inbound
|
/// Registers middleware, in the form of a closure, that runs during inbound processing in the
|
||||||
/// processing in the request life-cycle (request -> response), modifying
|
/// request life-cycle (request -> response), modifying request as necessary, across all
|
||||||
/// request as necessary, across all requests managed by the *Scope*.
|
/// requests managed by the *Scope*.
|
||||||
/// Scope-level middleware is more limited in what it can modify, relative
|
|
||||||
/// to Route or Application level middleware, in that Scope-level middleware
|
|
||||||
/// can not modify ServiceResponse.
|
|
||||||
///
|
///
|
||||||
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
/// use actix_service::Service;
|
/// use actix_service::Service;
|
||||||
/// use actix_web::{web, App};
|
/// use actix_web::{web, App};
|
||||||
|
@ -369,21 +368,22 @@ where
|
||||||
/// .route("/index.html", web::get().to(index)));
|
/// .route("/index.html", web::get().to(index)));
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn wrap_fn<F, R>(
|
pub fn wrap_fn<F, R, B1>(
|
||||||
self,
|
self,
|
||||||
mw: F,
|
mw: F,
|
||||||
) -> Scope<
|
) -> Scope<
|
||||||
impl ServiceFactory<
|
impl ServiceFactory<
|
||||||
ServiceRequest,
|
ServiceRequest,
|
||||||
Config = (),
|
Config = (),
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse<B1>,
|
||||||
Error = Error,
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
>,
|
||||||
|
B1,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
F: Fn(ServiceRequest, &T::Service) -> R + Clone,
|
F: Fn(ServiceRequest, &T::Service) -> R + Clone,
|
||||||
R: Future<Output = Result<ServiceResponse, Error>>,
|
R: Future<Output = Result<ServiceResponse<B1>, Error>>,
|
||||||
{
|
{
|
||||||
Scope {
|
Scope {
|
||||||
endpoint: apply_fn_factory(self.endpoint, mw),
|
endpoint: apply_fn_factory(self.endpoint, mw),
|
||||||
|
@ -394,6 +394,7 @@ where
|
||||||
default: self.default,
|
default: self.default,
|
||||||
external: self.external,
|
external: self.external,
|
||||||
factory_ref: self.factory_ref,
|
factory_ref: self.factory_ref,
|
||||||
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue