From 242fcf1582551f9b6243e12b23adbed2f952ef92 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Fri, 17 Dec 2021 06:02:15 +0300 Subject: [PATCH] make scope accept any MessageBody --- src/middleware/compat.rs | 2 +- src/scope.rs | 38 ++++++++++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/middleware/compat.rs b/src/middleware/compat.rs index d49c461c4..3568d5e84 100644 --- a/src/middleware/compat.rs +++ b/src/middleware/compat.rs @@ -17,7 +17,7 @@ use crate::{ }; /// Middleware for enabling any middleware to be used in [`Resource::wrap`](crate::Resource::wrap), -/// [`Scope::wrap`](crate::Scope::wrap) and [`Condition`](super::Condition). +/// and [`Condition`](super::Condition). /// /// # Examples /// ``` diff --git a/src/scope.rs b/src/scope.rs index 35bbb50ba..172fdc270 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -1,6 +1,9 @@ use std::{cell::RefCell, fmt, future::Future, marker::PhantomData, mem, rc::Rc}; -use actix_http::{body::BoxBody, Extensions}; +use actix_http::{ + body::{BoxBody, MessageBody}, + Extensions, +}; use actix_router::{ResourceDef, Router}; use actix_service::{ apply, apply_fn_factory, boxed, IntoServiceFactory, Service, ServiceFactory, @@ -399,15 +402,16 @@ where } } -impl HttpServiceFactory for Scope +impl HttpServiceFactory for Scope where T: ServiceFactory< ServiceRequest, Config = (), - Response = ServiceResponse, + Response = ServiceResponse, Error = Error, InitError = (), > + 'static, + B: MessageBody + 'static, { fn register(mut self, config: &mut AppService) { // update default resource if needed @@ -457,7 +461,9 @@ where req.add_data_container(Rc::clone(data)); } - srv.call(req) + let fut = srv.call(req); + + async { Ok(fut.await?.map_into_boxed_body()) } }); // register final service @@ -980,6 +986,30 @@ mod tests { ); } + /// Any output body type should be accepted; test for `EitherBody` + #[actix_rt::test] + async fn test_middleware_body_type() { + let srv = init_service( + App::new().service( + web::scope("app") + .wrap_fn(|req, srv| { + let fut = srv.call(req); + async { Ok(fut.await?.map_into_right_body::<()>()) } + }) + .service(web::resource("/test").route(web::get().to(|| async { "hello" }))), + ), + ) + .await; + + // test if `is_complete_body()` is preserved across scope layer + use actix_http::body::MessageBody as _; + let req = TestRequest::with_uri("/app/test").to_request(); + let resp = call_service(&srv, req).await; + let mut body = resp.into_body(); + assert!(body.is_complete_body()); + assert_eq!(body.take_complete_body(), b"hello".as_ref()); + } + #[actix_rt::test] async fn test_middleware_fn() { let srv = init_service(