1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-24 00:21:08 +01:00

fix resource match with params #841

This commit is contained in:
Nikolay Kim 2019-05-15 10:31:40 -07:00
parent 80f4ef9aac
commit e1ff3bf8fa
8 changed files with 77 additions and 18 deletions

View File

@ -1,5 +1,7 @@
# Changes # Changes
## [1.0.0-rc.1] - 2019-05-xx
### Add ### Add
* `QueryConfig`, similar to `JsonConfig` for customizing error handling of query extractors. * `QueryConfig`, similar to `JsonConfig` for customizing error handling of query extractors.
@ -8,6 +10,11 @@
* `JsonConfig` is now `Send + Sync`, this implies that `error_handler` must be `Send + Sync` too. * `JsonConfig` is now `Send + Sync`, this implies that `error_handler` must be `Send + Sync` too.
### Fixed
* Codegen with parameters in the path only resolves the first registered endpoint #841
## [1.0.0-beta.4] - 2019-05-12 ## [1.0.0-beta.4] - 2019-05-12
### Add ### Add

View File

@ -68,7 +68,7 @@ rust-tls = ["rustls", "actix-server/rust-tls"]
actix-codec = "0.1.2" actix-codec = "0.1.2"
actix-service = "0.4.0" actix-service = "0.4.0"
actix-utils = "0.4.0" actix-utils = "0.4.0"
actix-router = "0.1.3" actix-router = "0.1.5"
actix-rt = "0.2.2" actix-rt = "0.2.2"
actix-web-codegen = "0.1.0-beta.1" actix-web-codegen = "0.1.0-beta.1"
actix-http = { version = "0.2.0", features=["fail"] } actix-http = { version = "0.2.0", features=["fail"] }

View File

@ -18,7 +18,7 @@ name = "actix_web_actors"
path = "src/lib.rs" path = "src/lib.rs"
[dependencies] [dependencies]
actix = "0.8.0" actix = "0.8.2"
actix-web = "1.0.0-beta.5" actix-web = "1.0.0-beta.5"
actix-http = "0.2.0" actix-http = "0.2.0"
actix-codec = "0.1.2" actix-codec = "0.1.2"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "actix-web-codegen" name = "actix-web-codegen"
version = "0.1.0-beta.1" version = "0.1.0"
description = "Actix web proc macros" description = "Actix web proc macros"
readme = "README.md" readme = "README.md"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"] authors = ["Nikolay Kim <fafhrd91@gmail.com>"]

View File

@ -1,7 +1,7 @@
use actix_http::HttpService; use actix_http::HttpService;
use actix_http_test::TestServer; use actix_http_test::TestServer;
use actix_web::{http, App, HttpResponse, Responder, web::{Path}}; use actix_web::{http, web::Path, App, HttpResponse, Responder};
use actix_web_codegen::{get, post, put, delete}; use actix_web_codegen::{delete, get, post, put};
use futures::{future, Future}; use futures::{future, Future};
#[get("/test")] #[get("/test")]

View File

