mirror of https://github.com/fafhrd91/actix-web
Merge 6eefb33811
into 8846808804
This commit is contained in:
commit
98bfff0951
|
@ -764,7 +764,7 @@ mod tests {
|
||||||
},
|
},
|
||||||
)))
|
)))
|
||||||
.default_service(web::to(move |req: HttpRequest| {
|
.default_service(web::to(move |req: HttpRequest| {
|
||||||
assert!(req.match_pattern().is_none());
|
assert_eq!(req.match_pattern().as_deref(), Some("/user/{id}"));
|
||||||
HttpResponse::Ok().finish()
|
HttpResponse::Ok().finish()
|
||||||
})),
|
})),
|
||||||
),
|
),
|
||||||
|
|
18
src/rmap.rs
18
src/rmap.rs
|
@ -26,6 +26,10 @@ impl ResourceMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_root_prefix(&mut self, prefix: &str) {
|
||||||
|
rdef_set_root_prefix(&mut self.root, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, pattern: &mut ResourceDef, nested: Option<Rc<ResourceMap>>) {
|
pub fn add(&mut self, pattern: &mut ResourceDef, nested: Option<Rc<ResourceMap>>) {
|
||||||
pattern.set_id(self.patterns.len() as u16);
|
pattern.set_id(self.patterns.len() as u16);
|
||||||
self.patterns.push((pattern.clone(), nested));
|
self.patterns.push((pattern.clone(), nested));
|
||||||
|
@ -247,6 +251,20 @@ impl ResourceMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn rdef_set_root_prefix(rdef: &mut ResourceDef, prefix: &str) {
|
||||||
|
// TODO Doesn't work with multiple patterns
|
||||||
|
let pattern = if prefix.starts_with("/") {
|
||||||
|
[prefix, rdef.pattern()].concat()
|
||||||
|
} else {
|
||||||
|
["/", prefix, rdef.pattern()].concat()
|
||||||
|
};
|
||||||
|
let mut res = ResourceDef::new(pattern);
|
||||||
|
res.set_id(rdef.id());
|
||||||
|
*res.name_mut() = rdef.name().to_string();
|
||||||
|
|
||||||
|
*rdef = res;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
365
src/scope.rs
365
src/scope.rs
|
@ -1,17 +1,14 @@
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use actix_http::Extensions;
|
use actix_http::Extensions;
|
||||||
use actix_router::{ResourceDef, Router};
|
use actix_router::ResourceDef;
|
||||||
use actix_service::boxed::{self, BoxService, BoxServiceFactory};
|
use actix_service::boxed::{self, BoxServiceFactory};
|
||||||
use actix_service::{
|
use actix_service::{
|
||||||
apply, apply_fn_factory, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt,
|
apply, apply_fn_factory, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt,
|
||||||
Transform,
|
Transform,
|
||||||
};
|
};
|
||||||
use futures_core::future::LocalBoxFuture;
|
|
||||||
use futures_util::future::join_all;
|
|
||||||
|
|
||||||
use crate::config::ServiceConfig;
|
use crate::config::ServiceConfig;
|
||||||
use crate::data::Data;
|
use crate::data::Data;
|
||||||
|
@ -19,15 +16,51 @@ use crate::dev::{AppService, HttpServiceFactory};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::guard::Guard;
|
use crate::guard::Guard;
|
||||||
use crate::resource::Resource;
|
use crate::resource::Resource;
|
||||||
use crate::rmap::ResourceMap;
|
use crate::rmap::{self, ResourceMap};
|
||||||
use crate::route::Route;
|
use crate::route::Route;
|
||||||
use crate::service::{
|
use crate::service::{
|
||||||
AppServiceFactory, ServiceFactoryWrapper, ServiceRequest, ServiceResponse,
|
AppServiceFactory, ServiceFactoryWrapper, ServiceRequest, ServiceResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
type Guards = Vec<Box<dyn Guard>>;
|
type BoxedFactory = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>;
|
||||||
type HttpService = BoxService<ServiceRequest, ServiceResponse, Error>;
|
|
||||||
type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>;
|
pub trait EndpointConstructor {
|
||||||
|
type Output: ServiceFactory<
|
||||||
|
ServiceRequest,
|
||||||
|
Config = (),
|
||||||
|
Response = ServiceResponse,
|
||||||
|
Error = Error,
|
||||||
|
InitError = (),
|
||||||
|
> + 'static;
|
||||||
|
|
||||||
|
fn call(&self, f: BoxedFactory) -> Self::Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EndpointConstructor for () {
|
||||||
|
type Output = BoxedFactory;
|
||||||
|
|
||||||
|
fn call(&self, f: BoxedFactory) -> Self::Output {
|
||||||
|
f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F, O> EndpointConstructor for F
|
||||||
|
where
|
||||||
|
F: Fn(BoxedFactory) -> O,
|
||||||
|
O: ServiceFactory<
|
||||||
|
ServiceRequest,
|
||||||
|
Config = (),
|
||||||
|
Response = ServiceResponse,
|
||||||
|
Error = Error,
|
||||||
|
InitError = (),
|
||||||
|
> + 'static,
|
||||||
|
{
|
||||||
|
type Output = O;
|
||||||
|
|
||||||
|
fn call(&self, f: BoxedFactory) -> Self::Output {
|
||||||
|
self(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Resources scope.
|
/// Resources scope.
|
||||||
///
|
///
|
||||||
|
@ -57,44 +90,33 @@ type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Err
|
||||||
/// * /{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> {
|
// use actix_service::{boxed, IntoServiceFactory, ServiceFactory};
|
||||||
endpoint: T,
|
pub struct Scope<Cons = ()> {
|
||||||
rdef: String,
|
constructor: Cons,
|
||||||
|
prefix: String,
|
||||||
app_data: Option<Extensions>,
|
app_data: Option<Extensions>,
|
||||||
services: Vec<Box<dyn AppServiceFactory>>,
|
services: Vec<Box<dyn AppServiceFactory>>,
|
||||||
guards: Vec<Box<dyn Guard>>,
|
guards: Vec<Rc<dyn Guard>>,
|
||||||
default: Option<Rc<HttpNewService>>,
|
default: Option<BoxedFactory>,
|
||||||
external: Vec<ResourceDef>,
|
external: Vec<ResourceDef>,
|
||||||
factory_ref: Rc<RefCell<Option<ScopeFactory>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scope {
|
impl Scope {
|
||||||
/// Create a new scope
|
/// Create a new scope
|
||||||
pub fn new(path: &str) -> Scope {
|
pub fn new(path: &str) -> Scope {
|
||||||
let fref = Rc::new(RefCell::new(None));
|
|
||||||
Scope {
|
Scope {
|
||||||
endpoint: ScopeEndpoint::new(fref.clone()),
|
constructor: (),
|
||||||
rdef: path.to_string(),
|
prefix: path.to_string(),
|
||||||
app_data: None,
|
app_data: None,
|
||||||
guards: Vec::new(),
|
guards: Vec::new(),
|
||||||
services: Vec::new(),
|
services: Vec::new(),
|
||||||
default: None,
|
default: None,
|
||||||
external: Vec::new(),
|
external: Vec::new(),
|
||||||
factory_ref: fref,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Scope<T>
|
impl<C: EndpointConstructor> Scope<C> {
|
||||||
where
|
|
||||||
T: ServiceFactory<
|
|
||||||
ServiceRequest,
|
|
||||||
Config = (),
|
|
||||||
Response = ServiceResponse,
|
|
||||||
Error = Error,
|
|
||||||
InitError = (),
|
|
||||||
>,
|
|
||||||
{
|
|
||||||
/// Add match guard to a scope.
|
/// Add match guard to a scope.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -116,7 +138,7 @@ where
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn guard<G: Guard + 'static>(mut self, guard: G) -> Self {
|
pub fn guard<G: Guard + 'static>(mut self, guard: G) -> Self {
|
||||||
self.guards.push(Box::new(guard));
|
self.guards.push(Rc::new(guard));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,9 +308,9 @@ where
|
||||||
U::InitError: fmt::Debug,
|
U::InitError: fmt::Debug,
|
||||||
{
|
{
|
||||||
// create and configure default resource
|
// create and configure default resource
|
||||||
self.default = Some(Rc::new(boxed::factory(f.into_factory().map_init_err(
|
self.default = Some(boxed::factory(f.into_factory().map_init_err(|e| {
|
||||||
|e| log::error!("Can not construct default service: {:?}", e),
|
log::error!("Can not construct default service: {:?}", e)
|
||||||
))));
|
})));
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -302,36 +324,26 @@ where
|
||||||
/// ServiceResponse.
|
/// 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>(self, mw: M) -> Scope<impl EndpointConstructor>
|
||||||
self,
|
|
||||||
mw: M,
|
|
||||||
) -> Scope<
|
|
||||||
impl ServiceFactory<
|
|
||||||
ServiceRequest,
|
|
||||||
Config = (),
|
|
||||||
Response = ServiceResponse,
|
|
||||||
Error = Error,
|
|
||||||
InitError = (),
|
|
||||||
>,
|
|
||||||
>
|
|
||||||
where
|
where
|
||||||
M: Transform<
|
M: Transform<
|
||||||
T::Service,
|
<C::Output as ServiceFactory<ServiceRequest>>::Service,
|
||||||
ServiceRequest,
|
ServiceRequest,
|
||||||
Response = ServiceResponse,
|
Response = ServiceResponse,
|
||||||
Error = Error,
|
Error = Error,
|
||||||
InitError = (),
|
InitError = (),
|
||||||
>,
|
> + 'static,
|
||||||
{
|
{
|
||||||
|
let mw = Rc::new(mw);
|
||||||
|
let constructor = self.constructor;
|
||||||
Scope {
|
Scope {
|
||||||
endpoint: apply(mw, self.endpoint),
|
constructor: move |factory| apply(mw.clone(), constructor.call(factory)),
|
||||||
rdef: self.rdef,
|
prefix: self.prefix,
|
||||||
app_data: self.app_data,
|
app_data: self.app_data,
|
||||||
guards: self.guards,
|
guards: self.guards,
|
||||||
services: self.services,
|
services: self.services,
|
||||||
default: self.default,
|
default: self.default,
|
||||||
external: self.external,
|
external: self.external,
|
||||||
factory_ref: self.factory_ref,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,209 +379,104 @@ 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>(self, mw: F) -> Scope<impl EndpointConstructor>
|
||||||
self,
|
|
||||||
mw: F,
|
|
||||||
) -> Scope<
|
|
||||||
impl ServiceFactory<
|
|
||||||
ServiceRequest,
|
|
||||||
Config = (),
|
|
||||||
Response = ServiceResponse,
|
|
||||||
Error = Error,
|
|
||||||
InitError = (),
|
|
||||||
>,
|
|
||||||
>
|
|
||||||
where
|
where
|
||||||
F: Fn(ServiceRequest, &T::Service) -> R + Clone,
|
F: Fn(ServiceRequest, &<C::Output as ServiceFactory<ServiceRequest>>::Service) -> R
|
||||||
|
+ Clone
|
||||||
|
+ 'static,
|
||||||
|
|
||||||
R: Future<Output = Result<ServiceResponse, Error>>,
|
R: Future<Output = Result<ServiceResponse, Error>>,
|
||||||
{
|
{
|
||||||
|
let constructor = self.constructor;
|
||||||
Scope {
|
Scope {
|
||||||
endpoint: apply_fn_factory(self.endpoint, mw),
|
constructor: move |factory| apply_fn_factory(constructor.call(factory), mw.clone()),
|
||||||
rdef: self.rdef,
|
prefix: self.prefix,
|
||||||
app_data: self.app_data,
|
app_data: self.app_data,
|
||||||
guards: self.guards,
|
guards: self.guards,
|
||||||
services: self.services,
|
services: self.services,
|
||||||
default: self.default,
|
default: self.default,
|
||||||
external: self.external,
|
external: self.external,
|
||||||
factory_ref: self.factory_ref,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> HttpServiceFactory for Scope<T>
|
fn _register(mut self, config: &mut AppService) {
|
||||||
where
|
let default_service = self.default.take();
|
||||||
T: ServiceFactory<
|
let services = self.services.drain(..).collect::<Vec<_>>();
|
||||||
ServiceRequest,
|
let mut external_resources = self.external.drain(..).collect::<Vec<_>>();
|
||||||
Config = (),
|
|
||||||
Response = ServiceResponse,
|
|
||||||
Error = Error,
|
|
||||||
InitError = (),
|
|
||||||
> + 'static,
|
|
||||||
{
|
|
||||||
fn register(mut self, config: &mut AppService) {
|
|
||||||
// update default resource if needed
|
|
||||||
let default = self.default.unwrap_or_else(|| config.default_service());
|
|
||||||
|
|
||||||
// register nested services
|
let wrapped_guards = |guards: Option<Vec<Box<dyn Guard>>>| {
|
||||||
let mut cfg = config.clone_config();
|
let guards = self
|
||||||
self.services
|
.guards
|
||||||
.into_iter()
|
.iter()
|
||||||
.for_each(|mut srv| srv.register(&mut cfg));
|
.map(|g| Box::new(g.clone()) as Box<dyn Guard>)
|
||||||
|
.chain(guards.into_iter().flatten())
|
||||||
let mut rmap = ResourceMap::new(ResourceDef::root_prefix(&self.rdef));
|
.collect::<Vec<_>>();
|
||||||
|
match guards {
|
||||||
// external resources
|
guards if !guards.is_empty() => Some(guards),
|
||||||
for mut rdef in std::mem::take(&mut self.external) {
|
_ => None,
|
||||||
rmap.add(&mut rdef, None);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)| {
|
|
||||||
rmap.add(&mut rdef, nested);
|
|
||||||
(rdef, srv, RefCell::new(guards))
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.into_boxed_slice()
|
|
||||||
.into(),
|
|
||||||
});
|
|
||||||
|
|
||||||
// get guards
|
|
||||||
let guards = if self.guards.is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(self.guards)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// register final service
|
let wrapped_rdef = |mut rdef: ResourceDef| {
|
||||||
config.register_service(
|
rmap::rdef_set_root_prefix(&mut rdef, &self.prefix);
|
||||||
ResourceDef::root_prefix(&self.rdef),
|
rdef
|
||||||
guards,
|
};
|
||||||
self.endpoint,
|
|
||||||
Some(Rc::new(rmap)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ScopeFactory {
|
let mut wrapped_rmap = |rmap: Option<Rc<ResourceMap>>, rdef: &ResourceDef| {
|
||||||
app_data: Option<Rc<Extensions>>,
|
let rmap = rmap.map(|rmap| {
|
||||||
services: Rc<[(ResourceDef, HttpNewService, RefCell<Option<Guards>>)]>,
|
let mut rmap = (*rmap).clone();
|
||||||
default: Rc<HttpNewService>,
|
rmap.set_root_prefix(&self.prefix);
|
||||||
}
|
rmap
|
||||||
|
|
||||||
impl ServiceFactory<ServiceRequest> for ScopeFactory {
|
|
||||||
type Response = ServiceResponse;
|
|
||||||
type Error = Error;
|
|
||||||
type Config = ();
|
|
||||||
type Service = ScopeService;
|
|
||||||
type InitError = ();
|
|
||||||
type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
|
|
||||||
|
|
||||||
fn new_service(&self, _: ()) -> Self::Future {
|
|
||||||
// construct default service factory future
|
|
||||||
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();
|
|
||||||
|
|
||||||
Box::pin(async move {
|
|
||||||
let default = default_fut.await?;
|
|
||||||
|
|
||||||
// build router from the factory future result.
|
|
||||||
let router = factory_fut
|
|
||||||
.await
|
|
||||||
.into_iter()
|
|
||||||
.collect::<Result<Vec<_>, _>>()?
|
|
||||||
.drain(..)
|
|
||||||
.fold(Router::build(), |mut router, (path, guards, service)| {
|
|
||||||
router.rdef(path, service).2 = guards;
|
|
||||||
router
|
|
||||||
})
|
|
||||||
.finish();
|
|
||||||
|
|
||||||
Ok(ScopeService {
|
|
||||||
app_data,
|
|
||||||
router,
|
|
||||||
default,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ScopeService {
|
|
||||||
app_data: Option<Rc<Extensions>>,
|
|
||||||
router: Router<HttpService, Vec<Box<dyn Guard>>>,
|
|
||||||
default: HttpService,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Service<ServiceRequest> for ScopeService {
|
|
||||||
type Response = ServiceResponse;
|
|
||||||
type Error = Error;
|
|
||||||
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
|
|
||||||
|
|
||||||
actix_service::always_ready!();
|
|
||||||
|
|
||||||
fn call(&self, mut req: ServiceRequest) -> Self::Future {
|
|
||||||
let res = self.router.recognize_checked(&mut req, |req, guards| {
|
|
||||||
if let Some(ref guards) = guards {
|
|
||||||
for f in guards {
|
|
||||||
if !f.check(req.head()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
});
|
});
|
||||||
|
if external_resources.is_empty() {
|
||||||
if let Some(ref app_data) = self.app_data {
|
rmap
|
||||||
req.add_data_container(app_data.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some((srv, _info)) = res {
|
|
||||||
srv.call(req)
|
|
||||||
} else {
|
} else {
|
||||||
self.default.call(req)
|
let mut rmap = rmap.unwrap_or_else(|| ResourceMap::new(rdef.clone()));
|
||||||
|
for ext in external_resources.iter_mut() {
|
||||||
|
rmap.add(ext, None);
|
||||||
|
}
|
||||||
|
Some(rmap)
|
||||||
|
}
|
||||||
|
.map(Rc::new)
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut config_dummy = config.clone_config();
|
||||||
|
services
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|mut srv| srv.register(&mut config_dummy));
|
||||||
|
|
||||||
|
let (_, services) = config_dummy.into_services();
|
||||||
|
|
||||||
|
for (rdef, factory, guards, rmap) in services {
|
||||||
|
let rdef = wrapped_rdef(rdef);
|
||||||
|
let rmap = wrapped_rmap(rmap, &rdef);
|
||||||
|
let guards = wrapped_guards(guards);
|
||||||
|
let factory = self.constructor.call(factory);
|
||||||
|
config.register_service(rdef, guards, factory, rmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(default) = default_service {
|
||||||
|
let root_rdef = ResourceDef::root_prefix(&self.prefix);
|
||||||
|
let rmap = wrapped_rmap(None, &root_rdef);
|
||||||
|
let guards = wrapped_guards(None);
|
||||||
|
let factory = self.constructor.call(default);
|
||||||
|
config.register_service(root_rdef, guards, factory, rmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
impl<C: EndpointConstructor> HttpServiceFactory for Scope<C> {
|
||||||
pub struct ScopeEndpoint {
|
fn register(mut self, config: &mut AppService) {
|
||||||
factory: Rc<RefCell<Option<ScopeFactory>>>,
|
if let Some(app_data) = self.app_data.take().map(Rc::new) {
|
||||||
}
|
return self
|
||||||
|
.wrap_fn(move |mut req, srv| {
|
||||||
impl ScopeEndpoint {
|
req.add_data_container(app_data.clone());
|
||||||
fn new(factory: Rc<RefCell<Option<ScopeFactory>>>) -> Self {
|
srv.call(req)
|
||||||
ScopeEndpoint { factory }
|
})
|
||||||
|
._register(config);
|
||||||
|
} else {
|
||||||
|
self._register(config);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl ServiceFactory<ServiceRequest> for ScopeEndpoint {
|
|
||||||
type Response = ServiceResponse;
|
|
||||||
type Error = Error;
|
|
||||||
type Config = ();
|
|
||||||
type Service = ScopeService;
|
|
||||||
type InitError = ();
|
|
||||||
type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
|
|
||||||
|
|
||||||
fn new_service(&self, _: ()) -> Self::Future {
|
|
||||||
self.factory.borrow_mut().as_mut().unwrap().new_service(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue