Browse Source

allow to specify multi pattern for resources

master
Nikolay Kim 7 months ago
parent
commit
f86ce0390e
16 changed files with 54 additions and 33 deletions
  1. +1
    -0
      CHANGES.md
  2. +2
    -2
      Cargo.toml
  3. +1
    -1
      actix-cors/src/lib.rs
  4. +1
    -1
      actix-framed/src/helpers.rs
  5. +1
    -1
      actix-framed/src/route.rs
  6. +1
    -1
      actix-identity/src/lib.rs
  7. +1
    -1
      actix-session/src/cookie.rs
  8. +7
    -6
      src/lib.rs
  9. +1
    -1
      src/middleware/defaultheaders.rs
  10. +1
    -1
      src/middleware/errhandlers.rs
  11. +23
    -5
      src/resource.rs
  12. +7
    -7
      src/service.rs
  13. +1
    -1
      src/types/form.rs
  14. +1
    -1
      src/types/json.rs
  15. +2
    -2
      src/types/payload.rs
  16. +3
    -2
      src/web.rs

+ 1
- 0
CHANGES.md View File

@@ -8,6 +8,7 @@

* Allow to gracefully stop test server via `TestServer::stop()`

* Allow to specify multi-patterns for resources

## [2.0.0-rc] - 2019-12-20



+ 2
- 2
Cargo.toml View File

@@ -62,7 +62,7 @@ rustls = ["actix-tls/rustls", "awc/rustls", "rust-tls"]
actix-codec = "0.2.0"
actix-service = "1.0.1"
actix-utils = "1.0.4"
actix-router = "0.2.0"
actix-router = "0.2.1"
actix-rt = "1.0.0"
actix-server = "1.0.0"
actix-testing = "1.0.0"
@@ -115,4 +115,4 @@ actix-identity = { path = "actix-identity" }
actix-session = { path = "actix-session" }
actix-files = { path = "actix-files" }
actix-multipart = { path = "actix-multipart" }
awc = { path = "awc" }
awc = { path = "awc" }

+ 1
- 1
actix-cors/src/lib.rs View File

@@ -814,7 +814,7 @@ where
res
}
}
.boxed_local(),
.boxed_local(),
)
}
}


+ 1
- 1
actix-framed/src/helpers.rs View File

@@ -66,7 +66,7 @@ where
service
})
}
.boxed_local()
.boxed_local()
}
}



+ 1
- 1
actix-framed/src/route.rs View File

@@ -154,6 +154,6 @@ where
}
Ok(())
}
.boxed_local()
.boxed_local()
}
}

+ 1
- 1
actix-identity/src/lib.rs View File

@@ -294,7 +294,7 @@ where
Err(err) => Ok(req.error_response(err)),
}
}
.boxed_local()
.boxed_local()
}
}



+ 1
- 1
actix-session/src/cookie.rs View File

@@ -354,7 +354,7 @@ where
}
})
}
.boxed_local()
.boxed_local()
}
}



+ 7
- 6
src/lib.rs View File

@@ -151,12 +151,13 @@ pub mod dev {
pub use actix_server::Server;
pub use actix_service::{Service, Transform};

pub(crate) fn insert_slash(path: &str) -> String {
let mut path = path.to_owned();
if !path.is_empty() && !path.starts_with('/') {
path.insert(0, '/');
};
path
pub(crate) fn insert_slash(mut patterns: Vec<String>) -> Vec<String> {
for path in &mut patterns {
if !path.is_empty() && !path.starts_with('/') {
path.insert(0, '/');
};
}
patterns
}

use crate::http::header::ContentEncoding;


+ 1
- 1
src/middleware/defaultheaders.rs View File

@@ -150,7 +150,7 @@ where
}
Ok(res)
}
.boxed_local()
.boxed_local()
}
}



+ 1
- 1
src/middleware/errhandlers.rs View File

@@ -140,7 +140,7 @@ where
Ok(res)
}
}
.boxed_local()
.boxed_local()
}
}



+ 23
- 5
src/resource.rs View File

@@ -6,6 +6,7 @@ use std::rc::Rc;
use std::task::{Context, Poll};