@ -104,7 +104,9 @@ pub enum QueryPayloadError {
impl ResponseError for QueryPayloadError { impl ResponseError for QueryPayloadError {
fn error_response(&self) -> HttpResponse { fn error_response(&self) -> HttpResponse {
match *self { match *self {
QueryPayloadError::Deserialize(_) => HttpResponse::new(StatusCode::BAD_REQUEST), QueryPayloadError::Deserialize(_) => {
HttpResponse::new(StatusCode::BAD_REQUEST)
}
} }
} }
} }
@ -163,7 +165,10 @@ mod tests {
#[test] #[test]
fn test_query_payload_error() { fn test_query_payload_error() {
let resp: HttpResponse = QueryPayloadError::Deserialize(serde_urlencoded::from_str::<i32>("bad query").unwrap_err()).error_response(); let resp: HttpResponse = QueryPayloadError::Deserialize(
serde_urlencoded::from_str::<i32>("bad query").unwrap_err(),
)
.error_response();
assert_eq!(resp.status(), StatusCode::BAD_REQUEST); assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
} }

View File

@ -606,7 +606,7 @@ mod tests {
use crate::http::{header, HeaderValue, Method, StatusCode}; use crate::http::{header, HeaderValue, Method, StatusCode};
use crate::service::{ServiceRequest, ServiceResponse}; use crate::service::{ServiceRequest, ServiceResponse};
use crate::test::{call_service, init_service, TestRequest}; use crate::test::{call_service, init_service, TestRequest};
use crate::{web, App, Error, HttpResponse}; use crate::{guard, web, App, Error, HttpResponse};
fn md<S, B>( fn md<S, B>(
req: ServiceRequest, req: ServiceRequest,
@ -723,4 +723,45 @@ mod tests {
let resp = call_service(&mut srv, req); let resp = call_service(&mut srv, req);
assert_eq!(resp.status(), StatusCode::BAD_REQUEST); assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
} }
#[test]
fn test_resource_guards() {
let mut srv = init_service(
App::new()
.service(
web::resource("/test/{p}")
.guard(guard::Get())
.to(|| HttpResponse::Ok()),
)
.service(
web::resource("/test/{p}")
.guard(guard::Put())
.to(|| HttpResponse::Created()),
)
.service(
web::resource("/test/{p}")
.guard(guard::Delete())
.to(|| HttpResponse::NoContent()),
),
);
let req = TestRequest::with_uri("/test/it")
.method(Method::GET)
.to_request();
let resp = call_service(&mut srv, req);
assert_eq!(resp.status(), StatusCode::OK);
let req = TestRequest::with_uri("/test/it")
.method(Method::PUT)
.to_request();
let resp = call_service(&mut srv, req);
assert_eq!(resp.status(), StatusCode::CREATED);
let req = TestRequest::with_uri("/test/it")
.method(Method::DELETE)
.to_request();
let resp = call_service(&mut srv, req);
assert_eq!(resp.status(), StatusCode::NO_CONTENT);
}
} }

View File

@ -8,9 +8,9 @@ use serde::de;
use serde_urlencoded; use serde_urlencoded;
use crate::dev::Payload; use crate::dev::Payload;
use crate::error::QueryPayloadError;
use crate::extract::FromRequest; use crate::extract::FromRequest;
use crate::request::HttpRequest; use crate::request::HttpRequest;
use crate::error::QueryPayloadError;
#[derive(PartialEq, Eq, PartialOrd, Ord)] #[derive(PartialEq, Eq, PartialOrd, Ord)]
/// Extract typed information from from the request's query. /// Extract typed information from from the request's query.
@ -188,8 +188,8 @@ pub struct QueryConfig {
impl QueryConfig { impl QueryConfig {
/// Set custom error handler /// Set custom error handler
pub fn error_handler<F>(mut self, f: F) -> Self pub fn error_handler<F>(mut self, f: F) -> Self
where where
F: Fn(QueryPayloadError, &HttpRequest) -> Error + Send + Sync + 'static, F: Fn(QueryPayloadError, &HttpRequest) -> Error + Send + Sync + 'static,
{ {
self.ehandler = Some(Arc::new(f)); self.ehandler = Some(Arc::new(f));
self self
@ -198,21 +198,19 @@ impl QueryConfig {
impl Default for QueryConfig { impl Default for QueryConfig {
fn default() -> Self { fn default() -> Self {
QueryConfig { QueryConfig { ehandler: None }
ehandler: None,
}
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use actix_http::http::StatusCode;
use derive_more::Display; use derive_more::Display;
use serde_derive::Deserialize; use serde_derive::Deserialize;
use actix_http::http::StatusCode;
use super::*; use super::*;
use crate::test::TestRequest;
use crate::error::InternalError; use crate::error::InternalError;
use crate::test::TestRequest;
use crate::HttpResponse; use crate::HttpResponse;
#[derive(Deserialize, Debug, Display)] #[derive(Deserialize, Debug, Display)]
@ -244,12 +242,20 @@ mod tests {
.data(QueryConfig::default().error_handler(|e, _| { .data(QueryConfig::default().error_handler(|e, _| {
let resp = HttpResponse::UnprocessableEntity().finish(); let resp = HttpResponse::UnprocessableEntity().finish();
InternalError::from_response(e, resp).into() InternalError::from_response(e, resp).into()
})).to_srv_request(); }))
.to_srv_request();
let (req, mut pl) = req.into_parts(); let (req, mut pl) = req.into_parts();
let query = Query::<Id>::from_request(&req, &mut pl); let query = Query::<Id>::from_request(&req, &mut pl);
assert!(query.is_err()); assert!(query.is_err());
assert_eq!(query.unwrap_err().as_response_error().error_response().status(), StatusCode::UNPROCESSABLE_ENTITY); assert_eq!(
query
.unwrap_err()
.as_response_error()
.error_response()
.status(),
StatusCode::UNPROCESSABLE_ENTITY
);
} }
} }