diff --git a/actix-files/src/files.rs b/actix-files/src/files.rs index fc8fd2531..1e0aec454 100644 --- a/actix-files/src/files.rs +++ b/actix-files/src/files.rs @@ -291,7 +291,7 @@ impl HttpServiceFactory for Files { ResourceDef::prefix(&self.path) }; - config.register_service(rdef, guards, self, None) + config.register_service(rdef, guards, self, None, None) } } diff --git a/actix-files/src/named.rs b/actix-files/src/named.rs index 37f8def3e..23a0b27ed 100644 --- a/actix-files/src/named.rs +++ b/actix-files/src/named.rs @@ -562,6 +562,7 @@ impl HttpServiceFactory for NamedFile { None, self, None, + None, ) } } diff --git a/src/app_service.rs b/src/app_service.rs index ca6f36202..2139ebd7c 100644 --- a/src/app_service.rs +++ b/src/app_service.rs @@ -88,9 +88,9 @@ where default, services: services .into_iter() - .map(|(mut rdef, srv, guards, nested)| { + .map(|(mut rdef, srv, guards, nested, app_data)| { rmap.add(&mut rdef, nested); - (rdef, srv, RefCell::new(guards)) + (rdef, srv, RefCell::new(guards), app_data) }) .collect::>() .into_boxed_slice() @@ -228,7 +228,14 @@ where } pub struct AppRoutingFactory { - services: Rc<[(ResourceDef, HttpNewService, RefCell>)]>, + services: Rc< + [( + ResourceDef, + HttpNewService, + RefCell>, + Option>, + )], + >, default: Rc, } @@ -242,15 +249,18 @@ impl ServiceFactory for AppRoutingFactory { fn new_service(&self, _: ()) -> Self::Future { // construct all services factory future with it's resource def and guards. - let factory_fut = join_all(self.services.iter().map(|(path, factory, guards)| { - let path = path.clone(); - let guards = guards.borrow_mut().take(); - let factory_fut = factory.new_service(()); - async move { - let service = factory_fut.await?; - Ok((path, guards, service)) - } - })); + let factory_fut = join_all(self.services.iter().map( + |(path, factory, guards, app_data)| { + let path = path.clone(); + let guards = guards.borrow_mut().take(); + let factory_fut = factory.new_service(()); + let app_data = app_data.clone(); + async move { + let service = factory_fut.await?; + Ok((path, guards, service, app_data)) + } + }, + )); // construct default service factory future let default_fut = self.default.new_service(()); @@ -264,10 +274,13 @@ impl ServiceFactory for AppRoutingFactory { .into_iter() .collect::, _>>()? .drain(..) - .fold(Router::build(), |mut router, (path, guards, service)| { - router.rdef(path, service).2 = guards; - router - }) + .fold( + Router::build(), + |mut router, (path, guards, service, app_data)| { + router.rdef(path, (service, app_data)).2 = guards; + router + }, + ) .finish(); Ok(AppRouting { router, default }) @@ -276,7 +289,7 @@ impl ServiceFactory for AppRoutingFactory { } pub struct AppRouting { - router: Router, + router: Router<(HttpService, Option>), Guards>, default: HttpService, } @@ -299,7 +312,10 @@ impl Service for AppRouting { true }); - if let Some((srv, _info)) = res { + if let Some(((srv, app_data), _info)) = res { + if let Some(ref app_data) = app_data { + req.add_data_container(app_data.clone()); + } srv.call(req) } else { self.default.call(req) diff --git a/src/config.rs b/src/config.rs index 4bd76f2b7..a40dd94f2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -29,6 +29,7 @@ pub struct AppService { HttpNewService, Option, Option>, + Option>, )>, } @@ -57,6 +58,7 @@ impl AppService { HttpNewService, Option, Option>, + Option>, )>, ) { (self.config, self.services) @@ -88,6 +90,7 @@ impl AppService { guards: Option>>, factory: F, nested: Option>, + app_data: Option>, ) where F: IntoServiceFactory, S: ServiceFactory< @@ -98,8 +101,13 @@ impl AppService { InitError = (), > + 'static, { - self.services - .push((rdef, boxed::factory(factory.into_factory()), guards, nested)); + self.services.push(( + rdef, + boxed::factory(factory.into_factory()), + guards, + nested, + app_data, + )); } } diff --git a/src/resource.rs b/src/resource.rs index 8c2b83b60..e1299edd2 100644 --- a/src/resource.rs +++ b/src/resource.rs @@ -395,7 +395,9 @@ where *rdef.name_mut() = name.clone(); } - config.register_service(rdef, guards, self, None) + let app_data = self.app_data.take().map(Rc::new); + + config.register_service(rdef, guards, self, None, app_data) } } @@ -412,7 +414,6 @@ where fn into_factory(self) -> T { *self.factory_ref.borrow_mut() = Some(ResourceFactory { routes: self.routes, - app_data: self.app_data.map(Rc::new), default: self.default, }); @@ -422,7 +423,6 @@ where pub struct ResourceFactory { routes: Vec, - app_data: Option>, default: HttpNewService, } @@ -441,8 +441,6 @@ impl ServiceFactory for ResourceFactory { // construct route service factory futures let factory_fut = join_all(self.routes.iter().map(|route| route.new_service(()))); - let app_data = self.app_data.clone(); - Box::pin(async move { let default = default_fut.await?; let routes = factory_fut @@ -450,18 +448,13 @@ impl ServiceFactory for ResourceFactory { .into_iter() .collect::, _>>()?; - Ok(ResourceService { - routes, - app_data, - default, - }) + Ok(ResourceService { routes, default }) }) } } pub struct ResourceService { routes: Vec, - app_data: Option>, default: HttpService, } @@ -475,18 +468,10 @@ impl Service for ResourceService { fn call(&self, mut req: ServiceRequest) -> Self::Future { for route in self.routes.iter() { if route.check(&mut req) { - if let Some(ref app_data) = self.app_data { - req.add_data_container(app_data.clone()); - } - return route.call(req); } } - if let Some(ref app_data) = self.app_data { - req.add_data_container(app_data.clone()); - } - self.default.call(req) } } diff --git a/src/scope.rs b/src/scope.rs index 412c01d95..d2e7924c7 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -424,15 +424,14 @@ where // complete scope pipeline creation *self.factory_ref.borrow_mut() = Some(ScopeFactory { - app_data: self.app_data.take().map(Rc::new), default, services: cfg .into_services() .1 .into_iter() - .map(|(mut rdef, srv, guards, nested)| { + .map(|(mut rdef, srv, guards, nested, app_data)| { rmap.add(&mut rdef, nested); - (rdef, srv, RefCell::new(guards)) + (rdef, srv, RefCell::new(guards), app_data) }) .collect::>() .into_boxed_slice() @@ -452,13 +451,20 @@ where guards, self.endpoint, Some(Rc::new(rmap)), + self.app_data.take().map(Rc::new), ) } } pub struct ScopeFactory { - app_data: Option>, - services: Rc<[(ResourceDef, HttpNewService, RefCell>)]>, + services: Rc< + [( + ResourceDef, + HttpNewService, + RefCell>, + Option>, + )], + >, default: Rc, } @@ -475,17 +481,18 @@ impl ServiceFactory for ScopeFactory { let default_fut = self.default.new_service(()); // construct all services factory future with it's resource def and guards. - let factory_fut = join_all(self.services.iter().map(|(path, factory, guards)| { - let path = path.clone(); - let guards = guards.borrow_mut().take(); - let factory_fut = factory.new_service(()); - async move { - let service = factory_fut.await?; - Ok((path, guards, service)) - } - })); - - let app_data = self.app_data.clone(); + let factory_fut = join_all(self.services.iter().map( + |(path, factory, guards, app_data)| { + let path = path.clone(); + let guards = guards.borrow_mut().take(); + let factory_fut = factory.new_service(()); + let app_data = app_data.clone(); + async move { + let service = factory_fut.await?; + Ok((path, guards, service, app_data)) + } + }, + )); Box::pin(async move { let default = default_fut.await?; @@ -496,24 +503,22 @@ impl ServiceFactory for ScopeFactory { .into_iter() .collect::, _>>()? .drain(..) - .fold(Router::build(), |mut router, (path, guards, service)| { - router.rdef(path, service).2 = guards; - router - }) + .fold( + Router::build(), + |mut router, (path, guards, service, app_data)| { + router.rdef(path, (service, app_data)).2 = guards; + router + }, + ) .finish(); - Ok(ScopeService { - app_data, - router, - default, - }) + Ok(ScopeService { router, default }) }) } } pub struct ScopeService { - app_data: Option>, - router: Router>>, + router: Router<(HttpService, Option>), Vec>>, default: HttpService, } @@ -536,11 +541,10 @@ impl Service for ScopeService { true }); - if let Some(ref app_data) = self.app_data { - req.add_data_container(app_data.clone()); - } - - if let Some((srv, _info)) = res { + if let Some(((srv, app_data), _info)) = res { + if let Some(ref app_data) = app_data { + req.add_data_container(app_data.clone()); + } srv.call(req) } else { self.default.call(req) diff --git a/src/service.rs b/src/service.rs index 2956fe6cb..308b00ad3 100644 --- a/src/service.rs +++ b/src/service.rs @@ -562,7 +562,7 @@ where if let Some(ref name) = self.name { *rdef.name_mut() = name.clone(); } - config.register_service(rdef, guards, self.srv, None) + config.register_service(rdef, guards, self.srv, None, None) } }