use actix_http::{Error, Extensions, Response};
use actix_router::IntoPattern;
use actix_service::boxed::{self, BoxService, BoxServiceFactory};
use actix_service::{
apply, apply_fn_factory, IntoServiceFactory, Service, ServiceFactory, Transform,
@@ -48,7 +49,7 @@ type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Err
/// Default behavior could be overriden with `default_resource()` method.
pub struct Resource<T = ResourceEndpoint> {
endpoint: T,
rdef: String,
rdef: Vec<String>,
name: Option<String>,
routes: Vec<Route>,
data: Option<Extensions>,
@@ -58,12 +59,12 @@ pub struct Resource<T = ResourceEndpoint> {
}

impl Resource {
pub fn new(path: &str) -> Resource {
pub fn new<T: IntoPattern>(path: T) -> Resource {
let fref = Rc::new(RefCell::new(None));

Resource {
routes: Vec::new(),
rdef: path.to_string(),
rdef: path.patterns(),
name: None,
endpoint: ResourceEndpoint::new(fref.clone()),
factory_ref: fref,
@@ -381,9 +382,9 @@ where
Some(std::mem::replace(&mut self.guards, Vec::new()))
};
let mut rdef = if config.is_root() || !self.rdef.is_empty() {
ResourceDef::new(&insert_slash(&self.rdef))
ResourceDef::new(insert_slash(self.rdef.clone()))
} else {
ResourceDef::new(&self.rdef)
ResourceDef::new(self.rdef.clone())
};
if let Some(ref name) = self.name {
*rdef.name_mut() = name.clone();
@@ -660,6 +661,23 @@ mod tests {
assert_eq!(resp.status(), StatusCode::OK);
}

#[actix_rt::test]
async fn test_pattern() {
let mut srv =
init_service(App::new().service(web::resource(["/test", "/test2"]).to(|| {
async {
Ok::<_, Error>(HttpResponse::Ok())
}
})))
.await;
let req = TestRequest::with_uri("/test").to_request();
let resp = call_service(&mut srv, req).await;
assert_eq!(resp.status(), StatusCode::OK);
let req = TestRequest::with_uri("/test2").to_request();
let resp = call_service(&mut srv, req).await;
assert_eq!(resp.status(), StatusCode::OK);
}

#[actix_rt::test]
async fn test_default_resource() {
let mut srv = init_service(


+ 7
- 7
src/service.rs View File

@@ -8,7 +8,7 @@ use actix_http::{
Error, Extensions, HttpMessage, Payload, PayloadStream, RequestHead, Response,
ResponseHead,
};
use actix_router::{Path, Resource, ResourceDef, Url};
use actix_router::{IntoPattern, Path, Resource, ResourceDef, Url};
use actix_service::{IntoServiceFactory, ServiceFactory};

use crate::config::{AppConfig, AppService};
@@ -422,16 +422,16 @@ impl<B: MessageBody> fmt::Debug for ServiceResponse<B> {
}

pub struct WebService {
rdef: String,
rdef: Vec<String>,
name: Option<String>,
guards: Vec<Box<dyn Guard>>,
}

impl WebService {
/// Create new `WebService` instance.
pub fn new(path: &str) -> Self {
pub fn new<T: IntoPattern>(path: T) -> Self {
WebService {
rdef: path.to_string(),
rdef: path.patterns(),
name: None,
guards: Vec::new(),
}
@@ -491,7 +491,7 @@ impl WebService {

struct WebServiceImpl<T> {
srv: T,
rdef: String,
rdef: Vec<String>,
name: Option<String>,
guards: Vec<Box<dyn Guard>>,
}
@@ -514,9 +514,9 @@ where
};

let mut rdef = if config.is_root() || !self.rdef.is_empty() {
ResourceDef::new(&insert_slash(&self.rdef))
ResourceDef::new(insert_slash(self.rdef))
} else {
ResourceDef::new(&self.rdef)
ResourceDef::new(self.rdef)
};
if let Some(ref name) = self.name {
*rdef.name_mut() = name.clone();


+ 1
- 1
src/types/form.rs View File

@@ -365,7 +365,7 @@ where
.map_err(|_| UrlencodedError::Parse)
}
}
.boxed_local(),
.boxed_local(),
);
self.poll(cx)
}


+ 1
- 1
src/types/json.rs View File

@@ -396,7 +396,7 @@ where
}
Ok(serde_json::from_slice::<U>(&body)?)
}
.boxed_local(),
.boxed_local(),
);

self.poll(cx)


+ 2
- 2
src/types/payload.rs View File

@@ -229,7 +229,7 @@ impl FromRequest for String {
.ok_or_else(|| ErrorBadRequest("Can not decode body"))?)
}
}
.boxed_local(),
.boxed_local(),
)
}
}
@@ -391,7 +391,7 @@ impl Future for HttpMessageBody {
}
Ok(body.freeze())
}
.boxed_local(),
.boxed_local(),
);
self.poll(cx)
}


+ 3
- 2
src/web.rs View File

@@ -1,5 +1,6 @@
//! Essentials helper functions and types for application registration.
use actix_http::http::Method;
use actix_router::IntoPattern;
use futures::Future;

pub use actix_http::Response as HttpResponse;
@@ -50,7 +51,7 @@ pub use crate::types::*;
/// .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
/// );
/// ```
pub fn resource(path: &str) -> Resource {
pub fn resource<T: IntoPattern>(path: T) -> Resource {
Resource::new(path)
}

@@ -249,7 +250,7 @@ where
/// .finish(my_service)
/// );
/// ```
pub fn service(path: &str) -> WebService {
pub fn service<T: IntoPattern>(path: T) -> WebService {
WebService::new(path)
}



Loading…
Cancel
Save