From ede645ee4e65ee6ce930dd4a796c10d37fc1c4ce Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 18 Dec 2022 01:11:04 +0000 Subject: [PATCH 01/35] bump criterion to 0.4 --- actix-http/Cargo.toml | 2 +- actix-router/Cargo.toml | 2 +- actix-web/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index a8b888ef4..313764d35 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -105,7 +105,7 @@ actix-tls = { version = "3", features = ["openssl"] } actix-web = "4" async-stream = "0.3" -criterion = { version = "0.3", features = ["html_reports"] } +criterion = { version = "0.4", features = ["html_reports"] } env_logger = "0.9" futures-util = { version = "0.3.7", default-features = false, features = ["alloc"] } memchr = "2.4" diff --git a/actix-router/Cargo.toml b/actix-router/Cargo.toml index 19d6abc62..f3a5f15e4 100644 --- a/actix-router/Cargo.toml +++ b/actix-router/Cargo.toml @@ -27,7 +27,7 @@ serde = "1" tracing = { version = "0.1.30", default-features = false, features = ["log"] } [dev-dependencies] -criterion = { version = "0.3", features = ["html_reports"] } +criterion = { version = "0.4", features = ["html_reports"] } http = "0.2.5" serde = { version = "1", features = ["derive"] } percent-encoding = "2.1" diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index c7b54bd46..f60a35978 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -107,7 +107,7 @@ awc = { version = "3", features = ["openssl"] } brotli = "3.3.3" const-str = "0.4" -criterion = { version = "0.3", features = ["html_reports"] } +criterion = { version = "0.4", features = ["html_reports"] } env_logger = "0.9" flate2 = "1.0.13" futures-util = { version = "0.3.7", default-features = false, features = ["std"] } From 17f7cd2aae1cf6cd5b21e3225ab3b3b95b128885 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 18 Dec 2022 01:31:06 +0000 Subject: [PATCH 02/35] bump zstd to 0.12 --- actix-http/Cargo.toml | 2 +- actix-web/Cargo.toml | 7 ++----- awc/Cargo.toml | 4 ++-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 313764d35..3ee285c81 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -96,7 +96,7 @@ actix-tls = { version = "3", default-features = false, optional = true } # compress-* brotli = { version = "3.3.3", optional = true } flate2 = { version = "1.0.13", optional = true } -zstd = { version = "0.11", optional = true } +zstd = { version = "0.12", optional = true } [dev-dependencies] actix-http-test = { version = "3", features = ["openssl"] } diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index f60a35978..9ace68811 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -38,10 +38,7 @@ compress-gzip = ["actix-http/compress-gzip", "__compress"] compress-zstd = ["actix-http/compress-zstd", "__compress"] # Routing and runtime proc macros -macros = [ - "actix-macros", - "actix-web-codegen", -] +macros = ["actix-macros", "actix-web-codegen"] # Cookies support cookies = ["cookie"] @@ -119,7 +116,7 @@ static_assertions = "1" tls-openssl = { package = "openssl", version = "0.10.9" } tls-rustls = { package = "rustls", version = "0.20.0" } tokio = { version = "1.13.1", features = ["rt-multi-thread", "macros"] } -zstd = "0.11" +zstd = "0.12" [[test]] name = "test_server" diff --git a/awc/Cargo.toml b/awc/Cargo.toml index e7ac43d22..b40becfec 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -87,7 +87,7 @@ cookie = { version = "0.16", features = ["percent-encode"], optional = true } tls-openssl = { package = "openssl", version = "0.10.9", optional = true } tls-rustls = { package = "rustls", version = "0.20.0", optional = true, features = ["dangerous_configuration"] } -trust-dns-resolver = { version = "0.21", optional = true } +trust-dns-resolver = { version = "0.22", optional = true } [dev-dependencies] actix-http = { version = "3", features = ["openssl"] } @@ -107,7 +107,7 @@ static_assertions = "1.1" rcgen = "0.9" rustls-pemfile = "1" tokio = { version = "1.13.1", features = ["rt-multi-thread", "macros"] } -zstd = "0.11" +zstd = "0.12" [[example]] name = "client" From 29bd6a1dd57705fc44a40d63327086643de1d2ad Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 18 Dec 2022 01:34:48 +0000 Subject: [PATCH 03/35] fix version requirement for futures_util --- actix-files/Cargo.toml | 2 +- actix-http-test/Cargo.toml | 2 +- actix-http/Cargo.toml | 4 ++-- actix-http/src/h1/dispatcher_tests.rs | 2 +- actix-http/tests/test_openssl.rs | 2 +- actix-http/tests/test_server.rs | 5 +---- actix-multipart/Cargo.toml | 4 ++-- actix-multipart/src/extractor.rs | 2 +- actix-multipart/src/server.rs | 2 +- actix-test/Cargo.toml | 4 ++-- actix-web-actors/Cargo.toml | 4 ++-- actix-web-actors/tests/test_ws.rs | 2 +- actix-web-codegen/Cargo.toml | 2 +- actix-web/Cargo.toml | 6 +++--- actix-web/src/app.rs | 2 +- actix-web/src/middleware/condition.rs | 2 +- actix-web/src/middleware/err_handlers.rs | 2 +- actix-web/src/types/payload.rs | 2 +- actix-web/src/types/readlines.rs | 2 +- awc/Cargo.toml | 6 +++--- awc/src/client/pool.rs | 2 +- awc/src/lib.rs | 2 +- awc/src/ws.rs | 2 +- awc/tests/test_client.rs | 2 +- 24 files changed, 32 insertions(+), 35 deletions(-) diff --git a/actix-files/Cargo.toml b/actix-files/Cargo.toml index 018acdfb1..01dc2928a 100644 --- a/actix-files/Cargo.toml +++ b/actix-files/Cargo.toml @@ -29,7 +29,7 @@ actix-web = { version = "4", default-features = false } bitflags = "1" bytes = "1" derive_more = "0.99.5" -futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] } +futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] } http-range = "0.1.4" log = "0.4" mime = "0.3" diff --git a/actix-http-test/Cargo.toml b/actix-http-test/Cargo.toml index 0a9ddf947..86338fb06 100644 --- a/actix-http-test/Cargo.toml +++ b/actix-http-test/Cargo.toml @@ -39,7 +39,7 @@ awc = { version = "3", default-features = false } base64 = "0.13" bytes = "1" -futures-core = { version = "0.3.7", default-features = false } +futures-core = { version = "0.3.17", default-features = false } http = "0.2.5" log = "0.4" socket2 = "0.4" diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 3ee285c81..9f3977f0f 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -67,7 +67,7 @@ bytes = "1" bytestring = "1" derive_more = "0.99.5" encoding_rs = "0.8" -futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] } +futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] } http = "0.2.5" httparse = "1.5.1" httpdate = "1.0.1" @@ -107,7 +107,7 @@ actix-web = "4" async-stream = "0.3" criterion = { version = "0.4", features = ["html_reports"] } env_logger = "0.9" -futures-util = { version = "0.3.7", default-features = false, features = ["alloc"] } +futures-util = { version = "0.3.17", default-features = false, features = ["alloc"] } memchr = "2.4" once_cell = "1.9" rcgen = "0.9" diff --git a/actix-http/src/h1/dispatcher_tests.rs b/actix-http/src/h1/dispatcher_tests.rs index 3eea859bf..d39c5bd69 100644 --- a/actix-http/src/h1/dispatcher_tests.rs +++ b/actix-http/src/h1/dispatcher_tests.rs @@ -64,7 +64,7 @@ fn drop_payload_service( fn echo_payload_service() -> impl Service, Error = Error> { fn_service(|mut req: Request| { Box::pin(async move { - use futures_util::stream::StreamExt as _; + use futures_util::StreamExt as _; let mut pl = req.take_payload(); let mut body = BytesMut::new(); diff --git a/actix-http/tests/test_openssl.rs b/actix-http/tests/test_openssl.rs index b97b2e45b..40dbb6ba4 100644 --- a/actix-http/tests/test_openssl.rs +++ b/actix-http/tests/test_openssl.rs @@ -16,7 +16,7 @@ use actix_utils::future::{err, ok, ready}; use bytes::{Bytes, BytesMut}; use derive_more::{Display, Error}; use futures_core::Stream; -use futures_util::stream::{once, StreamExt as _}; +use futures_util::{stream::once, StreamExt as _}; use openssl::{ pkey::PKey, ssl::{SslAcceptor, SslMethod}, diff --git a/actix-http/tests/test_server.rs b/actix-http/tests/test_server.rs index e8d103c96..e70089b1d 100644 --- a/actix-http/tests/test_server.rs +++ b/actix-http/tests/test_server.rs @@ -15,10 +15,7 @@ use actix_service::fn_service; use actix_utils::future::{err, ok, ready}; use bytes::Bytes; use derive_more::{Display, Error}; -use futures_util::{ - stream::{once, StreamExt as _}, - FutureExt as _, -}; +use futures_util::{stream::once, FutureExt as _, StreamExt as _}; use regex::Regex; #[actix_rt::test] diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index 6f631fcf1..3226850db 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -19,7 +19,7 @@ actix-web = { version = "4", default-features = false } bytes = "1" derive_more = "0.99.5" -futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] } +futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] } httparse = "1.3" local-waker = "0.1" log = "0.4" @@ -29,6 +29,6 @@ memchr = "2.5" [dev-dependencies] actix-rt = "2.2" actix-http = "3" -futures-util = { version = "0.3.7", default-features = false, features = ["alloc"] } +futures-util = { version = "0.3.17", default-features = false, features = ["alloc"] } tokio = { version = "1.8.4", features = ["sync"] } tokio-stream = "0.1" diff --git a/actix-multipart/src/extractor.rs b/actix-multipart/src/extractor.rs index 1ad1f203d..d45c4869c 100644 --- a/actix-multipart/src/extractor.rs +++ b/actix-multipart/src/extractor.rs @@ -14,7 +14,7 @@ use crate::server::Multipart; /// ``` /// use actix_web::{web, HttpResponse, Error}; /// use actix_multipart::Multipart; -/// use futures_util::stream::StreamExt as _; +/// use futures_util::StreamExt as _; /// /// async fn index(mut payload: Multipart) -> Result { /// // iterate over multipart stream diff --git a/actix-multipart/src/server.rs b/actix-multipart/src/server.rs index 1d0510039..9e0becd5c 100644 --- a/actix-multipart/src/server.rs +++ b/actix-multipart/src/server.rs @@ -868,7 +868,7 @@ mod tests { use actix_web::test::TestRequest; use actix_web::FromRequest; use bytes::Bytes; - use futures_util::{future::lazy, StreamExt}; + use futures_util::{future::lazy, StreamExt as _}; use std::time::Duration; use tokio::sync::mpsc; use tokio_stream::wrappers::UnboundedReceiverStream; diff --git a/actix-test/Cargo.toml b/actix-test/Cargo.toml index eaea15d47..05d12c25a 100644 --- a/actix-test/Cargo.toml +++ b/actix-test/Cargo.toml @@ -37,8 +37,8 @@ actix-utils = "3" actix-web = { version = "4", default-features = false, features = ["cookies"] } awc = { version = "3", default-features = false, features = ["cookies"] } -futures-core = { version = "0.3.7", default-features = false, features = ["std"] } -futures-util = { version = "0.3.7", default-features = false, features = [] } +futures-core = { version = "0.3.17", default-features = false, features = ["std"] } +futures-util = { version = "0.3.17", default-features = false, features = [] } log = "0.4" serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/actix-web-actors/Cargo.toml b/actix-web-actors/Cargo.toml index 26b1c09de..633c3c373 100644 --- a/actix-web-actors/Cargo.toml +++ b/actix-web-actors/Cargo.toml @@ -21,7 +21,7 @@ actix-web = { version = "4", default-features = false } bytes = "1" bytestring = "1" -futures-core = { version = "0.3.7", default-features = false } +futures-core = { version = "0.3.17", default-features = false } pin-project-lite = "0.2" tokio = { version = "1.13.1", features = ["sync"] } tokio-util = { version = "0.7", features = ["codec"] } @@ -35,4 +35,4 @@ actix-web = { version = "4", features = ["macros"] } mime = "0.3" env_logger = "0.9" -futures-util = { version = "0.3.7", default-features = false } +futures-util = { version = "0.3.17", default-features = false } diff --git a/actix-web-actors/tests/test_ws.rs b/actix-web-actors/tests/test_ws.rs index a9eb37699..cf12a0052 100644 --- a/actix-web-actors/tests/test_ws.rs +++ b/actix-web-actors/tests/test_ws.rs @@ -3,7 +3,7 @@ use actix_http::ws::Codec; use actix_web::{web, App, HttpRequest}; use actix_web_actors::ws; use bytes::Bytes; -use futures_util::{SinkExt, StreamExt}; +use futures_util::{SinkExt as _, StreamExt as _}; struct Ws; diff --git a/actix-web-codegen/Cargo.toml b/actix-web-codegen/Cargo.toml index 2477364a6..da5577445 100644 --- a/actix-web-codegen/Cargo.toml +++ b/actix-web-codegen/Cargo.toml @@ -27,6 +27,6 @@ actix-test = "0.1" actix-utils = "3" actix-web = "4" -futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] } +futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] } trybuild = "1" rustversion = "1" diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index 9ace68811..6078d5739 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -79,8 +79,8 @@ cfg-if = "1" cookie = { version = "0.16", features = ["percent-encode"], optional = true } derive_more = "0.99.8" encoding_rs = "0.8" -futures-core = { version = "0.3.7", default-features = false } -futures-util = { version = "0.3.7", default-features = false } +futures-core = { version = "0.3.17", default-features = false } +futures-util = { version = "0.3.17", default-features = false } http = "0.2.8" itoa = "1" language-tags = "0.3" @@ -107,7 +107,7 @@ const-str = "0.4" criterion = { version = "0.4", features = ["html_reports"] } env_logger = "0.9" flate2 = "1.0.13" -futures-util = { version = "0.3.7", default-features = false, features = ["std"] } +futures-util = { version = "0.3.17", default-features = false, features = ["std"] } rand = "0.8" rcgen = "0.9" rustls-pemfile = "1" diff --git a/actix-web/src/app.rs b/actix-web/src/app.rs index ec37ff8a4..e53ab8080 100644 --- a/actix-web/src/app.rs +++ b/actix-web/src/app.rs @@ -5,7 +5,7 @@ use actix_service::{ apply, apply_fn_factory, boxed, IntoServiceFactory, ServiceFactory, ServiceFactoryExt, Transform, }; -use futures_util::future::FutureExt as _; +use futures_util::FutureExt as _; use crate::{ app_service::{AppEntry, AppInit, AppRoutingFactory}, diff --git a/actix-web/src/middleware/condition.rs b/actix-web/src/middleware/condition.rs index 65f25a67c..5e106c11f 100644 --- a/actix-web/src/middleware/condition.rs +++ b/actix-web/src/middleware/condition.rs @@ -7,7 +7,7 @@ use std::{ }; use futures_core::{future::LocalBoxFuture, ready}; -use futures_util::future::FutureExt as _; +use futures_util::FutureExt as _; use pin_project_lite::pin_project; use crate::{ diff --git a/actix-web/src/middleware/err_handlers.rs b/actix-web/src/middleware/err_handlers.rs index 3a4e44a2c..4ddbc6318 100644 --- a/actix-web/src/middleware/err_handlers.rs +++ b/actix-web/src/middleware/err_handlers.rs @@ -351,7 +351,7 @@ mod tests { use actix_service::IntoService; use actix_utils::future::ok; use bytes::Bytes; - use futures_util::future::FutureExt as _; + use futures_util::FutureExt as _; use super::*; use crate::{ diff --git a/actix-web/src/types/payload.rs b/actix-web/src/types/payload.rs index f17a4ed6d..4045cedb4 100644 --- a/actix-web/src/types/payload.rs +++ b/actix-web/src/types/payload.rs @@ -27,7 +27,7 @@ use crate::{ /// # Examples /// ``` /// use std::future::Future; -/// use futures_util::stream::StreamExt as _; +/// use futures_util::StreamExt as _; /// use actix_web::{post, web}; /// /// // `body: web::Payload` parameter extracts raw payload stream from request diff --git a/actix-web/src/types/readlines.rs b/actix-web/src/types/readlines.rs index 8a775a073..e75239968 100644 --- a/actix-web/src/types/readlines.rs +++ b/actix-web/src/types/readlines.rs @@ -177,7 +177,7 @@ where #[cfg(test)] mod tests { - use futures_util::stream::StreamExt as _; + use futures_util::StreamExt as _; use super::*; use crate::test::TestRequest; diff --git a/awc/Cargo.toml b/awc/Cargo.toml index b40becfec..cf64eed49 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -67,8 +67,8 @@ base64 = "0.13" bytes = "1" cfg-if = "1" derive_more = "0.99.5" -futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] } -futures-util = { version = "0.3.7", default-features = false, features = ["alloc", "sink"] } +futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] } +futures-util = { version = "0.3.17", default-features = false, features = ["alloc", "sink"] } h2 = "0.3.9" http = "0.2.5" itoa = "1" @@ -102,7 +102,7 @@ brotli = "3.3.3" const-str = "0.4" env_logger = "0.9" flate2 = "1.0.13" -futures-util = { version = "0.3.7", default-features = false } +futures-util = { version = "0.3.17", default-features = false } static_assertions = "1.1" rcgen = "0.9" rustls-pemfile = "1" diff --git a/awc/src/client/pool.rs b/awc/src/client/pool.rs index 5655b5845..47c1fdd67 100644 --- a/awc/src/client/pool.rs +++ b/awc/src/client/pool.rs @@ -19,7 +19,7 @@ use actix_rt::time::{sleep, Sleep}; use actix_service::Service; use ahash::AHashMap; use futures_core::future::LocalBoxFuture; -use futures_util::FutureExt; +use futures_util::FutureExt as _; use http::uri::Authority; use pin_project_lite::pin_project; use tokio::sync::{OwnedSemaphorePermit, Semaphore}; diff --git a/awc/src/lib.rs b/awc/src/lib.rs index 8d6ea759a..412ccbe61 100644 --- a/awc/src/lib.rs +++ b/awc/src/lib.rs @@ -83,7 +83,7 @@ //! ```no_run //! # #[actix_rt::main] //! # async fn main() -> Result<(), Box> { -//! use futures_util::{sink::SinkExt as _, stream::StreamExt as _}; +//! use futures_util::{SinkExt as _, StreamExt as _}; //! //! let (_resp, mut connection) = awc::Client::new() //! .ws("ws://echo.websocket.org") diff --git a/awc/src/ws.rs b/awc/src/ws.rs index b316f68b4..4ef2e2b36 100644 --- a/awc/src/ws.rs +++ b/awc/src/ws.rs @@ -6,7 +6,7 @@ //! //! ```no_run //! use awc::{Client, ws}; -//! use futures_util::{sink::SinkExt as _, stream::StreamExt as _}; +//! use futures_util::{SinkExt as _, StreamExt as _}; //! //! #[actix_rt::main] //! async fn main() { diff --git a/awc/tests/test_client.rs b/awc/tests/test_client.rs index c4b468eeb..db987fdfa 100644 --- a/awc/tests/test_client.rs +++ b/awc/tests/test_client.rs @@ -139,7 +139,7 @@ async fn timeout_override() { #[actix_rt::test] async fn response_timeout() { - use futures_util::stream::{once, StreamExt as _}; + use futures_util::{stream::once, StreamExt as _}; let srv = actix_test::start(|| { App::new().service(web::resource("/").route(web::to(|| async { From 06c3513bc0da212d87c6fae5332e845146991027 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Wed, 21 Dec 2022 20:28:45 +0000 Subject: [PATCH 04/35] add Allow header to resource's default 405 handler (#2949) --- actix-web/CHANGES.md | 4 +++ actix-web/src/guard/mod.rs | 16 ++++++++++- actix-web/src/resource.rs | 59 +++++++++++++++++++++++++++++++------- 3 files changed, 68 insertions(+), 11 deletions(-) diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 6440ad693..8ea60266e 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -8,11 +8,15 @@ - Add rudimentary redirection service at `web::redirect()` / `web::Redirect`. [#1961] - Add `guard::Acceptable` for matching against `Accept` header mime types. [#2265] +### Fixed +- Add `Allow` header to `Resource`'s default responses when no routes are matched. [#2949] + [#1961]: https://github.com/actix/actix-web/pull/1961 [#2265]: https://github.com/actix/actix-web/pull/2265 [#2631]: https://github.com/actix/actix-web/pull/2631 [#2784]: https://github.com/actix/actix-web/pull/2784 [#2867]: https://github.com/actix/actix-web/pull/2867 +[#2949]: https://github.com/actix/actix-web/pull/2949 ## 4.2.1 - 2022-09-12 diff --git a/actix-web/src/guard/mod.rs b/actix-web/src/guard/mod.rs index 7cd846b66..e086f8648 100644 --- a/actix-web/src/guard/mod.rs +++ b/actix-web/src/guard/mod.rs @@ -286,11 +286,25 @@ pub fn Method(method: HttpMethod) -> impl Guard { MethodGuard(method) } +#[derive(Debug, Clone)] +pub(crate) struct RegisteredMethods(pub(crate) Vec); + /// HTTP method guard. -struct MethodGuard(HttpMethod); +#[derive(Debug)] +pub(crate) struct MethodGuard(HttpMethod); impl Guard for MethodGuard { fn check(&self, ctx: &GuardContext<'_>) -> bool { + let registered = ctx.req_data_mut().remove::(); + + if let Some(mut methods) = registered { + methods.0.push(self.0.clone()); + ctx.req_data_mut().insert(methods); + } else { + ctx.req_data_mut() + .insert(RegisteredMethods(vec![self.0.clone()])); + } + ctx.head().method == self.0 } } diff --git a/actix-web/src/resource.rs b/actix-web/src/resource.rs index c5c6701e6..997036751 100644 --- a/actix-web/src/resource.rs +++ b/actix-web/src/resource.rs @@ -13,8 +13,9 @@ use crate::{ body::MessageBody, data::Data, dev::{ensure_leading_slash, AppService, ResourceDef}, - guard::Guard, + guard::{self, Guard}, handler::Handler, + http::header, route::{Route, RouteService}, service::{ BoxedHttpService, BoxedHttpServiceFactory, HttpServiceFactory, ServiceRequest, @@ -40,8 +41,11 @@ use crate::{ /// .route(web::get().to(|| HttpResponse::Ok()))); /// ``` /// -/// If no matching route could be found, *405* response code get returned. Default behavior could be -/// overridden with `default_resource()` method. +/// If no matching route is found, [a 405 response is returned with an appropriate Allow header][RFC +/// 9110 §15.5.6]. This default behavior can be overridden using +/// [`default_service()`](Self::default_service). +/// +/// [RFC 9110 §15.5.6]: https://www.rfc-editor.org/rfc/rfc9110.html#section-15.5.6 pub struct Resource { endpoint: T, rdef: Patterns, @@ -66,7 +70,19 @@ impl Resource { guards: Vec::new(), app_data: None, default: boxed::factory(fn_service(|req: ServiceRequest| async { - Ok(req.into_response(HttpResponse::MethodNotAllowed())) + use crate::HttpMessage as _; + + let allowed = req.extensions().get::().cloned(); + + if let Some(methods) = allowed { + Ok(req.into_response( + HttpResponse::MethodNotAllowed() + .insert_header(header::Allow(methods.0)) + .finish(), + )) + } else { + Ok(req.into_response(HttpResponse::MethodNotAllowed())) + } })), } } @@ -309,13 +325,28 @@ where } } - /// Default service to be used if no matching route could be found. + /// Sets the default service to be used if no matching route is found. /// - /// You can use a [`Route`] as default service. + /// Unlike [`Scope`]s, a `Resource` does _not_ inherit its parent's default service. You can + /// use a [`Route`] as default service. /// - /// If a default service is not registered, an empty `405 Method Not Allowed` response will be - /// sent to the client instead. Unlike [`Scope`](crate::Scope)s, a [`Resource`] does **not** - /// inherit its parent's default service. + /// If a custom default service is not registered, an empty `405 Method Not Allowed` response + /// with an appropriate Allow header will be sent instead. + /// + /// # Examples + /// ``` + /// use actix_web::{App, HttpResponse, web}; + /// + /// let resource = web::resource("/test") + /// .route(web::get().to(HttpResponse::Ok)) + /// .default_service(web::to(|| { + /// HttpResponse::BadRequest() + /// })); + /// + /// App::new().service(resource); + /// ``` + /// + /// [`Scope`]: crate::Scope pub fn default_service(mut self, f: F) -> Self where F: IntoServiceFactory, @@ -606,7 +637,11 @@ mod tests { async fn test_default_resource() { let srv = init_service( App::new() - .service(web::resource("/test").route(web::get().to(HttpResponse::Ok))) + .service( + web::resource("/test") + .route(web::get().to(HttpResponse::Ok)) + .route(web::delete().to(HttpResponse::Ok)), + ) .default_service(|r: ServiceRequest| { ok(r.into_response(HttpResponse::BadRequest())) }), @@ -621,6 +656,10 @@ mod tests { .to_request(); let resp = call_service(&srv, req).await; assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED); + assert_eq!( + resp.headers().get(header::ALLOW).unwrap().as_bytes(), + b"GET, DELETE" + ); let srv = init_service( App::new().service( From 6f0a6bd1bb7ffdd98fa5ce825b24a73c4d71d9a7 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 1 Jan 2023 20:56:27 +0000 Subject: [PATCH 05/35] address clippy lints For intrepid commit message readers: The choice to add allows for the inlined format args lint instead of actually inlining them is not very clear because our actual real world MSRV is not clear. We currently claim 1.60 is our MSRV but this is mainly due to dependencies. I'm fairly sure that we could support < 1.58 if those deps are outdated in a users lockfile. We'll remove these allows again at some point soon. --- actix-files/src/lib.rs | 1 + actix-http-test/src/lib.rs | 3 +++ actix-http/benches/quality-value.rs | 2 ++ actix-http/src/body/sized_stream.rs | 2 +- actix-http/src/h1/chunked.rs | 2 +- actix-http/src/h1/encoder.rs | 2 +- actix-http/src/lib.rs | 3 ++- actix-http/tests/test_openssl.rs | 1 + actix-http/tests/test_rustls.rs | 1 + actix-http/tests/test_server.rs | 2 ++ actix-http/tests/test_ws.rs | 2 ++ actix-multipart/src/lib.rs | 2 +- actix-router/benches/quoter.rs | 2 ++ actix-router/src/lib.rs | 1 + actix-test/src/lib.rs | 2 ++ actix-web-actors/src/lib.rs | 1 + actix-web-codegen/src/route.rs | 2 +- actix-web/benches/server.rs | 2 ++ actix-web/examples/basic.rs | 2 ++ actix-web/examples/macroless.rs | 2 ++ actix-web/examples/on-connect.rs | 2 ++ actix-web/examples/uds.rs | 2 ++ actix-web/src/app.rs | 1 + actix-web/src/lib.rs | 1 + actix-web/tests/test_httpserver.rs | 2 ++ awc/examples/client.rs | 2 ++ awc/src/builder.rs | 2 +- awc/src/lib.rs | 3 ++- awc/src/request.rs | 4 +++- awc/src/ws.rs | 4 +++- awc/tests/test_client.rs | 2 ++ 31 files changed, 52 insertions(+), 10 deletions(-) diff --git a/actix-files/src/lib.rs b/actix-files/src/lib.rs index 40327e5e8..0fbe39a8e 100644 --- a/actix-files/src/lib.rs +++ b/actix-files/src/lib.rs @@ -13,6 +13,7 @@ #![deny(rust_2018_idioms, nonstandard_style)] #![warn(future_incompatible, missing_docs, missing_debug_implementations)] +#![allow(clippy::uninlined_format_args)] use actix_service::boxed::{BoxService, BoxServiceFactory}; use actix_web::{ diff --git a/actix-http-test/src/lib.rs b/actix-http-test/src/lib.rs index 8636ef9c4..a66f7b486 100644 --- a/actix-http-test/src/lib.rs +++ b/actix-http-test/src/lib.rs @@ -2,6 +2,7 @@ #![deny(rust_2018_idioms, nonstandard_style)] #![warn(future_incompatible)] +#![allow(clippy::uninlined_format_args)] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] @@ -87,6 +88,7 @@ pub async fn test_server_with_addr>( // notify TestServer that server and system have shut down // all thread managed resources should be dropped at this point + #[allow(clippy::let_underscore_future)] let _ = thread_stop_tx.send(()); }); @@ -294,6 +296,7 @@ impl Drop for TestServer { // without needing to await anything // signal server to stop + #[allow(clippy::let_underscore_future)] let _ = self.server.stop(true); // signal system to stop diff --git a/actix-http/benches/quality-value.rs b/actix-http/benches/quality-value.rs index 33ba9c4c8..0ed274ded 100644 --- a/actix-http/benches/quality-value.rs +++ b/actix-http/benches/quality-value.rs @@ -1,3 +1,5 @@ +#![allow(clippy::uninlined_format_args)] + use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; const CODES: &[u16] = &[0, 1000, 201, 800, 550]; diff --git a/actix-http/src/body/sized_stream.rs b/actix-http/src/body/sized_stream.rs index e5e27b287..08cd81a0d 100644 --- a/actix-http/src/body/sized_stream.rs +++ b/actix-http/src/body/sized_stream.rs @@ -44,7 +44,7 @@ where #[inline] fn size(&self) -> BodySize { - BodySize::Sized(self.size as u64) + BodySize::Sized(self.size) } /// Attempts to pull out the next value of the underlying [`Stream`]. diff --git a/actix-http/src/h1/chunked.rs b/actix-http/src/h1/chunked.rs index 4005ed892..fc9081b81 100644 --- a/actix-http/src/h1/chunked.rs +++ b/actix-http/src/h1/chunked.rs @@ -71,7 +71,7 @@ impl ChunkedState { match size.checked_mul(radix) { Some(n) => { - *size = n as u64; + *size = n; *size += rem as u64; Poll::Ready(Ok(ChunkedState::Size)) diff --git a/actix-http/src/h1/encoder.rs b/actix-http/src/h1/encoder.rs index 21cfd75c4..abe396ce2 100644 --- a/actix-http/src/h1/encoder.rs +++ b/actix-http/src/h1/encoder.rs @@ -450,7 +450,7 @@ impl TransferEncoding { buf.extend_from_slice(&msg[..len as usize]); - *remaining -= len as u64; + *remaining -= len; Ok(*remaining == 0) } else { Ok(true) diff --git a/actix-http/src/lib.rs b/actix-http/src/lib.rs index 864db4986..05f80eba4 100644 --- a/actix-http/src/lib.rs +++ b/actix-http/src/lib.rs @@ -21,7 +21,8 @@ #![allow( clippy::type_complexity, clippy::too_many_arguments, - clippy::borrow_interior_mutable_const + clippy::borrow_interior_mutable_const, + clippy::uninlined_format_args )] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] diff --git a/actix-http/tests/test_openssl.rs b/actix-http/tests/test_openssl.rs index 40dbb6ba4..7464bee4e 100644 --- a/actix-http/tests/test_openssl.rs +++ b/actix-http/tests/test_openssl.rs @@ -1,4 +1,5 @@ #![cfg(feature = "openssl")] +#![allow(clippy::uninlined_format_args)] extern crate tls_openssl as openssl; diff --git a/actix-http/tests/test_rustls.rs b/actix-http/tests/test_rustls.rs index d9ff42b7d..0b8197a69 100644 --- a/actix-http/tests/test_rustls.rs +++ b/actix-http/tests/test_rustls.rs @@ -1,4 +1,5 @@ #![cfg(feature = "rustls")] +#![allow(clippy::uninlined_format_args)] extern crate tls_rustls as rustls; diff --git a/actix-http/tests/test_server.rs b/actix-http/tests/test_server.rs index e70089b1d..0816ab221 100644 --- a/actix-http/tests/test_server.rs +++ b/actix-http/tests/test_server.rs @@ -1,3 +1,5 @@ +#![allow(clippy::uninlined_format_args)] + use std::{ convert::Infallible, io::{Read, Write}, diff --git a/actix-http/tests/test_ws.rs b/actix-http/tests/test_ws.rs index 8b3ab8e1b..a9c1acd33 100644 --- a/actix-http/tests/test_ws.rs +++ b/actix-http/tests/test_ws.rs @@ -1,3 +1,5 @@ +#![allow(clippy::uninlined_format_args)] + use std::{ cell::Cell, convert::Infallible, diff --git a/actix-multipart/src/lib.rs b/actix-multipart/src/lib.rs index 3d536e08d..37d03db49 100644 --- a/actix-multipart/src/lib.rs +++ b/actix-multipart/src/lib.rs @@ -2,7 +2,7 @@ #![deny(rust_2018_idioms, nonstandard_style)] #![warn(future_incompatible)] -#![allow(clippy::borrow_interior_mutable_const)] +#![allow(clippy::borrow_interior_mutable_const, clippy::uninlined_format_args)] mod error; mod extractor; diff --git a/actix-router/benches/quoter.rs b/actix-router/benches/quoter.rs index c18f1620e..9ca06da39 100644 --- a/actix-router/benches/quoter.rs +++ b/actix-router/benches/quoter.rs @@ -1,3 +1,5 @@ +#![allow(clippy::uninlined_format_args)] + use criterion::{black_box, criterion_group, criterion_main, Criterion}; use std::borrow::Cow; diff --git a/actix-router/src/lib.rs b/actix-router/src/lib.rs index 0febcf1ac..418dd432b 100644 --- a/actix-router/src/lib.rs +++ b/actix-router/src/lib.rs @@ -2,6 +2,7 @@ #![deny(rust_2018_idioms, nonstandard_style)] #![warn(future_incompatible)] +#![allow(clippy::uninlined_format_args)] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] diff --git a/actix-test/src/lib.rs b/actix-test/src/lib.rs index 5efd9758e..1aff2dc83 100644 --- a/actix-test/src/lib.rs +++ b/actix-test/src/lib.rs @@ -321,6 +321,7 @@ where // all thread managed resources should be dropped at this point }); + #[allow(clippy::let_underscore_future)] let _ = thread_stop_tx.send(()); }); @@ -567,6 +568,7 @@ impl Drop for TestServer { // without needing to await anything // signal server to stop + #[allow(clippy::let_underscore_future)] let _ = self.server.stop(true); // signal system to stop diff --git a/actix-web-actors/src/lib.rs b/actix-web-actors/src/lib.rs index 106bc5202..7a34048da 100644 --- a/actix-web-actors/src/lib.rs +++ b/actix-web-actors/src/lib.rs @@ -57,6 +57,7 @@ #![deny(rust_2018_idioms, nonstandard_style)] #![warn(future_incompatible)] +#![allow(clippy::uninlined_format_args)] mod context; pub mod ws; diff --git a/actix-web-codegen/src/route.rs b/actix-web-codegen/src/route.rs index 7a0658468..e5493702d 100644 --- a/actix-web-codegen/src/route.rs +++ b/actix-web-codegen/src/route.rs @@ -155,7 +155,7 @@ impl Args { if !methods.insert(method) { return Err(syn::Error::new_spanned( &nv.lit, - &format!( + format!( "HTTP method defined more than once: `{}`", lit.value() ), diff --git a/actix-web/benches/server.rs b/actix-web/benches/server.rs index 0d45c9403..2c9f71dc5 100644 --- a/actix-web/benches/server.rs +++ b/actix-web/benches/server.rs @@ -1,3 +1,5 @@ +#![allow(clippy::uninlined_format_args)] + use actix_web::{web, App, HttpResponse}; use awc::Client; use criterion::{criterion_group, criterion_main, Criterion}; diff --git a/actix-web/examples/basic.rs b/actix-web/examples/basic.rs index 36b1cdd8f..60715f477 100644 --- a/actix-web/examples/basic.rs +++ b/actix-web/examples/basic.rs @@ -1,3 +1,5 @@ +#![allow(clippy::uninlined_format_args)] + use actix_web::{get, middleware, web, App, HttpRequest, HttpResponse, HttpServer}; #[get("/resource1/{name}/index.html")] diff --git a/actix-web/examples/macroless.rs b/actix-web/examples/macroless.rs index 78ffd45c1..d3589da21 100644 --- a/actix-web/examples/macroless.rs +++ b/actix-web/examples/macroless.rs @@ -1,3 +1,5 @@ +#![allow(clippy::uninlined_format_args)] + use actix_web::{middleware, rt, web, App, HttpRequest, HttpServer}; async fn index(req: HttpRequest) -> &'static str { diff --git a/actix-web/examples/on-connect.rs b/actix-web/examples/on-connect.rs index 24c6f8418..57017fcd6 100644 --- a/actix-web/examples/on-connect.rs +++ b/actix-web/examples/on-connect.rs @@ -4,6 +4,8 @@ //! For an example of extracting a client TLS certificate, see: //! +#![allow(clippy::uninlined_format_args)] + use std::{any::Any, io, net::SocketAddr}; use actix_web::{ diff --git a/actix-web/examples/uds.rs b/actix-web/examples/uds.rs index cf0ffebde..ba4b25a29 100644 --- a/actix-web/examples/uds.rs +++ b/actix-web/examples/uds.rs @@ -1,3 +1,5 @@ +#![allow(clippy::uninlined_format_args)] + use actix_web::{get, web, HttpRequest}; #[cfg(unix)] use actix_web::{middleware, App, Error, HttpResponse, HttpServer}; diff --git a/actix-web/src/app.rs b/actix-web/src/app.rs index e53ab8080..353b82b19 100644 --- a/actix-web/src/app.rs +++ b/actix-web/src/app.rs @@ -712,6 +712,7 @@ mod tests { .route("/", web::to(|| async { "hello" })) } + #[allow(clippy::let_underscore_future)] let _ = init_service(my_app()); } } diff --git a/actix-web/src/lib.rs b/actix-web/src/lib.rs index 338541208..6a94976c5 100644 --- a/actix-web/src/lib.rs +++ b/actix-web/src/lib.rs @@ -69,6 +69,7 @@ #![deny(rust_2018_idioms, nonstandard_style)] #![warn(future_incompatible)] +#![allow(clippy::uninlined_format_args)] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_cfg))] diff --git a/actix-web/tests/test_httpserver.rs b/actix-web/tests/test_httpserver.rs index 86e0575f3..861d76d93 100644 --- a/actix-web/tests/test_httpserver.rs +++ b/actix-web/tests/test_httpserver.rs @@ -1,3 +1,5 @@ +#![allow(clippy::uninlined_format_args)] + #[cfg(feature = "openssl")] extern crate tls_openssl as openssl; diff --git a/awc/examples/client.rs b/awc/examples/client.rs index 16ad330b8..26edcfd62 100644 --- a/awc/examples/client.rs +++ b/awc/examples/client.rs @@ -1,3 +1,5 @@ +#![allow(clippy::uninlined_format_args)] + use std::error::Error as StdError; #[tokio::main] diff --git a/awc/src/builder.rs b/awc/src/builder.rs index c101d18f0..34a5f8505 100644 --- a/awc/src/builder.rs +++ b/awc/src/builder.rs @@ -210,7 +210,7 @@ where }; self.add_default_header(( header::AUTHORIZATION, - format!("Basic {}", base64::encode(&auth)), + format!("Basic {}", base64::encode(auth)), )) } diff --git a/awc/src/lib.rs b/awc/src/lib.rs index 412ccbe61..bb7f06c93 100644 --- a/awc/src/lib.rs +++ b/awc/src/lib.rs @@ -105,7 +105,8 @@ #![allow( clippy::type_complexity, clippy::borrow_interior_mutable_const, - clippy::needless_doctest_main + clippy::needless_doctest_main, + clippy::uninlined_format_args )] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] diff --git a/awc/src/request.rs b/awc/src/request.rs index 102db3c16..331c80af7 100644 --- a/awc/src/request.rs +++ b/awc/src/request.rs @@ -238,7 +238,7 @@ impl ClientRequest { self.insert_header(( header::AUTHORIZATION, - format!("Basic {}", base64::encode(&auth)), + format!("Basic {}", base64::encode(auth)), )) } @@ -565,6 +565,8 @@ mod tests { assert_eq!(req.head.version, Version::HTTP_2); let _ = req.headers_mut(); + + #[allow(clippy::let_underscore_future)] let _ = req.send_body(""); } diff --git a/awc/src/ws.rs b/awc/src/ws.rs index 4ef2e2b36..f905b8ef2 100644 --- a/awc/src/ws.rs +++ b/awc/src/ws.rs @@ -236,7 +236,7 @@ impl WebsocketsRequest { Some(password) => format!("{}:{}", username, password), None => format!("{}:", username), }; - self.header(AUTHORIZATION, format!("Basic {}", base64::encode(&auth))) + self.header(AUTHORIZATION, format!("Basic {}", base64::encode(auth))) } /// Set HTTP bearer authentication header @@ -503,6 +503,8 @@ mod tests { .unwrap(), "Bearer someS3cr3tAutht0k3n" ); + + #[allow(clippy::let_underscore_future)] let _ = req.connect(); } diff --git a/awc/tests/test_client.rs b/awc/tests/test_client.rs index db987fdfa..0949595cb 100644 --- a/awc/tests/test_client.rs +++ b/awc/tests/test_client.rs @@ -1,3 +1,5 @@ +#![allow(clippy::uninlined_format_args)] + use std::{ collections::HashMap, convert::Infallible, From 77459ec415a44ab90ed5b11ec6165f0dd0fe5e37 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 2 Jan 2023 00:14:25 +0000 Subject: [PATCH 06/35] add h2c example --- actix-http/examples/h2c-detect.rs | 54 +++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 actix-http/examples/h2c-detect.rs diff --git a/actix-http/examples/h2c-detect.rs b/actix-http/examples/h2c-detect.rs new file mode 100644 index 000000000..e1491324b --- /dev/null +++ b/actix-http/examples/h2c-detect.rs @@ -0,0 +1,54 @@ +//! An example that supports automatic selection of plaintext h1/h2c connections. +//! +//! Notably, both the following commands will work. +//! ```console +//! $ curl --http1.1 'http://localhost:8080/' +//! $ curl --http2-prior-knowledge 'http://localhost:8080/' +//! ``` + +use std::{convert::Infallible, io}; + +use actix_http::{HttpService, Protocol, Request, Response, StatusCode}; +use actix_rt::net::TcpStream; +use actix_server::Server; +use actix_service::{fn_service, ServiceFactoryExt}; + +const H2_PREFACE: &[u8] = b"PRI * HTTP/2"; + +#[actix_rt::main] +async fn main() -> io::Result<()> { + env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); + + Server::build() + .bind("h2c-detect", ("127.0.0.1", 8080), || { + fn_service(move |io: TcpStream| async move { + let mut buf = [0; 12]; + + io.peek(&mut buf).await?; + + let proto = if buf == H2_PREFACE { + tracing::info!("selecting h2c"); + Protocol::Http2 + } else { + tracing::info!("selecting h1"); + Protocol::Http1 + }; + + let peer_addr = io.peer_addr().ok(); + Ok::<_, io::Error>((io, proto, peer_addr)) + }) + .and_then( + HttpService::build() + .finish(|_req: Request| async move { + Ok::<_, Infallible>(Response::build(StatusCode::OK).body("Hello!")) + }) + .map_err(|err| { + tracing::error!("{}", err); + io::Error::new(io::ErrorKind::Other, "http service dispatch error") + }), + ) + })? + .workers(2) + .run() + .await +} From d2364c80c4311d70f32a6a50e26a2a3ef43a9206 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 2 Jan 2023 00:16:59 +0000 Subject: [PATCH 07/35] improve error handling on new new example --- actix-http/examples/h2c-detect.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/actix-http/examples/h2c-detect.rs b/actix-http/examples/h2c-detect.rs index e1491324b..550a03d2a 100644 --- a/actix-http/examples/h2c-detect.rs +++ b/actix-http/examples/h2c-detect.rs @@ -8,7 +8,7 @@ use std::{convert::Infallible, io}; -use actix_http::{HttpService, Protocol, Request, Response, StatusCode}; +use actix_http::{error::DispatchError, HttpService, Protocol, Request, Response, StatusCode}; use actix_rt::net::TcpStream; use actix_server::Server; use actix_service::{fn_service, ServiceFactoryExt}; @@ -24,7 +24,7 @@ async fn main() -> io::Result<()> { fn_service(move |io: TcpStream| async move { let mut buf = [0; 12]; - io.peek(&mut buf).await?; + io.peek(&mut buf).await.map_err(DispatchError::Io)?; let proto = if buf == H2_PREFACE { tracing::info!("selecting h2c"); @@ -35,18 +35,11 @@ async fn main() -> io::Result<()> { }; let peer_addr = io.peer_addr().ok(); - Ok::<_, io::Error>((io, proto, peer_addr)) + Ok((io, proto, peer_addr)) }) - .and_then( - HttpService::build() - .finish(|_req: Request| async move { - Ok::<_, Infallible>(Response::build(StatusCode::OK).body("Hello!")) - }) - .map_err(|err| { - tracing::error!("{}", err); - io::Error::new(io::ErrorKind::Other, "http service dispatch error") - }), - ) + .and_then(HttpService::build().finish(|_req: Request| async move { + Ok::<_, Infallible>(Response::build(StatusCode::OK).body("Hello!")) + })) })? .workers(2) .run() From 7b936bc443d22fca679a1fca72b488adfecee3e6 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 2 Jan 2023 13:33:31 +0000 Subject: [PATCH 08/35] add some useful header name constants (#2956) --- actix-http/CHANGES.md | 8 +++++++ actix-http/src/header/common.rs | 39 +++++++++++++++++++++++++++++++++ actix-http/src/header/mod.rs | 35 +++++++++++++++++++---------- 3 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 actix-http/src/header/common.rs diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 045ae461f..3c820ccf8 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -4,12 +4,20 @@ ### Added - Implement `MessageBody` for `&mut B` where `B: MessageBody + Unpin`. [#2868] - Implement `MessageBody` for `Pin` where `B::Target: MessageBody`. [#2868] +- Header name constants in `header` module. [#2956] + - `CROSS_ORIGIN_EMBEDDER_POLICY` + - `CROSS_ORIGIN_OPENER_POLICY` + - `PERMISSIONS_POLICY` + - `X_FORWARDED_FOR` + - `X_FORWARDED_HOST` + - `X_FORWARDED_PROTO` ### Performance - Improve overall performance of operations on `Extensions`. [#2890] [#2868]: https://github.com/actix/actix-web/pull/2868 [#2890]: https://github.com/actix/actix-web/pull/2890 +[#2956]: https://github.com/actix/actix-web/pull/2956 ## 3.2.2 - 2022-09-11 diff --git a/actix-http/src/header/common.rs b/actix-http/src/header/common.rs new file mode 100644 index 000000000..52909099a --- /dev/null +++ b/actix-http/src/header/common.rs @@ -0,0 +1,39 @@ +//! Common header names not defined in [`http`]. +//! +//! Any headers added to this file will need to be re-exported from the list at `crate::headers`. + +use http::header::HeaderName; + +/// Response header that prevents a document from loading any cross-origin resources that don't +/// explicitly grant the document permission (using [CORP] or [CORS]). +/// +/// [CORP]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cross-Origin_Resource_Policy_(CORP) +/// [CORS]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS +pub const CROSS_ORIGIN_EMBEDDER_POLICY: HeaderName = + HeaderName::from_static("cross-origin-embedder-policy"); + +/// Response header that allows you to ensure a top-level document does not share a browsing context +/// group with cross-origin documents. +pub const CROSS_ORIGIN_OPENER_POLICY: HeaderName = + HeaderName::from_static("cross-origin-opener-policy"); + +/// Response header that conveys a desire that the browser blocks no-cors cross-origin/cross-site +/// requests to the given resource. +pub const CROSS_ORIGIN_RESOURCE_POLICY: HeaderName = + HeaderName::from_static("cross-origin-resource-policy"); + +/// Response header that provides a mechanism to allow and deny the use of browser features in a +/// document or within any `