1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-08-31 00:50:20 +02:00

allow parent data containers to be accessed from child scopes

This commit is contained in:
Rob Ede
2020-05-09 00:31:26 +01:00
parent 6e8ff5c905
commit 879cad9422
7 changed files with 109 additions and 103 deletions

View File

@@ -198,9 +198,7 @@ where
/// Add resource data.
///
/// If used, this method will create a new data context used for extracting
/// from requests. Data added here is *not* merged with data added on App
/// or containing scopes.
/// Data of different types from parent contexts will still be accessible.
pub fn app_data<U: 'static>(mut self, data: U) -> Self {
if self.data.is_none() {
self.data = Some(Extensions::new());
@@ -539,14 +537,14 @@ impl Service for ResourceService {
for route in self.routes.iter_mut() {
if route.check(&mut req) {
if let Some(ref data) = self.data {
req.set_data_container(data.clone());
req.add_data_container(data.clone());
}
return Either::Right(route.call(req));
}
}
if let Some(ref mut default) = self.default {
if let Some(ref data) = self.data {
req.set_data_container(data.clone());
req.add_data_container(data.clone());
}
Either::Right(default.call(req))
} else {
@@ -590,14 +588,13 @@ mod tests {
use actix_rt::time::delay_for;
use actix_service::Service;
use bytes::Bytes;
use futures::future::ok;
use crate::http::{header, HeaderValue, Method, StatusCode};
use crate::middleware::DefaultHeaders;
use crate::service::ServiceRequest;
use crate::test::{call_service, init_service, read_body, TestRequest};
use crate::{guard, web, App, Error, HttpRequest, HttpResponse};
use crate::test::{call_service, init_service, TestRequest};
use crate::{guard, web, App, Error, HttpResponse};
#[actix_rt::test]
async fn test_middleware() {
@@ -623,79 +620,6 @@ mod tests {
);
}
#[actix_rt::test]
async fn test_overwritten_data() {
#[allow(dead_code)]
fn echo_usize(req: HttpRequest) -> HttpResponse {
let num = req.app_data::<usize>().unwrap();
HttpResponse::Ok().body(format!("{}", num))
}
#[allow(dead_code)]
fn echo_u32(req: HttpRequest) -> HttpResponse {
let num = req.app_data::<u32>().unwrap();
HttpResponse::Ok().body(format!("{}", num))
}
#[allow(dead_code)]
fn echo_both(req: HttpRequest) -> HttpResponse {
let num = req.app_data::<usize>().unwrap();
let num2 = req.app_data::<u32>().unwrap();
HttpResponse::Ok().body(format!("{}-{}", num, num2))
}
let mut srv = init_service(
App::new()
.app_data(88usize)
.service(web::resource("/").route(web::get().to(echo_usize)))
.service(
web::resource("/one")
.app_data(1usize)
.route(web::get().to(echo_usize)),
)
.service(
web::resource("/two")
.app_data(2usize)
.route(web::get().to(echo_usize)),
)
.service(
web::resource("/three")
.app_data(3u32)
// this doesnt work because app_data "overrides" the
// entire data field potentially passed down
// .route(web::get().to(echo_both)),
.route(web::get().to(echo_u32)),
)
.service(web::resource("/eight").route(web::get().to(echo_usize))),
)
.await;
let req = TestRequest::get().uri("/").to_request();
let resp = srv.call(req).await.unwrap();
let body = read_body(resp).await;
assert_eq!(body, Bytes::from_static(b"88"));
let req = TestRequest::get().uri("/one").to_request();
let resp = srv.call(req).await.unwrap();
let body = read_body(resp).await;
assert_eq!(body, Bytes::from_static(b"1"));
let req = TestRequest::get().uri("/two").to_request();
let resp = srv.call(req).await.unwrap();
let body = read_body(resp).await;
assert_eq!(body, Bytes::from_static(b"2"));
// let req = TestRequest::get().uri("/three").to_request();
// let resp = srv.call(req).await.unwrap();
// let body = read_body(resp).await;
// assert_eq!(body, Bytes::from_static(b"88-3"));
let req = TestRequest::get().uri("/eight").to_request();
let resp = srv.call(req).await.unwrap();
let body = read_body(resp).await;
assert_eq!(body, Bytes::from_static(b"88"));
}
#[actix_rt::test]
async fn test_middleware_fn() {
let mut srv = init_service(