diff --git a/CHANGES.md b/CHANGES.md index 1364d6a9b..d9984224f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,21 @@ ## Unreleased - 2020-xx-xx +## 3.3.2 - 2020-12-01 +### Fixed +* Removed an occasional `unwrap` on `None` panic in `NormalizePathNormalization`. [#1762] +* Fix `match_pattern()` returning `None` for scope with empty path resource. [#1798] +* Increase minimum `socket2` version. [#1803] + +[#1762]: https://github.com/actix/actix-web/pull/1762 +[#1798]: https://github.com/actix/actix-web/pull/1798 +[#1803]: https://github.com/actix/actix-web/pull/1803 + + +## 3.3.1 - 2020-11-29 +* Ensure `actix-http` dependency uses same `serde_urlencoded`. + + ## 3.3.0 - 2020-11-25 ### Added * Add `Either` extractor helper. [#1788] diff --git a/Cargo.toml b/Cargo.toml index 3a3a92da9..31c4cca7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "actix-web" -version = "3.3.0" +version = "3.3.2" authors = ["Nikolay Kim "] -description = "Actix web is a powerful, pragmatic, and extremely fast web framework for Rust" +description = "Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust" readme = "README.md" keywords = ["actix", "http", "web", "framework", "async"] homepage = "https://actix.rs" @@ -34,7 +34,7 @@ members = [ "actix-multipart", "actix-web-actors", "actix-web-codegen", - "test-server", + "actix-http-test", ] [features] @@ -85,11 +85,11 @@ actix-threadpool = "0.3.1" actix-tls = "2.0.0" actix-web-codegen = "0.4.0" -actix-http = "2.1.0" -awc = { version = "2.0.0", default-features = false } +actix-http = "2.2.0" +awc = { version = "2.0.3", default-features = false } bytes = "0.5.3" -derive_more = "0.99.2" +derive_more = "0.99.5" encoding_rs = "0.8" futures-channel = { version = "0.3.5", default-features = false } futures-core = { version = "0.3.5", default-features = false } @@ -97,7 +97,7 @@ futures-util = { version = "0.3.5", default-features = false } fxhash = "0.2.1" log = "0.4" mime = "0.3" -socket2 = "0.3" +socket2 = "0.3.16" pin-project = "1.0.0" regex = "1.4" serde = { version = "1.0", features = ["derive"] } @@ -127,10 +127,10 @@ codegen-units = 1 [patch.crates-io] actix-web = { path = "." } actix-http = { path = "actix-http" } -actix-http-test = { path = "test-server" } +actix-http-test = { path = "actix-http-test" } actix-web-codegen = { path = "actix-web-codegen" } -actix-files = { path = "actix-files" } actix-multipart = { path = "actix-multipart" } +actix-files = { path = "actix-files" } awc = { path = "awc" } [[bench]] diff --git a/README.md b/README.md index c1d857f81..b9f2b7594 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@

Actix web

- Actix web is a powerful, pragmatic, and extremely fast web framework for Rust + Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust

[![crates.io](https://img.shields.io/crates/v/actix-web?label=latest)](https://crates.io/crates/actix-web) -[![Documentation](https://docs.rs/actix-web/badge.svg?version=3.3.0)](https://docs.rs/actix-web/3.3.0) +[![Documentation](https://docs.rs/actix-web/badge.svg?version=3.3.2)](https://docs.rs/actix-web/3.3.2) [![Version](https://img.shields.io/badge/rustc-1.42+-ab6000.svg)](https://blog.rust-lang.org/2020/03/12/Rust-1.42.html) ![License](https://img.shields.io/crates/l/actix-web.svg) -[![Dependency Status](https://deps.rs/crate/actix-web/3.3.0/status.svg)](https://deps.rs/crate/actix-web/3.3.0) +[![Dependency Status](https://deps.rs/crate/actix-web/3.3.2/status.svg)](https://deps.rs/crate/actix-web/3.3.2)
[![Build Status](https://travis-ci.org/actix/actix-web.svg?branch=master)](https://travis-ci.org/actix/actix-web) [![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web) diff --git a/test-server/CHANGES.md b/actix-http-test/CHANGES.md similarity index 100% rename from test-server/CHANGES.md rename to actix-http-test/CHANGES.md diff --git a/test-server/Cargo.toml b/actix-http-test/Cargo.toml similarity index 100% rename from test-server/Cargo.toml rename to actix-http-test/Cargo.toml diff --git a/test-server/LICENSE-APACHE b/actix-http-test/LICENSE-APACHE similarity index 100% rename from test-server/LICENSE-APACHE rename to actix-http-test/LICENSE-APACHE diff --git a/test-server/LICENSE-MIT b/actix-http-test/LICENSE-MIT similarity index 100% rename from test-server/LICENSE-MIT rename to actix-http-test/LICENSE-MIT diff --git a/test-server/README.md b/actix-http-test/README.md similarity index 100% rename from test-server/README.md rename to actix-http-test/README.md diff --git a/test-server/src/lib.rs b/actix-http-test/src/lib.rs similarity index 100% rename from test-server/src/lib.rs rename to actix-http-test/src/lib.rs diff --git a/awc/CHANGES.md b/awc/CHANGES.md index 3745079cd..7ca415336 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -3,6 +3,11 @@ ## Unreleased - 2020-xx-xx +## 2.0.3 - 2020-11-29 +### Fixed +* Ensure `actix-http` dependency uses same `serde_urlencoded`. + + ## 2.0.2 - 2020-11-25 ### Changed * Upgrade `serde_urlencoded` to `0.7`. [#1773] diff --git a/awc/Cargo.toml b/awc/Cargo.toml index d5b632a51..3c1963d6b 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "awc" -version = "2.0.2" +version = "2.0.3" authors = ["Nikolay Kim "] description = "Async HTTP and WebSocket client library built on the Actix ecosystem" readme = "README.md" @@ -39,7 +39,7 @@ compress = ["actix-http/compress"] [dependencies] actix-codec = "0.3.0" actix-service = "1.0.6" -actix-http = "2.0.0" +actix-http = "2.2.0" actix-rt = "1.0.0" base64 = "0.13" diff --git a/awc/README.md b/awc/README.md index d14dd82dd..b97d4fa00 100644 --- a/awc/README.md +++ b/awc/README.md @@ -3,9 +3,9 @@ > Async HTTP and WebSocket client library. [![crates.io](https://img.shields.io/crates/v/awc?label=latest)](https://crates.io/crates/awc) -[![Documentation](https://docs.rs/awc/badge.svg?version=2.0.2)](https://docs.rs/awc/2.0.2) +[![Documentation](https://docs.rs/awc/badge.svg?version=2.0.3)](https://docs.rs/awc/2.0.3) ![Apache 2.0 or MIT licensed](https://img.shields.io/crates/l/awc) -[![Dependency Status](https://deps.rs/crate/awc/2.0.2/status.svg)](https://deps.rs/crate/awc/2.0.2) +[![Dependency Status](https://deps.rs/crate/awc/2.0.3/status.svg)](https://deps.rs/crate/awc/2.0.3) [![Join the chat at https://gitter.im/actix/actix-web](https://badges.gitter.im/actix/actix-web.svg)](https://gitter.im/actix/actix-web?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ## Documentation & Resources diff --git a/docs/graphs/web-focus.dot b/docs/graphs/web-focus.dot index bcae36616..17228fe62 100644 --- a/docs/graphs/web-focus.dot +++ b/docs/graphs/web-focus.dot @@ -17,7 +17,7 @@ digraph { "multipart" -> { "web" "service" "utils" } "http" -> { "service" "codec" "connect" "utils" "rt" "threadpool" } "http" -> { "actix" "tls" }[color=blue] // optional - "files" -> { "web" "http" } + "files" -> { "web" } "http-test" -> { "service" "codec" "connect" "utils" "rt" "server" "testing" "awc" } // net diff --git a/docs/graphs/web-only.dot b/docs/graphs/web-only.dot index ee653e33b..9e1bb2805 100644 --- a/docs/graphs/web-only.dot +++ b/docs/graphs/web-only.dot @@ -11,11 +11,11 @@ digraph { "actix-http-test" } - "actix-web" -> { "actix-web-codegen" "actix-http" "awc" } + "actix-web" -> { "actix-web-codegen" "actix-http" "awc" } "awc" -> { "actix-http" } "actix-web-actors" -> { "actix" "actix-web" "actix-http" } "actix-multipart" -> { "actix-web" } "actix-http" -> { "actix" }[color=blue] // optional - "actix-files" -> { "actix-web" "actix-http" } + "actix-files" -> { "actix-web" } "actix-http-test" -> { "awc" } } diff --git a/src/lib.rs b/src/lib.rs index 13e02c098..a8fc50d83 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -//! Actix web is a powerful, pragmatic, and extremely fast web framework for Rust. +//! Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust. //! //! ## Example //! diff --git a/src/middleware/normalize.rs b/src/middleware/normalize.rs index e0ecd90dc..ac8ad71d5 100644 --- a/src/middleware/normalize.rs +++ b/src/middleware/normalize.rs @@ -137,9 +137,9 @@ where // so the change can not be deduced from the length comparison if path != original_path { let mut parts = head.uri.clone().into_parts(); - let pq = parts.path_and_query.as_ref().unwrap(); + let query = parts.path_and_query.as_ref().and_then(|pq| pq.query()); - let path = if let Some(q) = pq.query() { + let path = if let Some(q) = query { Bytes::from(format!("{}?{}", path, q)) } else { Bytes::copy_from_slice(path.as_bytes()) diff --git a/src/request.rs b/src/request.rs index a1b42f926..bd4bbbf58 100644 --- a/src/request.rs +++ b/src/request.rs @@ -675,4 +675,40 @@ mod tests { let res = call_service(&mut srv, req).await; assert_eq!(res.status(), StatusCode::OK); } + + #[actix_rt::test] + async fn extract_path_pattern_complex() { + let mut srv = init_service( + App::new() + .service(web::scope("/user").service(web::scope("/{id}").service( + web::resource("").to(move |req: HttpRequest| { + assert_eq!(req.match_pattern(), Some("/user/{id}".to_owned())); + + HttpResponse::Ok().finish() + }), + ))) + .service(web::resource("/").to(move |req: HttpRequest| { + assert_eq!(req.match_pattern(), Some("/".to_owned())); + + HttpResponse::Ok().finish() + })) + .default_service(web::to(move |req: HttpRequest| { + assert!(req.match_pattern().is_none()); + HttpResponse::Ok().finish() + })), + ) + .await; + + let req = TestRequest::get().uri("/user/test").to_request(); + let res = call_service(&mut srv, req).await; + assert_eq!(res.status(), StatusCode::OK); + + let req = TestRequest::get().uri("/").to_request(); + let res = call_service(&mut srv, req).await; + assert_eq!(res.status(), StatusCode::OK); + + let req = TestRequest::get().uri("/not-exist").to_request(); + let res = call_service(&mut srv, req).await; + assert_eq!(res.status(), StatusCode::OK); + } } diff --git a/src/rmap.rs b/src/rmap.rs index 05c1f3f15..6827a11b2 100644 --- a/src/rmap.rs +++ b/src/rmap.rs @@ -86,7 +86,7 @@ impl ResourceMap { if let Some(plen) = pattern.is_prefix_match(path) { return rmap.has_resource(&path[plen..]); } - } else if pattern.is_match(path) { + } else if pattern.is_match(path) || pattern.pattern() == "" && path == "/" { return true; } }