mirror of https://github.com/fafhrd91/actix-web
tweak
This commit is contained in:
parent
d5dfc80dea
commit
ffe4f2fb46
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
- Panic when calling `Route::to()` or `Route::service()` after `Route::wrap()` to prevent silently dropping route middleware. [#3944]
|
||||||
|
|
||||||
|
[#3944]: https://github.com/actix/actix-web/pull/3944
|
||||||
|
|
||||||
## 4.13.0
|
## 4.13.0
|
||||||
|
|
||||||
- Minimum supported Rust version (MSRV) is now 1.88.
|
- Minimum supported Rust version (MSRV) is now 1.88.
|
||||||
|
|
|
||||||
|
|
@ -44,11 +44,10 @@ impl Route {
|
||||||
/// `mw` is a middleware component (type), that can modify the requests and responses handled by
|
/// `mw` is a middleware component (type), that can modify the requests and responses handled by
|
||||||
/// this `Route`.
|
/// this `Route`.
|
||||||
///
|
///
|
||||||
/// **Important:** `.wrap()` must be called **after** `.to()` or `.service()`, not before.
|
/// This middleware wraps the currently configured route service. Call this method after
|
||||||
/// Calling `.to()` or `.service()` after `.wrap()` will panic, because `.to()` replaces the
|
/// [`Route::to`] or [`Route::service`] so the middleware is applied to the final handler.
|
||||||
/// service and any previously applied middleware would be silently lost.
|
|
||||||
///
|
///
|
||||||
/// # Correct Usage
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
/// # use actix_web::{web, HttpResponse, middleware};
|
/// # use actix_web::{web, HttpResponse, middleware};
|
||||||
/// web::get()
|
/// web::get()
|
||||||
|
|
@ -80,6 +79,17 @@ impl Route {
|
||||||
pub(crate) fn take_guards(&mut self) -> Vec<Box<dyn Guard>> {
|
pub(crate) fn take_guards(&mut self) -> Vec<Box<dyn Guard>> {
|
||||||
mem::take(Rc::get_mut(&mut self.guards).unwrap())
|
mem::take(Rc::get_mut(&mut self.guards).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
|
#[inline(never)]
|
||||||
|
#[track_caller]
|
||||||
|
fn panic_after_wrap(replaced: &str, example: &str) -> ! {
|
||||||
|
panic!(
|
||||||
|
"Route middleware was already registered with `.wrap()`. \
|
||||||
|
Calling `.{replaced}()` now would replace the wrapped service and silently drop middleware. \
|
||||||
|
Call `.{replaced}()` before `.wrap()` (for example: `{example}`)."
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServiceFactory<ServiceRequest> for Route {
|
impl ServiceFactory<ServiceRequest> for Route {
|
||||||
|
|
@ -227,6 +237,11 @@ impl Route {
|
||||||
/// .route(web::get().to(index))
|
/// .route(web::get().to(index))
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
/// Panics if called after [`Route::wrap`], since this would replace the wrapped service and
|
||||||
|
/// silently discard middleware.
|
||||||
|
#[track_caller]
|
||||||
pub fn to<F, Args>(mut self, handler: F) -> Self
|
pub fn to<F, Args>(mut self, handler: F) -> Self
|
||||||
where
|
where
|
||||||
F: Handler<Args>,
|
F: Handler<Args>,
|
||||||
|
|
@ -234,10 +249,7 @@ impl Route {
|
||||||
F::Output: Responder + 'static,
|
F::Output: Responder + 'static,
|
||||||
{
|
{
|
||||||
if self.wrapped {
|
if self.wrapped {
|
||||||
panic!(
|
Self::panic_after_wrap("to", "web::get().to(handler).wrap(mw)");
|
||||||
"Calling `.to()` after `.wrap()` will silently discard the middleware. \
|
|
||||||
Call `.to()` before `.wrap()` instead: `web::get().to(handler).wrap(mw)`"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.service = handler_service(handler);
|
self.service = handler_service(handler);
|
||||||
|
|
@ -276,6 +288,11 @@ impl Route {
|
||||||
/// web::get().service(fn_factory(|| async { Ok(HelloWorld) })),
|
/// web::get().service(fn_factory(|| async { Ok(HelloWorld) })),
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
/// Panics if called after [`Route::wrap`], since this would replace the wrapped service and
|
||||||
|
/// silently discard middleware.
|
||||||
|
#[track_caller]
|
||||||
pub fn service<S, E>(mut self, service_factory: S) -> Self
|
pub fn service<S, E>(mut self, service_factory: S) -> Self
|
||||||
where
|
where
|
||||||
S: ServiceFactory<
|
S: ServiceFactory<
|
||||||
|
|
@ -288,11 +305,7 @@ impl Route {
|
||||||
E: Into<Error> + 'static,
|
E: Into<Error> + 'static,
|
||||||
{
|
{
|
||||||
if self.wrapped {
|
if self.wrapped {
|
||||||
panic!(
|
Self::panic_after_wrap("service", "web::get().service(factory).wrap(mw)");
|
||||||
"Calling `.service()` after `.wrap()` will silently discard the middleware. \
|
|
||||||
Call `.service()` before `.wrap()` instead: \
|
|
||||||
`web::get().service(factory).wrap(mw)`"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.service = boxed::factory(service_factory.map_err(Into::into));
|
self.service = boxed::factory(service_factory.map_err(Into::into));
|
||||||
|
|
@ -491,7 +504,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "Calling `.to()` after `.wrap()`")]
|
#[should_panic(expected = "Route middleware was already registered with `.wrap()`")]
|
||||||
fn wrap_before_to_panics() {
|
fn wrap_before_to_panics() {
|
||||||
web::get()
|
web::get()
|
||||||
.wrap(DefaultHeaders::new().add(("x-test", "x-value")))
|
.wrap(DefaultHeaders::new().add(("x-test", "x-value")))
|
||||||
|
|
@ -499,7 +512,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "Calling `.service()` after `.wrap()`")]
|
#[should_panic(expected = "Route middleware was already registered with `.wrap()`")]
|
||||||
fn wrap_before_service_panics() {
|
fn wrap_before_service_panics() {
|
||||||
web::get()
|
web::get()
|
||||||
.wrap(DefaultHeaders::new().add(("x-test", "x-value")))
|
.wrap(DefaultHeaders::new().add(("x-test", "x-value")))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue