mirror of https://github.com/fafhrd91/actix-web
commit
94557c00ee
|
@ -4,10 +4,12 @@
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
* `{Resource,Scope}::default_service(f)` handlers now support app data extraction. [#1452]
|
||||||
* Implement `std::error::Error` for our custom errors [#1422]
|
* Implement `std::error::Error` for our custom errors [#1422]
|
||||||
* NormalizePath middleware now appends trailing / so that routes of form /example/ respond to /example requests.
|
* NormalizePath middleware now appends trailing / so that routes of form /example/ respond to /example requests.
|
||||||
|
|
||||||
[#1422]: https://github.com/actix/actix-web/pull/1422
|
[#1422]: https://github.com/actix/actix-web/pull/1422
|
||||||
|
[#1452]: https://github.com/actix/actix-web/pull/1452
|
||||||
|
|
||||||
## [3.0.0-alpha.1] - 2020-03-11
|
## [3.0.0-alpha.1] - 2020-03-11
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ members = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["compress", "failure"]
|
default = ["compress"]
|
||||||
|
|
||||||
# content-encoding support
|
# content-encoding support
|
||||||
compress = ["actix-http/compress", "awc/compress"]
|
compress = ["actix-http/compress", "awc/compress"]
|
||||||
|
@ -50,8 +50,6 @@ compress = ["actix-http/compress", "awc/compress"]
|
||||||
# sessions feature, session require "ring" crate and c compiler
|
# sessions feature, session require "ring" crate and c compiler
|
||||||
secure-cookies = ["actix-http/secure-cookies"]
|
secure-cookies = ["actix-http/secure-cookies"]
|
||||||
|
|
||||||
failure = ["actix-http/failure"]
|
|
||||||
|
|
||||||
# openssl
|
# openssl
|
||||||
openssl = ["actix-tls/openssl", "awc/openssl", "open-ssl"]
|
openssl = ["actix-tls/openssl", "awc/openssl", "open-ssl"]
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
* Implement `std::error::Error` for our custom errors [#1422]
|
* Implement `std::error::Error` for our custom errors [#1422]
|
||||||
|
* Remove `failure` support for `ResponseError` since that crate
|
||||||
|
will be deprecated in the near future.
|
||||||
|
|
||||||
[#1422]: https://github.com/actix/actix-web/pull/1422
|
[#1422]: https://github.com/actix/actix-web/pull/1422
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ license = "MIT/Apache-2.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["openssl", "rustls", "failure", "compress", "secure-cookies","actors"]
|
features = ["openssl", "rustls", "compress", "secure-cookies", "actors"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "actix_http"
|
name = "actix_http"
|
||||||
|
@ -33,9 +33,6 @@ rustls = ["actix-tls/rustls", "actix-connect/rustls"]
|
||||||
# enable compressison support
|
# enable compressison support
|
||||||
compress = ["flate2", "brotli2"]
|
compress = ["flate2", "brotli2"]
|
||||||
|
|
||||||
# failure integration. actix does not use failure anymore
|
|
||||||
failure = ["fail-ure"]
|
|
||||||
|
|
||||||
# support for secure cookies
|
# support for secure cookies
|
||||||
secure-cookies = ["ring"]
|
secure-cookies = ["ring"]
|
||||||
|
|
||||||
|
@ -89,9 +86,6 @@ ring = { version = "0.16.9", optional = true }
|
||||||
brotli2 = { version="0.3.2", optional = true }
|
brotli2 = { version="0.3.2", optional = true }
|
||||||
flate2 = { version = "1.0.13", optional = true }
|
flate2 = { version = "1.0.13", optional = true }
|
||||||
|
|
||||||
# optional deps
|
|
||||||
fail-ure = { version = "0.1.5", package="failure", optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-server = "1.0.1"
|
actix-server = "1.0.1"
|
||||||
actix-connect = { version = "2.0.0-alpha.2", features=["openssl"] }
|
actix-connect = { version = "2.0.0-alpha.2", features=["openssl"] }
|
||||||
|
|
|
@ -34,7 +34,7 @@ pub type Result<T, E = Error> = result::Result<T, E>;
|
||||||
|
|
||||||
/// General purpose actix web error.
|
/// General purpose actix web error.
|
||||||
///
|
///
|
||||||
/// An actix web error is used to carry errors from `failure` or `std::error`
|
/// An actix web error is used to carry errors from `std::error`
|
||||||
/// through actix in a convenient way. It can be created through
|
/// through actix in a convenient way. It can be created through
|
||||||
/// converting errors with `into()`.
|
/// converting errors with `into()`.
|
||||||
///
|
///
|
||||||
|
@ -950,10 +950,6 @@ where
|
||||||
InternalError::new(err, StatusCode::NETWORK_AUTHENTICATION_REQUIRED).into()
|
InternalError::new(err, StatusCode::NETWORK_AUTHENTICATION_REQUIRED).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "failure")]
|
|
||||||
/// Compatibility for `failure::Error`
|
|
||||||
impl ResponseError for fail_ure::Error {}
|
|
||||||
|
|
||||||
#[cfg(feature = "actors")]
|
#[cfg(feature = "actors")]
|
||||||
/// `InternalServerError` for `actix::MailboxError`
|
/// `InternalServerError` for `actix::MailboxError`
|
||||||
/// This is supported on feature=`actors` only
|
/// This is supported on feature=`actors` only
|
||||||
|
|
|
@ -542,6 +542,9 @@ impl Service for ResourceService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(ref mut default) = self.default {
|
if let Some(ref mut default) = self.default {
|
||||||
|
if let Some(ref data) = self.data {
|
||||||
|
req.set_data_container(data.clone());
|
||||||
|
}
|
||||||
Either::Right(default.call(req))
|
Either::Right(default.call(req))
|
||||||
} else {
|
} else {
|
||||||
let req = req.into_parts().0;
|
let req = req.into_parts().0;
|
||||||
|
@ -649,11 +652,9 @@ mod tests {
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_to() {
|
async fn test_to() {
|
||||||
let mut srv =
|
let mut srv =
|
||||||
init_service(App::new().service(web::resource("/test").to(|| {
|
init_service(App::new().service(web::resource("/test").to(|| async {
|
||||||
async {
|
delay_for(Duration::from_millis(100)).await;
|
||||||
delay_for(Duration::from_millis(100)).await;
|
Ok::<_, Error>(HttpResponse::Ok())
|
||||||
Ok::<_, Error>(HttpResponse::Ok())
|
|
||||||
}
|
|
||||||
})))
|
})))
|
||||||
.await;
|
.await;
|
||||||
let req = TestRequest::with_uri("/test").to_request();
|
let req = TestRequest::with_uri("/test").to_request();
|
||||||
|
@ -793,4 +794,23 @@ mod tests {
|
||||||
let resp = call_service(&mut srv, req).await;
|
let resp = call_service(&mut srv, req).await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn test_data_default_service() {
|
||||||
|
let mut srv = init_service(
|
||||||
|
App::new().data(1usize).service(
|
||||||
|
web::resource("/test")
|
||||||
|
.data(10usize)
|
||||||
|
.default_service(web::to(|data: web::Data<usize>| {
|
||||||
|
assert_eq!(**data, 10);
|
||||||
|
HttpResponse::Ok()
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let req = TestRequest::get().uri("/test").to_request();
|
||||||
|
let resp = call_service(&mut srv, req).await;
|
||||||
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
74
src/scope.rs
74
src/scope.rs
|
@ -54,7 +54,7 @@ type BoxedResponse = LocalBoxFuture<'static, Result<ServiceResponse, Error>>;
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// In the above example three routes get registered:
|
/// In the above example three routes get registered:
|
||||||
/// * /{project_id}/path1 - reponds 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
|
||||||
///
|
///
|
||||||
|
@ -626,6 +626,9 @@ impl Service for ScopeService {
|
||||||
}
|
}
|
||||||
Either::Left(srv.call(req))
|
Either::Left(srv.call(req))
|
||||||
} else if let Some(ref mut default) = self.default {
|
} else if let Some(ref mut default) = self.default {
|
||||||
|
if let Some(ref data) = self.data {
|
||||||
|
req.set_data_container(data.clone());
|
||||||
|
}
|
||||||
Either::Left(default.call(req))
|
Either::Left(default.call(req))
|
||||||
} else {
|
} else {
|
||||||
let req = req.into_parts().0;
|
let req = req.into_parts().0;
|
||||||
|
@ -825,11 +828,9 @@ mod tests {
|
||||||
async fn test_scope_variable_segment() {
|
async fn test_scope_variable_segment() {
|
||||||
let mut srv =
|
let mut srv =
|
||||||
init_service(App::new().service(web::scope("/ab-{project}").service(
|
init_service(App::new().service(web::scope("/ab-{project}").service(
|
||||||
web::resource("/path1").to(|r: HttpRequest| {
|
web::resource("/path1").to(|r: HttpRequest| async move {
|
||||||
async move {
|
HttpResponse::Ok()
|
||||||
HttpResponse::Ok()
|
.body(format!("project: {}", &r.match_info()["project"]))
|
||||||
.body(format!("project: {}", &r.match_info()["project"]))
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
)))
|
)))
|
||||||
.await;
|
.await;
|
||||||
|
@ -937,11 +938,9 @@ mod tests {
|
||||||
async fn test_nested_scope_with_variable_segment() {
|
async fn test_nested_scope_with_variable_segment() {
|
||||||
let mut srv = init_service(App::new().service(web::scope("/app").service(
|
let mut srv = init_service(App::new().service(web::scope("/app").service(
|
||||||
web::scope("/{project_id}").service(web::resource("/path1").to(
|
web::scope("/{project_id}").service(web::resource("/path1").to(
|
||||||
|r: HttpRequest| {
|
|r: HttpRequest| async move {
|
||||||
async move {
|
HttpResponse::Created()
|
||||||
HttpResponse::Created()
|
.body(format!("project: {}", &r.match_info()["project_id"]))
|
||||||
.body(format!("project: {}", &r.match_info()["project_id"]))
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
)))
|
)))
|
||||||
|
@ -964,14 +963,12 @@ mod tests {
|
||||||
async fn test_nested2_scope_with_variable_segment() {
|
async fn test_nested2_scope_with_variable_segment() {
|
||||||
let mut srv = init_service(App::new().service(web::scope("/app").service(
|
let mut srv = init_service(App::new().service(web::scope("/app").service(
|
||||||
web::scope("/{project}").service(web::scope("/{id}").service(
|
web::scope("/{project}").service(web::scope("/{id}").service(
|
||||||
web::resource("/path1").to(|r: HttpRequest| {
|
web::resource("/path1").to(|r: HttpRequest| async move {
|
||||||
async move {
|
HttpResponse::Created().body(format!(
|
||||||
HttpResponse::Created().body(format!(
|
"project: {} - {}",
|
||||||
"project: {} - {}",
|
&r.match_info()["project"],
|
||||||
&r.match_info()["project"],
|
&r.match_info()["id"],
|
||||||
&r.match_info()["id"],
|
))
|
||||||
))
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
)),
|
)),
|
||||||
)))
|
)))
|
||||||
|
@ -1119,6 +1116,23 @@ mod tests {
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn test_override_data_default_service() {
|
||||||
|
let mut srv = init_service(App::new().data(1usize).service(
|
||||||
|
web::scope("app").data(10usize).default_service(web::to(
|
||||||
|
|data: web::Data<usize>| {
|
||||||
|
assert_eq!(**data, 10);
|
||||||
|
HttpResponse::Ok()
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
))
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let req = TestRequest::with_uri("/app/t").to_request();
|
||||||
|
let resp = call_service(&mut srv, req).await;
|
||||||
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_override_app_data() {
|
async fn test_override_app_data() {
|
||||||
let mut srv = init_service(App::new().app_data(web::Data::new(1usize)).service(
|
let mut srv = init_service(App::new().app_data(web::Data::new(1usize)).service(
|
||||||
|
@ -1177,15 +1191,11 @@ mod tests {
|
||||||
);
|
);
|
||||||
s.route(
|
s.route(
|
||||||
"/",
|
"/",
|
||||||
web::get().to(|req: HttpRequest| {
|
web::get().to(|req: HttpRequest| async move {
|
||||||
async move {
|
HttpResponse::Ok().body(format!(
|
||||||
HttpResponse::Ok().body(format!(
|
"{}",
|
||||||
"{}",
|
req.url_for("youtube", &["xxxxxx"]).unwrap().as_str()
|
||||||
req.url_for("youtube", &["xxxxxx"])
|
))
|
||||||
.unwrap()
|
|
||||||
.as_str()
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}));
|
}));
|
||||||
|
@ -1203,11 +1213,9 @@ mod tests {
|
||||||
async fn test_url_for_nested() {
|
async fn test_url_for_nested() {
|
||||||
let mut srv = init_service(App::new().service(web::scope("/a").service(
|
let mut srv = init_service(App::new().service(web::scope("/a").service(
|
||||||
web::scope("/b").service(web::resource("/c/{stuff}").name("c").route(
|
web::scope("/b").service(web::resource("/c/{stuff}").name("c").route(
|
||||||
web::get().to(|req: HttpRequest| {
|
web::get().to(|req: HttpRequest| async move {
|
||||||
async move {
|
HttpResponse::Ok()
|
||||||
HttpResponse::Ok()
|
.body(format!("{}", req.url_for("c", &["12345"]).unwrap()))
|
||||||
.body(format!("{}", req.url_for("c", &["12345"]).unwrap()))
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
)),
|
)),
|
||||||
)))
|
)))
|
||||||
|
|
|
@ -52,7 +52,7 @@ sha1 = "0.6"
|
||||||
slab = "0.4"
|
slab = "0.4"
|
||||||
serde_urlencoded = "0.6.1"
|
serde_urlencoded = "0.6.1"
|
||||||
time = { version = "0.2.7", default-features = false, features = ["std"] }
|
time = { version = "0.2.7", default-features = false, features = ["std"] }
|
||||||
open-ssl = { version="0.10", package="openssl", optional = true }
|
open-ssl = { version="0.10", package = "openssl", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-web = "3.0.0-alpha.1"
|
actix-web = "3.0.0-alpha.1"
|
||||||
|
|
Loading…
Reference in New Issue