From 58c19b817fc248b4185f3e3d2151deac83c06d02 Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Fri, 9 Jun 2023 20:29:10 +0700 Subject: [PATCH 01/57] docs(actix-web/README.md): update benchmark link (#3046) Round 20 doesn't have actix score, but round 21 has. So I changed it to the round 21 link for everyone to see this is one of the best frameworks for Web/API. --- actix-web/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-web/README.md b/actix-web/README.md index 3c6524d36..32932cc0e 100644 --- a/actix-web/README.md +++ b/actix-web/README.md @@ -85,7 +85,7 @@ You may consider checking out [this directory](https://github.com/actix/examples ## Benchmarks -One of the fastest web frameworks available according to the [TechEmpower Framework Benchmark](https://www.techempower.com/benchmarks/#section=data-r20&test=composite). +One of the fastest web frameworks available according to the [TechEmpower Framework Benchmark](https://www.techempower.com/benchmarks/#section=data-r21&test=composite). ## License From 1072d0dacf3a5a7a8e2d5fd7fe5bb47658198bf8 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Fri, 9 Jun 2023 15:15:09 +0100 Subject: [PATCH 02/57] address lints --- actix-http/src/body/message_body.rs | 1 + actix-web/benches/responder.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/actix-http/src/body/message_body.rs b/actix-http/src/body/message_body.rs index e274cf8aa..c3f55ce7d 100644 --- a/actix-http/src/body/message_body.rs +++ b/actix-http/src/body/message_body.rs @@ -555,6 +555,7 @@ mod tests { }; } + #[allow(unused_allocation)] // triggered by `Box::new(()).size()` #[actix_rt::test] async fn boxing_equivalence() { assert_eq!(().size(), BodySize::Sized(0)); diff --git a/actix-web/benches/responder.rs b/actix-web/benches/responder.rs index 20aae3351..ac4d18324 100644 --- a/actix-web/benches/responder.rs +++ b/actix-web/benches/responder.rs @@ -87,7 +87,7 @@ fn future_responder(c: &mut Criterion) { let start = Instant::now(); - let _res = rt.block_on(async { futs.await }); + let _res = rt.block_on(futs); start.elapsed() }) From 241da6e0815d359cc29233a242624cbd28f46c92 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 2 Jul 2023 01:09:15 +0100 Subject: [PATCH 03/57] update MSRV to 1.65 (#3059) --- .github/workflows/ci.yml | 16 +++------- .github/workflows/clippy-fmt.yml | 3 +- actix-files/CHANGES.md | 2 ++ actix-files/Cargo.toml | 2 +- actix-files/README.md | 4 +-- actix-files/src/path_buf.rs | 2 -- actix-http-test/CHANGES.md | 2 ++ actix-http-test/Cargo.toml | 6 ++-- actix-http-test/README.md | 4 +-- actix-http/CHANGES.md | 4 +++ actix-http/Cargo.toml | 12 +++---- actix-http/README.md | 4 +-- actix-http/src/body/boxed.rs | 1 - actix-http/src/h1/decoder.rs | 2 +- actix-http/src/h1/service.rs | 1 - actix-http/src/header/into_pair.rs | 2 -- actix-http/src/header/into_value.rs | 2 -- .../src/header/shared/content_encoding.rs | 2 +- actix-http/src/header/shared/quality.rs | 5 +-- actix-http/src/header/shared/quality_item.rs | 2 +- actix-http/src/requests/request.rs | 1 - actix-http/src/service.rs | 6 ++-- actix-http/src/ws/frame.rs | 1 - actix-http/tests/test_rustls.rs | 2 +- actix-multipart-derive/CHANGES.md | 4 +++ actix-multipart-derive/Cargo.toml | 2 +- actix-multipart-derive/README.md | 4 +-- actix-multipart-derive/src/lib.rs | 2 +- actix-multipart-derive/tests/trybuild.rs | 2 +- actix-multipart/CHANGES.md | 2 ++ actix-multipart/Cargo.toml | 2 +- actix-multipart/README.md | 4 +-- actix-multipart/src/server.rs | 4 +-- actix-router/CHANGES.md | 2 ++ actix-router/Cargo.toml | 4 +-- actix-router/src/resource.rs | 2 -- actix-router/src/url.rs | 1 - actix-test/CHANGES.md | 2 ++ actix-test/Cargo.toml | 6 ++-- actix-web-actors/CHANGES.md | 2 ++ actix-web-actors/Cargo.toml | 7 ++-- actix-web-actors/README.md | 4 +-- actix-web-actors/src/ws.rs | 1 - actix-web-codegen/CHANGES.md | 2 ++ actix-web-codegen/Cargo.toml | 2 +- actix-web-codegen/README.md | 4 +-- actix-web-codegen/src/route.rs | 2 +- actix-web-codegen/tests/trybuild.rs | 2 +- .../trybuild/route-custom-lowercase.stderr | 12 ++++++- .../route-duplicate-method-fail.stderr | 32 ++++++++++++------- .../trybuild/route-missing-method-fail.stderr | 32 ++++++++++++------- .../trybuild/routes-missing-args-fail.stderr | 32 ++++++++++++------- .../routes-missing-method-fail.stderr | 32 ++++++++++++------- actix-web/CHANGES.md | 1 + actix-web/Cargo.toml | 16 +++++----- actix-web/README.md | 4 +-- actix-web/src/guard/mod.rs | 1 - actix-web/src/middleware/default_headers.rs | 1 - actix-web/src/middleware/err_handlers.rs | 4 +-- actix-web/src/middleware/logger.rs | 1 - actix-web/src/middleware/normalize.rs | 9 ++---- actix-web/src/request_data.rs | 1 - actix-web/src/response/builder.rs | 1 - actix-web/src/rmap.rs | 4 +-- actix-web/src/test/test_utils.rs | 1 - awc/CHANGES.md | 2 ++ awc/Cargo.toml | 12 +++---- awc/README.md | 2 +- awc/src/builder.rs | 2 +- awc/src/client/mod.rs | 2 +- awc/src/middleware/redirect.rs | 1 - awc/src/request.rs | 2 +- awc/src/ws.rs | 2 +- clippy.toml | 2 +- 74 files changed, 202 insertions(+), 166 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e0511339d..10e80b751 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: - { name: macOS, os: macos-latest, triple: x86_64-apple-darwin } - { name: Windows, os: windows-latest, triple: x86_64-pc-windows-msvc } version: - - 1.59.0 # MSRV + - 1.65.0 # MSRV - stable name: ${{ matrix.target.name }} / ${{ matrix.version }} @@ -49,17 +49,9 @@ jobs: - name: Install cargo-hack uses: taiki-e/install-action@cargo-hack - - name: workaround MSRV issues - if: matrix.version != 'stable' - run: | - cargo install cargo-edit --version=0.8.0 - cargo add const-str@0.3 --dev -p=actix-web - cargo add const-str@0.3 --dev -p=awc - - - name: workaround MSRV issues - if: matrix.version != 'stable' - run: | - cargo update -p=zstd-sys --precise=2.0.1+zstd.1.5.2 + # - name: workaround MSRV issues + # if: matrix.version != 'stable' + # run: | - name: check minimal run: cargo ci-check-min diff --git a/.github/workflows/clippy-fmt.yml b/.github/workflows/clippy-fmt.yml index a7da9b1c5..109165ce0 100644 --- a/.github/workflows/clippy-fmt.yml +++ b/.github/workflows/clippy-fmt.yml @@ -63,7 +63,8 @@ jobs: - uses: actions/checkout@v3 - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: { toolchain: nightly } + # temp: unpin once https://github.com/rust-lang/rust/issues/113152 is fixed + with: { toolchain: nightly-2023-06-28 } - uses: taiki-e/cache-cargo-install-action@v1 with: { tool: cargo-public-api } diff --git a/actix-files/CHANGES.md b/actix-files/CHANGES.md index d64380a8d..4e45ce517 100644 --- a/actix-files/CHANGES.md +++ b/actix-files/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased - 2023-xx-xx +- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. + ## 0.6.3 - 2023-01-21 - XHTML files now use `Content-Disposition: inline` instead of `attachment`. [#2903] diff --git a/actix-files/Cargo.toml b/actix-files/Cargo.toml index 41f3b1135..80c609d1d 100644 --- a/actix-files/Cargo.toml +++ b/actix-files/Cargo.toml @@ -11,7 +11,7 @@ homepage = "https://actix.rs" repository = "https://github.com/actix/actix-web" categories = ["asynchronous", "web-programming::http-server"] license = "MIT OR Apache-2.0" -edition = "2018" +edition = "2021" [lib] name = "actix_files" diff --git a/actix-files/README.md b/actix-files/README.md index 8869ca436..f01fc8566 100644 --- a/actix-files/README.md +++ b/actix-files/README.md @@ -4,7 +4,7 @@ [![crates.io](https://img.shields.io/crates/v/actix-files?label=latest)](https://crates.io/crates/actix-files) [![Documentation](https://docs.rs/actix-files/badge.svg?version=0.6.3)](https://docs.rs/actix-files/0.6.3) -![Version](https://img.shields.io/badge/rustc-1.59+-ab6000.svg) +![Version](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) ![License](https://img.shields.io/crates/l/actix-files.svg)
[![dependency status](https://deps.rs/crate/actix-files/0.6.3/status.svg)](https://deps.rs/crate/actix-files/0.6.3) @@ -15,4 +15,4 @@ - [API Documentation](https://docs.rs/actix-files) - [Example Project](https://github.com/actix/examples/tree/master/basics/static-files) -- Minimum Supported Rust Version (MSRV): 1.59 +- Minimum Supported Rust Version (MSRV): 1.65 diff --git a/actix-files/src/path_buf.rs b/actix-files/src/path_buf.rs index 650f55247..c1983279b 100644 --- a/actix-files/src/path_buf.rs +++ b/actix-files/src/path_buf.rs @@ -97,8 +97,6 @@ impl FromRequest for PathBufWrap { #[cfg(test)] mod tests { - use std::iter::FromIterator; - use super::*; #[test] diff --git a/actix-http-test/CHANGES.md b/actix-http-test/CHANGES.md index ec31b6196..3b8c83b3c 100644 --- a/actix-http-test/CHANGES.md +++ b/actix-http-test/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased - 2023-xx-xx +- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. + ## 3.1.0 - 2023-01-21 - Minimum supported Rust version (MSRV) is now 1.59. diff --git a/actix-http-test/Cargo.toml b/actix-http-test/Cargo.toml index 12739fbd4..87422551d 100644 --- a/actix-http-test/Cargo.toml +++ b/actix-http-test/Cargo.toml @@ -13,7 +13,7 @@ categories = [ "web-programming::websocket", ] license = "MIT OR Apache-2.0" -edition = "2018" +edition = "2021" [package.metadata.docs.rs] features = [] @@ -41,12 +41,12 @@ bytes = "1" futures-core = { version = "0.3.17", default-features = false } http = "0.2.7" log = "0.4" -socket2 = "0.4" +socket2 = "0.5" serde = "1" serde_json = "1" slab = "0.4" serde_urlencoded = "0.7" -tls-openssl = { version = "0.10.9", package = "openssl", optional = true } +tls-openssl = { version = "0.10.55", package = "openssl", optional = true } tokio = { version = "1.24.2", features = ["sync"] } [dev-dependencies] diff --git a/actix-http-test/README.md b/actix-http-test/README.md index 94f0e88a5..935be407f 100644 --- a/actix-http-test/README.md +++ b/actix-http-test/README.md @@ -4,7 +4,7 @@ [![crates.io](https://img.shields.io/crates/v/actix-http-test?label=latest)](https://crates.io/crates/actix-http-test) [![Documentation](https://docs.rs/actix-http-test/badge.svg?version=3.1.0)](https://docs.rs/actix-http-test/3.1.0) -![Version](https://img.shields.io/badge/rustc-1.59+-ab6000.svg) +![Version](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-http-test)
[![Dependency Status](https://deps.rs/crate/actix-http-test/3.1.0/status.svg)](https://deps.rs/crate/actix-http-test/3.1.0) @@ -14,4 +14,4 @@ ## Documentation & Resources - [API Documentation](https://docs.rs/actix-http-test) -- Minimum Supported Rust Version (MSRV): 1.59 +- Minimum Supported Rust Version (MSRV): 1.65 diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index aaf84d765..a105c02c1 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -7,6 +7,10 @@ - Add `body::to_body_limit()` function. - Add `body::BodyLimitExceeded` error type. +### Changed + +- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. + ## 3.3.1 - 2023-03-02 ### Fixed diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 222a04c8f..6909b785f 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -16,7 +16,7 @@ categories = [ "web-programming::websocket", ] license = "MIT OR Apache-2.0" -edition = "2018" +edition = "2021" [package.metadata.docs.rs] # features that docs.rs will build with @@ -105,20 +105,20 @@ actix-tls = { version = "3", features = ["openssl"] } actix-web = "4" async-stream = "0.3" -criterion = { version = "0.4", features = ["html_reports"] } -env_logger = "0.9" +criterion = { version = "0.5", features = ["html_reports"] } +env_logger = "0.10" futures-util = { version = "0.3.17", default-features = false, features = ["alloc"] } memchr = "2.4" once_cell = "1.9" -rcgen = "0.9" +rcgen = "0.11" regex = "1.3" rustversion = "1" rustls-pemfile = "1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" static_assertions = "1" -tls-openssl = { package = "openssl", version = "0.10.9" } -tls-rustls = { package = "rustls", version = "0.20.0" } +tls-openssl = { package = "openssl", version = "0.10.55" } +tls-rustls = { package = "rustls", version = "0.20" } tokio = { version = "1.24.2", features = ["net", "rt", "macros"] } [[example]] diff --git a/actix-http/README.md b/actix-http/README.md index f372096ff..0c5fcb6b6 100644 --- a/actix-http/README.md +++ b/actix-http/README.md @@ -4,7 +4,7 @@ [![crates.io](https://img.shields.io/crates/v/actix-http?label=latest)](https://crates.io/crates/actix-http) [![Documentation](https://docs.rs/actix-http/badge.svg?version=3.3.1)](https://docs.rs/actix-http/3.3.1) -![Version](https://img.shields.io/badge/rustc-1.59+-ab6000.svg) +![Version](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-http.svg)
[![dependency status](https://deps.rs/crate/actix-http/3.3.1/status.svg)](https://deps.rs/crate/actix-http/3.3.1) @@ -14,7 +14,7 @@ ## Documentation & Resources - [API Documentation](https://docs.rs/actix-http) -- Minimum Supported Rust Version (MSRV): 1.59 +- Minimum Supported Rust Version (MSRV): 1.65 ## Example diff --git a/actix-http/src/body/boxed.rs b/actix-http/src/body/boxed.rs index 5fcc42f56..2bbb75369 100644 --- a/actix-http/src/body/boxed.rs +++ b/actix-http/src/body/boxed.rs @@ -104,7 +104,6 @@ impl MessageBody for BoxBody { #[cfg(test)] mod tests { - use static_assertions::{assert_impl_all, assert_not_impl_any}; use super::*; diff --git a/actix-http/src/h1/decoder.rs b/actix-http/src/h1/decoder.rs index 0b06bfe24..829f40e10 100644 --- a/actix-http/src/h1/decoder.rs +++ b/actix-http/src/h1/decoder.rs @@ -1,4 +1,4 @@ -use std::{convert::TryFrom, io, marker::PhantomData, mem::MaybeUninit, task::Poll}; +use std::{io, marker::PhantomData, mem::MaybeUninit, task::Poll}; use actix_codec::Decoder; use bytes::{Bytes, BytesMut}; diff --git a/actix-http/src/h1/service.rs b/actix-http/src/h1/service.rs index a791ea8c3..9eebe2126 100644 --- a/actix-http/src/h1/service.rs +++ b/actix-http/src/h1/service.rs @@ -160,7 +160,6 @@ mod openssl { #[cfg(feature = "rustls")] mod rustls { - use std::io; use actix_service::ServiceFactoryExt as _; diff --git a/actix-http/src/header/into_pair.rs b/actix-http/src/header/into_pair.rs index 91c3e6640..0a71f857a 100644 --- a/actix-http/src/header/into_pair.rs +++ b/actix-http/src/header/into_pair.rs @@ -1,7 +1,5 @@ //! [`TryIntoHeaderPair`] trait and implementations. -use std::convert::TryFrom as _; - use super::{ Header, HeaderName, HeaderValue, InvalidHeaderName, InvalidHeaderValue, TryIntoHeaderValue, }; diff --git a/actix-http/src/header/into_value.rs b/actix-http/src/header/into_value.rs index 6d369ee65..253900633 100644 --- a/actix-http/src/header/into_value.rs +++ b/actix-http/src/header/into_value.rs @@ -1,7 +1,5 @@ //! [`TryIntoHeaderValue`] trait and implementations. -use std::convert::TryFrom as _; - use bytes::Bytes; use http::{header::InvalidHeaderValue, Error as HttpError, HeaderValue}; use mime::Mime; diff --git a/actix-http/src/header/shared/content_encoding.rs b/actix-http/src/header/shared/content_encoding.rs index bd25de704..c3b4bc4c2 100644 --- a/actix-http/src/header/shared/content_encoding.rs +++ b/actix-http/src/header/shared/content_encoding.rs @@ -1,4 +1,4 @@ -use std::{convert::TryFrom, str::FromStr}; +use std::str::FromStr; use derive_more::{Display, Error}; use http::header::InvalidHeaderValue; diff --git a/actix-http/src/header/shared/quality.rs b/actix-http/src/header/shared/quality.rs index c80dd0a8e..c2276cf1b 100644 --- a/actix-http/src/header/shared/quality.rs +++ b/actix-http/src/header/shared/quality.rs @@ -1,7 +1,4 @@ -use std::{ - convert::{TryFrom, TryInto}, - fmt, -}; +use std::fmt; use derive_more::{Display, Error}; diff --git a/actix-http/src/header/shared/quality_item.rs b/actix-http/src/header/shared/quality_item.rs index 0b35b5401..ee1fdb928 100644 --- a/actix-http/src/header/shared/quality_item.rs +++ b/actix-http/src/header/shared/quality_item.rs @@ -1,4 +1,4 @@ -use std::{cmp, convert::TryFrom as _, fmt, str}; +use std::{cmp, fmt, str}; use crate::error::ParseError; diff --git a/actix-http/src/requests/request.rs b/actix-http/src/requests/request.rs index ac358e8df..f4d605b39 100644 --- a/actix-http/src/requests/request.rs +++ b/actix-http/src/requests/request.rs @@ -234,7 +234,6 @@ impl

fmt::Debug for Request

{ #[cfg(test)] mod tests { use super::*; - use std::convert::TryFrom; #[test] fn test_basics() { diff --git a/actix-http/src/service.rs b/actix-http/src/service.rs index 22177b849..108b09c4e 100644 --- a/actix-http/src/service.rs +++ b/actix-http/src/service.rs @@ -30,9 +30,9 @@ use crate::{ /// /// # Automatic HTTP Version Selection /// There are two ways to select the HTTP version of an incoming connection: -/// - One is to rely on the ALPN information that is provided when using a TLS (HTTPS); both -/// versions are supported automatically when using either of the `.rustls()` or `.openssl()` -/// finalizing methods. +/// - One is to rely on the ALPN information that is provided when using TLS (HTTPS); both versions +/// are supported automatically when using either of the `.rustls()` or `.openssl()` finalizing +/// methods. /// - The other is to read the first few bytes of the TCP stream. This is the only viable approach /// for supporting H2C, which allows the HTTP/2 protocol to work over plaintext connections. Use /// the `.tcp_auto_h2c()` finalizing method to enable this behavior. diff --git a/actix-http/src/ws/frame.rs b/actix-http/src/ws/frame.rs index dddb03d18..ce6f1b256 100644 --- a/actix-http/src/ws/frame.rs +++ b/actix-http/src/ws/frame.rs @@ -1,5 +1,4 @@ use std::cmp::min; -use std::convert::TryFrom; use bytes::{Buf, BufMut, BytesMut}; use tracing::debug; diff --git a/actix-http/tests/test_rustls.rs b/actix-http/tests/test_rustls.rs index 0b8197a69..bf3a9243b 100644 --- a/actix-http/tests/test_rustls.rs +++ b/actix-http/tests/test_rustls.rs @@ -4,7 +4,7 @@ extern crate tls_rustls as rustls; use std::{ - convert::{Infallible, TryFrom}, + convert::Infallible, io::{self, BufReader, Write}, net::{SocketAddr, TcpStream as StdTcpStream}, sync::Arc, diff --git a/actix-multipart-derive/CHANGES.md b/actix-multipart-derive/CHANGES.md index 8dd7aa4d0..caf75aeb3 100644 --- a/actix-multipart-derive/CHANGES.md +++ b/actix-multipart-derive/CHANGES.md @@ -1,5 +1,9 @@ # Changes +## Unreleased + +- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. + ## 0.6.0 - 2023-02-26 - Add `MultipartForm` derive macro. diff --git a/actix-multipart-derive/Cargo.toml b/actix-multipart-derive/Cargo.toml index e0b78fa26..aca6de84a 100644 --- a/actix-multipart-derive/Cargo.toml +++ b/actix-multipart-derive/Cargo.toml @@ -7,7 +7,7 @@ keywords = ["http", "web", "framework", "async", "futures"] homepage = "https://actix.rs" repository = "https://github.com/actix/actix-web.git" license = "MIT OR Apache-2.0" -edition = "2018" +edition = "2021" [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] diff --git a/actix-multipart-derive/README.md b/actix-multipart-derive/README.md index 44f08c7bd..b077d355c 100644 --- a/actix-multipart-derive/README.md +++ b/actix-multipart-derive/README.md @@ -4,7 +4,7 @@ [![crates.io](https://img.shields.io/crates/v/actix-multipart-derive?label=latest)](https://crates.io/crates/actix-multipart-derive) [![Documentation](https://docs.rs/actix-multipart-derive/badge.svg?version=0.5.0)](https://docs.rs/actix-multipart-derive/0.5.0) -![Version](https://img.shields.io/badge/rustc-1.59+-ab6000.svg) +![Version](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-multipart-derive.svg)
[![dependency status](https://deps.rs/crate/actix-multipart-derive/0.5.0/status.svg)](https://deps.rs/crate/actix-multipart-derive/0.5.0) @@ -14,4 +14,4 @@ ## Documentation & Resources - [API Documentation](https://docs.rs/actix-multipart-derive) -- Minimum Supported Rust Version (MSRV): 1.59 +- Minimum Supported Rust Version (MSRV): 1.65 diff --git a/actix-multipart-derive/src/lib.rs b/actix-multipart-derive/src/lib.rs index 2af023aec..9552ad2d9 100644 --- a/actix-multipart-derive/src/lib.rs +++ b/actix-multipart-derive/src/lib.rs @@ -8,7 +8,7 @@ #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] -use std::{collections::HashSet, convert::TryFrom as _}; +use std::collections::HashSet; use darling::{FromDeriveInput, FromField, FromMeta}; use parse_size::parse_size; diff --git a/actix-multipart-derive/tests/trybuild.rs b/actix-multipart-derive/tests/trybuild.rs index 7b9f14ed7..829c1d771 100644 --- a/actix-multipart-derive/tests/trybuild.rs +++ b/actix-multipart-derive/tests/trybuild.rs @@ -1,4 +1,4 @@ -#[rustversion::stable(1.59)] // MSRV +#[rustversion::stable(1.65)] // MSRV #[test] fn compile_macros() { let t = trybuild::TestCases::new(); diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index 4bb120c61..410c8af17 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased - 2023-xx-xx +- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. + ## 0.6.0 - 2023-02-26 - Added `MultipartForm` typed data extractor. [#2883] diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index a36fbffc0..384c0e151 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["http", "web", "framework", "async", "futures"] homepage = "https://actix.rs" repository = "https://github.com/actix/actix-web.git" license = "MIT OR Apache-2.0" -edition = "2018" +edition = "2021" [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] diff --git a/actix-multipart/README.md b/actix-multipart/README.md index c4101e1ce..3e2a7a127 100644 --- a/actix-multipart/README.md +++ b/actix-multipart/README.md @@ -4,7 +4,7 @@ [![crates.io](https://img.shields.io/crates/v/actix-multipart?label=latest)](https://crates.io/crates/actix-multipart) [![Documentation](https://docs.rs/actix-multipart/badge.svg?version=0.6.0)](https://docs.rs/actix-multipart/0.6.0) -![Version](https://img.shields.io/badge/rustc-1.59+-ab6000.svg) +![Version](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-multipart.svg)
[![dependency status](https://deps.rs/crate/actix-multipart/0.6.0/status.svg)](https://deps.rs/crate/actix-multipart/0.6.0) @@ -14,4 +14,4 @@ ## Documentation & Resources - [API Documentation](https://docs.rs/actix-multipart) -- Minimum Supported Rust Version (MSRV): 1.59 +- Minimum Supported Rust Version (MSRV): 1.65 diff --git a/actix-multipart/src/server.rs b/actix-multipart/src/server.rs index 6726bc9d3..5dc4d6f69 100644 --- a/actix-multipart/src/server.rs +++ b/actix-multipart/src/server.rs @@ -2,9 +2,7 @@ use std::{ cell::{Cell, RefCell, RefMut}, - cmp, - convert::TryFrom, - fmt, + cmp, fmt, marker::PhantomData, pin::Pin, rc::Rc, diff --git a/actix-router/CHANGES.md b/actix-router/CHANGES.md index 7ef9497dc..1f5552193 100644 --- a/actix-router/CHANGES.md +++ b/actix-router/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased - 2023-xx-xx +- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. + ## 0.5.1 - 2022-09-19 - Correct typo in error string for `i32` deserialization. [#2876] diff --git a/actix-router/Cargo.toml b/actix-router/Cargo.toml index f8efd5350..adf43a086 100644 --- a/actix-router/Cargo.toml +++ b/actix-router/Cargo.toml @@ -10,7 +10,7 @@ description = "Resource path matching and router" keywords = ["actix", "router", "routing"] repository = "https://github.com/actix/actix-web.git" license = "MIT OR Apache-2.0" -edition = "2018" +edition = "2021" [lib] name = "actix_router" @@ -27,7 +27,7 @@ serde = "1" tracing = { version = "0.1.30", default-features = false, features = ["log"] } [dev-dependencies] -criterion = { version = "0.4", features = ["html_reports"] } +criterion = { version = "0.5", features = ["html_reports"] } http = "0.2.7" serde = { version = "1", features = ["derive"] } percent-encoding = "2.1" diff --git a/actix-router/src/resource.rs b/actix-router/src/resource.rs index f198115ad..c868a3e6f 100644 --- a/actix-router/src/resource.rs +++ b/actix-router/src/resource.rs @@ -1389,8 +1389,6 @@ mod tests { #[cfg(feature = "http")] #[test] fn parse_urlencoded_param() { - use std::convert::TryFrom; - let re = ResourceDef::new("/user/{id}/test"); let mut path = Path::new("/user/2345/test"); diff --git a/actix-router/src/url.rs b/actix-router/src/url.rs index 8ac033861..8ae9ea9d8 100644 --- a/actix-router/src/url.rs +++ b/actix-router/src/url.rs @@ -65,7 +65,6 @@ impl ResourcePath for Url { #[cfg(test)] mod tests { use http::Uri; - use std::convert::TryFrom; use super::*; use crate::{Path, ResourceDef}; diff --git a/actix-test/CHANGES.md b/actix-test/CHANGES.md index 47fea4173..e3a66c663 100644 --- a/actix-test/CHANGES.md +++ b/actix-test/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased - 2023-xx-xx +- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. + ## 0.1.1 - 2023-02-26 - Add `TestServerConfig::port()` setter method. diff --git a/actix-test/Cargo.toml b/actix-test/Cargo.toml index f2cbfe5cd..9cf5aa76c 100644 --- a/actix-test/Cargo.toml +++ b/actix-test/Cargo.toml @@ -16,7 +16,7 @@ categories = [ "web-programming::websocket", ] license = "MIT OR Apache-2.0" -edition = "2018" +edition = "2021" [features] default = [] @@ -43,6 +43,6 @@ log = "0.4" serde = { version = "1", features = ["derive"] } serde_json = "1" serde_urlencoded = "0.7" -tls-openssl = { package = "openssl", version = "0.10.9", optional = true } -tls-rustls = { package = "rustls", version = "0.20.0", optional = true } +tls-openssl = { package = "openssl", version = "0.10.55", optional = true } +tls-rustls = { package = "rustls", version = "0.20", optional = true } tokio = { version = "1.24.2", features = ["sync"] } diff --git a/actix-web-actors/CHANGES.md b/actix-web-actors/CHANGES.md index ea19411b5..4799c7b67 100644 --- a/actix-web-actors/CHANGES.md +++ b/actix-web-actors/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased - 2023-xx-xx +- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. + ## 4.2.0 - 2023-01-21 - Minimum supported Rust version (MSRV) is now 1.57 due to transitive `time` dependency. diff --git a/actix-web-actors/Cargo.toml b/actix-web-actors/Cargo.toml index e89baed96..c6f14554a 100644 --- a/actix-web-actors/Cargo.toml +++ b/actix-web-actors/Cargo.toml @@ -7,7 +7,7 @@ keywords = ["actix", "http", "web", "framework", "async"] homepage = "https://actix.rs" repository = "https://github.com/actix/actix-web" license = "MIT OR Apache-2.0" -edition = "2018" +edition = "2021" [lib] name = "actix_web_actors" @@ -32,7 +32,6 @@ actix-test = "0.1" awc = { version = "3", default-features = false } actix-web = { version = "4", features = ["macros"] } +env_logger = "0.10" +futures-util = { version = "0.3.17", default-features = false, features = ["std"] } mime = "0.3" - -env_logger = "0.9" -futures-util = { version = "0.3.17", default-features = false } diff --git a/actix-web-actors/README.md b/actix-web-actors/README.md index dce91f503..fe6122115 100644 --- a/actix-web-actors/README.md +++ b/actix-web-actors/README.md @@ -4,7 +4,7 @@ [![crates.io](https://img.shields.io/crates/v/actix-web-actors?label=latest)](https://crates.io/crates/actix-web-actors) [![Documentation](https://docs.rs/actix-web-actors/badge.svg?version=4.2.0)](https://docs.rs/actix-web-actors/4.2.0) -![Version](https://img.shields.io/badge/rustc-1.59+-ab6000.svg) +![Version](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) ![License](https://img.shields.io/crates/l/actix-web-actors.svg)
[![dependency status](https://deps.rs/crate/actix-web-actors/4.2.0/status.svg)](https://deps.rs/crate/actix-web-actors/4.2.0) @@ -14,4 +14,4 @@ ## Documentation & Resources - [API Documentation](https://docs.rs/actix-web-actors) -- Minimum Supported Rust Version (MSRV): 1.59 +- Minimum Supported Rust Version (MSRV): 1.65 diff --git a/actix-web-actors/src/ws.rs b/actix-web-actors/src/ws.rs index e1110eddb..731f33f86 100644 --- a/actix-web-actors/src/ws.rs +++ b/actix-web-actors/src/ws.rs @@ -58,7 +58,6 @@ use std::{ collections::VecDeque, - convert::TryFrom, future::Future, io, mem, pin::Pin, diff --git a/actix-web-codegen/CHANGES.md b/actix-web-codegen/CHANGES.md index 6e962a6ca..b9e4b0aad 100644 --- a/actix-web-codegen/CHANGES.md +++ b/actix-web-codegen/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased - 2023-xx-xx +- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. + ## 4.2.0 - 2023-02-26 - Add support for custom methods with the `#[route]` macro. [#2969] diff --git a/actix-web-codegen/Cargo.toml b/actix-web-codegen/Cargo.toml index 51cb0dfef..4f2fdc566 100644 --- a/actix-web-codegen/Cargo.toml +++ b/actix-web-codegen/Cargo.toml @@ -9,7 +9,7 @@ authors = [ "Rob Ede ", ] license = "MIT OR Apache-2.0" -edition = "2018" +edition = "2021" [lib] proc-macro = true diff --git a/actix-web-codegen/README.md b/actix-web-codegen/README.md index 8dd3e986e..531f44a5d 100644 --- a/actix-web-codegen/README.md +++ b/actix-web-codegen/README.md @@ -4,7 +4,7 @@ [![crates.io](https://img.shields.io/crates/v/actix-web-codegen?label=latest)](https://crates.io/crates/actix-web-codegen) [![Documentation](https://docs.rs/actix-web-codegen/badge.svg?version=4.2.0)](https://docs.rs/actix-web-codegen/4.2.0) -![Version](https://img.shields.io/badge/rustc-1.59+-ab6000.svg) +![Version](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) ![License](https://img.shields.io/crates/l/actix-web-codegen.svg)
[![dependency status](https://deps.rs/crate/actix-web-codegen/4.2.0/status.svg)](https://deps.rs/crate/actix-web-codegen/4.2.0) @@ -14,7 +14,7 @@ ## Documentation & Resources - [API Documentation](https://docs.rs/actix-web-codegen) -- Minimum Supported Rust Version (MSRV): 1.59 +- Minimum Supported Rust Version (MSRV): 1.65 ## Compile Testing diff --git a/actix-web-codegen/src/route.rs b/actix-web-codegen/src/route.rs index 0772dbd94..0b8bb0f38 100644 --- a/actix-web-codegen/src/route.rs +++ b/actix-web-codegen/src/route.rs @@ -1,4 +1,4 @@ -use std::{collections::HashSet, convert::TryFrom}; +use std::collections::HashSet; use actix_router::ResourceDef; use proc_macro::TokenStream; diff --git a/actix-web-codegen/tests/trybuild.rs b/actix-web-codegen/tests/trybuild.rs index 8839dca3d..9f0aa02f4 100644 --- a/actix-web-codegen/tests/trybuild.rs +++ b/actix-web-codegen/tests/trybuild.rs @@ -1,4 +1,4 @@ -#[rustversion::stable(1.59)] // MSRV +#[rustversion::stable(1.65)] // MSRV #[test] fn compile_macros() { let t = trybuild::TestCases::new(); diff --git a/actix-web-codegen/tests/trybuild/route-custom-lowercase.stderr b/actix-web-codegen/tests/trybuild/route-custom-lowercase.stderr index 243c4dd68..88198a55d 100644 --- a/actix-web-codegen/tests/trybuild/route-custom-lowercase.stderr +++ b/actix-web-codegen/tests/trybuild/route-custom-lowercase.stderr @@ -8,10 +8,20 @@ error[E0277]: the trait bound `fn() -> impl std::future::Future --> tests/trybuild/route-custom-lowercase.rs:14:55 | 14 | let srv = actix_test::start(|| App::new().service(index)); - | ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}` + | ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for fn item `fn() -> impl std::future::Future {index}` | | | required by a bound introduced by this call | + = help: the following other types implement trait `HttpServiceFactory`: + (A, B) + (A, B, C) + (A, B, C, D) + (A, B, C, D, E) + (A, B, C, D, E, F) + (A, B, C, D, E, F, G) + (A, B, C, D, E, F, G, H) + (A, B, C, D, E, F, G, H, I) + and $N others note: required by a bound in `App::::service` --> $WORKSPACE/actix-web/src/app.rs | diff --git a/actix-web-codegen/tests/trybuild/route-duplicate-method-fail.stderr b/actix-web-codegen/tests/trybuild/route-duplicate-method-fail.stderr index 7eac84f3e..bda736348 100644 --- a/actix-web-codegen/tests/trybuild/route-duplicate-method-fail.stderr +++ b/actix-web-codegen/tests/trybuild/route-duplicate-method-fail.stderr @@ -5,15 +5,25 @@ error: HTTP method defined more than once: `GET` | ^^^^^ error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied - --> tests/trybuild/route-duplicate-method-fail.rs:12:55 - | -12 | let srv = actix_test::start(|| App::new().service(index)); - | ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}` - | | - | required by a bound introduced by this call - | + --> tests/trybuild/route-duplicate-method-fail.rs:12:55 + | +12 | let srv = actix_test::start(|| App::new().service(index)); + | ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for fn item `fn() -> impl std::future::Future {index}` + | | + | required by a bound introduced by this call + | + = help: the following other types implement trait `HttpServiceFactory`: + (A, B) + (A, B, C) + (A, B, C, D) + (A, B, C, D, E) + (A, B, C, D, E, F) + (A, B, C, D, E, F, G) + (A, B, C, D, E, F, G, H) + (A, B, C, D, E, F, G, H, I) + and $N others note: required by a bound in `App::::service` - --> $WORKSPACE/actix-web/src/app.rs - | - | F: HttpServiceFactory + 'static, - | ^^^^^^^^^^^^^^^^^^ required by this bound in `App::::service` + --> $WORKSPACE/actix-web/src/app.rs + | + | F: HttpServiceFactory + 'static, + | ^^^^^^^^^^^^^^^^^^ required by this bound in `App::::service` diff --git a/actix-web-codegen/tests/trybuild/route-missing-method-fail.stderr b/actix-web-codegen/tests/trybuild/route-missing-method-fail.stderr index bc8497c10..9f2f788fb 100644 --- a/actix-web-codegen/tests/trybuild/route-missing-method-fail.stderr +++ b/actix-web-codegen/tests/trybuild/route-missing-method-fail.stderr @@ -7,15 +7,25 @@ error: The #[route(..)] macro requires at least one `method` attribute = note: this error originates in the attribute macro `route` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied - --> tests/trybuild/route-missing-method-fail.rs:12:55 - | -12 | let srv = actix_test::start(|| App::new().service(index)); - | ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}` - | | - | required by a bound introduced by this call - | + --> tests/trybuild/route-missing-method-fail.rs:12:55 + | +12 | let srv = actix_test::start(|| App::new().service(index)); + | ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for fn item `fn() -> impl std::future::Future {index}` + | | + | required by a bound introduced by this call + | + = help: the following other types implement trait `HttpServiceFactory`: + (A, B) + (A, B, C) + (A, B, C, D) + (A, B, C, D, E) + (A, B, C, D, E, F) + (A, B, C, D, E, F, G) + (A, B, C, D, E, F, G, H) + (A, B, C, D, E, F, G, H, I) + and $N others note: required by a bound in `App::::service` - --> $WORKSPACE/actix-web/src/app.rs - | - | F: HttpServiceFactory + 'static, - | ^^^^^^^^^^^^^^^^^^ required by this bound in `App::::service` + --> $WORKSPACE/actix-web/src/app.rs + | + | F: HttpServiceFactory + 'static, + | ^^^^^^^^^^^^^^^^^^ required by this bound in `App::::service` diff --git a/actix-web-codegen/tests/trybuild/routes-missing-args-fail.stderr b/actix-web-codegen/tests/trybuild/routes-missing-args-fail.stderr index 785d6f326..e845241a4 100644 --- a/actix-web-codegen/tests/trybuild/routes-missing-args-fail.stderr +++ b/actix-web-codegen/tests/trybuild/routes-missing-args-fail.stderr @@ -13,15 +13,25 @@ error: Invalid input for macro | ^^^^^^ error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied - --> tests/trybuild/routes-missing-args-fail.rs:13:55 - | -13 | let srv = actix_test::start(|| App::new().service(index)); - | ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}` - | | - | required by a bound introduced by this call - | + --> tests/trybuild/routes-missing-args-fail.rs:13:55 + | +13 | let srv = actix_test::start(|| App::new().service(index)); + | ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for fn item `fn() -> impl std::future::Future {index}` + | | + | required by a bound introduced by this call + | + = help: the following other types implement trait `HttpServiceFactory`: + (A, B) + (A, B, C) + (A, B, C, D) + (A, B, C, D, E) + (A, B, C, D, E, F) + (A, B, C, D, E, F, G) + (A, B, C, D, E, F, G, H) + (A, B, C, D, E, F, G, H, I) + and $N others note: required by a bound in `App::::service` - --> $WORKSPACE/actix-web/src/app.rs - | - | F: HttpServiceFactory + 'static, - | ^^^^^^^^^^^^^^^^^^ required by this bound in `App::::service` + --> $WORKSPACE/actix-web/src/app.rs + | + | F: HttpServiceFactory + 'static, + | ^^^^^^^^^^^^^^^^^^ required by this bound in `App::::service` diff --git a/actix-web-codegen/tests/trybuild/routes-missing-method-fail.stderr b/actix-web-codegen/tests/trybuild/routes-missing-method-fail.stderr index 38a6d2f9b..228dced9c 100644 --- a/actix-web-codegen/tests/trybuild/routes-missing-method-fail.stderr +++ b/actix-web-codegen/tests/trybuild/routes-missing-method-fail.stderr @@ -7,15 +7,25 @@ error: The #[routes] macro requires at least one `#[(..)]` attribute. = note: this error originates in the attribute macro `routes` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied - --> tests/trybuild/routes-missing-method-fail.rs:12:55 - | -12 | let srv = actix_test::start(|| App::new().service(index)); - | ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}` - | | - | required by a bound introduced by this call - | + --> tests/trybuild/routes-missing-method-fail.rs:12:55 + | +12 | let srv = actix_test::start(|| App::new().service(index)); + | ------- ^^^^^ the trait `HttpServiceFactory` is not implemented for fn item `fn() -> impl std::future::Future {index}` + | | + | required by a bound introduced by this call + | + = help: the following other types implement trait `HttpServiceFactory`: + (A, B) + (A, B, C) + (A, B, C, D) + (A, B, C, D, E) + (A, B, C, D, E, F) + (A, B, C, D, E, F, G) + (A, B, C, D, E, F, G, H) + (A, B, C, D, E, F, G, H, I) + and $N others note: required by a bound in `App::::service` - --> $WORKSPACE/actix-web/src/app.rs - | - | F: HttpServiceFactory + 'static, - | ^^^^^^^^^^^^^^^^^^ required by this bound in `App::::service` + --> $WORKSPACE/actix-web/src/app.rs + | + | F: HttpServiceFactory + 'static, + | ^^^^^^^^^^^^^^^^^^ required by this bound in `App::::service` diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 9688370b7..417bb5a4c 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -10,6 +10,7 @@ ### Changed - Handler functions can now receive up to 16 extractor parameters. +- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. ## 4.3.1 - 2023-02-26 diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index c7314422d..0091175be 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -16,7 +16,7 @@ categories = [ homepage = "https://actix.rs" repository = "https://github.com/actix/actix-web.git" license = "MIT OR Apache-2.0" -edition = "2018" +edition = "2021" [package.metadata.docs.rs] # features that docs.rs will build with @@ -92,7 +92,7 @@ serde = "1.0" serde_json = "1.0" serde_urlencoded = "0.7" smallvec = "1.6.1" -socket2 = "0.4" +socket2 = "0.5" time = { version = "0.3", default-features = false, features = ["formatting"] } url = "2.1" @@ -102,18 +102,18 @@ actix-test = { version = "0.1", features = ["openssl", "rustls"] } awc = { version = "3", features = ["openssl"] } brotli = "3.3.3" -const-str = "0.3" -criterion = { version = "0.4", features = ["html_reports"] } -env_logger = "0.9" +const-str = "0.5" +criterion = { version = "0.5", features = ["html_reports"] } +env_logger = "0.10" flate2 = "1.0.13" futures-util = { version = "0.3.17", default-features = false, features = ["std"] } rand = "0.8" -rcgen = "0.9" +rcgen = "0.11" rustls-pemfile = "1" serde = { version = "1.0", features = ["derive"] } static_assertions = "1" -tls-openssl = { package = "openssl", version = "0.10.9" } -tls-rustls = { package = "rustls", version = "0.20.0" } +tls-openssl = { package = "openssl", version = "0.10.55" } +tls-rustls = { package = "rustls", version = "0.20" } tokio = { version = "1.24.2", features = ["rt-multi-thread", "macros"] } zstd = "0.12" diff --git a/actix-web/README.md b/actix-web/README.md index 32932cc0e..cc2d9abe0 100644 --- a/actix-web/README.md +++ b/actix-web/README.md @@ -5,7 +5,7 @@

-[![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=4.3.1)](https://docs.rs/actix-web/4.3.1) ![MSRV](https://img.shields.io/badge/rustc-1.59+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-web.svg) [![Dependency Status](https://deps.rs/crate/actix-web/4.3.1/status.svg)](https://deps.rs/crate/actix-web/4.3.1)
[![CI](https://github.com/actix/actix-web/actions/workflows/ci.yml/badge.svg)](https://github.com/actix/actix-web/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web) ![downloads](https://img.shields.io/crates/d/actix-web.svg) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) +[![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=4.3.1)](https://docs.rs/actix-web/4.3.1) ![MSRV](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-web.svg) [![Dependency Status](https://deps.rs/crate/actix-web/4.3.1/status.svg)](https://deps.rs/crate/actix-web/4.3.1)
[![CI](https://github.com/actix/actix-web/actions/workflows/ci.yml/badge.svg)](https://github.com/actix/actix-web/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web) ![downloads](https://img.shields.io/crates/d/actix-web.svg) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)

@@ -24,7 +24,7 @@ - SSL support using OpenSSL or Rustls - Middlewares ([Logger, Session, CORS, etc](https://actix.rs/docs/middleware/)) - Integrates with the [`awc` HTTP client](https://docs.rs/awc/) -- Runs on stable Rust 1.59+ +- Runs on stable Rust 1.65+ ## Documentation diff --git a/actix-web/src/guard/mod.rs b/actix-web/src/guard/mod.rs index a9173a9d1..3aca11df2 100644 --- a/actix-web/src/guard/mod.rs +++ b/actix-web/src/guard/mod.rs @@ -51,7 +51,6 @@ use std::{ cell::{Ref, RefMut}, - convert::TryFrom, rc::Rc, }; diff --git a/actix-web/src/middleware/default_headers.rs b/actix-web/src/middleware/default_headers.rs index 003abd40d..b5a5a6998 100644 --- a/actix-web/src/middleware/default_headers.rs +++ b/actix-web/src/middleware/default_headers.rs @@ -1,7 +1,6 @@ //! For middleware documentation, see [`DefaultHeaders`]. use std::{ - convert::TryFrom, future::Future, marker::PhantomData, pin::Pin, diff --git a/actix-web/src/middleware/err_handlers.rs b/actix-web/src/middleware/err_handlers.rs index 5522cc021..051a0c6b3 100644 --- a/actix-web/src/middleware/err_handlers.rs +++ b/actix-web/src/middleware/err_handlers.rs @@ -270,8 +270,8 @@ impl ErrorHandlers { handlers .get(status) .map(|h| h.as_ref()) - .or_else(|| status.is_client_error().then(|| default_client).flatten()) - .or_else(|| status.is_server_error().then(|| default_server).flatten()) + .or_else(|| status.is_client_error().then_some(default_client).flatten()) + .or_else(|| status.is_server_error().then_some(default_server).flatten()) } } diff --git a/actix-web/src/middleware/logger.rs b/actix-web/src/middleware/logger.rs index 5fec5a013..0207798ae 100644 --- a/actix-web/src/middleware/logger.rs +++ b/actix-web/src/middleware/logger.rs @@ -3,7 +3,6 @@ use std::{ borrow::Cow, collections::HashSet, - convert::TryFrom, env, fmt::{self, Display as _}, future::Future, diff --git a/actix-web/src/middleware/normalize.rs b/actix-web/src/middleware/normalize.rs index 3ab908481..afcc0faac 100644 --- a/actix-web/src/middleware/normalize.rs +++ b/actix-web/src/middleware/normalize.rs @@ -15,11 +15,12 @@ use crate::{ /// /// The default is `TrailingSlash::Trim`. #[non_exhaustive] -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, Default)] pub enum TrailingSlash { /// Trim trailing slashes from the end of the path. /// /// Using this will require all routes to omit trailing slashes for them to be accessible. + #[default] Trim, /// Only merge any present multiple trailing slashes. @@ -33,12 +34,6 @@ pub enum TrailingSlash { Always, } -impl Default for TrailingSlash { - fn default() -> Self { - TrailingSlash::Trim - } -} - /// Middleware for normalizing a request's path so that routes can be matched more flexibly. /// /// # Normalization Steps diff --git a/actix-web/src/request_data.rs b/actix-web/src/request_data.rs index 719e6551f..bffbf74da 100644 --- a/actix-web/src/request_data.rs +++ b/actix-web/src/request_data.rs @@ -27,7 +27,6 @@ use crate::{ /// # Examples /// ```no_run /// # use actix_web::{web, HttpResponse, HttpRequest, Responder, HttpMessage as _}; -/// /// #[derive(Debug, Clone, PartialEq)] /// struct FlagFromMiddleware(String); /// diff --git a/actix-web/src/response/builder.rs b/actix-web/src/response/builder.rs index 120d4c358..a7f3f36c3 100644 --- a/actix-web/src/response/builder.rs +++ b/actix-web/src/response/builder.rs @@ -1,6 +1,5 @@ use std::{ cell::{Ref, RefMut}, - convert::TryInto, future::Future, pin::Pin, task::{Context, Poll}, diff --git a/actix-web/src/rmap.rs b/actix-web/src/rmap.rs index 6e10717c3..8a2ec3297 100644 --- a/actix-web/src/rmap.rs +++ b/actix-web/src/rmap.rs @@ -136,7 +136,7 @@ impl ResourceMap { .root_rmap_fn(String::with_capacity(AVG_PATH_LEN), |mut acc, node| { node.pattern .resource_path_from_iter(&mut acc, &mut elements) - .then(|| acc) + .then_some(acc) }) .ok_or(UrlGenerationError::NotEnoughElements)?; @@ -149,7 +149,7 @@ impl ResourceMap { // external resource; third slash would be the root slash in the path let third_slash_index = path .char_indices() - .filter_map(|(i, c)| (c == '/').then(|| i)) + .filter_map(|(i, c)| (c == '/').then_some(i)) .nth(2) .unwrap_or(path.len()); diff --git a/actix-web/src/test/test_utils.rs b/actix-web/src/test/test_utils.rs index b985c3b36..bba23a0fe 100644 --- a/actix-web/src/test/test_utils.rs +++ b/actix-web/src/test/test_utils.rs @@ -359,7 +359,6 @@ where #[cfg(test)] mod tests { - use serde::{Deserialize, Serialize}; use super::*; diff --git a/awc/CHANGES.md b/awc/CHANGES.md index 03cbf61d4..f5bddd04d 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased - 2023-xx-xx +- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. + ## 3.1.1 - 2023-02-26 ### Changed diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 8edc90fd1..9a23e4baf 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -13,7 +13,7 @@ categories = [ homepage = "https://actix.rs" repository = "https://github.com/actix/actix-web.git" license = "MIT OR Apache-2.0" -edition = "2018" +edition = "2021" [lib] name = "awc" @@ -83,8 +83,8 @@ tokio = { version = "1.24.2", features = ["sync"] } 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"] } +tls-openssl = { package = "openssl", version = "0.10.55", optional = true } +tls-rustls = { package = "rustls", version = "0.20", optional = true, features = ["dangerous_configuration"] } trust-dns-resolver = { version = "0.22", optional = true } @@ -98,12 +98,12 @@ actix-utils = "3" actix-web = { version = "4", features = ["openssl"] } brotli = "3.3.3" -const-str = "0.3" -env_logger = "0.9" +const-str = "0.5" +env_logger = "0.10" flate2 = "1.0.13" futures-util = { version = "0.3.17", default-features = false } static_assertions = "1.1" -rcgen = "0.9" +rcgen = "0.11" rustls-pemfile = "1" tokio = { version = "1.24.2", features = ["rt-multi-thread", "macros"] } zstd = "0.12" diff --git a/awc/README.md b/awc/README.md index a9d411067..1a480df12 100644 --- a/awc/README.md +++ b/awc/README.md @@ -12,7 +12,7 @@ - [API Documentation](https://docs.rs/awc) - [Example Project](https://github.com/actix/examples/tree/master/https-tls/awc-https) -- Minimum Supported Rust Version (MSRV): 1.59 +- Minimum Supported Rust Version (MSRV): 1.65 ## Example diff --git a/awc/src/builder.rs b/awc/src/builder.rs index 79838a3f6..b15e2de0b 100644 --- a/awc/src/builder.rs +++ b/awc/src/builder.rs @@ -1,4 +1,4 @@ -use std::{convert::TryFrom, fmt, net::IpAddr, rc::Rc, time::Duration}; +use std::{fmt, net::IpAddr, rc::Rc, time::Duration}; use base64::prelude::*; diff --git a/awc/src/client/mod.rs b/awc/src/client/mod.rs index e898d2d04..b1df1fd3d 100644 --- a/awc/src/client/mod.rs +++ b/awc/src/client/mod.rs @@ -1,6 +1,6 @@ //! HTTP client. -use std::{convert::TryFrom, rc::Rc, time::Duration}; +use std::{rc::Rc, time::Duration}; use actix_http::{error::HttpError, header::HeaderMap, Method, RequestHead, Uri}; use actix_rt::net::TcpStream; diff --git a/awc/src/middleware/redirect.rs b/awc/src/middleware/redirect.rs index 67ef5d76f..d1216fa57 100644 --- a/awc/src/middleware/redirect.rs +++ b/awc/src/middleware/redirect.rs @@ -1,5 +1,4 @@ use std::{ - convert::TryFrom, future::Future, net::SocketAddr, pin::Pin, diff --git a/awc/src/request.rs b/awc/src/request.rs index d3a4eda8c..5e04aa8de 100644 --- a/awc/src/request.rs +++ b/awc/src/request.rs @@ -1,4 +1,4 @@ -use std::{convert::TryFrom, fmt, net, rc::Rc, time::Duration}; +use std::{fmt, net, rc::Rc, time::Duration}; use base64::prelude::*; use bytes::Bytes; diff --git a/awc/src/ws.rs b/awc/src/ws.rs index 406368e62..67fcd2429 100644 --- a/awc/src/ws.rs +++ b/awc/src/ws.rs @@ -26,7 +26,7 @@ //! } //! ``` -use std::{convert::TryFrom, fmt, net::SocketAddr, str}; +use std::{fmt, net::SocketAddr, str}; use base64::prelude::*; diff --git a/clippy.toml b/clippy.toml index abe19b3a0..04371125d 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1 +1 @@ -msrv = "1.59" +msrv = "1.65" From 4eeb01415c05e6136ae0f17ac7f45160c907ad68 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sun, 2 Jul 2023 06:06:06 +0530 Subject: [PATCH 04/57] Fix failing test on Windows (#3037) --- actix-files/src/files.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/actix-files/src/files.rs b/actix-files/src/files.rs index be2a450d2..4a259d233 100644 --- a/actix-files/src/files.rs +++ b/actix-files/src/files.rs @@ -422,10 +422,14 @@ mod tests { assert_eq!(res.status(), StatusCode::OK); let body = test::read_body(res).await; + let body_str = std::str::from_utf8(&body).unwrap(); + let actual_path = Path::new(&body_str); + let expected_path = Path::new("actix-files/tests"); assert!( - body.ends_with(b"actix-files/tests/"), - "body {:?} does not end with `actix-files/tests/`", - body + actual_path.ends_with(expected_path), + "body {:?} does not end with {:?}", + actual_path, + expected_path ); } } From 0e8ed50e3a7ac93d94e6c1c6603d0048e1f33fb8 Mon Sep 17 00:00:00 2001 From: Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> Date: Sun, 2 Jul 2023 06:26:12 +0530 Subject: [PATCH 05/57] align awc's h2 version (#3051) Co-authored-by: Rob Ede --- awc/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 9a23e4baf..daec84ab9 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -68,7 +68,7 @@ cfg-if = "1" derive_more = "0.99.5" 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" +h2 = "0.3.17" http = "0.2.7" itoa = "1" log =" 0.4" From ce3af777a05e6be2673290417b25f714e6e25830 Mon Sep 17 00:00:00 2001 From: mitsubosh <8204936+MITSUBOSHI@users.noreply.github.com> Date: Thu, 6 Jul 2023 01:29:10 +0900 Subject: [PATCH 06/57] Fix typo (#3062) --- actix-http/src/http_message.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-http/src/http_message.rs b/actix-http/src/http_message.rs index 198254e02..20becc310 100644 --- a/actix-http/src/http_message.rs +++ b/actix-http/src/http_message.rs @@ -146,7 +146,7 @@ mod tests { .finish(); assert_eq!(req.content_type(), "text/plain"); let req = TestRequest::default() - .insert_header(("content-type", "application/json; charset=utf=8")) + .insert_header(("content-type", "application/json; charset=utf-8")) .finish(); assert_eq!(req.content_type(), "application/json"); let req = TestRequest::default().finish(); From c34a18f64a0d452ea36fcc20d92f106d564be5a0 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 17 Jul 2023 01:47:26 +0100 Subject: [PATCH 07/57] changelog file is optional in bump script --- scripts/bump | 58 ++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/scripts/bump b/scripts/bump index 40d43d429..b09d9d196 100755 --- a/scripts/bump +++ b/scripts/bump @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # developed on macOS and probably doesn't work on Linux yet due to minor # differences in flags on sed @@ -21,12 +21,9 @@ README_FILE=$DIR/README.md # determine changelog file name if [ -f "$DIR/CHANGES.md" ]; then - CHANGELOG_FILE=$DIR/CHANGES.md + CHANGELOG_FILE="$DIR/CHANGES.md" elif [ -f "$DIR/CHANGELOG.md" ]; then - CHANGELOG_FILE=$DIR/CHANGELOG.md -else - echo "No changelog file found" - exit 1 + CHANGELOG_FILE="$DIR/CHANGELOG.md" fi # get current version @@ -37,15 +34,17 @@ CHANGE_CHUNK_FILE="$(mktemp)" echo saving changelog to $CHANGE_CHUNK_FILE echo -# get changelog chunk and save to temp file -cat "$CHANGELOG_FILE" | - # skip up to unreleased heading - sed '1,/Unreleased/ d' | - # take up to previous version heading - sed "/$CURRENT_VERSION/ q" | - # drop last line - sed '$d' \ - >"$CHANGE_CHUNK_FILE" +if [ -n "${CHANGELOG_FILE-}" ]; then + # get changelog chunk and save to temp file + cat "$CHANGELOG_FILE" | + # skip up to unreleased heading + sed '1,/Unreleased/ d' | + # take up to previous version heading + sed "/$CURRENT_VERSION/ q" | + # drop last line + sed '$d' \ + >"$CHANGE_CHUNK_FILE" +fi # if word count of changelog chunk is 0 then insert filler changelog chunk if [ "$(wc -w "$CHANGE_CHUNK_FILE" | awk '{ print $1 }')" = "0" ]; then @@ -68,8 +67,7 @@ if [ "${NEW_VERSION:0:1}" = "v" ]; then NEW_VERSION="${NEW_VERSION:1}" fi -DATE="$(date -u +"%Y-%m-%d")" -echo "updating from $CURRENT_VERSION => $NEW_VERSION ($DATE)" +echo "updating from $CURRENT_VERSION => $NEW_VERSION" # update package.version field sed -i.bak -E "s/^version ?= ?\"[^\"]+\"$/version = \"$NEW_VERSION\"/" "$CARGO_MANIFEST" @@ -77,19 +75,21 @@ sed -i.bak -E "s/^version ?= ?\"[^\"]+\"$/version = \"$NEW_VERSION\"/" "$CARGO_M # update readme [ -f "$README_FILE" ] && sed -i.bak -E "s#$CURRENT_VERSION([/)])#$NEW_VERSION\1#g" "$README_FILE" -# update changelog file -( - sed '/Unreleased/ q' "$CHANGELOG_FILE" # up to unreleased heading - echo # blank line - echo "## $NEW_VERSION - $DATE" # new version heading - cat "$CHANGE_CHUNK_FILE" # previously unreleased changes - sed "/$CURRENT_VERSION/ q" "$CHANGELOG_FILE" | tail -n 1 # the previous version heading - sed "1,/$CURRENT_VERSION/ d" "$CHANGELOG_FILE" # everything after previous version heading -) >"$CHANGELOG_FILE.bak" -mv "$CHANGELOG_FILE.bak" "$CHANGELOG_FILE" +if [ -n "${CHANGELOG_FILE-}" ]; then + # update changelog file + ( + sed '/Unreleased/ q' "$CHANGELOG_FILE" # up to unreleased heading + echo # blank line + echo "## $NEW_VERSION" # new version heading + cat "$CHANGE_CHUNK_FILE" # previously unreleased changes + sed "/$CURRENT_VERSION/ q" "$CHANGELOG_FILE" | tail -n 1 # the previous version heading + sed "1,/$CURRENT_VERSION/ d" "$CHANGELOG_FILE" # everything after previous version heading + ) >"$CHANGELOG_FILE.bak" + mv "$CHANGELOG_FILE.bak" "$CHANGELOG_FILE" -# format CHANGELOG file according to prettier -npx -y prettier --write "$CHANGELOG_FILE" || true + # format CHANGELOG file according to prettier + npx -y prettier --write "$CHANGELOG_FILE" || true +fi # done; remove backup files rm -f $CARGO_MANIFEST.bak From e4e839f4d1cb53b201d9c9cc4c188cfa5701e527 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 17 Jul 2023 01:51:10 +0100 Subject: [PATCH 08/57] only enable actix-http's http2 feature when TLS features are enabled closes #3071 --- actix-web/Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index 0091175be..79ad005c2 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -47,10 +47,10 @@ cookies = ["cookie"] secure-cookies = ["cookies", "cookie/secure"] # TLS via OpenSSL -openssl = ["actix-http/openssl", "actix-tls/accept", "actix-tls/openssl"] +openssl = ["actix-http/http2", "actix-http/openssl", "actix-tls/accept", "actix-tls/openssl"] # TLS via Rustls -rustls = ["actix-http/rustls", "actix-tls/accept", "actix-tls/rustls"] +rustls = ["actix-http/http2", "actix-http/rustls", "actix-tls/accept", "actix-tls/rustls"] # Internal (PRIVATE!) features used to aid testing and checking feature status. # Don't rely on these whatsoever. They may disappear at anytime. @@ -68,7 +68,7 @@ actix-service = "2" actix-utils = "3" actix-tls = { version = "3", default-features = false, optional = true } -actix-http = { version = "3.3", features = ["http2", "ws"] } +actix-http = { version = "3.3", features = ["ws"] } actix-router = "0.5" actix-web-codegen = { version = "4.2", optional = true } From 60c76c5e10a016953bd2552b8e069e9cc902f2d2 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 17 Jul 2023 02:19:26 +0100 Subject: [PATCH 09/57] revert http2 feature flag change --- rustfmt.toml => .rustfmt.toml | 0 actix-web/Cargo.toml | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) rename rustfmt.toml => .rustfmt.toml (100%) diff --git a/rustfmt.toml b/.rustfmt.toml similarity index 100% rename from rustfmt.toml rename to .rustfmt.toml diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index 79ad005c2..0091175be 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -47,10 +47,10 @@ cookies = ["cookie"] secure-cookies = ["cookies", "cookie/secure"] # TLS via OpenSSL -openssl = ["actix-http/http2", "actix-http/openssl", "actix-tls/accept", "actix-tls/openssl"] +openssl = ["actix-http/openssl", "actix-tls/accept", "actix-tls/openssl"] # TLS via Rustls -rustls = ["actix-http/http2", "actix-http/rustls", "actix-tls/accept", "actix-tls/rustls"] +rustls = ["actix-http/rustls", "actix-tls/accept", "actix-tls/rustls"] # Internal (PRIVATE!) features used to aid testing and checking feature status. # Don't rely on these whatsoever. They may disappear at anytime. @@ -68,7 +68,7 @@ actix-service = "2" actix-utils = "3" actix-tls = { version = "3", default-features = false, optional = true } -actix-http = { version = "3.3", features = ["ws"] } +actix-http = { version = "3.3", features = ["http2", "ws"] } actix-router = "0.5" actix-web-codegen = { version = "4.2", optional = true } From 79a38e0628b2bf0d3261594eee82d7e6180a27bc Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 17 Jul 2023 02:38:12 +0100 Subject: [PATCH 10/57] apply standard formatting --- .rustfmt.toml | 5 +- actix-files/src/chunked.rs | 5 +- actix-files/src/directory.rs | 7 +- actix-files/src/files.rs | 11 +-- actix-files/src/lib.rs | 35 +++++----- actix-files/src/named.rs | 12 ++-- actix-files/src/range.rs | 4 +- actix-files/src/service.rs | 21 ++---- actix-files/tests/encoding.rs | 3 +- actix-files/tests/guard.rs | 4 +- actix-files/tests/traversal.rs | 3 +- actix-http/examples/hello-world.rs | 5 +- actix-http/src/body/boxed.rs | 8 +-- actix-http/src/body/mod.rs | 18 ++--- actix-http/src/config.rs | 6 +- actix-http/src/encoding/decoder.rs | 10 ++- actix-http/src/encoding/encoder.rs | 6 +- actix-http/src/encoding/mod.rs | 3 +- actix-http/src/error.rs | 3 +- actix-http/src/h1/codec.rs | 4 +- actix-http/src/h1/decoder.rs | 14 ++-- actix-http/src/h1/dispatcher.rs | 51 ++++---------- actix-http/src/h1/dispatcher_tests.rs | 21 +++--- actix-http/src/h1/mod.rs | 18 ++--- actix-http/src/h1/service.rs | 16 ++--- actix-http/src/h2/mod.rs | 8 +-- actix-http/src/h2/service.rs | 3 +- actix-http/src/header/map.rs | 4 +- actix-http/src/header/mod.rs | 50 ++++++------- actix-http/src/header/shared/mod.rs | 17 +++-- actix-http/src/header/shared/quality_item.rs | 3 +- actix-http/src/http_message.rs | 4 +- actix-http/src/lib.rs | 31 ++++---- actix-http/src/requests/mod.rs | 6 +- actix-http/src/requests/request.rs | 3 +- actix-http/src/responses/mod.rs | 4 +- actix-http/src/service.rs | 28 ++------ actix-http/src/ws/dispatcher.rs | 9 +-- actix-http/src/ws/frame.rs | 3 +- actix-http/src/ws/mod.rs | 17 +++-- actix-http/tests/test_openssl.rs | 3 +- actix-http/tests/test_rustls.rs | 8 +-- actix-http/tests/test_server.rs | 11 ++- actix-multipart/src/form/bytes.rs | 6 +- actix-multipart/src/form/json.rs | 3 +- actix-multipart/src/form/mod.rs | 16 ++--- actix-multipart/src/form/tempfile.rs | 33 ++++----- actix-multipart/src/lib.rs | 6 +- actix-multipart/src/server.rs | 18 ++--- actix-router/benches/quoter.rs | 4 +- actix-router/src/de.rs | 28 ++++---- actix-router/src/lib.rs | 17 ++--- actix-router/src/path.rs | 6 +- actix-router/src/resource.rs | 4 +- actix-router/src/router.rs | 12 ++-- actix-router/src/url.rs | 4 +- actix-test/src/lib.rs | 67 ++++++------------ actix-web-actors/src/context.rs | 22 +++--- actix-web-actors/src/ws.rs | 27 ++++--- actix-web-codegen/src/lib.rs | 62 ++++++++-------- actix-web-codegen/src/route.rs | 39 ++++++----- actix-web/benches/responder.rs | 3 +- actix-web/benches/service.rs | 15 ++-- actix-web/examples/on-connect.rs | 7 +- actix-web/src/app.rs | 8 +-- actix-web/src/app_service.rs | 12 ++-- actix-web/src/config.rs | 16 ++--- actix-web/src/data.rs | 27 +++---- actix-web/src/dev.rs | 21 +++--- actix-web/src/error/macros.rs | 9 ++- actix-web/src/error/mod.rs | 14 ++-- actix-web/src/extract.rs | 6 +- actix-web/src/guard/mod.rs | 6 +- actix-web/src/http/header/accept_encoding.rs | 9 +-- .../src/http/header/content_disposition.rs | 27 +++---- actix-web/src/http/header/content_range.rs | 3 +- actix-web/src/http/header/content_type.rs | 3 +- actix-web/src/http/header/date.rs | 3 +- actix-web/src/http/header/entity.rs | 4 +- actix-web/src/http/header/if_range.rs | 4 +- actix-web/src/http/header/macros.rs | 4 +- actix-web/src/http/header/mod.rs | 56 +++++++-------- actix-web/src/lib.rs | 35 +++++----- actix-web/src/middleware/compat.rs | 9 ++- actix-web/src/middleware/err_handlers.rs | 30 +++----- actix-web/src/middleware/logger.rs | 12 +--- actix-web/src/middleware/mod.rs | 17 ++--- actix-web/src/redirect.rs | 3 +- actix-web/src/request.rs | 13 ++-- actix-web/src/resource.rs | 46 +++++------- actix-web/src/response/builder.rs | 11 +-- actix-web/src/response/customize_responder.rs | 7 +- actix-web/src/response/http_codes.rs | 3 +- actix-web/src/response/mod.rs | 9 ++- actix-web/src/response/responder.rs | 3 +- actix-web/src/response/response.rs | 1 - actix-web/src/route.rs | 51 +++++++------- actix-web/src/rt.rs | 3 +- actix-web/src/scope.rs | 70 +++++++++---------- actix-web/src/server.rs | 24 +++---- actix-web/src/service.rs | 65 +++++++++-------- actix-web/src/test/mod.rs | 18 ++--- actix-web/src/test/test_request.rs | 14 ++-- actix-web/src/test/test_utils.rs | 69 +++++++++--------- actix-web/src/types/either.rs | 34 ++++----- actix-web/src/types/form.rs | 8 +-- actix-web/src/types/header.rs | 6 +- actix-web/src/types/json.rs | 18 ++--- actix-web/src/types/mod.rs | 18 ++--- actix-web/src/types/path.rs | 6 +- actix-web/src/types/payload.rs | 11 +-- actix-web/src/web.rs | 14 ++-- actix-web/tests/test_server.rs | 34 ++++----- actix-web/tests/utils.rs | 12 ++-- awc/src/any_body.rs | 3 +- awc/src/builder.rs | 21 ++---- awc/src/client/connection.rs | 13 +--- awc/src/client/connector.rs | 25 ++----- awc/src/client/error.rs | 4 +- awc/src/client/h1proto.rs | 3 +- awc/src/client/h2proto.rs | 25 +++---- awc/src/client/mod.rs | 8 ++- awc/src/client/pool.rs | 16 +++-- awc/src/connect.rs | 16 ++--- awc/src/error.rs | 1 - awc/src/frozen.rs | 7 +- awc/src/lib.rs | 19 +++-- awc/src/middleware/mod.rs | 4 +- awc/src/middleware/redirect.rs | 8 +-- awc/src/request.rs | 19 ++--- awc/src/responses/mod.rs | 3 +- awc/src/responses/response.rs | 7 +- awc/src/sender.rs | 13 ++-- awc/src/ws.rs | 11 ++- awc/tests/test_client.rs | 36 ++++------ awc/tests/test_connector.rs | 3 +- awc/tests/test_ssl_client.rs | 9 +-- awc/tests/utils.rs | 12 ++-- 138 files changed, 916 insertions(+), 1180 deletions(-) diff --git a/.rustfmt.toml b/.rustfmt.toml index 973e002c0..71b9be3ae 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1,2 +1,3 @@ -max_width = 96 -reorder_imports = true +group_imports = "StdExternalCrate" +imports_granularity = "Crate" +use_field_init_shorthand = true diff --git a/actix-files/src/chunked.rs b/actix-files/src/chunked.rs index 241b4dccb..c6c019038 100644 --- a/actix-files/src/chunked.rs +++ b/actix-files/src/chunked.rs @@ -7,11 +7,10 @@ use std::{ }; use actix_web::{error::Error, web::Bytes}; -use futures_core::{ready, Stream}; -use pin_project_lite::pin_project; - #[cfg(feature = "experimental-io-uring")] use bytes::BytesMut; +use futures_core::{ready, Stream}; +use pin_project_lite::pin_project; use super::named::File; diff --git a/actix-files/src/directory.rs b/actix-files/src/directory.rs index 3af53a31a..6ade424b9 100644 --- a/actix-files/src/directory.rs +++ b/actix-files/src/directory.rs @@ -1,4 +1,9 @@ -use std::{fmt::Write, fs::DirEntry, io, path::Path, path::PathBuf}; +use std::{ + fmt::Write, + fs::DirEntry, + io, + path::{Path, PathBuf}, +}; use actix_web::{dev::ServiceResponse, HttpRequest, HttpResponse}; use percent_encoding::{utf8_percent_encode, CONTROLS}; diff --git a/actix-files/src/files.rs b/actix-files/src/files.rs index 4a259d233..e34b5f26a 100644 --- a/actix-files/src/files.rs +++ b/actix-files/src/files.rs @@ -8,8 +8,7 @@ use std::{ use actix_service::{boxed, IntoServiceFactory, ServiceFactory, ServiceFactoryExt}; use actix_web::{ dev::{ - AppService, HttpServiceFactory, RequestHead, ResourceDef, ServiceRequest, - ServiceResponse, + AppService, HttpServiceFactory, RequestHead, ResourceDef, ServiceRequest, ServiceResponse, }, error::Error, guard::Guard, @@ -301,12 +300,8 @@ impl Files { pub fn default_handler(mut self, f: F) -> Self where F: IntoServiceFactory, - U: ServiceFactory< - ServiceRequest, - Config = (), - Response = ServiceResponse, - Error = Error, - > + 'static, + U: ServiceFactory + + 'static, { // create and configure default resource self.default = Rc::new(RefCell::new(Some(Rc::new(boxed::factory( diff --git a/actix-files/src/lib.rs b/actix-files/src/lib.rs index bed8194c8..1d8609889 100644 --- a/actix-files/src/lib.rs +++ b/actix-files/src/lib.rs @@ -18,6 +18,8 @@ #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] +use std::path::Path; + use actix_service::boxed::{BoxService, BoxServiceFactory}; use actix_web::{ dev::{RequestHead, ServiceRequest, ServiceResponse}, @@ -25,7 +27,6 @@ use actix_web::{ http::header::DispositionType, }; use mime_guess::from_ext; -use std::path::Path; mod chunked; mod directory; @@ -37,16 +38,15 @@ mod path_buf; mod range; mod service; -pub use self::chunked::ChunkedReadFile; -pub use self::directory::Directory; -pub use self::files::Files; -pub use self::named::NamedFile; -pub use self::range::HttpRange; -pub use self::service::FilesService; - -use self::directory::{directory_listing, DirectoryRenderer}; -use self::error::FilesError; -use self::path_buf::PathBufWrap; +pub use self::{ + chunked::ChunkedReadFile, directory::Directory, files::Files, named::NamedFile, + range::HttpRange, service::FilesService, +}; +use self::{ + directory::{directory_listing, DirectoryRenderer}, + error::FilesError, + path_buf::PathBufWrap, +}; type HttpService = BoxService; type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>; @@ -554,10 +554,9 @@ mod tests { #[actix_rt::test] async fn test_static_files_with_spaces() { - let srv = test::init_service( - App::new().service(Files::new("/", ".").index_file("Cargo.toml")), - ) - .await; + let srv = + test::init_service(App::new().service(Files::new("/", ".").index_file("Cargo.toml"))) + .await; let request = TestRequest::get() .uri("/tests/test%20space.binary") .to_request(); @@ -667,8 +666,7 @@ mod tests { #[actix_rt::test] async fn test_static_files() { let srv = - test::init_service(App::new().service(Files::new("/", ".").show_files_listing())) - .await; + test::init_service(App::new().service(Files::new("/", ".").show_files_listing())).await; let req = TestRequest::with_uri("/missing").to_request(); let resp = test::call_service(&srv, req).await; @@ -681,8 +679,7 @@ mod tests { assert_eq!(resp.status(), StatusCode::NOT_FOUND); let srv = - test::init_service(App::new().service(Files::new("/", ".").show_files_listing())) - .await; + test::init_service(App::new().service(Files::new("/", ".").show_files_listing())).await; let req = TestRequest::with_uri("/tests").to_request(); let resp = test::call_service(&srv, req).await; assert_eq!( diff --git a/actix-files/src/named.rs b/actix-files/src/named.rs index c10bc00ed..d7795ba73 100644 --- a/actix-files/src/named.rs +++ b/actix-files/src/named.rs @@ -8,13 +8,13 @@ use std::{ use actix_web::{ body::{self, BoxBody, SizedStream}, dev::{ - self, AppService, HttpServiceFactory, ResourceDef, Service, ServiceFactory, - ServiceRequest, ServiceResponse, + self, AppService, HttpServiceFactory, ResourceDef, Service, ServiceFactory, ServiceRequest, + ServiceResponse, }, http::{ header::{ - self, Charset, ContentDisposition, ContentEncoding, DispositionParam, - DispositionType, ExtendedValue, HeaderValue, + self, Charset, ContentDisposition, ContentEncoding, DispositionParam, DispositionType, + ExtendedValue, HeaderValue, }, StatusCode, }, @@ -85,6 +85,7 @@ pub struct NamedFile { #[cfg(not(feature = "experimental-io-uring"))] pub(crate) use std::fs::File; + #[cfg(feature = "experimental-io-uring")] pub(crate) use tokio_uring::fs::File; @@ -139,8 +140,7 @@ impl NamedFile { _ => DispositionType::Attachment, }; - let mut parameters = - vec![DispositionParam::Filename(String::from(filename.as_ref()))]; + let mut parameters = vec![DispositionParam::Filename(String::from(filename.as_ref()))]; if !filename.is_ascii() { parameters.push(DispositionParam::FilenameExt(ExtendedValue { diff --git a/actix-files/src/range.rs b/actix-files/src/range.rs index 65c680ede..528911ae0 100644 --- a/actix-files/src/range.rs +++ b/actix-files/src/range.rs @@ -48,8 +48,8 @@ impl HttpRange { /// `header` is HTTP Range header (e.g. `bytes=bytes=0-9`). /// `size` is full size of response (file). pub fn parse(header: &str, size: u64) -> Result, ParseRangeErr> { - let ranges = http_range::HttpRange::parse(header, size) - .map_err(|err| ParseRangeErr(err.into()))?; + let ranges = + http_range::HttpRange::parse(header, size).map_err(|err| ParseRangeErr(err.into()))?; Ok(ranges .iter() diff --git a/actix-files/src/service.rs b/actix-files/src/service.rs index d94fd5850..3d3b36c40 100644 --- a/actix-files/src/service.rs +++ b/actix-files/src/service.rs @@ -62,11 +62,7 @@ impl FilesService { } } - fn serve_named_file( - &self, - req: ServiceRequest, - mut named_file: NamedFile, - ) -> ServiceResponse { + fn serve_named_file(&self, req: ServiceRequest, mut named_file: NamedFile) -> ServiceResponse { if let Some(ref mime_override) = self.mime_override { let new_disposition = mime_override(&named_file.content_type.type_()); named_file.content_disposition.disposition = new_disposition; @@ -120,13 +116,11 @@ impl Service for FilesService { )); } - let path_on_disk = match PathBufWrap::parse_path( - req.match_info().unprocessed(), - this.hidden_files, - ) { - Ok(item) => item, - Err(err) => return Ok(req.error_response(err)), - }; + let path_on_disk = + match PathBufWrap::parse_path(req.match_info().unprocessed(), this.hidden_files) { + Ok(item) => item, + Err(err) => return Ok(req.error_response(err)), + }; if let Some(filter) = &this.path_filter { if !filter(path_on_disk.as_ref(), req.head()) { @@ -177,8 +171,7 @@ impl Service for FilesService { match NamedFile::open_async(&path).await { Ok(mut named_file) => { if let Some(ref mime_override) = this.mime_override { - let new_disposition = - mime_override(&named_file.content_type.type_()); + let new_disposition = mime_override(&named_file.content_type.type_()); named_file.content_disposition.disposition = new_disposition; } named_file.flags = this.file_flags; diff --git a/actix-files/tests/encoding.rs b/actix-files/tests/encoding.rs index 7aec25ff9..3c8bdb59b 100644 --- a/actix-files/tests/encoding.rs +++ b/actix-files/tests/encoding.rs @@ -24,8 +24,7 @@ async fn test_utf8_file_contents() { // disable UTF-8 attribute let srv = - test::init_service(App::new().service(Files::new("/", "./tests").prefer_utf8(false))) - .await; + test::init_service(App::new().service(Files::new("/", "./tests").prefer_utf8(false))).await; let req = TestRequest::with_uri("/utf8.txt").to_request(); let res = test::call_service(&srv, req).await; diff --git a/actix-files/tests/guard.rs b/actix-files/tests/guard.rs index d053f3fdc..5a97f75d6 100644 --- a/actix-files/tests/guard.rs +++ b/actix-files/tests/guard.rs @@ -12,9 +12,7 @@ async fn test_guard_filter() { let srv = test::init_service( App::new() .service(Files::new("/", "./tests/fixtures/guards/first").guard(Host("first.com"))) - .service( - Files::new("/", "./tests/fixtures/guards/second").guard(Host("second.com")), - ), + .service(Files::new("/", "./tests/fixtures/guards/second").guard(Host("second.com"))), ) .await; diff --git a/actix-files/tests/traversal.rs b/actix-files/tests/traversal.rs index c890b3fe4..4eecb8dde 100644 --- a/actix-files/tests/traversal.rs +++ b/actix-files/tests/traversal.rs @@ -9,8 +9,7 @@ use actix_web::{ async fn test_directory_traversal_prevention() { let srv = test::init_service(App::new().service(Files::new("/", "./tests"))).await; - let req = - TestRequest::with_uri("/../../../../../../../../../../../etc/passwd").to_request(); + let req = TestRequest::with_uri("/../../../../../../../../../../../etc/passwd").to_request(); let res = test::call_service(&srv, req).await; assert_eq!(res.status(), StatusCode::NOT_FOUND); diff --git a/actix-http/examples/hello-world.rs b/actix-http/examples/hello-world.rs index c749cdd00..cf10beddf 100644 --- a/actix-http/examples/hello-world.rs +++ b/actix-http/examples/hello-world.rs @@ -23,10 +23,7 @@ async fn main() -> io::Result<()> { res.insert_header(("x-head", HeaderValue::from_static("dummy value!"))); let forty_two = req.conn_data::().unwrap().to_string(); - res.insert_header(( - "x-forty-two", - HeaderValue::from_str(&forty_two).unwrap(), - )); + res.insert_header(("x-forty-two", HeaderValue::from_str(&forty_two).unwrap())); Ok::<_, Infallible>(res.body("Hello world!")) }) diff --git a/actix-http/src/body/boxed.rs b/actix-http/src/body/boxed.rs index 2bbb75369..0151ff3a5 100644 --- a/actix-http/src/body/boxed.rs +++ b/actix-http/src/body/boxed.rs @@ -77,12 +77,8 @@ impl MessageBody for BoxBody { cx: &mut Context<'_>, ) -> Poll>> { match &mut self.0 { - BoxBodyInner::None(body) => { - Pin::new(body).poll_next(cx).map_err(|err| match err {}) - } - BoxBodyInner::Bytes(body) => { - Pin::new(body).poll_next(cx).map_err(|err| match err {}) - } + BoxBodyInner::None(body) => Pin::new(body).poll_next(cx).map_err(|err| match err {}), + BoxBodyInner::Bytes(body) => Pin::new(body).poll_next(cx).map_err(|err| match err {}), BoxBodyInner::Stream(body) => Pin::new(body).poll_next(cx), } } diff --git a/actix-http/src/body/mod.rs b/actix-http/src/body/mod.rs index d1708b9d5..1a12f3336 100644 --- a/actix-http/src/body/mod.rs +++ b/actix-http/src/body/mod.rs @@ -14,12 +14,14 @@ mod size; mod sized_stream; mod utils; -pub use self::body_stream::BodyStream; -pub use self::boxed::BoxBody; -pub use self::either::EitherBody; -pub use self::message_body::MessageBody; pub(crate) use self::message_body::MessageBodyMapErr; -pub use self::none::None; -pub use self::size::BodySize; -pub use self::sized_stream::SizedStream; -pub use self::utils::{to_bytes, to_bytes_limited, BodyLimitExceeded}; +pub use self::{ + body_stream::BodyStream, + boxed::BoxBody, + either::EitherBody, + message_body::MessageBody, + none::None, + size::BodySize, + sized_stream::SizedStream, + utils::{to_bytes, to_bytes_limited, BodyLimitExceeded}, +}; diff --git a/actix-http/src/config.rs b/actix-http/src/config.rs index c0d297a20..b3b215da4 100644 --- a/actix-http/src/config.rs +++ b/actix-http/src/config.rs @@ -132,15 +132,15 @@ impl ServiceConfig { #[cfg(test)] mod tests { - use super::*; - use crate::{date::DATE_VALUE_LENGTH, notify_on_drop}; - use actix_rt::{ task::yield_now, time::{sleep, sleep_until}, }; use memchr::memmem; + use super::*; + use crate::{date::DATE_VALUE_LENGTH, notify_on_drop}; + #[actix_rt::test] async fn test_date_service_update() { let settings = diff --git a/actix-http/src/encoding/decoder.rs b/actix-http/src/encoding/decoder.rs index 06b672fd8..e9aba25e7 100644 --- a/actix-http/src/encoding/decoder.rs +++ b/actix-http/src/encoding/decoder.rs @@ -9,11 +9,9 @@ use std::{ use actix_rt::task::{spawn_blocking, JoinHandle}; use bytes::Bytes; -use futures_core::{ready, Stream}; - #[cfg(feature = "compress-gzip")] use flate2::write::{GzDecoder, ZlibDecoder}; - +use futures_core::{ready, Stream}; #[cfg(feature = "compress-zstd")] use zstd::stream::write::Decoder as ZstdDecoder; @@ -49,9 +47,9 @@ where ))), #[cfg(feature = "compress-gzip")] - ContentEncoding::Deflate => Some(ContentDecoder::Deflate(Box::new( - ZlibDecoder::new(Writer::new()), - ))), + ContentEncoding::Deflate => Some(ContentDecoder::Deflate(Box::new(ZlibDecoder::new( + Writer::new(), + )))), #[cfg(feature = "compress-gzip")] ContentEncoding::Gzip => Some(ContentDecoder::Gzip(Box::new(GzDecoder::new( diff --git a/actix-http/src/encoding/encoder.rs b/actix-http/src/encoding/encoder.rs index bbe53e8e8..527bfebaa 100644 --- a/actix-http/src/encoding/encoder.rs +++ b/actix-http/src/encoding/encoder.rs @@ -11,12 +11,10 @@ use std::{ use actix_rt::task::{spawn_blocking, JoinHandle}; use bytes::Bytes; use derive_more::Display; -use futures_core::ready; -use pin_project_lite::pin_project; - #[cfg(feature = "compress-gzip")] use flate2::write::{GzEncoder, ZlibEncoder}; - +use futures_core::ready; +use pin_project_lite::pin_project; use tracing::trace; #[cfg(feature = "compress-zstd")] use zstd::stream::write::Encoder as ZstdEncoder; diff --git a/actix-http/src/encoding/mod.rs b/actix-http/src/encoding/mod.rs index d51dd66c0..7823f3979 100644 --- a/actix-http/src/encoding/mod.rs +++ b/actix-http/src/encoding/mod.rs @@ -7,8 +7,7 @@ use bytes::{Bytes, BytesMut}; mod decoder; mod encoder; -pub use self::decoder::Decoder; -pub use self::encoder::Encoder; +pub use self::{decoder::Decoder, encoder::Encoder}; /// Special-purpose writer for streaming (de-)compression. /// diff --git a/actix-http/src/error.rs b/actix-http/src/error.rs index fa0228a50..fbd2eb7ae 100644 --- a/actix-http/src/error.rs +++ b/actix-http/src/error.rs @@ -3,12 +3,11 @@ use std::{error::Error as StdError, fmt, io, str::Utf8Error, string::FromUtf8Error}; use derive_more::{Display, Error, From}; +pub use http::Error as HttpError; use http::{uri::InvalidUri, StatusCode}; use crate::{body::BoxBody, Response}; -pub use http::Error as HttpError; - pub struct Error { inner: Box, } diff --git a/actix-http/src/h1/codec.rs b/actix-http/src/h1/codec.rs index e1b629146..8dae2e43e 100644 --- a/actix-http/src/h1/codec.rs +++ b/actix-http/src/h1/codec.rs @@ -9,9 +9,7 @@ use super::{ decoder::{self, PayloadDecoder, PayloadItem, PayloadType}, encoder, Message, MessageType, }; -use crate::{ - body::BodySize, error::ParseError, ConnectionType, Request, Response, ServiceConfig, -}; +use crate::{body::BodySize, error::ParseError, ConnectionType, Request, Response, ServiceConfig}; bitflags! { #[derive(Debug, Clone, Copy)] diff --git a/actix-http/src/h1/decoder.rs b/actix-http/src/h1/decoder.rs index 829f40e10..9e9b253d6 100644 --- a/actix-http/src/h1/decoder.rs +++ b/actix-http/src/h1/decoder.rs @@ -94,9 +94,7 @@ pub(crate) trait MessageType: Sized { // SAFETY: httparse already checks header value is only visible ASCII bytes // from_maybe_shared_unchecked contains debug assertions so they are omitted here let value = unsafe { - HeaderValue::from_maybe_shared_unchecked( - slice.slice(idx.value.0..idx.value.1), - ) + HeaderValue::from_maybe_shared_unchecked(slice.slice(idx.value.0..idx.value.1)) }; match name { @@ -275,8 +273,7 @@ impl MessageType for Request { let mut msg = Request::new(); // convert headers - let mut length = - msg.set_headers(&src.split_to(len).freeze(), &headers[..h_len], ver)?; + let mut length = msg.set_headers(&src.split_to(len).freeze(), &headers[..h_len], ver)?; // disallow HTTP/1.0 POST requests that do not contain a Content-Length headers // see https://datatracker.ietf.org/doc/html/rfc1945#section-7.2.2 @@ -356,8 +353,8 @@ impl MessageType for ResponseHead { Version::HTTP_10 }; - let status = StatusCode::from_u16(res.code.unwrap()) - .map_err(|_| ParseError::Status)?; + let status = + StatusCode::from_u16(res.code.unwrap()).map_err(|_| ParseError::Status)?; HeaderIndex::record(src, res.headers, &mut headers); (len, version, status, res.headers.len()) @@ -378,8 +375,7 @@ impl MessageType for ResponseHead { msg.version = ver; // convert headers - let mut length = - msg.set_headers(&src.split_to(len).freeze(), &headers[..h_len], ver)?; + let mut length = msg.set_headers(&src.split_to(len).freeze(), &headers[..h_len], ver)?; // Remove CL value if 0 now that all headers and HTTP/1.0 special cases are processed. // Protects against some request smuggling attacks. diff --git a/actix-http/src/h1/dispatcher.rs b/actix-http/src/h1/dispatcher.rs index c2f8ea453..270707807 100644 --- a/actix-http/src/h1/dispatcher.rs +++ b/actix-http/src/h1/dispatcher.rs @@ -19,14 +19,6 @@ use tokio::io::{AsyncRead, AsyncWrite}; use tokio_util::codec::{Decoder as _, Encoder as _}; use tracing::{error, trace}; -use crate::{ - body::{BodySize, BoxBody, MessageBody}, - config::ServiceConfig, - error::{DispatchError, ParseError, PayloadError}, - service::HttpFlow, - Error, Extensions, OnConnectData, Request, Response, StatusCode, -}; - use super::{ codec::Codec, decoder::MAX_BUFFER_SIZE, @@ -34,6 +26,13 @@ use super::{ timer::TimerState, Message, MessageType, }; +use crate::{ + body::{BodySize, BoxBody, MessageBody}, + config::ServiceConfig, + error::{DispatchError, ParseError, PayloadError}, + service::HttpFlow, + Error, Extensions, OnConnectData, Request, Response, StatusCode, +}; const LW_BUFFER_SIZE: usize = 1024; const HW_BUFFER_SIZE: usize = 1024 * 8; @@ -213,9 +212,7 @@ where fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::None => write!(f, "State::None"), - Self::ExpectCall { .. } => { - f.debug_struct("State::ExpectCall").finish_non_exhaustive() - } + Self::ExpectCall { .. } => f.debug_struct("State::ExpectCall").finish_non_exhaustive(), Self::ServiceCall { .. } => { f.debug_struct("State::ServiceCall").finish_non_exhaustive() } @@ -276,9 +273,7 @@ where head_timer: TimerState::new(config.client_request_deadline().is_some()), ka_timer: TimerState::new(config.keep_alive().enabled()), - shutdown_timer: TimerState::new( - config.client_disconnect_deadline().is_some(), - ), + shutdown_timer: TimerState::new(config.client_disconnect_deadline().is_some()), io: Some(io), read_buf: BytesMut::with_capacity(HW_BUFFER_SIZE), @@ -456,9 +451,7 @@ where } // return with upgrade request and poll it exclusively - Some(DispatcherMessage::Upgrade(req)) => { - return Ok(PollResponse::Upgrade(req)) - } + Some(DispatcherMessage::Upgrade(req)) => return Ok(PollResponse::Upgrade(req)), // all messages are dealt with None => { @@ -675,9 +668,7 @@ where } _ => { - unreachable!( - "State must be set to ServiceCall or ExceptCall in handle_request" - ) + unreachable!("State must be set to ServiceCall or ExceptCall in handle_request") } } } @@ -686,10 +677,7 @@ where /// Process one incoming request. /// /// Returns true if any meaningful work was done. - fn poll_request( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Result { + fn poll_request(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result { let pipeline_queue_full = self.messages.len() >= MAX_PIPELINED_MESSAGES; let can_not_read = !self.can_read(cx); @@ -859,10 +847,7 @@ where Ok(()) } - fn poll_ka_timer( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Result<(), DispatchError> { + fn poll_ka_timer(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result<(), DispatchError> { let this = self.as_mut().project(); if let TimerState::Active { timer } = this.ka_timer { debug_assert!( @@ -927,10 +912,7 @@ where } /// Poll head, keep-alive, and disconnect timer. - fn poll_timers( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Result<(), DispatchError> { + fn poll_timers(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result<(), DispatchError> { self.as_mut().poll_head_timer(cx)?; self.as_mut().poll_ka_timer(cx)?; self.as_mut().poll_shutdown_timer(cx)?; @@ -944,10 +926,7 @@ where /// - `std::io::ErrorKind::ConnectionReset` after partial read; /// - all data read done. #[inline(always)] // TODO: bench this inline - fn read_available( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Result { + fn read_available(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result { let this = self.project(); if this.flags.contains(Flags::READ_DISCONNECT) { diff --git a/actix-http/src/h1/dispatcher_tests.rs b/actix-http/src/h1/dispatcher_tests.rs index db46cdefc..50259e6ce 100644 --- a/actix-http/src/h1/dispatcher_tests.rs +++ b/actix-http/src/h1/dispatcher_tests.rs @@ -1,14 +1,11 @@ use std::{future::Future, str, task::Poll, time::Duration}; -use actix_rt::{pin, time::sleep}; -use actix_service::fn_service; -use actix_utils::future::{ready, Ready}; -use bytes::Bytes; -use futures_util::future::lazy; - use actix_codec::Framed; -use actix_service::Service; -use bytes::{Buf, BytesMut}; +use actix_rt::{pin, time::sleep}; +use actix_service::{fn_service, Service}; +use actix_utils::future::{ready, Ready}; +use bytes::{Buf, Bytes, BytesMut}; +use futures_util::future::lazy; use super::dispatcher::{Dispatcher, DispatcherState, DispatcherStateProj, Flags}; use crate::{ @@ -43,8 +40,8 @@ fn status_service( fn_service(move |_req: Request| ready(Ok::<_, Error>(Response::new(status)))) } -fn echo_path_service( -) -> impl Service, Error = Error> { +fn echo_path_service() -> impl Service, Error = Error> +{ fn_service(|req: Request| { let path = req.path().as_bytes(); ready(Ok::<_, Error>( @@ -53,8 +50,8 @@ fn echo_path_service( }) } -fn drop_payload_service( -) -> impl Service, Error = Error> { +fn drop_payload_service() -> impl Service, Error = Error> +{ fn_service(|mut req: Request| async move { let _ = req.take_payload(); Ok::<_, Error>(Response::with_body(StatusCode::OK, "payload dropped")) diff --git a/actix-http/src/h1/mod.rs b/actix-http/src/h1/mod.rs index 858cf542a..9e44608d8 100644 --- a/actix-http/src/h1/mod.rs +++ b/actix-http/src/h1/mod.rs @@ -17,14 +17,16 @@ mod timer; mod upgrade; mod utils; -pub use self::client::{ClientCodec, ClientPayloadCodec}; -pub use self::codec::Codec; -pub use self::dispatcher::Dispatcher; -pub use self::expect::ExpectHandler; -pub use self::payload::Payload; -pub use self::service::{H1Service, H1ServiceHandler}; -pub use self::upgrade::UpgradeHandler; -pub use self::utils::SendResponse; +pub use self::{ + client::{ClientCodec, ClientPayloadCodec}, + codec::Codec, + dispatcher::Dispatcher, + expect::ExpectHandler, + payload::Payload, + service::{H1Service, H1ServiceHandler}, + upgrade::UpgradeHandler, + utils::SendResponse, +}; #[derive(Debug)] /// Codec message diff --git a/actix-http/src/h1/service.rs b/actix-http/src/h1/service.rs index 9eebe2126..fbda7138e 100644 --- a/actix-http/src/h1/service.rs +++ b/actix-http/src/h1/service.rs @@ -15,6 +15,7 @@ use actix_utils::future::ready; use futures_core::future::LocalBoxFuture; use tracing::error; +use super::{codec::Codec, dispatcher::Dispatcher, ExpectHandler, UpgradeHandler}; use crate::{ body::{BoxBody, MessageBody}, config::ServiceConfig, @@ -23,8 +24,6 @@ use crate::{ ConnectCallback, OnConnectData, Request, Response, }; -use super::{codec::Codec, dispatcher::Dispatcher, ExpectHandler, UpgradeHandler}; - /// `ServiceFactory` implementation for HTTP1 transport pub struct H1Service { srv: S, @@ -82,13 +81,8 @@ where /// Create simple tcp stream service pub fn tcp( self, - ) -> impl ServiceFactory< - TcpStream, - Config = (), - Response = (), - Error = DispatchError, - InitError = (), - > { + ) -> impl ServiceFactory + { fn_service(|io: TcpStream| { let peer_addr = io.peer_addr().ok(); ready(Ok((io, peer_addr))) @@ -99,8 +93,6 @@ where #[cfg(feature = "openssl")] mod openssl { - use super::*; - use actix_tls::accept::{ openssl::{ reexports::{Error as SslError, SslAcceptor}, @@ -109,6 +101,8 @@ mod openssl { TlsError, }; + use super::*; + impl H1Service, S, B, X, U> where S: ServiceFactory, diff --git a/actix-http/src/h2/mod.rs b/actix-http/src/h2/mod.rs index 39198e0fe..e47099cac 100644 --- a/actix-http/src/h2/mod.rs +++ b/actix-http/src/h2/mod.rs @@ -23,8 +23,7 @@ use crate::{ mod dispatcher; mod service; -pub use self::dispatcher::Dispatcher; -pub use self::service::H2Service; +pub use self::{dispatcher::Dispatcher, service::H2Service}; /// HTTP/2 peer stream. pub struct Payload { @@ -58,10 +57,7 @@ impl Stream for Payload { } } -pub(crate) fn handshake_with_timeout( - io: T, - config: &ServiceConfig, -) -> HandshakeWithTimeout +pub(crate) fn handshake_with_timeout(io: T, config: &ServiceConfig) -> HandshakeWithTimeout where T: AsyncRead + AsyncWrite + Unpin, { diff --git a/actix-http/src/h2/service.rs b/actix-http/src/h2/service.rs index e526918c7..3f742135a 100644 --- a/actix-http/src/h2/service.rs +++ b/actix-http/src/h2/service.rs @@ -16,6 +16,7 @@ use actix_utils::future::ready; use futures_core::{future::LocalBoxFuture, ready}; use tracing::{error, trace}; +use super::{dispatcher::Dispatcher, handshake_with_timeout, HandshakeWithTimeout}; use crate::{ body::{BoxBody, MessageBody}, config::ServiceConfig, @@ -24,8 +25,6 @@ use crate::{ ConnectCallback, OnConnectData, Request, Response, }; -use super::{dispatcher::Dispatcher, handshake_with_timeout, HandshakeWithTimeout}; - /// `ServiceFactory` implementation for HTTP/2 transport pub struct H2Service { srv: S, diff --git a/actix-http/src/header/map.rs b/actix-http/src/header/map.rs index d7b4e6dde..e8118be93 100644 --- a/actix-http/src/header/map.rs +++ b/actix-http/src/header/map.rs @@ -1120,9 +1120,7 @@ mod tests { assert!(vals.next().is_none()); } - fn owned_pair<'a>( - (name, val): (&'a HeaderName, &'a HeaderValue), - ) -> (HeaderName, HeaderValue) { + fn owned_pair<'a>((name, val): (&'a HeaderName, &'a HeaderValue)) -> (HeaderName, HeaderValue) { (name.clone(), val.clone()) } } diff --git a/actix-http/src/header/mod.rs b/actix-http/src/header/mod.rs index a63174a92..79f91afef 100644 --- a/actix-http/src/header/mod.rs +++ b/actix-http/src/header/mod.rs @@ -3,33 +3,30 @@ // declaring new header consts will yield this error #![allow(clippy::declare_interior_mutable_const)] -use percent_encoding::{AsciiSet, CONTROLS}; - // re-export from http except header map related items pub use ::http::header::{ HeaderName, HeaderValue, InvalidHeaderName, InvalidHeaderValue, ToStrError, }; - // re-export const header names, list is explicit so that any updates to `common` module do not // conflict with this set pub use ::http::header::{ ACCEPT, ACCEPT_CHARSET, ACCEPT_ENCODING, ACCEPT_LANGUAGE, ACCEPT_RANGES, - ACCESS_CONTROL_ALLOW_CREDENTIALS, ACCESS_CONTROL_ALLOW_HEADERS, - ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_EXPOSE_HEADERS, - ACCESS_CONTROL_MAX_AGE, ACCESS_CONTROL_REQUEST_HEADERS, ACCESS_CONTROL_REQUEST_METHOD, AGE, - ALLOW, ALT_SVC, AUTHORIZATION, CACHE_CONTROL, CONNECTION, CONTENT_DISPOSITION, - CONTENT_ENCODING, CONTENT_LANGUAGE, CONTENT_LENGTH, CONTENT_LOCATION, CONTENT_RANGE, - CONTENT_SECURITY_POLICY, CONTENT_SECURITY_POLICY_REPORT_ONLY, CONTENT_TYPE, COOKIE, DATE, - DNT, ETAG, EXPECT, EXPIRES, FORWARDED, FROM, HOST, IF_MATCH, IF_MODIFIED_SINCE, - IF_NONE_MATCH, IF_RANGE, IF_UNMODIFIED_SINCE, LAST_MODIFIED, LINK, LOCATION, MAX_FORWARDS, - ORIGIN, PRAGMA, PROXY_AUTHENTICATE, PROXY_AUTHORIZATION, PUBLIC_KEY_PINS, - PUBLIC_KEY_PINS_REPORT_ONLY, RANGE, REFERER, REFERRER_POLICY, REFRESH, RETRY_AFTER, - SEC_WEBSOCKET_ACCEPT, SEC_WEBSOCKET_EXTENSIONS, SEC_WEBSOCKET_KEY, SEC_WEBSOCKET_PROTOCOL, - SEC_WEBSOCKET_VERSION, SERVER, SET_COOKIE, STRICT_TRANSPORT_SECURITY, TE, TRAILER, - TRANSFER_ENCODING, UPGRADE, UPGRADE_INSECURE_REQUESTS, USER_AGENT, VARY, VIA, WARNING, - WWW_AUTHENTICATE, X_CONTENT_TYPE_OPTIONS, X_DNS_PREFETCH_CONTROL, X_FRAME_OPTIONS, - X_XSS_PROTECTION, + ACCESS_CONTROL_ALLOW_CREDENTIALS, ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_METHODS, + ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_EXPOSE_HEADERS, ACCESS_CONTROL_MAX_AGE, + ACCESS_CONTROL_REQUEST_HEADERS, ACCESS_CONTROL_REQUEST_METHOD, AGE, ALLOW, ALT_SVC, + AUTHORIZATION, CACHE_CONTROL, CONNECTION, CONTENT_DISPOSITION, CONTENT_ENCODING, + CONTENT_LANGUAGE, CONTENT_LENGTH, CONTENT_LOCATION, CONTENT_RANGE, CONTENT_SECURITY_POLICY, + CONTENT_SECURITY_POLICY_REPORT_ONLY, CONTENT_TYPE, COOKIE, DATE, DNT, ETAG, EXPECT, EXPIRES, + FORWARDED, FROM, HOST, IF_MATCH, IF_MODIFIED_SINCE, IF_NONE_MATCH, IF_RANGE, + IF_UNMODIFIED_SINCE, LAST_MODIFIED, LINK, LOCATION, MAX_FORWARDS, ORIGIN, PRAGMA, + PROXY_AUTHENTICATE, PROXY_AUTHORIZATION, PUBLIC_KEY_PINS, PUBLIC_KEY_PINS_REPORT_ONLY, RANGE, + REFERER, REFERRER_POLICY, REFRESH, RETRY_AFTER, SEC_WEBSOCKET_ACCEPT, SEC_WEBSOCKET_EXTENSIONS, + SEC_WEBSOCKET_KEY, SEC_WEBSOCKET_PROTOCOL, SEC_WEBSOCKET_VERSION, SERVER, SET_COOKIE, + STRICT_TRANSPORT_SECURITY, TE, TRAILER, TRANSFER_ENCODING, UPGRADE, UPGRADE_INSECURE_REQUESTS, + USER_AGENT, VARY, VIA, WARNING, WWW_AUTHENTICATE, X_CONTENT_TYPE_OPTIONS, + X_DNS_PREFETCH_CONTROL, X_FRAME_OPTIONS, X_XSS_PROTECTION, }; +use percent_encoding::{AsciiSet, CONTROLS}; use crate::{error::ParseError, HttpMessage}; @@ -43,23 +40,22 @@ mod utils; pub use self::{ as_name::AsHeaderName, + // re-export list is explicit so that any updates to `http` do not conflict with this set + common::{ + CACHE_STATUS, CDN_CACHE_CONTROL, CROSS_ORIGIN_EMBEDDER_POLICY, CROSS_ORIGIN_OPENER_POLICY, + CROSS_ORIGIN_RESOURCE_POLICY, PERMISSIONS_POLICY, X_FORWARDED_FOR, X_FORWARDED_HOST, + X_FORWARDED_PROTO, + }, into_pair::TryIntoHeaderPair, into_value::TryIntoHeaderValue, map::HeaderMap, shared::{ - parse_extended_value, q, Charset, ContentEncoding, ExtendedValue, HttpDate, - LanguageTag, Quality, QualityItem, + parse_extended_value, q, Charset, ContentEncoding, ExtendedValue, HttpDate, LanguageTag, + Quality, QualityItem, }, utils::{fmt_comma_delimited, from_comma_delimited, from_one_raw_str, http_percent_encode}, }; -// re-export list is explicit so that any updates to `http` do not conflict with this set -pub use self::common::{ - CACHE_STATUS, CDN_CACHE_CONTROL, CROSS_ORIGIN_EMBEDDER_POLICY, CROSS_ORIGIN_OPENER_POLICY, - CROSS_ORIGIN_RESOURCE_POLICY, PERMISSIONS_POLICY, X_FORWARDED_FOR, X_FORWARDED_HOST, - X_FORWARDED_PROTO, -}; - /// An interface for types that already represent a valid header. pub trait Header: TryIntoHeaderValue { /// Returns the name of the header field. diff --git a/actix-http/src/header/shared/mod.rs b/actix-http/src/header/shared/mod.rs index 257e54d7a..889c73c45 100644 --- a/actix-http/src/header/shared/mod.rs +++ b/actix-http/src/header/shared/mod.rs @@ -1,5 +1,7 @@ //! Originally taken from `hyper::header::shared`. +pub use language_tags::LanguageTag; + mod charset; mod content_encoding; mod extended; @@ -7,10 +9,11 @@ mod http_date; mod quality; mod quality_item; -pub use self::charset::Charset; -pub use self::content_encoding::ContentEncoding; -pub use self::extended::{parse_extended_value, ExtendedValue}; -pub use self::http_date::HttpDate; -pub use self::quality::{q, Quality}; -pub use self::quality_item::QualityItem; -pub use language_tags::LanguageTag; +pub use self::{ + charset::Charset, + content_encoding::ContentEncoding, + extended::{parse_extended_value, ExtendedValue}, + http_date::HttpDate, + quality::{q, Quality}, + quality_item::QualityItem, +}; diff --git a/actix-http/src/header/shared/quality_item.rs b/actix-http/src/header/shared/quality_item.rs index ee1fdb928..a41369c20 100644 --- a/actix-http/src/header/shared/quality_item.rs +++ b/actix-http/src/header/shared/quality_item.rs @@ -1,8 +1,7 @@ use std::{cmp, fmt, str}; -use crate::error::ParseError; - use super::Quality; +use crate::error::ParseError; /// Represents an item with a quality value as defined /// in [RFC 7231 §5.3.1](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.1). diff --git a/actix-http/src/http_message.rs b/actix-http/src/http_message.rs index 20becc310..3ba9ef752 100644 --- a/actix-http/src/http_message.rs +++ b/actix-http/src/http_message.rs @@ -61,9 +61,7 @@ pub trait HttpMessage: Sized { fn encoding(&self) -> Result<&'static Encoding, ContentTypeError> { if let Some(mime_type) = self.mime_type()? { if let Some(charset) = mime_type.get_param("charset") { - if let Some(enc) = - Encoding::for_label_no_replacement(charset.as_str().as_bytes()) - { + if let Some(enc) = Encoding::for_label_no_replacement(charset.as_str().as_bytes()) { Ok(enc) } else { Err(ContentTypeError::UnknownEncoding) diff --git a/actix-http/src/lib.rs b/actix-http/src/lib.rs index 8bf834f73..8b755f2f4 100644 --- a/actix-http/src/lib.rs +++ b/actix-http/src/lib.rs @@ -28,8 +28,7 @@ #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] -pub use ::http::{uri, uri::Uri}; -pub use ::http::{Method, StatusCode, Version}; +pub use ::http::{uri, uri::Uri, Method, StatusCode, Version}; pub mod body; mod builder; @@ -57,22 +56,24 @@ pub mod test; #[cfg(feature = "ws")] pub mod ws; -pub use self::builder::HttpServiceBuilder; -pub use self::config::ServiceConfig; -pub use self::error::Error; -pub use self::extensions::Extensions; -pub use self::header::ContentEncoding; -pub use self::http_message::HttpMessage; -pub use self::keep_alive::KeepAlive; -pub use self::message::ConnectionType; -pub use self::message::Message; #[allow(deprecated)] -pub use self::payload::{BoxedPayloadStream, Payload, PayloadStream}; -pub use self::requests::{Request, RequestHead, RequestHeadType}; -pub use self::responses::{Response, ResponseBuilder, ResponseHead}; -pub use self::service::HttpService; +pub use self::payload::PayloadStream; #[cfg(any(feature = "openssl", feature = "rustls"))] pub use self::service::TlsAcceptorConfig; +pub use self::{ + builder::HttpServiceBuilder, + config::ServiceConfig, + error::Error, + extensions::Extensions, + header::ContentEncoding, + http_message::HttpMessage, + keep_alive::KeepAlive, + message::{ConnectionType, Message}, + payload::{BoxedPayloadStream, Payload}, + requests::{Request, RequestHead, RequestHeadType}, + responses::{Response, ResponseBuilder, ResponseHead}, + service::HttpService, +}; /// A major HTTP protocol version. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] diff --git a/actix-http/src/requests/mod.rs b/actix-http/src/requests/mod.rs index fc35da65a..4a27818a5 100644 --- a/actix-http/src/requests/mod.rs +++ b/actix-http/src/requests/mod.rs @@ -3,5 +3,7 @@ mod head; mod request; -pub use self::head::{RequestHead, RequestHeadType}; -pub use self::request::Request; +pub use self::{ + head::{RequestHead, RequestHeadType}, + request::Request, +}; diff --git a/actix-http/src/requests/request.rs b/actix-http/src/requests/request.rs index f4d605b39..1750fb2f7 100644 --- a/actix-http/src/requests/request.rs +++ b/actix-http/src/requests/request.rs @@ -10,8 +10,7 @@ use std::{ use http::{header, Method, Uri, Version}; use crate::{ - header::HeaderMap, BoxedPayloadStream, Extensions, HttpMessage, Message, Payload, - RequestHead, + header::HeaderMap, BoxedPayloadStream, Extensions, HttpMessage, Message, Payload, RequestHead, }; /// An HTTP request. diff --git a/actix-http/src/responses/mod.rs b/actix-http/src/responses/mod.rs index 899232b9f..d99628232 100644 --- a/actix-http/src/responses/mod.rs +++ b/actix-http/src/responses/mod.rs @@ -5,7 +5,5 @@ mod head; #[allow(clippy::module_inception)] mod response; -pub use self::builder::ResponseBuilder; pub(crate) use self::head::BoxedResponseHead; -pub use self::head::ResponseHead; -pub use self::response::Response; +pub use self::{builder::ResponseBuilder, head::ResponseHead, response::Response}; diff --git a/actix-http/src/service.rs b/actix-http/src/service.rs index 108b09c4e..e118d8361 100644 --- a/actix-http/src/service.rs +++ b/actix-http/src/service.rs @@ -200,13 +200,8 @@ where /// The resulting service only supports HTTP/1.x. pub fn tcp( self, - ) -> impl ServiceFactory< - TcpStream, - Config = (), - Response = (), - Error = DispatchError, - InitError = (), - > { + ) -> impl ServiceFactory + { fn_service(|io: TcpStream| async { let peer_addr = io.peer_addr().ok(); Ok((io, Protocol::Http1, peer_addr)) @@ -219,13 +214,8 @@ where #[cfg(feature = "http2")] pub fn tcp_auto_h2c( self, - ) -> impl ServiceFactory< - TcpStream, - Config = (), - Response = (), - Error = DispatchError, - InitError = (), - > { + ) -> impl ServiceFactory + { fn_service(move |io: TcpStream| async move { // subset of HTTP/2 preface defined by RFC 9113 §3.4 // this subset was chosen to maximize likelihood that peeking only once will allow us to @@ -563,10 +553,7 @@ where } } - pub(super) fn _poll_ready( - &self, - cx: &mut Context<'_>, - ) -> Poll>> { + pub(super) fn _poll_ready(&self, cx: &mut Context<'_>) -> Poll>> { ready!(self.flow.expect.poll_ready(cx).map_err(Into::into))?; ready!(self.flow.service.poll_ready(cx).map_err(Into::into))?; @@ -625,10 +612,7 @@ where }) } - fn call( - &self, - (io, proto, peer_addr): (T, Protocol, Option), - ) -> Self::Future { + fn call(&self, (io, proto, peer_addr): (T, Protocol, Option)) -> Self::Future { let conn_data = OnConnectData::from_io(&io, self.on_connect_ext.as_deref()); match proto { diff --git a/actix-http/src/ws/dispatcher.rs b/actix-http/src/ws/dispatcher.rs index 396f1e86c..1354d5ae1 100644 --- a/actix-http/src/ws/dispatcher.rs +++ b/actix-http/src/ws/dispatcher.rs @@ -70,15 +70,14 @@ mod inner { task::{Context, Poll}, }; + use actix_codec::Framed; use actix_service::{IntoService, Service}; use futures_core::stream::Stream; use local_channel::mpsc; use pin_project_lite::pin_project; - use tracing::debug; - - use actix_codec::Framed; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_util::codec::{Decoder, Encoder}; + use tracing::debug; use crate::{body::BoxBody, Response}; @@ -413,9 +412,7 @@ mod inner { } State::Error(_) => { // flush write buffer - if !this.framed.is_write_buf_empty() - && this.framed.flush(cx).is_pending() - { + if !this.framed.is_write_buf_empty() && this.framed.flush(cx).is_pending() { return Poll::Pending; } Poll::Ready(Err(this.state.take_error())) diff --git a/actix-http/src/ws/frame.rs b/actix-http/src/ws/frame.rs index ce6f1b256..c9fb0cde9 100644 --- a/actix-http/src/ws/frame.rs +++ b/actix-http/src/ws/frame.rs @@ -221,9 +221,10 @@ impl Parser { #[cfg(test)] mod tests { - use super::*; use bytes::Bytes; + use super::*; + struct F { finished: bool, opcode: OpCode, diff --git a/actix-http/src/ws/mod.rs b/actix-http/src/ws/mod.rs index 2a0b0a99c..87f9b38f3 100644 --- a/actix-http/src/ws/mod.rs +++ b/actix-http/src/ws/mod.rs @@ -8,8 +8,7 @@ use std::io; use derive_more::{Display, Error, From}; use http::{header, Method, StatusCode}; -use crate::body::BoxBody; -use crate::{header::HeaderValue, RequestHead, Response, ResponseBuilder}; +use crate::{body::BoxBody, header::HeaderValue, RequestHead, Response, ResponseBuilder}; mod codec; mod dispatcher; @@ -17,10 +16,12 @@ mod frame; mod mask; mod proto; -pub use self::codec::{Codec, Frame, Item, Message}; -pub use self::dispatcher::Dispatcher; -pub use self::frame::Parser; -pub use self::proto::{hash_key, CloseCode, CloseReason, OpCode}; +pub use self::{ + codec::{Codec, Frame, Item, Message}, + dispatcher::Dispatcher, + frame::Parser, + proto::{hash_key, CloseCode, CloseReason, OpCode}, +}; /// WebSocket protocol errors. #[derive(Debug, Display, Error, From)] @@ -219,10 +220,8 @@ pub fn handshake_response(req: &RequestHead) -> ResponseBuilder { #[cfg(test)] mod tests { - use crate::{header, Method}; - use super::*; - use crate::test::TestRequest; + use crate::{header, test::TestRequest, Method}; #[test] fn test_handshake() { diff --git a/actix-http/tests/test_openssl.rs b/actix-http/tests/test_openssl.rs index 7464bee4e..b4d8ed1a5 100644 --- a/actix-http/tests/test_openssl.rs +++ b/actix-http/tests/test_openssl.rs @@ -321,8 +321,7 @@ async fn h2_body_length() { let mut srv = test_server(move || { HttpService::build() .h2(|_| async { - let body = - once(async { Ok::<_, Infallible>(Bytes::from_static(STR.as_ref())) }); + let body = once(async { Ok::<_, Infallible>(Bytes::from_static(STR.as_ref())) }); Ok::<_, Infallible>( Response::ok().set_body(SizedStream::new(STR.len() as u64, body)), diff --git a/actix-http/tests/test_rustls.rs b/actix-http/tests/test_rustls.rs index bf3a9243b..3d9a39cbd 100644 --- a/actix-http/tests/test_rustls.rs +++ b/actix-http/tests/test_rustls.rs @@ -90,11 +90,9 @@ pub fn get_negotiated_alpn_protocol( config.alpn_protocols.push(client_alpn_protocol.to_vec()); - let mut sess = rustls::ClientConnection::new( - Arc::new(config), - ServerName::try_from("localhost").unwrap(), - ) - .unwrap(); + let mut sess = + rustls::ClientConnection::new(Arc::new(config), ServerName::try_from("localhost").unwrap()) + .unwrap(); let mut sock = StdTcpStream::connect(addr).unwrap(); let mut stream = rustls::Stream::new(&mut sess, &mut sock); diff --git a/actix-http/tests/test_server.rs b/actix-http/tests/test_server.rs index 2efb336ae..cfb4d17b8 100644 --- a/actix-http/tests/test_server.rs +++ b/actix-http/tests/test_server.rs @@ -166,8 +166,7 @@ async fn chunked_payload() { for chunk_size in chunk_sizes.iter() { let mut bytes = Vec::new(); - let random_bytes: Vec = - (0..*chunk_size).map(|_| rand::random::()).collect(); + let random_bytes: Vec = (0..*chunk_size).map(|_| rand::random::()).collect(); bytes.extend(format!("{:X}\r\n", chunk_size).as_bytes()); bytes.extend(&random_bytes[..]); @@ -352,8 +351,7 @@ async fn http10_keepalive() { .await; let mut stream = net::TcpStream::connect(srv.addr()).unwrap(); - let _ = - stream.write_all(b"GET /test/tests/test HTTP/1.0\r\nconnection: keep-alive\r\n\r\n"); + let _ = stream.write_all(b"GET /test/tests/test HTTP/1.0\r\nconnection: keep-alive\r\n\r\n"); let mut data = vec![0; 1024]; let _ = stream.read(&mut data); assert_eq!(&data[..17], b"HTTP/1.0 200 OK\r\n"); @@ -795,8 +793,9 @@ async fn not_modified_spec_h1() { .map_into_boxed_body(), // with no content-length - "/body" => Response::with_body(StatusCode::NOT_MODIFIED, "1234") - .map_into_boxed_body(), + "/body" => { + Response::with_body(StatusCode::NOT_MODIFIED, "1234").map_into_boxed_body() + } // with manual content-length header and specific None body "/cl-none" => { diff --git a/actix-multipart/src/form/bytes.rs b/actix-multipart/src/form/bytes.rs index 7d64fffce..3c5e2eb10 100644 --- a/actix-multipart/src/form/bytes.rs +++ b/actix-multipart/src/form/bytes.rs @@ -27,11 +27,7 @@ pub struct Bytes { impl<'t> FieldReader<'t> for Bytes { type Future = LocalBoxFuture<'t, Result>; - fn read_field( - _: &'t HttpRequest, - mut field: Field, - limits: &'t mut Limits, - ) -> Self::Future { + fn read_field(_: &'t HttpRequest, mut field: Field, limits: &'t mut Limits) -> Self::Future { Box::pin(async move { let mut buf = BytesMut::with_capacity(131_072); diff --git a/actix-multipart/src/form/json.rs b/actix-multipart/src/form/json.rs index 9951eaaaf..fb90a82b9 100644 --- a/actix-multipart/src/form/json.rs +++ b/actix-multipart/src/form/json.rs @@ -7,13 +7,12 @@ use derive_more::{Deref, DerefMut, Display, Error}; use futures_core::future::LocalBoxFuture; use serde::de::DeserializeOwned; +use super::FieldErrorHandler; use crate::{ form::{bytes::Bytes, FieldReader, Limits}, Field, MultipartError, }; -use super::FieldErrorHandler; - /// Deserialize from JSON. #[derive(Debug, Deref, DerefMut)] pub struct Json(pub T); diff --git a/actix-multipart/src/form/mod.rs b/actix-multipart/src/form/mod.rs index 711d4aeb6..67adfd4b2 100644 --- a/actix-multipart/src/form/mod.rs +++ b/actix-multipart/src/form/mod.rs @@ -429,8 +429,7 @@ mod tests { #[actix_rt::test] async fn test_options() { - let srv = - actix_test::start(|| App::new().route("/", web::post().to(test_options_route))); + let srv = actix_test::start(|| App::new().route("/", web::post().to(test_options_route))); let mut form = multipart::Form::default(); form.add_text("field1", "value"); @@ -481,9 +480,7 @@ mod tests { field3: Text, } - async fn test_field_renaming_route( - form: MultipartForm, - ) -> impl Responder { + async fn test_field_renaming_route(form: MultipartForm) -> impl Responder { assert_eq!(&*form.field1, "renamed"); assert_eq!(&*form.field2, "field1"); assert_eq!(&*form.field3, "field3"); @@ -492,9 +489,8 @@ mod tests { #[actix_rt::test] async fn test_field_renaming() { - let srv = actix_test::start(|| { - App::new().route("/", web::post().to(test_field_renaming_route)) - }); + let srv = + actix_test::start(|| App::new().route("/", web::post().to(test_field_renaming_route))); let mut form = multipart::Form::default(); form.add_text("renamed", "renamed"); @@ -623,9 +619,7 @@ mod tests { HttpResponse::Ok().finish() } - async fn test_upload_limits_file( - form: MultipartForm, - ) -> impl Responder { + async fn test_upload_limits_file(form: MultipartForm) -> impl Responder { assert!(form.field.size > 0); HttpResponse::Ok().finish() } diff --git a/actix-multipart/src/form/tempfile.rs b/actix-multipart/src/form/tempfile.rs index 3c637e717..2f611ba04 100644 --- a/actix-multipart/src/form/tempfile.rs +++ b/actix-multipart/src/form/tempfile.rs @@ -39,23 +39,20 @@ pub struct TempFile { impl<'t> FieldReader<'t> for TempFile { type Future = LocalBoxFuture<'t, Result>; - fn read_field( - req: &'t HttpRequest, - mut field: Field, - limits: &'t mut Limits, - ) -> Self::Future { + fn read_field(req: &'t HttpRequest, mut field: Field, limits: &'t mut Limits) -> Self::Future { Box::pin(async move { let config = TempFileConfig::from_req(req); let field_name = field.name().to_owned(); let mut size = 0; - let file = config.create_tempfile().map_err(|err| { - config.map_error(req, &field_name, TempFileError::FileIo(err)) - })?; + let file = config + .create_tempfile() + .map_err(|err| config.map_error(req, &field_name, TempFileError::FileIo(err)))?; - let mut file_async = tokio::fs::File::from_std(file.reopen().map_err(|err| { - config.map_error(req, &field_name, TempFileError::FileIo(err)) - })?); + let mut file_async = + tokio::fs::File::from_std(file.reopen().map_err(|err| { + config.map_error(req, &field_name, TempFileError::FileIo(err)) + })?); while let Some(chunk) = field.try_next().await? { limits.try_consume_limits(chunk.len(), false)?; @@ -65,9 +62,10 @@ impl<'t> FieldReader<'t> for TempFile { })?; } - file_async.flush().await.map_err(|err| { - config.map_error(req, &field_name, TempFileError::FileIo(err)) - })?; + file_async + .flush() + .await + .map_err(|err| config.map_error(req, &field_name, TempFileError::FileIo(err)))?; Ok(TempFile { file, @@ -131,12 +129,7 @@ impl TempFileConfig { .unwrap_or(&DEFAULT_CONFIG) } - fn map_error( - &self, - req: &HttpRequest, - field_name: &str, - err: TempFileError, - ) -> MultipartError { + fn map_error(&self, req: &HttpRequest, field_name: &str, err: TempFileError) -> MultipartError { let source = if let Some(ref err_handler) = self.err_handler { (err_handler)(err, req) } else { diff --git a/actix-multipart/src/lib.rs b/actix-multipart/src/lib.rs index 73e10c913..615a8e6de 100644 --- a/actix-multipart/src/lib.rs +++ b/actix-multipart/src/lib.rs @@ -17,5 +17,7 @@ mod server; pub mod form; -pub use self::error::MultipartError; -pub use self::server::{Field, Multipart}; +pub use self::{ + error::MultipartError, + server::{Field, Multipart}, +}; diff --git a/actix-multipart/src/server.rs b/actix-multipart/src/server.rs index 5dc4d6f69..b20429040 100644 --- a/actix-multipart/src/server.rs +++ b/actix-multipart/src/server.rs @@ -161,8 +161,8 @@ impl InnerMultipart { for h in hdrs { let name = HeaderName::try_from(h.name).map_err(|_| ParseError::Header)?; - let value = HeaderValue::try_from(h.value) - .map_err(|_| ParseError::Header)?; + let value = + HeaderValue::try_from(h.value).map_err(|_| ParseError::Header)?; headers.append(name, value); } @@ -222,8 +222,7 @@ impl InnerMultipart { if chunk.len() < boundary.len() { continue; } - if &chunk[..2] == b"--" && &chunk[2..chunk.len() - 2] == boundary.as_bytes() - { + if &chunk[..2] == b"--" && &chunk[2..chunk.len() - 2] == boundary.as_bytes() { break; } else { if chunk.len() < boundary.len() + 2 { @@ -268,9 +267,7 @@ impl InnerMultipart { match field.borrow_mut().poll(safety) { Poll::Pending => return Poll::Pending, Poll::Ready(Some(Ok(_))) => continue, - Poll::Ready(Some(Err(err))) => { - return Poll::Ready(Some(Err(err))) - } + Poll::Ready(Some(Err(err))) => return Poll::Ready(Some(Err(err))), Poll::Ready(None) => true, } } @@ -289,8 +286,7 @@ impl InnerMultipart { match self.state { // read until first boundary InnerState::FirstBoundary => { - match InnerMultipart::skip_until_boundary(&mut payload, &self.boundary)? - { + match InnerMultipart::skip_until_boundary(&mut payload, &self.boundary)? { Some(eof) => { if eof { self.state = InnerState::Eof; @@ -667,9 +663,7 @@ impl InnerField { Ok(None) => Poll::Pending, Ok(Some(line)) => { if line.as_ref() != b"\r\n" { - log::warn!( - "multipart field did not read all the data or it is malformed" - ); + log::warn!("multipart field did not read all the data or it is malformed"); } Poll::Ready(None) } diff --git a/actix-router/benches/quoter.rs b/actix-router/benches/quoter.rs index 9ca06da39..2065fd563 100644 --- a/actix-router/benches/quoter.rs +++ b/actix-router/benches/quoter.rs @@ -1,9 +1,9 @@ #![allow(clippy::uninlined_format_args)] -use criterion::{black_box, criterion_group, criterion_main, Criterion}; - use std::borrow::Cow; +use criterion::{black_box, criterion_group, criterion_main, Criterion}; + fn compare_quoters(c: &mut Criterion) { let mut group = c.benchmark_group("Compare Quoters"); diff --git a/actix-router/src/de.rs b/actix-router/src/de.rs index 458e08930..e8c7c658e 100644 --- a/actix-router/src/de.rs +++ b/actix-router/src/de.rs @@ -1,10 +1,14 @@ use std::borrow::Cow; -use serde::de::{self, Deserializer, Error as DeError, Visitor}; -use serde::forward_to_deserialize_any; +use serde::{ + de::{self, Deserializer, Error as DeError, Visitor}, + forward_to_deserialize_any, +}; -use crate::path::{Path, PathIter}; -use crate::{Quoter, ResourcePath}; +use crate::{ + path::{Path, PathIter}, + Quoter, ResourcePath, +}; thread_local! { static FULL_QUOTER: Quoter = Quoter::new(b"", b""); @@ -486,11 +490,7 @@ impl<'de> de::VariantAccess<'de> for UnitVariant { Err(de::value::Error::custom("not supported")) } - fn struct_variant( - self, - _: &'static [&'static str], - _: V, - ) -> Result + fn struct_variant(self, _: &'static [&'static str], _: V) -> Result where V: Visitor<'de>, { @@ -503,9 +503,7 @@ mod tests { use serde::{de, Deserialize}; use super::*; - use crate::path::Path; - use crate::router::Router; - use crate::ResourceDef; + use crate::{path::Path, router::Router, ResourceDef}; #[derive(Deserialize)] struct MyStruct { @@ -572,13 +570,11 @@ mod tests { assert_eq!(s.key, "name"); assert_eq!(s.value, 32); - let s: (String, u8) = - de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap(); + let s: (String, u8) = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap(); assert_eq!(s.0, "name"); assert_eq!(s.1, 32); - let res: Vec = - de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap(); + let res: Vec = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap(); assert_eq!(res[0], "name".to_owned()); assert_eq!(res[1], "32".to_owned()); } diff --git a/actix-router/src/lib.rs b/actix-router/src/lib.rs index a02129495..53c0ad82a 100644 --- a/actix-router/src/lib.rs +++ b/actix-router/src/lib.rs @@ -18,13 +18,14 @@ mod router; #[cfg(feature = "http")] mod url; -pub use self::de::PathDeserializer; -pub use self::path::Path; -pub use self::pattern::{IntoPatterns, Patterns}; -pub use self::quoter::Quoter; -pub use self::resource::ResourceDef; -pub use self::resource_path::{Resource, ResourcePath}; -pub use self::router::{ResourceId, Router, RouterBuilder}; - #[cfg(feature = "http")] pub use self::url::Url; +pub use self::{ + de::PathDeserializer, + path::Path, + pattern::{IntoPatterns, Patterns}, + quoter::Quoter, + resource::ResourceDef, + resource_path::{Resource, ResourcePath}, + router::{ResourceId, Router, RouterBuilder}, +}; diff --git a/actix-router/src/path.rs b/actix-router/src/path.rs index 34dabcfbe..dc4150ddc 100644 --- a/actix-router/src/path.rs +++ b/actix-router/src/path.rs @@ -1,5 +1,7 @@ -use std::borrow::Cow; -use std::ops::{DerefMut, Index}; +use std::{ + borrow::Cow, + ops::{DerefMut, Index}, +}; use serde::de; diff --git a/actix-router/src/resource.rs b/actix-router/src/resource.rs index c868a3e6f..860993a37 100644 --- a/actix-router/src/resource.rs +++ b/actix-router/src/resource.rs @@ -1741,9 +1741,7 @@ mod tests { ResourceDef::new("/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}/{j}/{k}/{l}/{m}/{n}/{o}/{p}"); // panics - ResourceDef::new( - "/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}/{j}/{k}/{l}/{m}/{n}/{o}/{p}/{q}", - ); + ResourceDef::new("/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}/{j}/{k}/{l}/{m}/{n}/{o}/{p}/{q}"); } #[test] diff --git a/actix-router/src/router.rs b/actix-router/src/router.rs index 064c5e904..d31d10ce8 100644 --- a/actix-router/src/router.rs +++ b/actix-router/src/router.rs @@ -117,11 +117,7 @@ where U: Default, { /// Registers resource for specified path. - pub fn path( - &mut self, - path: impl IntoPatterns, - val: T, - ) -> (&mut ResourceDef, &mut T, &mut U) { + pub fn path(&mut self, path: impl IntoPatterns, val: T) -> (&mut ResourceDef, &mut T, &mut U) { self.push(ResourceDef::new(path), val, U::default()) } @@ -142,8 +138,10 @@ where #[cfg(test)] mod tests { - use crate::path::Path; - use crate::router::{ResourceId, Router}; + use crate::{ + path::Path, + router::{ResourceId, Router}, + }; #[allow(clippy::cognitive_complexity)] #[test] diff --git a/actix-router/src/url.rs b/actix-router/src/url.rs index 8ae9ea9d8..2920e271d 100644 --- a/actix-router/src/url.rs +++ b/actix-router/src/url.rs @@ -1,6 +1,4 @@ -use crate::ResourcePath; - -use crate::Quoter; +use crate::{Quoter, ResourcePath}; thread_local! { static DEFAULT_QUOTER: Quoter = Quoter::new(b"", b"%/+"); diff --git a/actix-test/src/lib.rs b/actix-test/src/lib.rs index 2beb64dca..7781edab4 100644 --- a/actix-test/src/lib.rs +++ b/actix-test/src/lib.rs @@ -45,8 +45,8 @@ use actix_http::{header::HeaderMap, ws, HttpService, Method, Request, Response}; pub use actix_http_test::unused_addr; use actix_service::{map_config, IntoServiceFactory, ServiceFactory, ServiceFactoryExt as _}; pub use actix_web::test::{ - call_and_read_body, call_and_read_body_json, call_service, init_service, ok_service, - read_body, read_body_json, status_service, TestRequest, + call_and_read_body, call_and_read_body_json, call_service, init_service, ok_service, read_body, + read_body_json, status_service, TestRequest, }; use actix_web::{ body::MessageBody, @@ -159,11 +159,8 @@ where let srv = match srv_cfg.stream { StreamType::Tcp => match srv_cfg.tp { HttpVer::Http1 => builder.listen("test", tcp, move || { - let app_cfg = AppConfig::__priv_test_new( - false, - local_addr.to_string(), - local_addr, - ); + let app_cfg = + AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); let fac = factory() .into_factory() @@ -175,11 +172,8 @@ where .tcp() }), HttpVer::Http2 => builder.listen("test", tcp, move || { - let app_cfg = AppConfig::__priv_test_new( - false, - local_addr.to_string(), - local_addr, - ); + let app_cfg = + AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); let fac = factory() .into_factory() @@ -191,11 +185,8 @@ where .tcp() }), HttpVer::Both => builder.listen("test", tcp, move || { - let app_cfg = AppConfig::__priv_test_new( - false, - local_addr.to_string(), - local_addr, - ); + let app_cfg = + AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); let fac = factory() .into_factory() @@ -210,11 +201,8 @@ where #[cfg(feature = "openssl")] StreamType::Openssl(acceptor) => match cfg.tp { HttpVer::Http1 => builder.listen("test", tcp, move || { - let app_cfg = AppConfig::__priv_test_new( - false, - local_addr.to_string(), - local_addr, - ); + let app_cfg = + AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); let fac = factory() .into_factory() @@ -226,11 +214,8 @@ where .openssl(acceptor.clone()) }), HttpVer::Http2 => builder.listen("test", tcp, move || { - let app_cfg = AppConfig::__priv_test_new( - false, - local_addr.to_string(), - local_addr, - ); + let app_cfg = + AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); let fac = factory() .into_factory() @@ -242,11 +227,8 @@ where .openssl(acceptor.clone()) }), HttpVer::Both => builder.listen("test", tcp, move || { - let app_cfg = AppConfig::__priv_test_new( - false, - local_addr.to_string(), - local_addr, - ); + let app_cfg = + AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); let fac = factory() .into_factory() @@ -261,11 +243,8 @@ where #[cfg(feature = "rustls")] StreamType::Rustls(config) => match cfg.tp { HttpVer::Http1 => builder.listen("test", tcp, move || { - let app_cfg = AppConfig::__priv_test_new( - false, - local_addr.to_string(), - local_addr, - ); + let app_cfg = + AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); let fac = factory() .into_factory() @@ -277,11 +256,8 @@ where .rustls(config.clone()) }), HttpVer::Http2 => builder.listen("test", tcp, move || { - let app_cfg = AppConfig::__priv_test_new( - false, - local_addr.to_string(), - local_addr, - ); + let app_cfg = + AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); let fac = factory() .into_factory() @@ -293,11 +269,8 @@ where .rustls(config.clone()) }), HttpVer::Both => builder.listen("test", tcp, move || { - let app_cfg = AppConfig::__priv_test_new( - false, - local_addr.to_string(), - local_addr, - ); + let app_cfg = + AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); let fac = factory() .into_factory() diff --git a/actix-web-actors/src/context.rs b/actix-web-actors/src/context.rs index f7b11c780..be8fd387c 100644 --- a/actix-web-actors/src/context.rs +++ b/actix-web-actors/src/context.rs @@ -1,11 +1,13 @@ -use std::collections::VecDeque; -use std::future::Future; -use std::pin::Pin; -use std::task::{Context, Poll}; +use std::{ + collections::VecDeque, + future::Future, + pin::Pin, + task::{Context, Poll}, +}; -use actix::dev::{AsyncContextParts, ContextFut, ContextParts, Envelope, Mailbox, ToEnvelope}; -use actix::fut::ActorFuture; use actix::{ + dev::{AsyncContextParts, ContextFut, ContextParts, Envelope, Mailbox, ToEnvelope}, + fut::ActorFuture, Actor, ActorContext, ActorState, Addr, AsyncContext, Handler, Message, SpawnHandle, }; use actix_web::error::Error; @@ -247,9 +249,11 @@ mod tests { use std::time::Duration; use actix::Actor; - use actix_web::http::StatusCode; - use actix_web::test::{call_service, init_service, read_body, TestRequest}; - use actix_web::{web, App, HttpResponse}; + use actix_web::{ + http::StatusCode, + test::{call_service, init_service, read_body, TestRequest}, + web, App, HttpResponse, + }; use bytes::Bytes; use super::*; diff --git a/actix-web-actors/src/ws.rs b/actix-web-actors/src/ws.rs index 731f33f86..6ce3e69a1 100644 --- a/actix-web-actors/src/ws.rs +++ b/actix-web-actors/src/ws.rs @@ -66,17 +66,14 @@ use std::{ use actix::{ dev::{ - AsyncContextParts, ContextFut, ContextParts, Envelope, Mailbox, StreamHandler, - ToEnvelope, + AsyncContextParts, ContextFut, ContextParts, Envelope, Mailbox, StreamHandler, ToEnvelope, }, fut::ActorFuture, Actor, ActorContext, ActorState, Addr, AsyncContext, Handler, Message as ActixMessage, SpawnHandle, }; use actix_http::ws::{hash_key, Codec}; -pub use actix_http::ws::{ - CloseCode, CloseReason, Frame, HandshakeError, Message, ProtocolError, -}; +pub use actix_http::ws::{CloseCode, CloseReason, Frame, HandshakeError, Message, ProtocolError}; use actix_web::{ error::{Error, PayloadError}, http::{ @@ -426,16 +423,16 @@ pub fn handshake_with_protocols( }; // check requested protocols - let protocol = - req.headers() - .get(&header::SEC_WEBSOCKET_PROTOCOL) - .and_then(|req_protocols| { - let req_protocols = req_protocols.to_str().ok()?; - req_protocols - .split(',') - .map(|req_p| req_p.trim()) - .find(|req_p| protocols.iter().any(|p| p == req_p)) - }); + let protocol = req + .headers() + .get(&header::SEC_WEBSOCKET_PROTOCOL) + .and_then(|req_protocols| { + let req_protocols = req_protocols.to_str().ok()?; + req_protocols + .split(',') + .map(|req_p| req_p.trim()) + .find(|req_p| protocols.iter().any(|p| p == req_p)) + }); let mut response = HttpResponse::build(StatusCode::SWITCHING_PROTOCOLS) .upgrade("websocket") diff --git a/actix-web-codegen/src/lib.rs b/actix-web-codegen/src/lib.rs index 8b68ea16b..6d6f4f79d 100644 --- a/actix-web-codegen/src/lib.rs +++ b/actix-web-codegen/src/lib.rs @@ -153,37 +153,37 @@ pub fn routes(_: TokenStream, input: TokenStream) -> TokenStream { macro_rules! method_macro { ($variant:ident, $method:ident) => { -#[doc = concat!("Creates route handler with `actix_web::guard::", stringify!($variant), "`.")] -/// -/// # Syntax -/// ```plain -#[doc = concat!("#[", stringify!($method), r#"("path"[, attributes])]"#)] -/// ``` -/// -/// # Attributes -/// - `"path"`: Raw literal string with path for which to register handler. -/// - `name = "resource_name"`: Specifies resource name for the handler. If not set, the function -/// name of handler is used. -/// - `guard = "function_name"`: Registers function as guard using `actix_web::guard::fn_guard`. -/// - `wrap = "Middleware"`: Registers a resource middleware. -/// -/// # Notes -/// Function name can be specified as any expression that is going to be accessible to the -/// generate code, e.g `my_guard` or `my_module::my_guard`. -/// -/// # Examples -/// ``` -/// # use actix_web::HttpResponse; -#[doc = concat!("# use actix_web_codegen::", stringify!($method), ";")] -#[doc = concat!("#[", stringify!($method), r#"("/")]"#)] -/// async fn example() -> HttpResponse { -/// HttpResponse::Ok().finish() -/// } -/// ``` -#[proc_macro_attribute] -pub fn $method(args: TokenStream, input: TokenStream) -> TokenStream { - route::with_method(Some(route::MethodType::$variant), args, input) -} + #[doc = concat!("Creates route handler with `actix_web::guard::", stringify!($variant), "`.")] + /// + /// # Syntax + /// ```plain + #[doc = concat!("#[", stringify!($method), r#"("path"[, attributes])]"#)] + /// ``` + /// + /// # Attributes + /// - `"path"`: Raw literal string with path for which to register handler. + /// - `name = "resource_name"`: Specifies resource name for the handler. If not set, the + /// function name of handler is used. + /// - `guard = "function_name"`: Registers function as guard using `actix_web::guard::fn_guard`. + /// - `wrap = "Middleware"`: Registers a resource middleware. + /// + /// # Notes + /// Function name can be specified as any expression that is going to be accessible to the + /// generate code, e.g `my_guard` or `my_module::my_guard`. + /// + /// # Examples + /// ``` + /// # use actix_web::HttpResponse; + #[doc = concat!("# use actix_web_codegen::", stringify!($method), ";")] + #[doc = concat!("#[", stringify!($method), r#"("/")]"#)] + /// async fn example() -> HttpResponse { + /// HttpResponse::Ok().finish() + /// } + /// ``` + #[proc_macro_attribute] + pub fn $method(args: TokenStream, input: TokenStream) -> TokenStream { + route::with_method(Some(route::MethodType::$variant), args, input) + } }; } diff --git a/actix-web-codegen/src/route.rs b/actix-web-codegen/src/route.rs index 0b8bb0f38..e87d37941 100644 --- a/actix-web-codegen/src/route.rs +++ b/actix-web-codegen/src/route.rs @@ -488,31 +488,32 @@ pub(crate) fn with_methods(input: TokenStream) -> TokenStream { ast.attrs = others.into_iter().map(Result::unwrap_err).collect(); - let methods = - match methods - .into_iter() - .map(Result::unwrap) - .map(|(method, attr)| { - attr.parse_meta().and_then(|args| { - if let Meta::List(args) = args { - Args::new(args.nested.into_iter().collect(), Some(method)) - } else { - Err(syn::Error::new_spanned(attr, "Invalid input for macro")) - } - }) + let methods = match methods + .into_iter() + .map(Result::unwrap) + .map(|(method, attr)| { + attr.parse_meta().and_then(|args| { + if let Meta::List(args) = args { + Args::new(args.nested.into_iter().collect(), Some(method)) + } else { + Err(syn::Error::new_spanned(attr, "Invalid input for macro")) + } }) - .collect::, _>>() - { - Ok(methods) if methods.is_empty() => return input_and_compile_error( + }) + .collect::, _>>() + { + Ok(methods) if methods.is_empty() => { + return input_and_compile_error( input, syn::Error::new( Span::call_site(), "The #[routes] macro requires at least one `#[(..)]` attribute.", ), - ), - Ok(methods) => methods, - Err(err) => return input_and_compile_error(input, err), - }; + ) + } + Ok(methods) => methods, + Err(err) => return input_and_compile_error(input, err), + }; match Route::multiple(methods, ast) { Ok(route) => route.into_token_stream().into(), diff --git a/actix-web/benches/responder.rs b/actix-web/benches/responder.rs index ac4d18324..c675eadff 100644 --- a/actix-web/benches/responder.rs +++ b/actix-web/benches/responder.rs @@ -99,8 +99,7 @@ fn responder(c: &mut Criterion) { let req = TestRequest::default().to_http_request(); c.bench_function("responder", move |b| { b.iter_custom(|_| { - let responders = - (0..100_000).map(|_| StringResponder(String::from("Hello World!!"))); + let responders = (0..100_000).map(|_| StringResponder(String::from("Hello World!!"))); let start = Instant::now(); let _res = rt.block_on(async { diff --git a/actix-web/benches/service.rs b/actix-web/benches/service.rs index 87e51f170..9b29df8e5 100644 --- a/actix-web/benches/service.rs +++ b/actix-web/benches/service.rs @@ -1,11 +1,12 @@ -use actix_service::Service; -use actix_web::dev::{ServiceRequest, ServiceResponse}; -use actix_web::{web, App, Error, HttpResponse}; -use criterion::{criterion_main, Criterion}; -use std::cell::RefCell; -use std::rc::Rc; +use std::{cell::RefCell, rc::Rc}; -use actix_web::test::{init_service, ok_service, TestRequest}; +use actix_service::Service; +use actix_web::{ + dev::{ServiceRequest, ServiceResponse}, + test::{init_service, ok_service, TestRequest}, + web, App, Error, HttpResponse, +}; +use criterion::{criterion_main, Criterion}; /// Criterion Benchmark for async Service /// Should be used from within criterion group: diff --git a/actix-web/examples/on-connect.rs b/actix-web/examples/on-connect.rs index 0d56a8f25..dc9273b46 100644 --- a/actix-web/examples/on-connect.rs +++ b/actix-web/examples/on-connect.rs @@ -7,8 +7,7 @@ use std::{any::Any, io, net::SocketAddr}; use actix_web::{ - dev::Extensions, rt::net::TcpStream, web, App, HttpRequest, HttpResponse, HttpServer, - Responder, + dev::Extensions, rt::net::TcpStream, web, App, HttpRequest, HttpResponse, HttpServer, Responder, }; #[allow(dead_code)] @@ -24,9 +23,7 @@ async fn route_whoami(req: HttpRequest) -> impl Responder { Some(info) => HttpResponse::Ok().body(format!( "Here is some info about your connection:\n\n{info:#?}", )), - None => { - HttpResponse::InternalServerError().body("Missing expected request extension data") - } + None => HttpResponse::InternalServerError().body("Missing expected request extension data"), } } diff --git a/actix-web/src/app.rs b/actix-web/src/app.rs index 353b82b19..a4b576b0e 100644 --- a/actix-web/src/app.rs +++ b/actix-web/src/app.rs @@ -264,12 +264,8 @@ where pub fn default_service(mut self, svc: F) -> Self where F: IntoServiceFactory, - U: ServiceFactory< - ServiceRequest, - Config = (), - Response = ServiceResponse, - Error = Error, - > + 'static, + U: ServiceFactory + + 'static, U::InitError: fmt::Debug, { let svc = svc diff --git a/actix-web/src/app_service.rs b/actix-web/src/app_service.rs index 0fc856203..513e7a8a1 100644 --- a/actix-web/src/app_service.rs +++ b/actix-web/src/app_service.rs @@ -348,13 +348,17 @@ impl ServiceFactory for AppEntry { #[cfg(test)] mod tests { - use std::sync::atomic::{AtomicBool, Ordering}; - use std::sync::Arc; + use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }; use actix_service::Service; - use crate::test::{init_service, TestRequest}; - use crate::{web, App, HttpResponse}; + use crate::{ + test::{init_service, TestRequest}, + web, App, HttpResponse, + }; struct DropData(Arc); diff --git a/actix-web/src/config.rs b/actix-web/src/config.rs index 11eaf8720..fba0c2717 100644 --- a/actix-web/src/config.rs +++ b/actix-web/src/config.rs @@ -232,12 +232,8 @@ impl ServiceConfig { pub fn default_service(&mut self, f: F) -> &mut Self where F: IntoServiceFactory, - U: ServiceFactory< - ServiceRequest, - Config = (), - Response = ServiceResponse, - Error = Error, - > + 'static, + U: ServiceFactory + + 'static, U::InitError: std::fmt::Debug, { let svc = f @@ -308,9 +304,11 @@ mod tests { use bytes::Bytes; use super::*; - use crate::http::{Method, StatusCode}; - use crate::test::{assert_body_eq, call_service, init_service, read_body, TestRequest}; - use crate::{web, App, HttpRequest, HttpResponse}; + use crate::{ + http::{Method, StatusCode}, + test::{assert_body_eq, call_service, init_service, read_body, TestRequest}, + web, App, HttpRequest, HttpResponse, + }; // allow deprecated `ServiceConfig::data` #[allow(deprecated)] diff --git a/actix-web/src/data.rs b/actix-web/src/data.rs index 89104a1ac..423dd598c 100644 --- a/actix-web/src/data.rs +++ b/actix-web/src/data.rs @@ -186,12 +186,14 @@ mod tests { #[allow(deprecated)] #[actix_rt::test] async fn test_data_extractor() { - let srv = init_service(App::new().data("TEST".to_string()).service( - web::resource("/").to(|data: web::Data| { - assert_eq!(data.to_lowercase(), "test"); - HttpResponse::Ok() - }), - )) + let srv = init_service( + App::new() + .data("TEST".to_string()) + .service(web::resource("/").to(|data: web::Data| { + assert_eq!(data.to_lowercase(), "test"); + HttpResponse::Ok() + })), + ) .await; let req = TestRequest::default().to_request(); @@ -286,16 +288,17 @@ mod tests { #[allow(deprecated)] #[actix_rt::test] async fn test_override_data() { - let srv = - init_service(App::new().data(1usize).service( - web::resource("/").data(10usize).route(web::get().to( + let srv = init_service( + App::new() + .data(1usize) + .service(web::resource("/").data(10usize).route(web::get().to( |data: web::Data| { assert_eq!(**data, 10); HttpResponse::Ok() }, - )), - )) - .await; + ))), + ) + .await; let req = TestRequest::default().to_request(); let resp = srv.call(req).await.unwrap(); diff --git a/actix-web/src/dev.rs b/actix-web/src/dev.rs index 5c7adfdaf..2a0791a1c 100644 --- a/actix-web/src/dev.rs +++ b/actix-web/src/dev.rs @@ -7,26 +7,25 @@ //! - [`ConnectionInfo`]: Connection information //! - [`PeerAddr`]: Connection information +#[cfg(feature = "__compress")] +pub use actix_http::encoding::Decoder as Decompress; pub use actix_http::{Extensions, Payload, RequestHead, Response, ResponseHead}; +use actix_router::Patterns; pub use actix_router::{Path, ResourceDef, ResourcePath, Url}; pub use actix_server::{Server, ServerHandle}; pub use actix_service::{ always_ready, fn_factory, fn_service, forward_ready, Service, ServiceFactory, Transform, }; -#[cfg(feature = "__compress")] -pub use actix_http::encoding::Decoder as Decompress; - -pub use crate::config::{AppConfig, AppService}; #[doc(hidden)] pub use crate::handler::Handler; -pub use crate::info::{ConnectionInfo, PeerAddr}; -pub use crate::rmap::ResourceMap; -pub use crate::service::{HttpServiceFactory, ServiceRequest, ServiceResponse, WebService}; - -pub use crate::types::{JsonBody, Readlines, UrlEncoded}; - -use actix_router::Patterns; +pub use crate::{ + config::{AppConfig, AppService}, + info::{ConnectionInfo, PeerAddr}, + rmap::ResourceMap, + service::{HttpServiceFactory, ServiceRequest, ServiceResponse, WebService}, + types::{JsonBody, Readlines, UrlEncoded}, +}; pub(crate) fn ensure_leading_slash(mut patterns: Patterns) -> Patterns { match &mut patterns { diff --git a/actix-web/src/error/macros.rs b/actix-web/src/error/macros.rs index 78b1ed9f6..8634557c9 100644 --- a/actix-web/src/error/macros.rs +++ b/actix-web/src/error/macros.rs @@ -42,8 +42,7 @@ macro_rules! downcast_dyn { /// Downcasts generic body to a specific type. #[allow(dead_code)] pub fn downcast_ref(&self) -> Option<&T> { - if self.__private_get_type_id__(PrivateHelper(())).0 - == std::any::TypeId::of::() + if self.__private_get_type_id__(PrivateHelper(())).0 == std::any::TypeId::of::() { // SAFETY: external crates cannot override the default // implementation of `__private_get_type_id__`, since @@ -59,8 +58,7 @@ macro_rules! downcast_dyn { /// Downcasts a generic body to a mutable specific type. #[allow(dead_code)] pub fn downcast_mut(&mut self) -> Option<&mut T> { - if self.__private_get_type_id__(PrivateHelper(())).0 - == std::any::TypeId::of::() + if self.__private_get_type_id__(PrivateHelper(())).0 == std::any::TypeId::of::() { // SAFETY: external crates cannot override the default // implementation of `__private_get_type_id__`, since @@ -76,7 +74,8 @@ macro_rules! downcast_dyn { }; } -pub(crate) use {downcast_dyn, downcast_get_type_id}; +pub(crate) use downcast_dyn; +pub(crate) use downcast_get_type_id; #[cfg(test)] mod tests { diff --git a/actix-web/src/error/mod.rs b/actix-web/src/error/mod.rs index 604c539f3..91a6bcc3f 100644 --- a/actix-web/src/error/mod.rs +++ b/actix-web/src/error/mod.rs @@ -5,14 +5,10 @@ // expanded manually. // // See -pub use actix_http::error::{ - ContentTypeError, DispatchError, HttpError, ParseError, PayloadError, -}; - +pub use actix_http::error::{ContentTypeError, DispatchError, HttpError, ParseError, PayloadError}; use derive_more::{Display, Error, From}; use serde_json::error::Error as JsonError; -use serde_urlencoded::de::Error as FormDeError; -use serde_urlencoded::ser::Error as FormError; +use serde_urlencoded::{de::Error as FormDeError, ser::Error as FormError}; use url::ParseError as UrlParseError; use crate::http::StatusCode; @@ -23,10 +19,8 @@ mod internal; mod macros; mod response_error; -pub use self::error::Error; -pub use self::internal::*; -pub use self::response_error::ResponseError; -pub(crate) use macros::{downcast_dyn, downcast_get_type_id}; +pub(crate) use self::macros::{downcast_dyn, downcast_get_type_id}; +pub use self::{error::Error, internal::*, response_error::ResponseError}; /// A convenience [`Result`](std::result::Result) for Actix Web operations. /// diff --git a/actix-web/src/extract.rs b/actix-web/src/extract.rs index 84904a9eb..a2afd3827 100644 --- a/actix-web/src/extract.rs +++ b/actix-web/src/extract.rs @@ -429,8 +429,10 @@ mod tests { use serde::Deserialize; use super::*; - use crate::test::TestRequest; - use crate::types::{Form, FormConfig}; + use crate::{ + test::TestRequest, + types::{Form, FormConfig}, + }; #[derive(Deserialize, Debug, PartialEq)] struct Info { diff --git a/actix-web/src/guard/mod.rs b/actix-web/src/guard/mod.rs index 3aca11df2..35294a3c4 100644 --- a/actix-web/src/guard/mod.rs +++ b/actix-web/src/guard/mod.rs @@ -61,8 +61,10 @@ use crate::{http::header::Header, service::ServiceRequest, HttpMessage as _}; mod acceptable; mod host; -pub use self::acceptable::Acceptable; -pub use self::host::{Host, HostGuard}; +pub use self::{ + acceptable::Acceptable, + host::{Host, HostGuard}, +}; /// Provides access to request parts that are useful during routing. #[derive(Debug)] diff --git a/actix-web/src/http/header/accept_encoding.rs b/actix-web/src/http/header/accept_encoding.rs index 8c35179b6..715126a03 100644 --- a/actix-web/src/http/header/accept_encoding.rs +++ b/actix-web/src/http/header/accept_encoding.rs @@ -94,10 +94,7 @@ impl AcceptEncoding { /// includes the server's supported encodings in the body plus a [`Vary`] header. /// /// [`Vary`]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary - pub fn negotiate<'a>( - &self, - supported: impl Iterator, - ) -> Option { + pub fn negotiate<'a>(&self, supported: impl Iterator) -> Option { // 1. If no Accept-Encoding field is in the request, any content-coding is considered // acceptable by the user agent. @@ -375,9 +372,7 @@ mod tests { Some(Encoding::deflate()) ); assert_eq!( - test.negotiate( - [Encoding::gzip(), Encoding::deflate(), Encoding::identity()].iter() - ), + test.negotiate([Encoding::gzip(), Encoding::deflate(), Encoding::identity()].iter()), Some(Encoding::gzip()) ); assert_eq!( diff --git a/actix-web/src/http/header/content_disposition.rs b/actix-web/src/http/header/content_disposition.rs index f743302a2..0606f5aef 100644 --- a/actix-web/src/http/header/content_disposition.rs +++ b/actix-web/src/http/header/content_disposition.rs @@ -592,9 +592,8 @@ mod tests { fn test_from_raw_basic() { assert!(ContentDisposition::from_raw(&HeaderValue::from_static("")).is_err()); - let a = HeaderValue::from_static( - "form-data; dummy=3; name=upload; filename=\"sample.png\"", - ); + let a = + HeaderValue::from_static("form-data; dummy=3; name=upload; filename=\"sample.png\""); let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap(); let b = ContentDisposition { disposition: DispositionType::FormData, @@ -648,8 +647,8 @@ mod tests { charset: Charset::Ext(String::from("UTF-8")), language_tag: None, value: vec![ - 0xc2, 0xa3, 0x20, b'a', b'n', b'd', 0x20, 0xe2, 0x82, 0xac, 0x20, b'r', - b'a', b't', b'e', b's', + 0xc2, 0xa3, 0x20, b'a', b'n', b'd', 0x20, 0xe2, 0x82, 0xac, 0x20, b'r', b'a', + b't', b'e', b's', ], })], }; @@ -665,8 +664,8 @@ mod tests { charset: Charset::Ext(String::from("UTF-8")), language_tag: None, value: vec![ - 0xc2, 0xa3, 0x20, b'a', b'n', b'd', 0x20, 0xe2, 0x82, 0xac, 0x20, b'r', - b'a', b't', b'e', b's', + 0xc2, 0xa3, 0x20, b'a', b'n', b'd', 0x20, 0xe2, 0x82, 0xac, 0x20, b'r', b'a', + b't', b'e', b's', ], })], }; @@ -742,8 +741,8 @@ mod tests { }; assert_eq!(a, b); - let a = ContentDisposition::from_raw(&HeaderValue::from_static("unknown-disp-param")) - .unwrap(); + let a = + ContentDisposition::from_raw(&HeaderValue::from_static("unknown-disp-param")).unwrap(); let b = ContentDisposition { disposition: DispositionType::Ext(String::from("unknown-disp-param")), parameters: vec![], @@ -782,8 +781,7 @@ mod tests { Mainstream browsers like Firefox (gecko) and Chrome use UTF-8 directly as above. (And now, only UTF-8 is handled by this implementation.) */ - let a = - HeaderValue::from_str("form-data; name=upload; filename=\"文件.webp\"").unwrap(); + let a = HeaderValue::from_str("form-data; name=upload; filename=\"文件.webp\"").unwrap(); let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap(); let b = ContentDisposition { disposition: DispositionType::FormData, @@ -803,9 +801,7 @@ mod tests { disposition: DispositionType::FormData, parameters: vec![ DispositionParam::Name(String::from("upload")), - DispositionParam::Filename(String::from( - "余固知謇謇之為患兮,忍而不能舍也.pptx", - )), + DispositionParam::Filename(String::from("余固知謇謇之為患兮,忍而不能舍也.pptx")), ], }; assert_eq!(a, b); @@ -870,8 +866,7 @@ mod tests { }; assert_eq!(a, b); - let a = - HeaderValue::from_static("form-data; name=photo; filename=\"%74%65%73%74.png\""); + let a = HeaderValue::from_static("form-data; name=photo; filename=\"%74%65%73%74.png\""); let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap(); let b = ContentDisposition { disposition: DispositionType::FormData, diff --git a/actix-web/src/http/header/content_range.rs b/actix-web/src/http/header/content_range.rs index bcbe77e66..8befffd95 100644 --- a/actix-web/src/http/header/content_range.rs +++ b/actix-web/src/http/header/content_range.rs @@ -127,8 +127,7 @@ impl FromStr for ContentRangeSpec { fn from_str(s: &str) -> Result { let res = match split_in_two(s, ' ') { Some(("bytes", resp)) => { - let (range, instance_length) = - split_in_two(resp, '/').ok_or(ParseError::Header)?; + let (range, instance_length) = split_in_two(resp, '/').ok_or(ParseError::Header)?; let instance_length = if instance_length == "*" { None diff --git a/actix-web/src/http/header/content_type.rs b/actix-web/src/http/header/content_type.rs index 1fc75d0e2..41c0c1fc9 100644 --- a/actix-web/src/http/header/content_type.rs +++ b/actix-web/src/http/header/content_type.rs @@ -1,6 +1,7 @@ -use super::CONTENT_TYPE; use mime::Mime; +use super::CONTENT_TYPE; + crate::http::header::common_header! { /// `Content-Type` header, defined /// in [RFC 7231 §3.1.1.5](https://datatracker.ietf.org/doc/html/rfc7231#section-3.1.1.5) diff --git a/actix-web/src/http/header/date.rs b/actix-web/src/http/header/date.rs index f62740211..a8ac65660 100644 --- a/actix-web/src/http/header/date.rs +++ b/actix-web/src/http/header/date.rs @@ -1,6 +1,7 @@ -use super::{HttpDate, DATE}; use std::time::SystemTime; +use super::{HttpDate, DATE}; + crate::http::header::common_header! { /// `Date` header, defined /// in [RFC 7231 §7.1.1.2](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.2) diff --git a/actix-web/src/http/header/entity.rs b/actix-web/src/http/header/entity.rs index 0eaa12b5d..a5ef3c5b7 100644 --- a/actix-web/src/http/header/entity.rs +++ b/actix-web/src/http/header/entity.rs @@ -152,9 +152,7 @@ impl FromStr for EntityTag { return Err(crate::error::ParseError::Header); } // The etag is weak if its first char is not a DQUOTE. - if slice.len() >= 2 - && slice.starts_with('"') - && check_slice_validity(&slice[1..length - 1]) + if slice.len() >= 2 && slice.starts_with('"') && check_slice_validity(&slice[1..length - 1]) { // No need to check if the last char is a DQUOTE, // we already did that above. diff --git a/actix-web/src/http/header/if_range.rs b/actix-web/src/http/header/if_range.rs index eb3632a4d..d7375c4c5 100644 --- a/actix-web/src/http/header/if_range.rs +++ b/actix-web/src/http/header/if_range.rs @@ -4,9 +4,7 @@ use super::{ from_one_raw_str, EntityTag, Header, HeaderName, HeaderValue, HttpDate, InvalidHeaderValue, TryIntoHeaderValue, Writer, }; -use crate::error::ParseError; -use crate::http::header; -use crate::HttpMessage; +use crate::{error::ParseError, http::header, HttpMessage}; /// `If-Range` header, defined /// in [RFC 7233 §3.2](https://datatracker.ietf.org/doc/html/rfc7233#section-3.2) diff --git a/actix-web/src/http/header/macros.rs b/actix-web/src/http/header/macros.rs index b40eca03b..d9755e15e 100644 --- a/actix-web/src/http/header/macros.rs +++ b/actix-web/src/http/header/macros.rs @@ -314,7 +314,7 @@ macro_rules! common_header { }; } -pub(crate) use {common_header, common_header_test_module}; - +pub(crate) use common_header; #[cfg(test)] pub(crate) use common_header_test; +pub(crate) use common_header_test_module; diff --git a/actix-web/src/http/header/mod.rs b/actix-web/src/http/header/mod.rs index 9807d5f5e..65c5c88a0 100644 --- a/actix-web/src/http/header/mod.rs +++ b/actix-web/src/http/header/mod.rs @@ -6,8 +6,6 @@ use std::fmt; -use bytes::{Bytes, BytesMut}; - // re-export from actix-http // - header name / value types // - relevant traits for converting to header name / value @@ -16,6 +14,7 @@ use bytes::{Bytes, BytesMut}; // - the few typed headers from actix-http // - header parsing utils pub use actix_http::header::*; +use bytes::{Bytes, BytesMut}; mod accept; mod accept_charset; @@ -43,32 +42,33 @@ mod preference; mod range; #[cfg(test)] -pub(crate) use macros::common_header_test; -pub(crate) use macros::{common_header, common_header_test_module}; - -pub use self::accept::Accept; -pub use self::accept_charset::AcceptCharset; -pub use self::accept_encoding::AcceptEncoding; -pub use self::accept_language::AcceptLanguage; -pub use self::allow::Allow; -pub use self::cache_control::{CacheControl, CacheDirective}; -pub use self::content_disposition::{ContentDisposition, DispositionParam, DispositionType}; -pub use self::content_language::ContentLanguage; -pub use self::content_range::{ContentRange, ContentRangeSpec}; -pub use self::content_type::ContentType; -pub use self::date::Date; -pub use self::encoding::Encoding; -pub use self::entity::EntityTag; -pub use self::etag::ETag; -pub use self::expires::Expires; -pub use self::if_match::IfMatch; -pub use self::if_modified_since::IfModifiedSince; -pub use self::if_none_match::IfNoneMatch; -pub use self::if_range::IfRange; -pub use self::if_unmodified_since::IfUnmodifiedSince; -pub use self::last_modified::LastModified; -pub use self::preference::Preference; -pub use self::range::{ByteRangeSpec, Range}; +pub(crate) use self::macros::common_header_test; +pub(crate) use self::macros::{common_header, common_header_test_module}; +pub use self::{ + accept::Accept, + accept_charset::AcceptCharset, + accept_encoding::AcceptEncoding, + accept_language::AcceptLanguage, + allow::Allow, + cache_control::{CacheControl, CacheDirective}, + content_disposition::{ContentDisposition, DispositionParam, DispositionType}, + content_language::ContentLanguage, + content_range::{ContentRange, ContentRangeSpec}, + content_type::ContentType, + date::Date, + encoding::Encoding, + entity::EntityTag, + etag::ETag, + expires::Expires, + if_match::IfMatch, + if_modified_since::IfModifiedSince, + if_none_match::IfNoneMatch, + if_range::IfRange, + if_unmodified_since::IfUnmodifiedSince, + last_modified::LastModified, + preference::Preference, + range::{ByteRangeSpec, Range}, +}; /// Format writer ([`fmt::Write`]) for a [`BytesMut`]. #[derive(Debug, Default)] diff --git a/actix-web/src/lib.rs b/actix-web/src/lib.rs index 57cdaea69..e982a43b1 100644 --- a/actix-web/src/lib.rs +++ b/actix-web/src/lib.rs @@ -74,6 +74,11 @@ #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] +pub use actix_http::{body, HttpMessage}; +#[cfg(feature = "cookies")] +#[doc(inline)] +pub use cookie; + mod app; mod app_service; mod config; @@ -102,25 +107,21 @@ pub mod test; pub(crate) mod types; pub mod web; -pub use crate::app::App; #[doc(inline)] pub use crate::error::Result; -pub use crate::error::{Error, ResponseError}; -pub use crate::extract::FromRequest; -pub use crate::handler::Handler; -pub use crate::request::HttpRequest; -pub use crate::resource::Resource; -pub use crate::response::{CustomizeResponder, HttpResponse, HttpResponseBuilder, Responder}; -pub use crate::route::Route; -pub use crate::scope::Scope; -pub use crate::server::HttpServer; -pub use crate::types::Either; - -pub use actix_http::{body, HttpMessage}; - -#[cfg(feature = "cookies")] -#[doc(inline)] -pub use cookie; +pub use crate::{ + app::App, + error::{Error, ResponseError}, + extract::FromRequest, + handler::Handler, + request::HttpRequest, + resource::Resource, + response::{CustomizeResponder, HttpResponse, HttpResponseBuilder, Responder}, + route::Route, + scope::Scope, + server::HttpServer, + types::Either, +}; macro_rules! codegen_reexport { ($name:ident) => { diff --git a/actix-web/src/middleware/compat.rs b/actix-web/src/middleware/compat.rs index ee8b8a498..7df510a5c 100644 --- a/actix-web/src/middleware/compat.rs +++ b/actix-web/src/middleware/compat.rs @@ -146,10 +146,9 @@ mod tests { // easier to code when cookies feature is disabled #![allow(unused_imports)] - use super::*; - use actix_service::IntoService; + use super::*; use crate::{ dev::ServiceRequest, http::StatusCode, @@ -207,9 +206,9 @@ mod tests { #[actix_rt::test] async fn test_condition_scope_middleware() { let srv = |req: ServiceRequest| { - Box::pin(async move { - Ok(req.into_response(HttpResponse::InternalServerError().finish())) - }) + Box::pin( + async move { Ok(req.into_response(HttpResponse::InternalServerError().finish())) }, + ) }; let logger = Logger::default(); diff --git a/actix-web/src/middleware/err_handlers.rs b/actix-web/src/middleware/err_handlers.rs index 051a0c6b3..e640bba08 100644 --- a/actix-web/src/middleware/err_handlers.rs +++ b/actix-web/src/middleware/err_handlers.rs @@ -540,21 +540,17 @@ mod tests { let mw_server = make_mw(StatusCode::INTERNAL_SERVER_ERROR).await; let mw_client = make_mw(StatusCode::BAD_REQUEST).await; - let resp = - test::call_service(&mw_client, TestRequest::default().to_srv_request()).await; + let resp = test::call_service(&mw_client, TestRequest::default().to_srv_request()).await; assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); - let resp = - test::call_service(&mw_server, TestRequest::default().to_srv_request()).await; + let resp = test::call_service(&mw_server, TestRequest::default().to_srv_request()).await; assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); } #[actix_rt::test] async fn default_handlers_separate_client_server() { #[allow(clippy::unnecessary_wraps)] - fn error_handler_client( - mut res: ServiceResponse, - ) -> Result> { + fn error_handler_client(mut res: ServiceResponse) -> Result> { res.response_mut() .headers_mut() .insert(CONTENT_TYPE, HeaderValue::from_static("0001")); @@ -562,9 +558,7 @@ mod tests { } #[allow(clippy::unnecessary_wraps)] - fn error_handler_server( - mut res: ServiceResponse, - ) -> Result> { + fn error_handler_server(mut res: ServiceResponse) -> Result> { res.response_mut() .headers_mut() .insert(CONTENT_TYPE, HeaderValue::from_static("0002")); @@ -582,21 +576,17 @@ mod tests { let mw_server = make_mw(StatusCode::INTERNAL_SERVER_ERROR).await; let mw_client = make_mw(StatusCode::BAD_REQUEST).await; - let resp = - test::call_service(&mw_client, TestRequest::default().to_srv_request()).await; + let resp = test::call_service(&mw_client, TestRequest::default().to_srv_request()).await; assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); - let resp = - test::call_service(&mw_server, TestRequest::default().to_srv_request()).await; + let resp = test::call_service(&mw_server, TestRequest::default().to_srv_request()).await; assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0002"); } #[actix_rt::test] async fn default_handlers_specialization() { #[allow(clippy::unnecessary_wraps)] - fn error_handler_client( - mut res: ServiceResponse, - ) -> Result> { + fn error_handler_client(mut res: ServiceResponse) -> Result> { res.response_mut() .headers_mut() .insert(CONTENT_TYPE, HeaderValue::from_static("0001")); @@ -624,12 +614,10 @@ mod tests { let mw_client = make_mw(StatusCode::BAD_REQUEST).await; let mw_specific = make_mw(StatusCode::UNPROCESSABLE_ENTITY).await; - let resp = - test::call_service(&mw_client, TestRequest::default().to_srv_request()).await; + let resp = test::call_service(&mw_client, TestRequest::default().to_srv_request()).await; assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); - let resp = - test::call_service(&mw_specific, TestRequest::default().to_srv_request()).await; + let resp = test::call_service(&mw_specific, TestRequest::default().to_srv_request()).await; assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0003"); } } diff --git a/actix-web/src/middleware/logger.rs b/actix-web/src/middleware/logger.rs index 0207798ae..06d26617a 100644 --- a/actix-web/src/middleware/logger.rs +++ b/actix-web/src/middleware/logger.rs @@ -489,12 +489,8 @@ impl Format { unreachable!("regex and code mismatch") } } - "i" => { - FormatText::RequestHeader(HeaderName::try_from(key.as_str()).unwrap()) - } - "o" => { - FormatText::ResponseHeader(HeaderName::try_from(key.as_str()).unwrap()) - } + "i" => FormatText::RequestHeader(HeaderName::try_from(key.as_str()).unwrap()), + "o" => FormatText::ResponseHeader(HeaderName::try_from(key.as_str()).unwrap()), "e" => FormatText::EnvironHeader(key.as_str().to_owned()), "xi" => FormatText::CustomRequest(key.as_str().to_owned(), None), "xo" => FormatText::CustomResponse(key.as_str().to_owned(), None), @@ -710,9 +706,7 @@ impl FormatText { } /// Converter to get a String from something that writes to a Formatter. -pub(crate) struct FormatDisplay<'a>( - &'a dyn Fn(&mut fmt::Formatter<'_>) -> Result<(), fmt::Error>, -); +pub(crate) struct FormatDisplay<'a>(&'a dyn Fn(&mut fmt::Formatter<'_>) -> Result<(), fmt::Error>); impl<'a> fmt::Display for FormatDisplay<'a> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { diff --git a/actix-web/src/middleware/mod.rs b/actix-web/src/middleware/mod.rs index 0a61ad6cb..eb3550b52 100644 --- a/actix-web/src/middleware/mod.rs +++ b/actix-web/src/middleware/mod.rs @@ -9,14 +9,16 @@ mod logger; mod noop; mod normalize; -pub use self::compat::Compat; -pub use self::condition::Condition; -pub use self::default_headers::DefaultHeaders; -pub use self::err_handlers::{ErrorHandlerResponse, ErrorHandlers}; -pub use self::logger::Logger; #[cfg(test)] pub(crate) use self::noop::Noop; -pub use self::normalize::{NormalizePath, TrailingSlash}; +pub use self::{ + compat::Compat, + condition::Condition, + default_headers::DefaultHeaders, + err_handlers::{ErrorHandlerResponse, ErrorHandlers}, + logger::Logger, + normalize::{NormalizePath, TrailingSlash}, +}; #[cfg(feature = "__compress")] mod compress; @@ -26,9 +28,8 @@ pub use self::compress::Compress; #[cfg(test)] mod tests { - use crate::{http::StatusCode, App}; - use super::*; + use crate::{http::StatusCode, App}; #[test] fn common_combinations() { diff --git a/actix-web/src/redirect.rs b/actix-web/src/redirect.rs index 5611cc368..f9e9f2d7a 100644 --- a/actix-web/src/redirect.rs +++ b/actix-web/src/redirect.rs @@ -181,9 +181,8 @@ impl Responder for Redirect { #[cfg(test)] mod tests { - use crate::{dev::Service, http::StatusCode, test, App}; - use super::*; + use crate::{dev::Service, http::StatusCode, test, App}; #[actix_rt::test] async fn absolute_redirects() { diff --git a/actix-web/src/request.rs b/actix-web/src/request.rs index 16a947b65..543c9dfbe 100644 --- a/actix-web/src/request.rs +++ b/actix-web/src/request.rs @@ -653,13 +653,13 @@ mod tests { #[actix_rt::test] async fn test_drop_http_request_pool() { - let srv = init_service(App::new().service(web::resource("/").to( - |req: HttpRequest| { + let srv = init_service( + App::new().service(web::resource("/").to(|req: HttpRequest| { HttpResponse::Ok() .insert_header(("pool_cap", req.app_state().pool().cap)) .finish() - }, - ))) + })), + ) .await; let req = TestRequest::default().to_request(); @@ -807,10 +807,7 @@ mod tests { web::scope("/user/{id}") .service(web::resource("/profile").route(web::get().to( move |req: HttpRequest| { - assert_eq!( - req.match_pattern(), - Some("/user/{id}/profile".to_owned()) - ); + assert_eq!(req.match_pattern(), Some("/user/{id}/profile".to_owned())); HttpResponse::Ok().finish() }, diff --git a/actix-web/src/resource.rs b/actix-web/src/resource.rs index 5d2c9706a..95185b80a 100644 --- a/actix-web/src/resource.rs +++ b/actix-web/src/resource.rs @@ -353,12 +353,8 @@ where pub fn default_service(mut self, f: F) -> Self where F: IntoServiceFactory, - U: ServiceFactory< - ServiceRequest, - Config = (), - Response = ServiceResponse, - Error = Error, - > + 'static, + U: ServiceFactory + + 'static, U::InitError: fmt::Debug, { // create and configure default resource @@ -625,10 +621,8 @@ mod tests { let fut = srv.call(req); async { fut.await.map(|mut res| { - res.headers_mut().insert( - header::CONTENT_TYPE, - HeaderValue::from_static("0001"), - ); + res.headers_mut() + .insert(header::CONTENT_TYPE, HeaderValue::from_static("0001")); res }) } @@ -660,12 +654,9 @@ mod tests { #[actix_rt::test] async fn test_pattern() { - let srv = init_service( - App::new().service( - web::resource(["/test", "/test2"]) - .to(|| async { Ok::<_, Error>(HttpResponse::Ok()) }), - ), - ) + let 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(&srv, req).await; @@ -804,17 +795,18 @@ mod tests { #[allow(deprecated)] #[actix_rt::test] async fn test_data_default_service() { - let srv = init_service( - App::new().data(1usize).service( - web::resource("/test") - .data(10usize) - .default_service(web::to(|data: web::Data| { - assert_eq!(**data, 10); - HttpResponse::Ok() - })), - ), - ) - .await; + let srv = + init_service( + App::new().data(1usize).service( + web::resource("/test") + .data(10usize) + .default_service(web::to(|data: web::Data| { + assert_eq!(**data, 10); + HttpResponse::Ok() + })), + ), + ) + .await; let req = TestRequest::get().uri("/test").to_request(); let resp = call_service(&srv, req).await; diff --git a/actix-web/src/response/builder.rs b/actix-web/src/response/builder.rs index a7f3f36c3..2c06941cd 100644 --- a/actix-web/src/response/builder.rs +++ b/actix-web/src/response/builder.rs @@ -14,8 +14,10 @@ use crate::{ body::{BodyStream, BoxBody, MessageBody}, dev::Extensions, error::{Error, JsonPayloadError}, - http::header::{self, HeaderName, TryIntoHeaderPair, TryIntoHeaderValue}, - http::{ConnectionType, StatusCode}, + http::{ + header::{self, HeaderName, TryIntoHeaderPair, TryIntoHeaderValue}, + ConnectionType, StatusCode, + }, BoxError, HttpRequest, HttpResponse, Responder, }; @@ -472,9 +474,8 @@ mod tests { #[actix_rt::test] async fn test_serde_json_in_body() { - let resp = HttpResponse::Ok().body( - serde_json::to_vec(&serde_json::json!({ "test-key": "test-value" })).unwrap(), - ); + let resp = HttpResponse::Ok() + .body(serde_json::to_vec(&serde_json::json!({ "test-key": "test-value" })).unwrap()); assert_eq!( body::to_bytes(resp.into_body()).await.unwrap().as_ref(), diff --git a/actix-web/src/response/customize_responder.rs b/actix-web/src/response/customize_responder.rs index f6f4b9236..aad0039e0 100644 --- a/actix-web/src/response/customize_responder.rs +++ b/actix-web/src/response/customize_responder.rs @@ -1,5 +1,7 @@ use actix_http::{ - body::EitherBody, error::HttpError, header::HeaderMap, header::TryIntoHeaderPair, + body::EitherBody, + error::HttpError, + header::{HeaderMap, TryIntoHeaderPair}, StatusCode, }; @@ -168,9 +170,8 @@ where #[cfg(test)] mod tests { - use bytes::Bytes; - use actix_http::body::to_bytes; + use bytes::Bytes; use super::*; use crate::{ diff --git a/actix-web/src/response/http_codes.rs b/actix-web/src/response/http_codes.rs index 986735346..2ac83046a 100644 --- a/actix-web/src/response/http_codes.rs +++ b/actix-web/src/response/http_codes.rs @@ -87,8 +87,7 @@ impl HttpResponse { #[cfg(test)] mod tests { - use crate::http::StatusCode; - use crate::HttpResponse; + use crate::{http::StatusCode, HttpResponse}; #[test] fn test_build() { diff --git a/actix-web/src/response/mod.rs b/actix-web/src/response/mod.rs index 977147104..11fd28301 100644 --- a/actix-web/src/response/mod.rs +++ b/actix-web/src/response/mod.rs @@ -5,10 +5,9 @@ mod responder; #[allow(clippy::module_inception)] mod response; -pub use self::builder::HttpResponseBuilder; -pub use self::customize_responder::CustomizeResponder; -pub use self::responder::Responder; -pub use self::response::HttpResponse; - #[cfg(feature = "cookies")] pub use self::response::CookieIter; +pub use self::{ + builder::HttpResponseBuilder, customize_responder::CustomizeResponder, responder::Responder, + response::HttpResponse, +}; diff --git a/actix-web/src/response/responder.rs b/actix-web/src/response/responder.rs index 965163a1f..7d0b0e585 100644 --- a/actix-web/src/response/responder.rs +++ b/actix-web/src/response/responder.rs @@ -186,11 +186,10 @@ impl_into_string_responder!(Cow<'_, str>); #[cfg(test)] pub(crate) mod tests { + use actix_http::body::to_bytes; use actix_service::Service; use bytes::{Bytes, BytesMut}; - use actix_http::body::to_bytes; - use super::*; use crate::{ error, diff --git a/actix-web/src/response/response.rs b/actix-web/src/response/response.rs index ead8badba..fbd87e10c 100644 --- a/actix-web/src/response/response.rs +++ b/actix-web/src/response/response.rs @@ -8,7 +8,6 @@ use actix_http::{ header::HeaderMap, Extensions, Response, ResponseHead, StatusCode, }; - #[cfg(feature = "cookies")] use { actix_http::{ diff --git a/actix-web/src/route.rs b/actix-web/src/route.rs index b37128f2c..674d0082a 100644 --- a/actix-web/src/route.rs +++ b/actix-web/src/route.rs @@ -290,31 +290,32 @@ mod tests { #[actix_rt::test] async fn test_route() { - let srv = init_service( - App::new() - .service( - web::resource("/test") - .route(web::get().to(HttpResponse::Ok)) - .route(web::put().to(|| async { - Err::(error::ErrorBadRequest("err")) - })) - .route(web::post().to(|| async { - sleep(Duration::from_millis(100)).await; - Ok::<_, Infallible>(HttpResponse::Created()) - })) - .route(web::delete().to(|| async { - sleep(Duration::from_millis(100)).await; - Err::(error::ErrorBadRequest("err")) - })), - ) - .service(web::resource("/json").route(web::get().to(|| async { - sleep(Duration::from_millis(25)).await; - web::Json(MyObject { - name: "test".to_string(), - }) - }))), - ) - .await; + let srv = + init_service( + App::new() + .service( + web::resource("/test") + .route(web::get().to(HttpResponse::Ok)) + .route(web::put().to(|| async { + Err::(error::ErrorBadRequest("err")) + })) + .route(web::post().to(|| async { + sleep(Duration::from_millis(100)).await; + Ok::<_, Infallible>(HttpResponse::Created()) + })) + .route(web::delete().to(|| async { + sleep(Duration::from_millis(100)).await; + Err::(error::ErrorBadRequest("err")) + })), + ) + .service(web::resource("/json").route(web::get().to(|| async { + sleep(Duration::from_millis(25)).await; + web::Json(MyObject { + name: "test".to_string(), + }) + }))), + ) + .await; let req = TestRequest::with_uri("/test") .method(Method::GET) diff --git a/actix-web/src/rt.rs b/actix-web/src/rt.rs index 7973da73c..629ffe3a0 100644 --- a/actix-web/src/rt.rs +++ b/actix-web/src/rt.rs @@ -66,8 +66,7 @@ // - Re-export but hide the runtime macros because they won't work directly but are required for // `#[actix_web::main]` and `#[actix_web::test]` to work. -pub use actix_rt::{net, pin, signal, spawn, task, time, Runtime, System, SystemRunner}; - #[cfg(feature = "macros")] #[doc(hidden)] pub use actix_macros::{main, test}; +pub use actix_rt::{net, pin, signal, spawn, task, time, Runtime, System, SystemRunner}; diff --git a/actix-web/src/scope.rs b/actix-web/src/scope.rs index 9af05674b..e7c4e047a 100644 --- a/actix-web/src/scope.rs +++ b/actix-web/src/scope.rs @@ -3,8 +3,8 @@ use std::{cell::RefCell, fmt, future::Future, mem, rc::Rc}; use actix_http::{body::MessageBody, Extensions}; use actix_router::{ResourceDef, Router}; use actix_service::{ - apply, apply_fn_factory, boxed, IntoServiceFactory, Service, ServiceFactory, - ServiceFactoryExt, Transform, + apply, apply_fn_factory, boxed, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt, + Transform, }; use futures_core::future::LocalBoxFuture; use futures_util::future::join_all; @@ -273,12 +273,8 @@ where pub fn default_service(mut self, f: F) -> Self where F: IntoServiceFactory, - U: ServiceFactory< - ServiceRequest, - Config = (), - Response = ServiceResponse, - Error = Error, - > + 'static, + U: ServiceFactory + + 'static, U::InitError: fmt::Debug, { // create and configure default resource @@ -604,11 +600,11 @@ mod tests { #[actix_rt::test] async fn test_scope() { - let srv = - init_service(App::new().service( - web::scope("/app").service(web::resource("/path1").to(HttpResponse::Ok)), - )) - .await; + let srv = init_service( + App::new() + .service(web::scope("/app").service(web::resource("/path1").to(HttpResponse::Ok))), + ) + .await; let req = TestRequest::with_uri("/app/path1").to_request(); let resp = srv.call(req).await.unwrap(); @@ -638,8 +634,7 @@ mod tests { #[actix_rt::test] async fn test_scope_root2() { let srv = init_service( - App::new() - .service(web::scope("/app/").service(web::resource("").to(HttpResponse::Ok))), + App::new().service(web::scope("/app/").service(web::resource("").to(HttpResponse::Ok))), ) .await; @@ -784,10 +779,11 @@ mod tests { #[actix_rt::test] async fn test_nested_scope_no_slash() { - let srv = init_service(App::new().service(web::scope("/app").service( - web::scope("t1").service(web::resource("/path1").to(HttpResponse::Created)), - ))) - .await; + let srv = + init_service(App::new().service(web::scope("/app").service( + web::scope("t1").service(web::resource("/path1").to(HttpResponse::Created)), + ))) + .await; let req = TestRequest::with_uri("/app/t1/path1").to_request(); let resp = srv.call(req).await.unwrap(); @@ -845,12 +841,9 @@ mod tests { #[actix_rt::test] async fn test_nested_scope_with_variable_segment() { let srv = init_service(App::new().service(web::scope("/app").service( - web::scope("/{project_id}").service(web::resource("/path1").to( - |r: HttpRequest| { - HttpResponse::Created() - .body(format!("project: {}", &r.match_info()["project_id"])) - }, - )), + web::scope("/{project_id}").service(web::resource("/path1").to(|r: HttpRequest| { + HttpResponse::Created().body(format!("project: {}", &r.match_info()["project_id"])) + })), ))) .await; @@ -1065,15 +1058,16 @@ mod tests { #[allow(deprecated)] #[actix_rt::test] async fn test_override_data_default_service() { - let srv = init_service(App::new().data(1usize).service( - web::scope("app").data(10usize).default_service(web::to( - |data: web::Data| { - assert_eq!(**data, 10); - HttpResponse::Ok() - }, - )), - )) - .await; + let srv = + init_service(App::new().data(1usize).service( + web::scope("app").data(10usize).default_service(web::to( + |data: web::Data| { + assert_eq!(**data, 10); + HttpResponse::Ok() + }, + )), + )) + .await; let req = TestRequest::with_uri("/app/t").to_request(); let resp = call_service(&srv, req).await; @@ -1150,11 +1144,11 @@ mod tests { #[actix_rt::test] async fn test_url_for_nested() { let srv = init_service(App::new().service(web::scope("/a").service( - web::scope("/b").service(web::resource("/c/{stuff}").name("c").route( - web::get().to(|req: HttpRequest| { + web::scope("/b").service(web::resource("/c/{stuff}").name("c").route(web::get().to( + |req: HttpRequest| { HttpResponse::Ok().body(format!("{}", req.url_for("c", ["12345"]).unwrap())) - }), - )), + }, + ))), ))) .await; diff --git a/actix-web/src/server.rs b/actix-web/src/server.rs index c11d0ef53..b96a84939 100644 --- a/actix-web/src/server.rs +++ b/actix-web/src/server.rs @@ -7,20 +7,18 @@ use std::{ time::Duration, }; +#[cfg(any(feature = "openssl", feature = "rustls"))] +use actix_http::TlsAcceptorConfig; use actix_http::{body::MessageBody, Extensions, HttpService, KeepAlive, Request, Response}; use actix_server::{Server, ServerBuilder}; use actix_service::{ map_config, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt as _, }; - #[cfg(feature = "openssl")] use actix_tls::accept::openssl::reexports::{AlpnError, SslAcceptor, SslAcceptorBuilder}; #[cfg(feature = "rustls")] use actix_tls::accept::rustls::reexports::ServerConfig as RustlsServerConfig; -#[cfg(any(feature = "openssl", feature = "rustls"))] -use actix_http::TlsAcceptorConfig; - use crate::{config::AppConfig, Error}; struct Socket { @@ -437,9 +435,8 @@ where .local_addr(addr); if let Some(handler) = on_connect_fn.clone() { - svc = svc.on_connect_ext(move |io: &_, ext: _| { - (handler)(io as &dyn Any, ext) - }) + svc = + svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext)) }; let fac = factory() @@ -481,9 +478,8 @@ where .local_addr(addr); if let Some(handler) = on_connect_fn.clone() { - svc = svc.on_connect_ext(move |io: &_, ext: _| { - (handler)(io as &dyn Any, ext) - }) + svc = + svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext)) }; let fac = factory() @@ -715,8 +711,7 @@ where .client_disconnect_timeout(c.client_disconnect_timeout); if let Some(handler) = on_connect_fn.clone() { - svc = svc - .on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext)); + svc = svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext)); } let fac = factory() @@ -759,10 +754,7 @@ where } /// Bind TCP listeners to socket addresses resolved from `addrs` with options. -fn bind_addrs( - addrs: impl net::ToSocketAddrs, - backlog: u32, -) -> io::Result> { +fn bind_addrs(addrs: impl net::ToSocketAddrs, backlog: u32) -> io::Result> { let mut err = None; let mut success = false; let mut sockets = Vec::new(); diff --git a/actix-web/src/service.rs b/actix-web/src/service.rs index f7692ce16..0e17c9949 100644 --- a/actix-web/src/service.rs +++ b/actix-web/src/service.rs @@ -696,30 +696,36 @@ service_tuple! { A B C D E F G H I J K L } #[cfg(test)] mod tests { - use super::*; - use crate::test::{self, init_service, TestRequest}; - use crate::{guard, http, web, App, HttpResponse}; use actix_service::Service; use actix_utils::future::ok; + use super::*; + use crate::{ + guard, http, + test::{self, init_service, TestRequest}, + web, App, HttpResponse, + }; + #[actix_rt::test] async fn test_service() { - let srv = init_service( - App::new().service(web::service("/test").name("test").finish( - |req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())), - )), - ) - .await; + let srv = + init_service( + App::new().service(web::service("/test").name("test").finish( + |req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())), + )), + ) + .await; let req = TestRequest::with_uri("/test").to_request(); let resp = srv.call(req).await.unwrap(); assert_eq!(resp.status(), http::StatusCode::OK); - let srv = init_service( - App::new().service(web::service("/test").guard(guard::Get()).finish( - |req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())), - )), - ) - .await; + let srv = + init_service( + App::new().service(web::service("/test").guard(guard::Get()).finish( + |req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())), + )), + ) + .await; let req = TestRequest::with_uri("/test") .method(http::Method::PUT) .to_request(); @@ -731,18 +737,19 @@ mod tests { #[allow(deprecated)] #[actix_rt::test] async fn test_service_data() { - let srv = - init_service( - App::new() - .data(42u32) - .service(web::service("/test").name("test").finish( - |req: ServiceRequest| { + let srv = init_service( + App::new() + .data(42u32) + .service( + web::service("/test") + .name("test") + .finish(|req: ServiceRequest| { assert_eq!(req.app_data::>().unwrap().as_ref(), &42); ok(req.into_response(HttpResponse::Ok().finish())) - }, - )), - ) - .await; + }), + ), + ) + .await; let req = TestRequest::with_uri("/test").to_request(); let resp = srv.call(req).await.unwrap(); assert_eq!(resp.status(), http::StatusCode::OK); @@ -773,9 +780,7 @@ mod tests { async fn test_services_macro() { let scoped = services![ web::service("/scoped_test1").name("scoped_test1").finish( - |req: ServiceRequest| async { - Ok(req.into_response(HttpResponse::Ok().finish())) - } + |req: ServiceRequest| async { Ok(req.into_response(HttpResponse::Ok().finish())) } ), web::resource("/scoped_test2").to(|| async { "test2" }), ]; @@ -861,9 +866,7 @@ mod tests { svc.call(req) }) .route("/", web::get().to(|| async { "" })) - .service( - web::resource("/resource1/{name}/index.html").route(web::get().to(index)), - ), + .service(web::resource("/resource1/{name}/index.html").route(web::get().to(index))), ) .await; diff --git a/actix-web/src/test/mod.rs b/actix-web/src/test/mod.rs index 5d9367b82..5e647956b 100644 --- a/actix-web/src/test/mod.rs +++ b/actix-web/src/test/mod.rs @@ -29,18 +29,20 @@ mod test_request; mod test_services; mod test_utils; -pub use self::test_request::TestRequest; #[allow(deprecated)] pub use self::test_services::{default_service, ok_service, simple_service, status_service}; -#[allow(deprecated)] -pub use self::test_utils::{ - call_and_read_body, call_and_read_body_json, call_service, init_service, read_body, - read_body_json, read_response, read_response_json, try_call_and_read_body_json, - try_call_service, try_read_body, try_read_body_json, -}; - #[cfg(test)] pub(crate) use self::test_utils::try_init_service; +#[allow(deprecated)] +pub use self::test_utils::{read_response, read_response_json}; +pub use self::{ + test_request::TestRequest, + test_utils::{ + call_and_read_body, call_and_read_body_json, call_service, init_service, read_body, + read_body_json, try_call_and_read_body_json, try_call_service, try_read_body, + try_read_body_json, + }, +}; /// Reduces boilerplate code when testing expected response payloads. /// diff --git a/actix-web/src/test/test_request.rs b/actix-web/src/test/test_request.rs index e81561d17..5491af0ac 100644 --- a/actix-web/src/test/test_request.rs +++ b/actix-web/src/test/test_request.rs @@ -3,13 +3,17 @@ use std::{borrow::Cow, net::SocketAddr, rc::Rc}; use actix_http::{test::TestRequest as HttpTestRequest, Request}; use serde::Serialize; +#[cfg(feature = "cookies")] +use crate::cookie::{Cookie, CookieJar}; use crate::{ app_service::AppInitServiceState, config::AppConfig, data::Data, dev::{Extensions, Path, Payload, ResourceDef, Service, Url}, - http::header::ContentType, - http::{header::TryIntoHeaderPair, Method, Uri, Version}, + http::{ + header::{ContentType, TryIntoHeaderPair}, + Method, Uri, Version, + }, rmap::ResourceMap, service::{ServiceRequest, ServiceResponse}, test, @@ -17,9 +21,6 @@ use crate::{ HttpRequest, HttpResponse, }; -#[cfg(feature = "cookies")] -use crate::cookie::{Cookie, CookieJar}; - /// Test `Request` builder. /// /// For unit testing, actix provides a request builder type and a simple handler runner. TestRequest implements a builder-like pattern. @@ -197,8 +198,7 @@ impl TestRequest { /// /// The `Content-Type` header is set to `application/json`. pub fn set_json(mut self, data: impl Serialize) -> Self { - let bytes = - serde_json::to_string(&data).expect("Failed to serialize test data to json"); + let bytes = serde_json::to_string(&data).expect("Failed to serialize test data to json"); self.req.set_payload(bytes); self.req.insert_header(ContentType::json()); self diff --git a/actix-web/src/test/test_utils.rs b/actix-web/src/test/test_utils.rs index bba23a0fe..4540d8a6b 100644 --- a/actix-web/src/test/test_utils.rs +++ b/actix-web/src/test/test_utils.rs @@ -201,9 +201,7 @@ where } /// Fallible version of [`read_body`] that allows testing MessageBody reading errors. -pub async fn try_read_body( - res: ServiceResponse, -) -> Result::Error> +pub async fn try_read_body(res: ServiceResponse) -> Result::Error> where B: MessageBody, { @@ -363,8 +361,7 @@ mod tests { use super::*; use crate::{ - dev::ServiceRequest, http::header, test::TestRequest, web, App, HttpMessage, - HttpResponse, + dev::ServiceRequest, http::header, test::TestRequest, web, App, HttpMessage, HttpResponse, }; #[actix_rt::test] @@ -408,10 +405,11 @@ mod tests { #[actix_rt::test] async fn test_response_json() { - let app = init_service(App::new().service(web::resource("/people").route( - web::post().to(|person: web::Json| HttpResponse::Ok().json(person)), - ))) - .await; + let app = + init_service(App::new().service(web::resource("/people").route( + web::post().to(|person: web::Json| HttpResponse::Ok().json(person)), + ))) + .await; let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes(); @@ -427,10 +425,11 @@ mod tests { #[actix_rt::test] async fn test_try_response_json_error() { - let app = init_service(App::new().service(web::resource("/people").route( - web::post().to(|person: web::Json| HttpResponse::Ok().json(person)), - ))) - .await; + let app = + init_service(App::new().service(web::resource("/people").route( + web::post().to(|person: web::Json| HttpResponse::Ok().json(person)), + ))) + .await; let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes(); @@ -447,10 +446,11 @@ mod tests { #[actix_rt::test] async fn test_body_json() { - let app = init_service(App::new().service(web::resource("/people").route( - web::post().to(|person: web::Json| HttpResponse::Ok().json(person)), - ))) - .await; + let app = + init_service(App::new().service(web::resource("/people").route( + web::post().to(|person: web::Json| HttpResponse::Ok().json(person)), + ))) + .await; let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes(); @@ -467,10 +467,11 @@ mod tests { #[actix_rt::test] async fn test_try_body_json_error() { - let app = init_service(App::new().service(web::resource("/people").route( - web::post().to(|person: web::Json| HttpResponse::Ok().json(person)), - ))) - .await; + let app = + init_service(App::new().service(web::resource("/people").route( + web::post().to(|person: web::Json| HttpResponse::Ok().json(person)), + ))) + .await; // Use a number for id to cause a deserialization error. let payload = r#"{"id":12345,"name":"User name"}"#.as_bytes(); @@ -488,10 +489,11 @@ mod tests { #[actix_rt::test] async fn test_request_response_form() { - let app = init_service(App::new().service(web::resource("/people").route( - web::post().to(|person: web::Form| HttpResponse::Ok().json(person)), - ))) - .await; + let app = + init_service(App::new().service(web::resource("/people").route( + web::post().to(|person: web::Form| HttpResponse::Ok().json(person)), + ))) + .await; let payload = Person { id: "12345".to_string(), @@ -531,10 +533,11 @@ mod tests { #[actix_rt::test] async fn test_request_response_json() { - let app = init_service(App::new().service(web::resource("/people").route( - web::post().to(|person: web::Json| HttpResponse::Ok().json(person)), - ))) - .await; + let app = + init_service(App::new().service(web::resource("/people").route( + web::post().to(|person: web::Json| HttpResponse::Ok().json(person)), + ))) + .await; let payload = Person { id: "12345".to_string(), @@ -565,9 +568,11 @@ mod tests { InitError = (), >, > { - App::new().service(web::resource("/people").route( - web::post().to(|person: web::Json| HttpResponse::Ok().json(person)), - )) + App::new().service( + web::resource("/people").route( + web::post().to(|person: web::Json| HttpResponse::Ok().json(person)), + ), + ) } async fn test_service( diff --git a/actix-web/src/types/either.rs b/actix-web/src/types/either.rs index df93fb5ec..db244fd9a 100644 --- a/actix-web/src/types/either.rs +++ b/actix-web/src/types/either.rs @@ -238,8 +238,7 @@ where match res { Ok(bytes) => { let fallback = bytes.clone(); - let left = - L::from_request(this.req, &mut payload_from_bytes(bytes)); + let left = L::from_request(this.req, &mut payload_from_bytes(bytes)); EitherExtractState::Left { left, fallback } } Err(err) => break Err(EitherExtractError::Bytes(err)), @@ -266,10 +265,7 @@ where match res { Ok(data) => break Ok(Either::Right(data)), Err(err) => { - break Err(EitherExtractError::Extract( - left_err.take().unwrap(), - err, - )); + break Err(EitherExtractError::Extract(left_err.take().unwrap(), err)); } } } @@ -339,12 +335,11 @@ mod tests { .set_payload(Bytes::from_static(b"!@$%^&*()")) .to_http_parts(); - let payload = Either::, Json>, Bytes>::from_request( - &req, &mut pl, - ) - .await - .unwrap() - .unwrap_right(); + let payload = + Either::, Json>, Bytes>::from_request(&req, &mut pl) + .await + .unwrap() + .unwrap_right(); assert_eq!(&payload.as_ref(), &b"!@$%^&*()"); } @@ -356,14 +351,13 @@ mod tests { }) .to_http_parts(); - let form = Either::, Json>, Bytes>::from_request( - &req, &mut pl, - ) - .await - .unwrap() - .unwrap_left() - .unwrap_right() - .into_inner(); + let form = + Either::, Json>, Bytes>::from_request(&req, &mut pl) + .await + .unwrap() + .unwrap_left() + .unwrap_right() + .into_inner(); assert_eq!(&form.hello, "world"); } } diff --git a/actix-web/src/types/form.rs b/actix-web/src/types/form.rs index d73f8ba74..7096b1e9c 100644 --- a/actix-web/src/types/form.rs +++ b/actix-web/src/types/form.rs @@ -20,9 +20,8 @@ use serde::{de::DeserializeOwned, Serialize}; #[cfg(feature = "__compress")] use crate::dev::Decompress; use crate::{ - body::EitherBody, error::UrlencodedError, extract::FromRequest, - http::header::CONTENT_LENGTH, web, Error, HttpMessage, HttpRequest, HttpResponse, - Responder, + body::EitherBody, error::UrlencodedError, extract::FromRequest, http::header::CONTENT_LENGTH, + web, Error, HttpMessage, HttpRequest, HttpResponse, Responder, }; /// URL encoded payload extractor and responder. @@ -417,13 +416,12 @@ mod tests { use serde::{Deserialize, Serialize}; use super::*; - use crate::test::TestRequest; use crate::{ http::{ header::{HeaderValue, CONTENT_LENGTH, CONTENT_TYPE}, StatusCode, }, - test::assert_body_eq, + test::{assert_body_eq, TestRequest}, }; #[derive(Deserialize, Serialize, Debug, PartialEq)] diff --git a/actix-web/src/types/header.rs b/actix-web/src/types/header.rs index 6ea77faf6..8b1740e6c 100644 --- a/actix-web/src/types/header.rs +++ b/actix-web/src/types/header.rs @@ -75,8 +75,10 @@ where #[cfg(test)] mod tests { use super::*; - use crate::http::{header, Method}; - use crate::test::TestRequest; + use crate::{ + http::{header, Method}, + test::TestRequest, + }; #[actix_rt::test] async fn test_header_extract() { diff --git a/actix-web/src/types/json.rs b/actix-web/src/types/json.rs index 4eab55175..2523e55f2 100644 --- a/actix-web/src/types/json.rs +++ b/actix-web/src/types/json.rs @@ -10,12 +10,11 @@ use std::{ task::{Context, Poll}, }; +use actix_http::Payload; use bytes::BytesMut; use futures_core::{ready, Stream as _}; use serde::{de::DeserializeOwned, Serialize}; -use actix_http::Payload; - #[cfg(feature = "__compress")] use crate::dev::Decompress; use crate::{ @@ -158,8 +157,7 @@ impl FromRequest for Json { } } -type JsonErrorHandler = - Option Error + Send + Sync>>; +type JsonErrorHandler = Option Error + Send + Sync>>; pub struct JsonExtractFut { req: Option, @@ -423,9 +421,7 @@ impl Future for JsonBody { let chunk = chunk?; let buf_len = buf.len() + chunk.len(); if buf_len > *limit { - return Poll::Ready(Err(JsonPayloadError::Overflow { - limit: *limit, - })); + return Poll::Ready(Err(JsonPayloadError::Overflow { limit: *limit })); } else { buf.extend_from_slice(&chunk); } @@ -508,8 +504,7 @@ mod tests { let msg = MyObject { name: "invalid request".to_string(), }; - let resp = - HttpResponse::BadRequest().body(serde_json::to_string(&msg).unwrap()); + let resp = HttpResponse::BadRequest().body(serde_json::to_string(&msg).unwrap()); InternalError::from_response(err, resp).into() })) .to_http_parts(); @@ -747,7 +742,8 @@ mod tests { assert!(s.is_err()); let err_str = s.err().unwrap().to_string(); - assert!(err_str - .contains("JSON payload (16 bytes) is larger than allowed (limit: 10 bytes).")); + assert!( + err_str.contains("JSON payload (16 bytes) is larger than allowed (limit: 10 bytes).") + ); } } diff --git a/actix-web/src/types/mod.rs b/actix-web/src/types/mod.rs index bab7c3bc0..792edd650 100644 --- a/actix-web/src/types/mod.rs +++ b/actix-web/src/types/mod.rs @@ -9,11 +9,13 @@ mod payload; mod query; mod readlines; -pub use self::either::Either; -pub use self::form::{Form, FormConfig, UrlEncoded}; -pub use self::header::Header; -pub use self::json::{Json, JsonBody, JsonConfig}; -pub use self::path::{Path, PathConfig}; -pub use self::payload::{Payload, PayloadConfig}; -pub use self::query::{Query, QueryConfig}; -pub use self::readlines::Readlines; +pub use self::{ + either::Either, + form::{Form, FormConfig, UrlEncoded}, + header::Header, + json::{Json, JsonBody, JsonConfig}, + path::{Path, PathConfig}, + payload::{Payload, PayloadConfig}, + query::{Query, QueryConfig}, + readlines::Readlines, +}; diff --git a/actix-web/src/types/path.rs b/actix-web/src/types/path.rs index a90c912f6..cc87bb80f 100644 --- a/actix-web/src/types/path.rs +++ b/actix-web/src/types/path.rs @@ -156,8 +156,7 @@ mod tests { use serde::Deserialize; use super::*; - use crate::test::TestRequest; - use crate::{error, http, HttpResponse}; + use crate::{error, http, test::TestRequest, HttpResponse}; #[derive(Deserialize, Debug, Display)] #[display(fmt = "MyStruct({}, {})", key, value)] @@ -276,8 +275,7 @@ mod tests { async fn test_custom_err_handler() { let (req, mut pl) = TestRequest::with_uri("/name/user1/") .app_data(PathConfig::default().error_handler(|err, _| { - error::InternalError::from_response(err, HttpResponse::Conflict().finish()) - .into() + error::InternalError::from_response(err, HttpResponse::Conflict().finish()).into() })) .to_http_parts(); diff --git a/actix-web/src/types/payload.rs b/actix-web/src/types/payload.rs index 4045cedb4..1d9c6aba5 100644 --- a/actix-web/src/types/payload.rs +++ b/actix-web/src/types/payload.rs @@ -16,8 +16,7 @@ use futures_core::{ready, stream::Stream}; use mime::Mime; use crate::{ - dev, error::ErrorBadRequest, http::header, web, Error, FromRequest, HttpMessage, - HttpRequest, + dev, error::ErrorBadRequest, http::header, web, Error, FromRequest, HttpMessage, HttpRequest, }; /// Extract a request's raw payload stream. @@ -377,9 +376,11 @@ mod tests { use bytes::Bytes; use super::*; - use crate::http::{header, StatusCode}; - use crate::test::{call_service, init_service, TestRequest}; - use crate::{web, App, Responder}; + use crate::{ + http::{header, StatusCode}, + test::{call_service, init_service, TestRequest}, + web, App, Responder, + }; #[actix_rt::test] async fn test_payload_config() { diff --git a/actix-web/src/web.rs b/actix-web/src/web.rs index 0533f7f8f..204313752 100644 --- a/actix-web/src/web.rs +++ b/actix-web/src/web.rs @@ -21,17 +21,14 @@ use std::{borrow::Cow, future::Future}; use actix_router::IntoPatterns; pub use bytes::{Buf, BufMut, Bytes, BytesMut}; +pub use crate::{ + config::ServiceConfig, data::Data, redirect::Redirect, request_data::ReqData, types::*, +}; use crate::{ error::BlockingError, http::Method, service::WebService, FromRequest, Handler, Resource, Responder, Route, Scope, }; -pub use crate::config::ServiceConfig; -pub use crate::data::Data; -pub use crate::redirect::Redirect; -pub use crate::request_data::ReqData; -pub use crate::types::*; - /// Creates a new resource for a specific path. /// /// Resources may have dynamic path segments. For example, a resource with the path `/a/{name}/c` @@ -200,10 +197,7 @@ pub fn service(path: T) -> WebService { /// // the client will resolve this redirect to /api/to-path /// .service(web::redirect("/api/from-path", "to-path")); /// ``` -pub fn redirect( - from: impl Into>, - to: impl Into>, -) -> Redirect { +pub fn redirect(from: impl Into>, to: impl Into>) -> Redirect { Redirect::new(from, to) } diff --git a/actix-web/tests/test_server.rs b/actix-web/tests/test_server.rs index 270223d69..8ce889396 100644 --- a/actix-web/tests/test_server.rs +++ b/actix-web/tests/test_server.rs @@ -19,14 +19,13 @@ use actix_web::{ }; use bytes::Bytes; use futures_core::ready; -use rand::{distributions::Alphanumeric, Rng as _}; - #[cfg(feature = "openssl")] use openssl::{ pkey::PKey, ssl::{SslAcceptor, SslMethod}, x509::X509, }; +use rand::{distributions::Alphanumeric, Rng as _}; mod utils; @@ -94,9 +93,8 @@ impl futures_core::stream::Stream for TestBody { #[actix_rt::test] async fn test_body() { let srv = actix_test::start(|| { - App::new().service( - web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) })), - ) + App::new() + .service(web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) }))) }); let mut res = srv.get("/").send().await.unwrap(); @@ -226,8 +224,7 @@ async fn test_body_chunked_implicit() { App::new() .wrap(Compress::default()) .service(web::resource("/").route(web::get().to(|| async { - HttpResponse::Ok() - .streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24)) + HttpResponse::Ok().streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24)) }))) }); @@ -256,8 +253,7 @@ async fn test_body_br_streaming() { App::new() .wrap(Compress::default()) .service(web::resource("/").route(web::to(|| async { - HttpResponse::Ok() - .streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24)) + HttpResponse::Ok().streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24)) }))) }); @@ -392,8 +388,7 @@ async fn test_body_zstd_streaming() { App::new() .wrap(Compress::default()) .service(web::resource("/").route(web::to(move || async { - HttpResponse::Ok() - .streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24)) + HttpResponse::Ok().streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24)) }))) }); @@ -686,15 +681,14 @@ async fn test_brotli_encoding_large_openssl() { use actix_web::http::header; let data = STR.repeat(10); - let srv = - actix_test::start_with(actix_test::config().openssl(openssl_config()), move || { - App::new().service(web::resource("/").route(web::to(|bytes: Bytes| async { - // echo decompressed request body back in response - HttpResponse::Ok() - .insert_header(header::ContentEncoding::Identity) - .body(bytes) - }))) - }); + let srv = actix_test::start_with(actix_test::config().openssl(openssl_config()), move || { + App::new().service(web::resource("/").route(web::to(|bytes: Bytes| async { + // echo decompressed request body back in response + HttpResponse::Ok() + .insert_header(header::ContentEncoding::Identity) + .body(bytes) + }))) + }); let mut res = srv .post("/") diff --git a/actix-web/tests/utils.rs b/actix-web/tests/utils.rs index 2532640c6..b9c708884 100644 --- a/actix-web/tests/utils.rs +++ b/actix-web/tests/utils.rs @@ -4,9 +4,10 @@ use std::io::{Read as _, Write as _}; pub mod gzip { - use super::*; use flate2::{read::GzDecoder, write::GzEncoder, Compression}; + use super::*; + pub fn encode(bytes: impl AsRef<[u8]>) -> Vec { let mut encoder = GzEncoder::new(Vec::new(), Compression::fast()); encoder.write_all(bytes.as_ref()).unwrap(); @@ -22,9 +23,10 @@ pub mod gzip { } pub mod deflate { - use super::*; use flate2::{read::ZlibDecoder, write::ZlibEncoder, Compression}; + use super::*; + pub fn encode(bytes: impl AsRef<[u8]>) -> Vec { let mut encoder = ZlibEncoder::new(Vec::new(), Compression::fast()); encoder.write_all(bytes.as_ref()).unwrap(); @@ -40,9 +42,10 @@ pub mod deflate { } pub mod brotli { - use super::*; use ::brotli::{reader::Decompressor as BrotliDecoder, CompressorWriter as BrotliEncoder}; + use super::*; + pub fn encode(bytes: impl AsRef<[u8]>) -> Vec { let mut encoder = BrotliEncoder::new( Vec::new(), @@ -64,9 +67,10 @@ pub mod brotli { } pub mod zstd { - use super::*; use ::zstd::stream::{read::Decoder, write::Encoder}; + use super::*; + pub fn encode(bytes: impl AsRef<[u8]>) -> Vec { let mut encoder = Encoder::new(Vec::new(), 3).unwrap(); encoder.write_all(bytes.as_ref()).unwrap(); diff --git a/awc/src/any_body.rs b/awc/src/any_body.rs index d9c259d8f..08f5cc25e 100644 --- a/awc/src/any_body.rs +++ b/awc/src/any_body.rs @@ -4,11 +4,10 @@ use std::{ task::{Context, Poll}, }; +use actix_http::body::{BodySize, BoxBody, MessageBody}; use bytes::Bytes; use pin_project_lite::pin_project; -use actix_http::body::{BodySize, BoxBody, MessageBody}; - pin_project! { /// Represents various types of HTTP message body. #[derive(Clone)] diff --git a/awc/src/builder.rs b/awc/src/builder.rs index b15e2de0b..a54960382 100644 --- a/awc/src/builder.rs +++ b/awc/src/builder.rs @@ -1,7 +1,5 @@ use std::{fmt, net::IpAddr, rc::Rc, time::Duration}; -use base64::prelude::*; - use actix_http::{ error::HttpError, header::{self, HeaderMap, HeaderName, TryIntoHeaderPair}, @@ -9,6 +7,7 @@ use actix_http::{ }; use actix_rt::net::{ActixStream, TcpStream}; use actix_service::{boxed, Service}; +use base64::prelude::*; use crate::{ client::{ @@ -72,11 +71,8 @@ where /// Use custom connector service. pub fn connector(self, connector: Connector) -> ClientBuilder where - S1: Service< - ConnectInfo, - Response = TcpConnection, - Error = TcpConnectError, - > + Clone + S1: Service, Response = TcpConnection, Error = TcpConnectError> + + Clone + 'static, Io1: ActixStream + fmt::Debug + 'static, { @@ -227,10 +223,7 @@ where /// Registers middleware, in the form of a middleware component (type), that runs during inbound /// and/or outbound processing in the request life-cycle (request -> response), /// modifying request/response as necessary, across all requests managed by the `Client`. - pub fn wrap( - self, - mw: M1, - ) -> ClientBuilder> + pub fn wrap(self, mw: M1) -> ClientBuilder> where M: Transform, M1: Transform, @@ -253,8 +246,7 @@ where pub fn finish(self) -> Client where M: Transform>, ConnectRequest> + 'static, - M::Transform: - Service, + M::Transform: Service, { let max_redirects = self.max_redirects; @@ -269,8 +261,7 @@ where fn _finish(self) -> Client where M: Transform>, ConnectRequest> + 'static, - M::Transform: - Service, + M::Transform: Service, { let mut connector = self.connector; diff --git a/awc/src/client/connection.rs b/awc/src/client/connection.rs index 9de4ece4f..64075eae8 100644 --- a/awc/src/client/connection.rs +++ b/awc/src/client/connection.rs @@ -7,19 +7,15 @@ use std::{ }; use actix_codec::{AsyncRead, AsyncWrite, Framed, ReadBuf}; +use actix_http::{body::MessageBody, h1::ClientCodec, Payload, RequestHeadType, ResponseHead}; use actix_rt::task::JoinHandle; use bytes::Bytes; use futures_core::future::LocalBoxFuture; use h2::client::SendRequest; -use actix_http::{body::MessageBody, h1::ClientCodec, Payload, RequestHeadType, ResponseHead}; - +use super::{error::SendRequestError, h1proto, h2proto, pool::Acquired}; use crate::BoxError; -use super::error::SendRequestError; -use super::pool::Acquired; -use super::{h1proto, h2proto}; - /// Trait alias for types impl [tokio::io::AsyncRead] and [tokio::io::AsyncWrite]. pub trait ConnectionIo: AsyncRead + AsyncWrite + Unpin + 'static {} @@ -83,10 +79,7 @@ impl AsyncWrite for H1Connection { self.io_pin_mut().poll_flush(cx) } - fn poll_shutdown( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { + fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.io_pin_mut().poll_shutdown(cx) } diff --git a/awc/src/client/connector.rs b/awc/src/client/connector.rs index 51d6e180b..1ecaf9947 100644 --- a/awc/src/client/connector.rs +++ b/awc/src/client/connector.rs @@ -133,11 +133,8 @@ impl Connector { pub fn connector(self, connector: S1) -> Connector where Io1: ActixStream + fmt::Debug + 'static, - S1: Service< - ConnectInfo, - Response = TcpConnection, - Error = TcpConnectError, - > + Clone, + S1: Service, Response = TcpConnection, Error = TcpConnectError> + + Clone, { Connector { connector, @@ -189,10 +186,7 @@ where #[doc(hidden)] #[cfg(feature = "openssl")] #[deprecated(since = "3.0.0", note = "Renamed to `Connector::openssl`.")] - pub fn ssl( - mut self, - connector: actix_tls::connect::openssl::reexports::SslConnector, - ) -> Self { + pub fn ssl(mut self, connector: actix_tls::connect::openssl::reexports::SslConnector) -> Self { self.tls = OurTlsConnector::Openssl(connector); self } @@ -312,9 +306,7 @@ where let tls = match self.tls { #[cfg(feature = "openssl")] - OurTlsConnector::OpensslBuilder(builder) => { - OurTlsConnector::Openssl(builder.build()) - } + OurTlsConnector::OpensslBuilder(builder) => OurTlsConnector::Openssl(builder.build()), tls => tls, }; @@ -467,9 +459,7 @@ pub struct TcpConnectorService { impl Service for TcpConnectorService where - S: Service, Error = ConnectError> - + Clone - + 'static, + S: Service, Error = ConnectError> + Clone + 'static, { type Response = (Io, Protocol); type Error = ConnectError; @@ -520,9 +510,8 @@ struct TlsConnectorService { impl Service for TlsConnectorService where - Tcp: Service, Error = ConnectError> - + Clone - + 'static, + Tcp: + Service, Error = ConnectError> + Clone + 'static, Tls: Service, Error = std::io::Error> + Clone + 'static, Tls::Response: IntoConnectionIo, IO: ConnectionIo, diff --git a/awc/src/client/error.rs b/awc/src/client/error.rs index 9f290c5c0..d351e1067 100644 --- a/awc/src/client/error.rs +++ b/awc/src/client/error.rs @@ -1,11 +1,9 @@ use std::{fmt, io}; -use derive_more::{Display, From}; - use actix_http::error::{HttpError, ParseError}; - #[cfg(feature = "openssl")] use actix_tls::accept::openssl::reexports::Error as OpensslError; +use derive_more::{Display, From}; use crate::BoxError; diff --git a/awc/src/client/h1proto.rs b/awc/src/client/h1proto.rs index 8738c2f7f..c756179a4 100644 --- a/awc/src/client/h1proto.rs +++ b/awc/src/client/h1proto.rs @@ -18,12 +18,11 @@ use futures_core::{ready, Stream}; use futures_util::SinkExt as _; use pin_project_lite::pin_project; -use crate::BoxError; - use super::{ connection::{ConnectionIo, H1Connection}, error::{ConnectError, SendRequestError}, }; +use crate::BoxError; pub(crate) async fn send_request( io: H1Connection, diff --git a/awc/src/client/h2proto.rs b/awc/src/client/h2proto.rs index 709896ddd..d18db1410 100644 --- a/awc/src/client/h2proto.rs +++ b/awc/src/client/h2proto.rs @@ -1,28 +1,29 @@ use std::future::Future; -use actix_utils::future::poll_fn; -use bytes::Bytes; -use h2::{ - client::{Builder, Connection, SendRequest}, - SendStream, -}; -use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, TRANSFER_ENCODING}; -use http::{request::Request, Method, Version}; -use log::trace; - use actix_http::{ body::{BodySize, MessageBody}, header::HeaderMap, Payload, RequestHeadType, ResponseHead, }; - -use crate::BoxError; +use actix_utils::future::poll_fn; +use bytes::Bytes; +use h2::{ + client::{Builder, Connection, SendRequest}, + SendStream, +}; +use http::{ + header::{HeaderValue, CONNECTION, CONTENT_LENGTH, TRANSFER_ENCODING}, + request::Request, + Method, Version, +}; +use log::trace; use super::{ config::ConnectorConfig, connection::{ConnectionIo, H2Connection}, error::SendRequestError, }; +use crate::BoxError; pub(crate) async fn send_request( mut io: H2Connection, diff --git a/awc/src/client/mod.rs b/awc/src/client/mod.rs index b1df1fd3d..c9fa37253 100644 --- a/awc/src/client/mod.rs +++ b/awc/src/client/mod.rs @@ -19,9 +19,11 @@ mod h1proto; mod h2proto; mod pool; -pub use self::connection::{Connection, ConnectionIo}; -pub use self::connector::{Connector, ConnectorService}; -pub use self::error::{ConnectError, FreezeRequestError, InvalidUrl, SendRequestError}; +pub use self::{ + connection::{Connection, ConnectionIo}, + connector::{Connector, ConnectorService}, + error::{ConnectError, FreezeRequestError, InvalidUrl, SendRequestError}, +}; #[derive(Clone)] pub struct Connect { diff --git a/awc/src/client/pool.rs b/awc/src/client/pool.rs index 632608c45..2cf1f3ace 100644 --- a/awc/src/client/pool.rs +++ b/awc/src/client/pool.rs @@ -23,11 +23,13 @@ use http::uri::Authority; use pin_project_lite::pin_project; use tokio::sync::{OwnedSemaphorePermit, Semaphore}; -use super::config::ConnectorConfig; -use super::connection::{ConnectionInnerType, ConnectionIo, ConnectionType, H2ConnectionInner}; -use super::error::ConnectError; -use super::h2proto::handshake; -use super::Connect; +use super::{ + config::ConnectorConfig, + connection::{ConnectionInnerType, ConnectionIo, ConnectionType, H2ConnectionInner}, + error::ConnectError, + h2proto::handshake, + Connect, +}; #[derive(Hash, Eq, PartialEq, Clone, Debug)] pub struct Key { @@ -201,7 +203,9 @@ where // check if the connection is still usable if let ConnectionInnerType::H1(ref mut io) = c.conn { let check = ConnectionCheckFuture { io }; - match check.now_or_never().expect("ConnectionCheckFuture must never yield with Poll::Pending.") { + match check.now_or_never().expect( + "ConnectionCheckFuture must never yield with Poll::Pending.", + ) { ConnectionState::Tainted => { inner.close(c.conn); continue; diff --git a/awc/src/connect.rs b/awc/src/connect.rs index be1ea0fee..14ed9e958 100644 --- a/awc/src/connect.rs +++ b/awc/src/connect.rs @@ -13,9 +13,7 @@ use futures_core::{future::LocalBoxFuture, ready}; use crate::{ any_body::AnyBody, - client::{ - Connect as ClientConnect, ConnectError, Connection, ConnectionIo, SendRequestError, - }, + client::{Connect as ClientConnect, ConnectError, Connection, ConnectionIo, SendRequestError}, ClientResponse, }; @@ -62,9 +60,9 @@ impl ConnectResponse { pub fn into_client_response(self) -> ClientResponse { match self { ConnectResponse::Client(res) => res, - _ => panic!( - "ClientResponse only reachable with ConnectResponse::ClientResponse variant" - ), + _ => { + panic!("ClientResponse only reachable with ConnectResponse::ClientResponse variant") + } } } @@ -75,9 +73,9 @@ impl ConnectResponse { pub fn into_tunnel_response(self) -> (ResponseHead, Framed) { match self { ConnectResponse::Tunnel(head, framed) => (head, framed), - _ => panic!( - "TunnelResponse only reachable with ConnectResponse::TunnelResponse variant" - ), + _ => { + panic!("TunnelResponse only reachable with ConnectResponse::TunnelResponse variant") + } } } } diff --git a/awc/src/error.rs b/awc/src/error.rs index aa9dc4d99..0104e5fe8 100644 --- a/awc/src/error.rs +++ b/awc/src/error.rs @@ -7,7 +7,6 @@ pub use actix_http::{ ws::{HandshakeError as WsHandshakeError, ProtocolError as WsProtocolError}, StatusCode, }; - use derive_more::{Display, From}; use serde_json::error::Error as JsonError; diff --git a/awc/src/frozen.rs b/awc/src/frozen.rs index 4023bd1c8..8f3244997 100644 --- a/awc/src/frozen.rs +++ b/awc/src/frozen.rs @@ -1,15 +1,14 @@ use std::{net, rc::Rc, time::Duration}; -use bytes::Bytes; -use futures_core::Stream; -use serde::Serialize; - use actix_http::{ body::MessageBody, error::HttpError, header::{HeaderMap, TryIntoHeaderPair}, Method, RequestHead, Uri, }; +use bytes::Bytes; +use futures_core::Stream; +use serde::Serialize; use crate::{ client::ClientConfig, diff --git a/awc/src/lib.rs b/awc/src/lib.rs index b06df6b7d..ce2dfb34f 100644 --- a/awc/src/lib.rs +++ b/awc/src/lib.rs @@ -113,7 +113,6 @@ #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub use actix_http::body; - #[cfg(feature = "cookies")] pub use cookie; @@ -134,18 +133,18 @@ pub mod http { //! Various HTTP related types. // TODO: figure out how best to expose http::Error vs actix_http::Error - pub use actix_http::{ - header, uri, ConnectionType, Error, Method, StatusCode, Uri, Version, - }; + pub use actix_http::{header, uri, ConnectionType, Error, Method, StatusCode, Uri, Version}; } -pub use self::builder::ClientBuilder; -pub use self::client::{Client, Connect, Connector}; -pub use self::connect::{BoxConnectorService, BoxedSocket, ConnectRequest, ConnectResponse}; -pub use self::frozen::{FrozenClientRequest, FrozenSendBuilder}; -pub use self::request::ClientRequest; #[allow(deprecated)] pub use self::responses::{ClientResponse, JsonBody, MessageBody, ResponseBody}; -pub use self::sender::SendClientRequest; +pub use self::{ + builder::ClientBuilder, + client::{Client, Connect, Connector}, + connect::{BoxConnectorService, BoxedSocket, ConnectRequest, ConnectResponse}, + frozen::{FrozenClientRequest, FrozenSendBuilder}, + request::ClientRequest, + sender::SendClientRequest, +}; pub(crate) type BoxError = Box; diff --git a/awc/src/middleware/mod.rs b/awc/src/middleware/mod.rs index 330e3b7fe..8c63e9c75 100644 --- a/awc/src/middleware/mod.rs +++ b/awc/src/middleware/mod.rs @@ -1,11 +1,11 @@ mod redirect; -pub use self::redirect::Redirect; - use std::marker::PhantomData; use actix_service::Service; +pub use self::redirect::Redirect; + /// Trait for transform a type to another one. /// Both the input and output type should impl [actix_service::Service] trait. pub trait Transform { diff --git a/awc/src/middleware/redirect.rs b/awc/src/middleware/redirect.rs index d1216fa57..c38d6ad92 100644 --- a/awc/src/middleware/redirect.rs +++ b/awc/src/middleware/redirect.rs @@ -449,8 +449,7 @@ mod tests { } async fn test(req: HttpRequest, body: Bytes) -> HttpResponse { - if (req.method() == Method::GET || req.method() == Method::HEAD) - && body.is_empty() + if (req.method() == Method::GET || req.method() == Method::HEAD) && body.is_empty() { HttpResponse::Ok().finish() } else { @@ -550,10 +549,7 @@ mod tests { let port = *req.app_data::().unwrap(); if req.headers().get(header::AUTHORIZATION).is_some() { HttpResponse::Found() - .append_header(( - "location", - format!("http://localhost:{}/", port).as_str(), - )) + .append_header(("location", format!("http://localhost:{}/", port).as_str())) .finish() } else { HttpResponse::InternalServerError().finish() diff --git a/awc/src/request.rs b/awc/src/request.rs index 5e04aa8de..4e34e5771 100644 --- a/awc/src/request.rs +++ b/awc/src/request.rs @@ -1,17 +1,18 @@ use std::{fmt, net, rc::Rc, time::Duration}; -use base64::prelude::*; -use bytes::Bytes; -use futures_core::Stream; -use serde::Serialize; - use actix_http::{ body::MessageBody, error::HttpError, header::{self, HeaderMap, HeaderValue, TryIntoHeaderPair}, ConnectionType, Method, RequestHead, Uri, Version, }; +use base64::prelude::*; +use bytes::Bytes; +use futures_core::Stream; +use serde::Serialize; +#[cfg(feature = "cookies")] +use crate::cookie::{Cookie, CookieJar}; use crate::{ client::ClientConfig, error::{FreezeRequestError, InvalidUrl}, @@ -20,9 +21,6 @@ use crate::{ BoxError, }; -#[cfg(feature = "cookies")] -use crate::cookie::{Cookie, CookieJar}; - /// An HTTP Client request builder /// /// This type can be used to construct an instance of `ClientRequest` through a @@ -291,10 +289,7 @@ impl ClientRequest { } /// Sets the query part of the request - pub fn query( - mut self, - query: &T, - ) -> Result { + pub fn query(mut self, query: &T) -> Result { let mut parts = self.head.uri.clone().into_parts(); if let Some(path_and_query) = parts.path_and_query { diff --git a/awc/src/responses/mod.rs b/awc/src/responses/mod.rs index 588ce014c..95a078093 100644 --- a/awc/src/responses/mod.rs +++ b/awc/src/responses/mod.rs @@ -8,10 +8,9 @@ mod read_body; mod response; mod response_body; -pub use self::json_body::JsonBody; -pub use self::response::ClientResponse; #[allow(deprecated)] pub use self::response_body::{MessageBody, ResponseBody}; +pub use self::{json_body::JsonBody, response::ClientResponse}; /// Default body size limit: 2 MiB const DEFAULT_BODY_LIMIT: usize = 2 * 1024 * 1024; diff --git a/awc/src/responses/response.rs b/awc/src/responses/response.rs index c7c0a6362..0eafcff0a 100644 --- a/awc/src/responses/response.rs +++ b/awc/src/responses/response.rs @@ -7,8 +7,8 @@ use std::{ }; use actix_http::{ - error::PayloadError, header::HeaderMap, BoxedPayloadStream, Extensions, HttpMessage, - Payload, ResponseHead, StatusCode, Version, + error::PayloadError, header::HeaderMap, BoxedPayloadStream, Extensions, HttpMessage, Payload, + ResponseHead, StatusCode, Version, }; use actix_rt::time::{sleep, Sleep}; use bytes::Bytes; @@ -16,11 +16,10 @@ use futures_core::Stream; use pin_project_lite::pin_project; use serde::de::DeserializeOwned; +use super::{JsonBody, ResponseBody, ResponseTimeout}; #[cfg(feature = "cookies")] use crate::cookie::{Cookie, ParseError as CookieParseError}; -use super::{JsonBody, ResponseBody, ResponseTimeout}; - pin_project! { /// Client Response pub struct ClientResponse { diff --git a/awc/src/sender.rs b/awc/src/sender.rs index cd30e571d..c2191d11b 100644 --- a/awc/src/sender.rs +++ b/awc/src/sender.rs @@ -13,15 +13,14 @@ use actix_http::{ header::{self, HeaderMap, HeaderName, TryIntoHeaderValue}, RequestHead, RequestHeadType, }; +#[cfg(feature = "__compress")] +use actix_http::{encoding::Decoder, header::ContentEncoding, Payload}; use actix_rt::time::{sleep, Sleep}; use bytes::Bytes; use derive_more::From; use futures_core::Stream; use serde::Serialize; -#[cfg(feature = "__compress")] -use actix_http::{encoding::Decoder, header::ContentEncoding, Payload}; - use crate::{ any_body::AnyBody, client::ClientConfig, @@ -106,8 +105,9 @@ impl Future for SendClientRequest { } let res = futures_core::ready!(send.as_mut().poll(cx)).map(|res| { - res.into_client_response()._timeout(delay.take()).map_body( - |head, payload| { + res.into_client_response() + ._timeout(delay.take()) + .map_body(|head, payload| { if *response_decompress { Payload::Stream { payload: Decoder::from_headers(payload, &head.headers), @@ -117,8 +117,7 @@ impl Future for SendClientRequest { payload: Decoder::new(payload, ContentEncoding::Identity), } } - }, - ) + }) }); Poll::Ready(res) diff --git a/awc/src/ws.rs b/awc/src/ws.rs index 67fcd2429..836ff2024 100644 --- a/awc/src/ws.rs +++ b/awc/src/ws.rs @@ -28,15 +28,15 @@ use std::{fmt, net::SocketAddr, str}; -use base64::prelude::*; - use actix_codec::Framed; +pub use actix_http::ws::{CloseCode, CloseReason, Codec, Frame, Message}; use actix_http::{ws, Payload, RequestHead}; use actix_rt::time::timeout; use actix_service::Service as _; +use base64::prelude::*; -pub use actix_http::ws::{CloseCode, CloseReason, Codec, Frame, Message}; - +#[cfg(feature = "cookies")] +use crate::cookie::{Cookie, CookieJar}; use crate::{ client::ClientConfig, connect::{BoxedSocket, ConnectRequest}, @@ -48,9 +48,6 @@ use crate::{ ClientResponse, }; -#[cfg(feature = "cookies")] -use crate::cookie::{Cookie, CookieJar}; - /// WebSocket connection. pub struct WebsocketsRequest { pub(crate) head: RequestHead, diff --git a/awc/tests/test_client.rs b/awc/tests/test_client.rs index 9c3543ff0..6d1459ac0 100644 --- a/awc/tests/test_client.rs +++ b/awc/tests/test_client.rs @@ -12,19 +12,18 @@ use std::{ time::Duration, }; +use actix_http::{HttpService, StatusCode}; +use actix_http_test::test_server; +use actix_service::{fn_service, map_config, ServiceFactoryExt as _}; use actix_utils::future::ok; +use actix_web::{dev::AppConfig, http::header, web, App, Error, HttpRequest, HttpResponse}; +use awc::error::{JsonPayloadError, PayloadError, SendRequestError}; use base64::prelude::*; use bytes::Bytes; use cookie::Cookie; use futures_util::stream; use rand::Rng; -use actix_http::{HttpService, StatusCode}; -use actix_http_test::test_server; -use actix_service::{fn_service, map_config, ServiceFactoryExt as _}; -use actix_web::{dev::AppConfig, http::header, web, App, Error, HttpRequest, HttpResponse}; -use awc::error::{JsonPayloadError, PayloadError, SendRequestError}; - mod utils; const S: &str = "Hello World "; @@ -33,9 +32,8 @@ const STR: &str = const_str::repeat!(S, 100); #[actix_rt::test] async fn simple() { let srv = actix_test::start(|| { - App::new().service( - web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) })), - ) + App::new() + .service(web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) }))) }); let request = srv.get("/").insert_header(("x-test", "111")).send(); @@ -61,9 +59,8 @@ async fn simple() { #[actix_rt::test] async fn json() { let srv = actix_test::start(|| { - App::new().service( - web::resource("/").route(web::to(|_: web::Json| HttpResponse::Ok())), - ) + App::new() + .service(web::resource("/").route(web::to(|_: web::Json| HttpResponse::Ok()))) }); let request = srv @@ -340,8 +337,7 @@ async fn connection_wait_queue() { .and_then( HttpService::new(map_config( App::new().service( - web::resource("/") - .route(web::to(|| async { HttpResponse::Ok().body(STR) })), + web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) })), ), |_| AppConfig::default(), )) @@ -449,9 +445,7 @@ async fn no_decompress() { let srv = actix_test::start(|| { App::new() .wrap(actix_web::middleware::Compress::default()) - .service( - web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) })), - ) + .service(web::resource("/").route(web::to(|| async { HttpResponse::Ok().body(STR) }))) }); let mut res = awc::Client::new() @@ -833,12 +827,12 @@ async fn local_address() { let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)); let srv = actix_test::start(move || { - App::new().service(web::resource("/").route(web::to( - move |req: HttpRequest| async move { + App::new().service( + web::resource("/").route(web::to(move |req: HttpRequest| async move { assert_eq!(req.peer_addr().unwrap().ip(), ip); Ok::<_, Error>(HttpResponse::Ok()) - }, - ))) + })), + ) }); let client = awc::Client::builder().local_address(ip).finish(); diff --git a/awc/tests/test_connector.rs b/awc/tests/test_connector.rs index 0f0b81414..b3eb97367 100644 --- a/awc/tests/test_connector.rs +++ b/awc/tests/test_connector.rs @@ -5,8 +5,7 @@ extern crate tls_openssl as openssl; use actix_http::HttpService; use actix_http_test::test_server; use actix_service::{map_config, ServiceFactoryExt}; -use actix_web::http::Version; -use actix_web::{dev::AppConfig, web, App, HttpResponse}; +use actix_web::{dev::AppConfig, http::Version, web, App, HttpResponse}; use openssl::{ pkey::PKey, ssl::{SslAcceptor, SslConnector, SslMethod, SslVerifyMode}, diff --git a/awc/tests/test_ssl_client.rs b/awc/tests/test_ssl_client.rs index 40c9ab8f0..5273c3fff 100644 --- a/awc/tests/test_ssl_client.rs +++ b/awc/tests/test_ssl_client.rs @@ -2,15 +2,16 @@ extern crate tls_openssl as openssl; -use std::sync::atomic::{AtomicUsize, Ordering}; -use std::sync::Arc; +use std::sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, +}; use actix_http::HttpService; use actix_http_test::test_server; use actix_service::{fn_service, map_config, ServiceFactoryExt}; use actix_utils::future::ok; -use actix_web::http::Version; -use actix_web::{dev::AppConfig, web, App, HttpResponse}; +use actix_web::{dev::AppConfig, http::Version, web, App, HttpResponse}; use openssl::{ pkey::PKey, ssl::{SslAcceptor, SslConnector, SslMethod, SslVerifyMode}, diff --git a/awc/tests/utils.rs b/awc/tests/utils.rs index 2532640c6..b9c708884 100644 --- a/awc/tests/utils.rs +++ b/awc/tests/utils.rs @@ -4,9 +4,10 @@ use std::io::{Read as _, Write as _}; pub mod gzip { - use super::*; use flate2::{read::GzDecoder, write::GzEncoder, Compression}; + use super::*; + pub fn encode(bytes: impl AsRef<[u8]>) -> Vec { let mut encoder = GzEncoder::new(Vec::new(), Compression::fast()); encoder.write_all(bytes.as_ref()).unwrap(); @@ -22,9 +23,10 @@ pub mod gzip { } pub mod deflate { - use super::*; use flate2::{read::ZlibDecoder, write::ZlibEncoder, Compression}; + use super::*; + pub fn encode(bytes: impl AsRef<[u8]>) -> Vec { let mut encoder = ZlibEncoder::new(Vec::new(), Compression::fast()); encoder.write_all(bytes.as_ref()).unwrap(); @@ -40,9 +42,10 @@ pub mod deflate { } pub mod brotli { - use super::*; use ::brotli::{reader::Decompressor as BrotliDecoder, CompressorWriter as BrotliEncoder}; + use super::*; + pub fn encode(bytes: impl AsRef<[u8]>) -> Vec { let mut encoder = BrotliEncoder::new( Vec::new(), @@ -64,9 +67,10 @@ pub mod brotli { } pub mod zstd { - use super::*; use ::zstd::stream::{read::Decoder, write::Encoder}; + use super::*; + pub fn encode(bytes: impl AsRef<[u8]>) -> Vec { let mut encoder = Encoder::new(Vec::new(), 3).unwrap(); encoder.write_all(bytes.as_ref()).unwrap(); From bf03207ca9b85232a2b3b2f7cc8311238ec5a2d6 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Mon, 17 Jul 2023 16:59:10 -0400 Subject: [PATCH 11/57] Add http2 optional feature (#3072) Co-authored-by: Rob Ede --- actix-multipart/Cargo.toml | 2 +- actix-web/CHANGES.md | 2 +- actix-web/Cargo.toml | 10 ++++++---- actix-web/src/rmap.rs | 2 +- actix-web/src/server.rs | 2 ++ 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index 384c0e151..f186bf8d9 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -40,7 +40,7 @@ serde_json = "1" serde_plain = "1" # TODO(MSRV 1.60): replace with dep: prefix tempfile-dep = { package = "tempfile", version = "3.4", optional = true } -tokio = { version = "1.24.2", features = ["sync"] } +tokio = { version = "1.24.2", features = ["io-util", "sync"] } [dev-dependencies] actix-http = "3" diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 417bb5a4c..6c83d129b 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -4,7 +4,7 @@ ### Added -- Add `HttpServer::{bind,listen}_auto_h2c()` method. +- Add `HttpServer::{bind, listen}_auto_h2c()` method behind new `http2` crate feature. - Add `Resource::{get, post, etc...}` methods for more concisely adding routes that don't need additional guards. ### Changed diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index 0091175be..4322fb871 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -28,7 +28,7 @@ name = "actix_web" path = "src/lib.rs" [features] -default = ["macros", "compress-brotli", "compress-gzip", "compress-zstd", "cookies"] +default = ["macros", "compress-brotli", "compress-gzip", "compress-zstd", "cookies", "http2"] # Brotli algorithm content-encoding support compress-brotli = ["actix-http/compress-brotli", "__compress"] @@ -46,11 +46,13 @@ cookies = ["cookie"] # Secure & signed cookies secure-cookies = ["cookies", "cookie/secure"] +http2 = ["actix-http/http2"] + # TLS via OpenSSL -openssl = ["actix-http/openssl", "actix-tls/accept", "actix-tls/openssl"] +openssl = ["http2", "actix-http/openssl", "actix-tls/accept", "actix-tls/openssl"] # TLS via Rustls -rustls = ["actix-http/rustls", "actix-tls/accept", "actix-tls/rustls"] +rustls = ["http2", "actix-http/rustls", "actix-tls/accept", "actix-tls/rustls"] # Internal (PRIVATE!) features used to aid testing and checking feature status. # Don't rely on these whatsoever. They may disappear at anytime. @@ -68,7 +70,7 @@ actix-service = "2" actix-utils = "3" actix-tls = { version = "3", default-features = false, optional = true } -actix-http = { version = "3.3", features = ["http2", "ws"] } +actix-http = { version = "3.3", features = ["ws"] } actix-router = "0.5" actix-web-codegen = { version = "4.2", optional = true } diff --git a/actix-web/src/rmap.rs b/actix-web/src/rmap.rs index 8a2ec3297..462f3b313 100644 --- a/actix-web/src/rmap.rs +++ b/actix-web/src/rmap.rs @@ -81,7 +81,7 @@ impl ResourceMap { "`pattern` and `nested` mismatch" ); // parents absorb references to the named resources of children - self.named.extend(new_node.named.clone().into_iter()); + self.named.extend(new_node.named.clone()); self.nodes.as_mut().unwrap().push(new_node); } else { let new_node = Rc::new(ResourceMap { diff --git a/actix-web/src/server.rs b/actix-web/src/server.rs index b96a84939..a540da7c8 100644 --- a/actix-web/src/server.rs +++ b/actix-web/src/server.rs @@ -356,6 +356,7 @@ where /// Resolves socket address(es) and binds server to created listener(s) for plaintext HTTP/1.x /// or HTTP/2 connections. + #[cfg(feature = "http2")] pub fn bind_auto_h2c(mut self, addrs: A) -> io::Result { let sockets = bind_addrs(addrs, self.backlog)?; @@ -453,6 +454,7 @@ where } /// Binds to existing listener for accepting incoming plaintext HTTP/1.x or HTTP/2 connections. + #[cfg(feature = "http2")] pub fn listen_auto_h2c(mut self, lst: net::TcpListener) -> io::Result { let cfg = self.config.clone(); let factory = self.factory.clone(); From a4c9361791a9204e395ab99cb737cf821b7e2d16 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 18 Jul 2023 02:18:19 +0100 Subject: [PATCH 12/57] ci: fix windows openssl --- .github/workflows/ci-post-merge.yml | 59 ++++++++--------------------- .github/workflows/ci.yml | 8 ++-- actix-multipart/Cargo.toml | 7 ++-- 3 files changed, 22 insertions(+), 52 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 8dd941e04..d293fea95 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -26,39 +26,26 @@ jobs: name: ${{ matrix.target.name }} / ${{ matrix.version }} runs-on: ${{ matrix.target.os }} - env: - CI: 1 - CARGO_INCREMENTAL: 0 - VCPKGRS_DYNAMIC: 1 - CARGO_UNSTABLE_SPARSE_REGISTRY: true - steps: - uses: actions/checkout@v3 - # install OpenSSL on Windows - # TODO: GitHub actions docs state that OpenSSL is - # already installed on these Windows machines somewhere - - name: Set vcpkg root - if: matrix.target.triple == 'x86_64-pc-windows-msvc' - run: echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append - name: Install OpenSSL - if: matrix.target.triple == 'x86_64-pc-windows-msvc' - run: vcpkg install openssl:x64-windows - - - name: Install ${{ matrix.version }} + if: matrix.target.os == 'windows-latest' + run: choco install openssl -y --forcex64 --no-progress + - name: Set OpenSSL dir in env + if: matrix.target.os == 'windows-latest' run: | - rustup set profile minimal - rustup install ${{ matrix.version }} - rustup override set ${{ matrix.version }} + echo 'OPENSSL_DIR=C:\Program Files\OpenSSL-Win64' | Out-File -FilePath $env:GITHUB_ENV -Append + echo 'OPENSSL_DIR=C:\Program Files\OpenSSL' | Out-File -FilePath $env:GITHUB_ENV -Append + + - name: Install Rust (${{ matrix.version }}) + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: ${{ matrix.version }} - name: Install cargo-hack uses: taiki-e/install-action@cargo-hack - - name: Generate Cargo.lock - run: cargo generate-lockfile - - name: Cache Dependencies - uses: Swatinem/rust-cache@v2.2.1 - - name: check minimal run: cargo ci-check-min @@ -88,23 +75,15 @@ jobs: name: Verify Feature Combinations runs-on: ubuntu-latest - env: - CI: 1 - CARGO_INCREMENTAL: 0 - steps: - uses: actions/checkout@v3 - - uses: dtolnay/rust-toolchain@stable + - name: Install Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 - name: Install cargo-hack uses: taiki-e/install-action@cargo-hack - - name: Generate Cargo.lock - run: cargo generate-lockfile - - name: Cache Dependencies - uses: Swatinem/rust-cache@v2.2.1 - - name: check feature combinations run: cargo ci-check-all-feature-powerset @@ -115,22 +94,14 @@ jobs: name: nextest runs-on: ubuntu-latest - env: - CI: 1 - CARGO_INCREMENTAL: 0 - steps: - uses: actions/checkout@v3 - - uses: dtolnay/rust-toolchain@stable + - name: Install Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 - name: Install nextest uses: taiki-e/install-action@nextest - - name: Generate Cargo.lock - run: cargo generate-lockfile - - name: Cache Dependencies - uses: Swatinem/rust-cache@v2.2.1 - - name: Test with cargo-nextest run: cargo nextest run diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 10e80b751..f85548505 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,17 +29,17 @@ jobs: name: ${{ matrix.target.name }} / ${{ matrix.version }} runs-on: ${{ matrix.target.os }} - env: {} - steps: - uses: actions/checkout@v3 - name: Install OpenSSL if: matrix.target.os == 'windows-latest' - run: choco install openssl + run: choco install openssl -y --forcex64 --no-progress - name: Set OpenSSL dir in env if: matrix.target.os == 'windows-latest' - run: echo 'OPENSSL_DIR=C:\Program Files\OpenSSL-Win64' | Out-File -FilePath $env:GITHUB_ENV -Append + run: | + echo 'OPENSSL_DIR=C:\Program Files\OpenSSL-Win64' | Out-File -FilePath $env:GITHUB_ENV -Append + echo 'OPENSSL_DIR=C:\Program Files\OpenSSL' | Out-File -FilePath $env:GITHUB_ENV -Append - name: Install Rust (${{ matrix.version }}) uses: actions-rust-lang/setup-rust-toolchain@v1 diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index f186bf8d9..63cd99707 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -19,7 +19,7 @@ all-features = true [features] default = ["tempfile", "derive"] derive = ["actix-multipart-derive"] -tempfile = ["tempfile-dep", "tokio/fs"] +tempfile = ["dep:tempfile", "tokio/fs"] [dependencies] actix-multipart-derive = { version = "=0.6.0", optional = true } @@ -38,9 +38,8 @@ mime = "0.3" serde = "1" serde_json = "1" serde_plain = "1" -# TODO(MSRV 1.60): replace with dep: prefix -tempfile-dep = { package = "tempfile", version = "3.4", optional = true } -tokio = { version = "1.24.2", features = ["io-util", "sync"] } +tempfile-dep = { version = "3.4", optional = true } +tokio = { version = "1.24.2", features = ["sync", "io-util"] } [dev-dependencies] actix-http = "3" From 3b9b38c44e5d0c8775b371154116f04a4ef60ce0 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 18 Jul 2023 02:22:09 +0100 Subject: [PATCH 13/57] fix tempfile dep spec --- actix-multipart/Cargo.toml | 2 +- actix-multipart/src/form/tempfile.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index 63cd99707..9220e793c 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -38,7 +38,7 @@ mime = "0.3" serde = "1" serde_json = "1" serde_plain = "1" -tempfile-dep = { version = "3.4", optional = true } +tempfile = { version = "3.4", optional = true } tokio = { version = "1.24.2", features = ["sync", "io-util"] } [dev-dependencies] diff --git a/actix-multipart/src/form/tempfile.rs b/actix-multipart/src/form/tempfile.rs index 2f611ba04..9371a026b 100644 --- a/actix-multipart/src/form/tempfile.rs +++ b/actix-multipart/src/form/tempfile.rs @@ -11,7 +11,7 @@ use derive_more::{Display, Error}; use futures_core::future::LocalBoxFuture; use futures_util::TryStreamExt as _; use mime::Mime; -use tempfile_dep::NamedTempFile; +use tempfile::NamedTempFile; use tokio::io::AsyncWriteExt; use super::FieldErrorHandler; From b061f004219b1e970c3801e8ea7df2c007bf2ac3 Mon Sep 17 00:00:00 2001 From: nerix Date: Wed, 19 Jul 2023 12:24:14 +0200 Subject: [PATCH 14/57] Provide documentation in the `middleware` module (#3070) Co-authored-by: Rob Ede --- actix-web/src/app.rs | 11 +- actix-web/src/middleware/mod.rs | 217 ++++++++++++++++++++++++++++++++ 2 files changed, 218 insertions(+), 10 deletions(-) diff --git a/actix-web/src/app.rs b/actix-web/src/app.rs index a4b576b0e..a4cd8d819 100644 --- a/actix-web/src/app.rs +++ b/actix-web/src/app.rs @@ -319,16 +319,7 @@ where /// Middleware can be applied similarly to individual `Scope`s and `Resource`s. /// See [`Scope::wrap`](crate::Scope::wrap) and [`Resource::wrap`]. /// - /// # Middleware Order - /// Notice that the keyword for registering middleware is `wrap`. As you register middleware - /// using `wrap` in the App builder, imagine wrapping layers around an inner App. The first - /// middleware layer exposed to a Request is the outermost layer (i.e., the *last* registered in - /// the builder chain). Consequently, the *first* middleware registered in the builder chain is - /// the *last* to start executing during request processing. - /// - /// Ordering is less obvious when wrapped services also have middleware applied. In this case, - /// middlewares are run in reverse order for `App` _and then_ in reverse order for the - /// wrapped service. + /// For more info on middleware take a look at the [`middleware` module][crate::middleware]. /// /// # Examples /// ``` diff --git a/actix-web/src/middleware/mod.rs b/actix-web/src/middleware/mod.rs index eb3550b52..8dbd1ff2c 100644 --- a/actix-web/src/middleware/mod.rs +++ b/actix-web/src/middleware/mod.rs @@ -1,4 +1,221 @@ //! A collection of common middleware. +//! +//! # What Is Middleware? +//! +//! Actix Web's middleware system allows us to add additional behavior to request/response +//! processing. Middleware can hook into incoming request and outgoing response processes, enabling +//! us to modify requests and responses as well as halt request processing to return a response +//! early. +//! +//! Typically, middleware is involved in the following actions: +//! +//! - Pre-process the request (e.g., [normalizing paths](NormalizePath)) +//! - Post-process a response (e.g., [logging][Logger]) +//! - Modify application state (through [`ServiceRequest`][crate::dev::ServiceRequest]) +//! - Access external services (e.g., [sessions](https://docs.rs/actix-session), etc.) +//! +//! Middleware is registered for each [`App`], [`Scope`](crate::Scope), or +//! [`Resource`](crate::Resource) and executed in opposite order as registration. In general, a +//! middleware is a pair of types that implements the [`Service`] trait and [`Transform`] trait, +//! respectively. The [`new_transform`] and [`call`] methods must return a [`Future`], though it +//! can often be [an immediately-ready one](actix_utils::future::Ready). +//! +//! # Ordering +//! +//! ``` +//! # use actix_web::{web, middleware, get, App, Responder}; +//! # +//! # // some basic types to make sure this compiles +//! # type ExtractorA = web::Json; +//! # type ExtractorB = ExtractorA; +//! #[get("/")] +//! async fn service(a: ExtractorA, b: ExtractorB) -> impl Responder { "Hello, World!" } +//! +//! # fn main() { +//! # // These aren't snake_case, because they are supposed to be unit structs. +//! # let MiddlewareA = middleware::Compress::default(); +//! # let MiddlewareB = middleware::Compress::default(); +//! # let MiddlewareC = middleware::Compress::default(); +//! let app = App::new() +//! .wrap(MiddlewareA) +//! .wrap(MiddlewareB) +//! .wrap(MiddlewareC) +//! .service(service); +//! # } +//! ``` +//! +//! ```plain +//! Request +//! ⭣ +//! ╭────────────────────┼────╮ +//! │ MiddlewareC │ │ +//! │ ╭──────────────────┼───╮│ +//! │ │ MiddlewareB │ ││ +//! │ │ ╭────────────────┼──╮││ +//! │ │ │ MiddlewareA │ │││ +//! │ │ │ ╭──────────────┼─╮│││ +//! │ │ │ │ ExtractorA │ ││││ +//! │ │ │ ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┼┈┤│││ +//! │ │ │ │ ExtractorB │ ││││ +//! │ │ │ ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┼┈┤│││ +//! │ │ │ │ service │ ││││ +//! │ │ │ ╰──────────────┼─╯│││ +//! │ │ ╰────────────────┼──╯││ +//! │ ╰──────────────────┼───╯│ +//! ╰────────────────────┼────╯ +//! ⭣ +//! Response +//! ``` +//! The request _first_ gets processed by the middleware specified _last_ - `MiddlewareC`. It passes +//! the request (modified a modified one) to the next middleware - `MiddlewareB` - _or_ directly +//! responds to the request (e.g. when the request was invalid or an error occurred). `MiddlewareB` +//! processes the request as well and passes it to `MiddlewareA`, which then passes it to the +//! [`Service`]. In the [`Service`], the extractors will run first. They don't pass the request on, +//! but only view it (see [`FromRequest`]). After the [`Service`] responds to the request, the +//! response it passed back through `MiddlewareA`, `MiddlewareB`, and `MiddlewareC`. +//! +//! As you register middleware using [`wrap`][crate::App::wrap] and [`wrap_fn`][crate::App::wrap_fn] +//! in the [`App`] builder, imagine wrapping layers around an inner [`App`]. The first middleware +//! layer exposed to a Request is the outermost layer (i.e., the _last_ registered in the builder +//! chain, in the example above: `MiddlewareC`). Consequently, the _first_ middleware registered in +//! the builder chain is the _last_ to start executing during request processing (`MiddlewareA`). +//! Ordering is less obvious when wrapped services also have middleware applied. In this case, +//! middleware are run in reverse order for [`App`] _and then_ in reverse order for the wrapped +//! service. +//! +//! # Middleware Traits +//! +//! ## `Transform` +//! +//! The [`Transform`] trait is the builder for the actual [`Service`]s that handle the requests. All +//! the middleware you pass to the `wrap` methods implement this trait. During construction, each +//! thread assembles a chain of [`Service`]s by calling [`new_transform`] and passing the next +//! [`Service`] (`S`) in the chain. The created [`Service`] handles requests of type `Req`. +//! +//! In the example from the [ordering](#ordering) section, the chain would be: +//! +//! ```plain +//! MiddlewareCService { +//! next: MiddlewareBService { +//! next: MiddlewareAService { ... } +//! } +//! } +//! ``` +//! +//! ## `Service` +//! +//! A [`Service`] `S` represents an asynchronous operation that turns a request of type `Req` into a +//! response of type [`S::Response`](crate::dev::Service::Response) or an error of type +//! [`S::Error`](crate::dev::Service::Error). You can think of the service of being roughly: +//! +//! ```ignore +//! async fn(&self, req: Req) -> Result +//! ``` +//! +//! In most cases the [`Service`] implementation will, at some point, call the wrapped [`Service`] +//! in its [`call`] implementation. +//! +//! Note that the [`Service`]s created by [`new_transform`] don't need to be [`Send`] or [`Sync`]. +//! +//! # Example +//! +//! ``` +//! use std::{future::{ready, Ready, Future}, pin::Pin}; +//! +//! use actix_web::{ +//! dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform}, +//! web, Error, +//! # App +//! }; +//! +//! pub struct SayHi; +//! +//! // `S` - type of the next service +//! // `B` - type of response's body +//! impl Transform for SayHi +//! where +//! S: Service, Error = Error>, +//! S::Future: 'static, +//! B: 'static, +//! { +//! type Response = ServiceResponse; +//! type Error = Error; +//! type InitError = (); +//! type Transform = SayHiMiddleware; +//! type Future = Ready>; +//! +//! fn new_transform(&self, service: S) -> Self::Future { +//! ready(Ok(SayHiMiddleware { service })) +//! } +//! } +//! +//! pub struct SayHiMiddleware { +//! /// The next service to call +//! service: S, +//! } +//! +//! // This future doesn't have the requirement of being `Send`. +//! // See: futures_util::future::LocalBoxFuture +//! type LocalBoxFuture = Pin + 'static>>; +//! +//! // `S`: type of the wrapped service +//! // `B`: type of the body - try to be generic over the body where possible +//! impl Service for SayHiMiddleware +//! where +//! S: Service, Error = Error>, +//! S::Future: 'static, +//! B: 'static, +//! { +//! type Response = ServiceResponse; +//! type Error = Error; +//! type Future = LocalBoxFuture>; +//! +//! // This service is ready when its next service is ready +//! forward_ready!(service); +//! +//! fn call(&self, req: ServiceRequest) -> Self::Future { +//! println!("Hi from start. You requested: {}", req.path()); +//! +//! // A more complex middleware, could return an error or an early response here. +//! +//! let fut = self.service.call(req); +//! +//! Box::pin(async move { +//! let res = fut.await?; +//! +//! println!("Hi from response"); +//! Ok(res) +//! }) +//! } +//! } +//! +//! # fn main() { +//! let app = App::new() +//! .wrap(SayHi) +//! .route("/", web::get().to(|| async { "Hello, middleware!" })); +//! # } +//! ``` +//! +//! # Simpler Middleware +//! +//! In many cases, you _can_ actually use an async function via a helper that will provide a more +//! natural flow for your behavior. +//! +//! The experimental `actix_web_lab` crate provides a [`from_fn`][lab_from_fn] utility which allows +//! an async fn to be wrapped and used in the same way as other middleware. See the +//! [`from_fn`][lab_from_fn] docs for more info and examples of it's use. +//! +//! While [`from_fn`][lab_from_fn] is experimental currently, it's likely this helper will graduate +//! to Actix Web in some form, so feedback is appreciated. +//! +//! [`Future`]: std::future::Future +//! [`App`]: crate::App +//! [`FromRequest`]: crate::FromRequest +//! [`Service`]: crate::dev::Service +//! [`Transform`]: crate::dev::Transform +//! [`call`]: crate::dev::Service::call() +//! [`new_transform`]: crate::dev::Transform::new_transform() +//! [lab_from_fn]: https://docs.rs/actix-web-lab/latest/actix_web_lab/middleware/fn.from_fn.html mod compat; mod condition; From 908fb2606ecd42450b31eb5b19aa186d5b0cd882 Mon Sep 17 00:00:00 2001 From: Kristian Gaylord Date: Wed, 19 Jul 2023 12:48:43 -0400 Subject: [PATCH 15/57] allow configuring number of test server workers (#3069) Co-authored-by: Rob Ede --- actix-test/CHANGES.md | 1 + actix-test/src/lib.rs | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/actix-test/CHANGES.md b/actix-test/CHANGES.md index e3a66c663..2a30ee95b 100644 --- a/actix-test/CHANGES.md +++ b/actix-test/CHANGES.md @@ -2,6 +2,7 @@ ## Unreleased - 2023-xx-xx +- Add `TestServerConfig::workers()` setter method - Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. ## 0.1.1 - 2023-02-26 diff --git a/actix-test/src/lib.rs b/actix-test/src/lib.rs index 7781edab4..c667e564d 100644 --- a/actix-test/src/lib.rs +++ b/actix-test/src/lib.rs @@ -154,7 +154,10 @@ where let srv_cfg = cfg.clone(); let timeout = cfg.client_request_timeout; - let builder = Server::build().workers(1).disable_signals().system_exit(); + let builder = Server::build() + .workers(cfg.workers) + .disable_signals() + .system_exit(); let srv = match srv_cfg.stream { StreamType::Tcp => match srv_cfg.tp { @@ -367,6 +370,7 @@ pub struct TestServerConfig { stream: StreamType, client_request_timeout: Duration, port: u16, + workers: usize, } impl Default for TestServerConfig { @@ -383,6 +387,7 @@ impl TestServerConfig { stream: StreamType::Tcp, client_request_timeout: Duration::from_secs(5), port: 0, + workers: 1, } } @@ -425,6 +430,14 @@ impl TestServerConfig { self.port = port; self } + + /// Sets number of workers in the test server process. + /// + /// By default, the server boots with 1 worker + pub fn workers(mut self, workers: usize) -> Self { + self.workers = workers; + self + } } /// A basic HTTP server controller that simplifies the process of writing integration tests for From 4272510261844dbef1e9ef5c9ee01574bd16a9b7 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Wed, 19 Jul 2023 19:27:20 +0100 Subject: [PATCH 16/57] doc amendments --- actix-test/CHANGES.md | 2 +- actix-test/src/lib.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/actix-test/CHANGES.md b/actix-test/CHANGES.md index 2a30ee95b..aba27dbfc 100644 --- a/actix-test/CHANGES.md +++ b/actix-test/CHANGES.md @@ -2,7 +2,7 @@ ## Unreleased - 2023-xx-xx -- Add `TestServerConfig::workers()` setter method +- Add `TestServerConfig::workers()` setter method. - Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. ## 0.1.1 - 2023-02-26 diff --git a/actix-test/src/lib.rs b/actix-test/src/lib.rs index c667e564d..751ab3161 100644 --- a/actix-test/src/lib.rs +++ b/actix-test/src/lib.rs @@ -431,9 +431,9 @@ impl TestServerConfig { self } - /// Sets number of workers in the test server process. + /// Sets number of workers for the test server. /// - /// By default, the server boots with 1 worker + /// By default, the server uses 1 worker pub fn workers(mut self, workers: usize) -> Self { self.workers = workers; self From 80185ce741729108301d26d2cd18598baf1f9af3 Mon Sep 17 00:00:00 2001 From: Nathan Shaaban <86252985+ctrlaltf24@users.noreply.github.com> Date: Wed, 19 Jul 2023 18:51:17 +0000 Subject: [PATCH 17/57] Hide authorization header in httprequest debug output (#2953) Co-authored-by: Nathan Shaaban <86252985+nshaaban-cPacket@users.noreply.github.com> Co-authored-by: Rob Ede --- actix-web/CHANGES.md | 1 + actix-web/src/request.rs | 57 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 6c83d129b..7e82d095a 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -10,6 +10,7 @@ ### Changed - Handler functions can now receive up to 16 extractor parameters. +- Hide sensitive header values in `HttpRequest`'s `Debug` output. - Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. ## 4.3.1 - 2023-02-26 diff --git a/actix-web/src/request.rs b/actix-web/src/request.rs index 543c9dfbe..ece36a388 100644 --- a/actix-web/src/request.rs +++ b/actix-web/src/request.rs @@ -435,16 +435,28 @@ impl fmt::Debug for HttpRequest { self.inner.head.method, self.path() )?; + if !self.query_string().is_empty() { writeln!(f, " query: ?{:?}", self.query_string())?; } + if !self.match_info().is_empty() { writeln!(f, " params: {:?}", self.match_info())?; } + writeln!(f, " headers:")?; + for (key, val) in self.headers().iter() { - writeln!(f, " {:?}: {:?}", key, val)?; + match key { + // redact sensitive header values from debug output + &crate::http::header::AUTHORIZATION + | &crate::http::header::PROXY_AUTHORIZATION + | &crate::http::header::COOKIE => writeln!(f, " {:?}: {:?}", key, "*redacted*")?, + + _ => writeln!(f, " {:?}: {:?}", key, val)?, + } } + Ok(()) } } @@ -908,4 +920,47 @@ mod tests { let body = read_body(bar_resp).await; assert_eq!(body, "http://localhost:8080/bar/nested"); } + + #[test] + fn authorization_header_hidden_in_debug() { + let authorization_header = "Basic bXkgdXNlcm5hbWU6bXkgcGFzc3dvcmQK"; + let req = TestRequest::get() + .insert_header((crate::http::header::AUTHORIZATION, authorization_header)) + .to_http_request(); + + assert!(!format!("{:?}", req).contains(authorization_header)); + } + + #[test] + fn proxy_authorization_header_hidden_in_debug() { + let proxy_authorization_header = "secret value"; + let req = TestRequest::get() + .insert_header(( + crate::http::header::PROXY_AUTHORIZATION, + proxy_authorization_header, + )) + .to_http_request(); + + assert!(!format!("{:?}", req).contains(proxy_authorization_header)); + } + + #[test] + fn cookie_header_hidden_in_debug() { + let cookie_header = "secret"; + let req = TestRequest::get() + .insert_header((crate::http::header::COOKIE, cookie_header)) + .to_http_request(); + + assert!(!format!("{:?}", req).contains(cookie_header)); + } + + #[test] + fn other_header_visible_in_debug() { + let location_header = "192.0.0.1"; + let req = TestRequest::get() + .insert_header((crate::http::header::LOCATION, location_header)) + .to_http_request(); + + assert!(format!("{:?}", req).contains(location_header)); + } } From db99da5daf8e52f31513921819047fa07a9cf168 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Wed, 19 Jul 2023 20:24:32 +0100 Subject: [PATCH 18/57] do not compress media types (#3075) * misc: add temporary nix file * Add test to check content type image/* * misc: add unit test for expected behaviour jpeg * feat(compress): add compress function to middleware * feat(compress): use response content type to decide compress * feat(compress): give more control to the user * misc: improve default compress function * add Compress::with_predicate * remove predicate options * assert auto traits on Compress * fix changelog --------- Co-authored-by: William R. Arellano --- actix-web/CHANGES.md | 1 + actix-web/src/http/header/content_type.rs | 79 ++++++------- actix-web/src/middleware/compress.rs | 129 ++++++++++++++++++++-- 3 files changed, 154 insertions(+), 55 deletions(-) diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 7e82d095a..35d695328 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -10,6 +10,7 @@ ### Changed - Handler functions can now receive up to 16 extractor parameters. +- The `Compress` middleware no longer compresses image or video content. - Hide sensitive header values in `HttpRequest`'s `Debug` output. - Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. diff --git a/actix-web/src/http/header/content_type.rs b/actix-web/src/http/header/content_type.rs index 41c0c1fc9..bf86afffa 100644 --- a/actix-web/src/http/header/content_type.rs +++ b/actix-web/src/http/header/content_type.rs @@ -3,109 +3,102 @@ use mime::Mime; use super::CONTENT_TYPE; crate::http::header::common_header! { - /// `Content-Type` header, defined - /// in [RFC 7231 §3.1.1.5](https://datatracker.ietf.org/doc/html/rfc7231#section-3.1.1.5) + /// `Content-Type` header, defined in [RFC 9110 §8.3]. /// - /// The `Content-Type` header field indicates the media type of the - /// associated representation: either the representation enclosed in the - /// message payload or the selected representation, as determined by the - /// message semantics. The indicated media type defines both the data - /// format and how that data is intended to be processed by a recipient, - /// within the scope of the received message semantics, after any content - /// codings indicated by Content-Encoding are decoded. + /// The `Content-Type` header field indicates the media type of the associated representation: + /// either the representation enclosed in the message payload or the selected representation, + /// as determined by the message semantics. The indicated media type defines both the data + /// format and how that data is intended to be processed by a recipient, within the scope of the + /// received message semantics, after any content codings indicated by Content-Encoding are + /// decoded. /// - /// Although the `mime` crate allows the mime options to be any slice, this crate - /// forces the use of Vec. This is to make sure the same header can't have more than 1 type. If - /// this is an issue, it's possible to implement `Header` on a custom struct. + /// Although the `mime` crate allows the mime options to be any slice, this crate forces the use + /// of Vec. This is to make sure the same header can't have more than 1 type. If this is an + /// issue, it's possible to implement `Header` on a custom struct. /// /// # ABNF + /// /// ```plain /// Content-Type = media-type /// ``` /// /// # Example Values - /// * `text/html; charset=utf-8` - /// * `application/json` + /// + /// - `text/html; charset=utf-8` + /// - `application/json` /// /// # Examples - /// ``` - /// use actix_web::HttpResponse; - /// use actix_web::http::header::ContentType; - /// - /// let mut builder = HttpResponse::Ok(); - /// builder.insert_header( - /// ContentType::json() - /// ); - /// ``` /// /// ``` - /// use actix_web::HttpResponse; - /// use actix_web::http::header::ContentType; + /// use actix_web::{http::header::ContentType, HttpResponse}; /// - /// let mut builder = HttpResponse::Ok(); - /// builder.insert_header( - /// ContentType(mime::TEXT_HTML) - /// ); + /// let res_json = HttpResponse::Ok() + /// .insert_header(ContentType::json()); + /// + /// let res_html = HttpResponse::Ok() + /// .insert_header(ContentType(mime::TEXT_HTML)); /// ``` + /// + /// [RFC 9110 §8.3]: https://datatracker.ietf.org/doc/html/rfc9110#section-8.3 (ContentType, CONTENT_TYPE) => [Mime] test_parse_and_format { crate::http::header::common_header_test!( - test1, + test_text_html, vec![b"text/html"], Some(HeaderField(mime::TEXT_HTML))); + crate::http::header::common_header_test!( + test_image_star, + vec![b"image/*"], + Some(HeaderField(mime::IMAGE_STAR))); + } } impl ContentType { - /// A constructor to easily create a `Content-Type: application/json` - /// header. + /// Constructs a `Content-Type: application/json` header. #[inline] pub fn json() -> ContentType { ContentType(mime::APPLICATION_JSON) } - /// A constructor to easily create a `Content-Type: text/plain; - /// charset=utf-8` header. + /// Constructs a `Content-Type: text/plain; charset=utf-8` header. #[inline] pub fn plaintext() -> ContentType { ContentType(mime::TEXT_PLAIN_UTF_8) } - /// A constructor to easily create a `Content-Type: text/html; charset=utf-8` - /// header. + /// Constructs a `Content-Type: text/html; charset=utf-8` header. #[inline] pub fn html() -> ContentType { ContentType(mime::TEXT_HTML_UTF_8) } - /// A constructor to easily create a `Content-Type: text/xml` header. + /// Constructs a `Content-Type: text/xml` header. #[inline] pub fn xml() -> ContentType { ContentType(mime::TEXT_XML) } - /// A constructor to easily create a `Content-Type: - /// application/www-form-url-encoded` header. + /// Constructs a `Content-Type: application/www-form-url-encoded` header. #[inline] pub fn form_url_encoded() -> ContentType { ContentType(mime::APPLICATION_WWW_FORM_URLENCODED) } - /// A constructor to easily create a `Content-Type: image/jpeg` header. + /// Constructs a `Content-Type: image/jpeg` header. #[inline] pub fn jpeg() -> ContentType { ContentType(mime::IMAGE_JPEG) } - /// A constructor to easily create a `Content-Type: image/png` header. + /// Constructs a `Content-Type: image/png` header. #[inline] pub fn png() -> ContentType { ContentType(mime::IMAGE_PNG) } - /// A constructor to easily create a `Content-Type: - /// application/octet-stream` header. + /// Constructs a `Content-Type: application/octet-stream` header. #[inline] pub fn octet_stream() -> ContentType { ContentType(mime::APPLICATION_OCTET_STREAM) diff --git a/actix-web/src/middleware/compress.rs b/actix-web/src/middleware/compress.rs index 51b44c6ef..a55b46264 100644 --- a/actix-web/src/middleware/compress.rs +++ b/actix-web/src/middleware/compress.rs @@ -11,13 +11,14 @@ use actix_http::encoding::Encoder; use actix_service::{Service, Transform}; use actix_utils::future::{ok, Either, Ready}; use futures_core::ready; +use mime::Mime; use once_cell::sync::Lazy; use pin_project_lite::pin_project; use crate::{ body::{EitherBody, MessageBody}, http::{ - header::{self, AcceptEncoding, Encoding, HeaderValue}, + header::{self, AcceptEncoding, ContentEncoding, Encoding, HeaderValue}, StatusCode, }, service::{ServiceRequest, ServiceResponse}, @@ -170,19 +171,40 @@ where { type Output = Result>>, Error>; - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let this = self.project(); + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = self.as_mut().project(); match ready!(this.fut.poll(cx)) { Ok(resp) => { let enc = match this.encoding { Encoding::Known(enc) => *enc, Encoding::Unknown(enc) => { - unimplemented!("encoding {} should not be here", enc); + unimplemented!("encoding '{enc}' should not be here"); } }; Poll::Ready(Ok(resp.map_body(move |head, body| { + let content_type = head.headers.get(header::CONTENT_TYPE); + + fn default_compress_predicate(content_type: Option<&HeaderValue>) -> bool { + match content_type { + None => true, + Some(hdr) => { + match hdr.to_str().ok().and_then(|hdr| hdr.parse::().ok()) { + Some(mime) if mime.type_().as_str() == "image" => false, + Some(mime) if mime.type_().as_str() == "video" => false, + _ => true, + } + } + } + } + + let enc = if default_compress_predicate(content_type) { + enc + } else { + ContentEncoding::Identity + }; + EitherBody::left(Encoder::response(enc, head, body)) }))) } @@ -246,8 +268,18 @@ static SUPPORTED_ENCODINGS: &[Encoding] = &[ mod tests { use std::collections::HashSet; + use static_assertions::assert_impl_all; + use super::*; - use crate::{middleware::DefaultHeaders, test, web, App}; + use crate::{http::header::ContentType, middleware::DefaultHeaders, test, web, App}; + + const HTML_DATA_PART: &str = "

hello world

) -> Vec { use std::io::Read as _; @@ -257,23 +289,55 @@ mod tests { buf } + #[track_caller] + fn assert_successful_res_with_content_type(res: &ServiceResponse, ct: &str) { + assert!(res.status().is_success()); + assert!( + res.headers() + .get(header::CONTENT_TYPE) + .expect("content-type header should be present") + .to_str() + .expect("content-type header should be utf-8") + .contains(ct), + "response's content-type did not match {}", + ct + ); + } + + #[track_caller] + fn assert_successful_gzip_res_with_content_type(res: &ServiceResponse, ct: &str) { + assert_successful_res_with_content_type(res, ct); + assert_eq!( + res.headers() + .get(header::CONTENT_ENCODING) + .expect("response should be gzip compressed"), + "gzip", + ); + } + + #[track_caller] + fn assert_successful_identity_res_with_content_type(res: &ServiceResponse, ct: &str) { + assert_successful_res_with_content_type(res, ct); + assert!( + res.headers().get(header::CONTENT_ENCODING).is_none(), + "response should not be compressed", + ); + } + #[actix_rt::test] async fn prevents_double_compressing() { - const D: &str = "hello world "; - const DATA: &str = const_str::repeat!(D, 100); - let app = test::init_service({ App::new() .wrap(Compress::default()) .route( "/single", - web::get().to(move || HttpResponse::Ok().body(DATA)), + web::get().to(move || HttpResponse::Ok().body(TEXT_DATA)), ) .service( web::resource("/double") .wrap(Compress::default()) .wrap(DefaultHeaders::new().add(("x-double", "true"))) - .route(web::get().to(move || HttpResponse::Ok().body(DATA))), + .route(web::get().to(move || HttpResponse::Ok().body(TEXT_DATA))), ) }) .await; @@ -287,7 +351,7 @@ mod tests { assert_eq!(res.headers().get("x-double"), None); assert_eq!(res.headers().get(header::CONTENT_ENCODING).unwrap(), "gzip"); let bytes = test::read_body(res).await; - assert_eq!(gzip_decode(bytes), DATA.as_bytes()); + assert_eq!(gzip_decode(bytes), TEXT_DATA.as_bytes()); let req = test::TestRequest::default() .uri("/double") @@ -298,7 +362,7 @@ mod tests { assert_eq!(res.headers().get("x-double").unwrap(), "true"); assert_eq!(res.headers().get(header::CONTENT_ENCODING).unwrap(), "gzip"); let bytes = test::read_body(res).await; - assert_eq!(gzip_decode(bytes), DATA.as_bytes()); + assert_eq!(gzip_decode(bytes), TEXT_DATA.as_bytes()); } #[actix_rt::test] @@ -324,4 +388,45 @@ mod tests { assert!(vary_headers.contains(&HeaderValue::from_static("x-test"))); assert!(vary_headers.contains(&HeaderValue::from_static("accept-encoding"))); } + + fn configure_predicate_test(cfg: &mut web::ServiceConfig) { + cfg.route( + "/html", + web::get().to(|| { + HttpResponse::Ok() + .content_type(ContentType::html()) + .body(HTML_DATA) + }), + ) + .route( + "/image", + web::get().to(|| { + HttpResponse::Ok() + .content_type(ContentType::jpeg()) + .body(TEXT_DATA) + }), + ); + } + + #[actix_rt::test] + async fn prevents_compression_jpeg() { + let app = test::init_service( + App::new() + .wrap(Compress::default()) + .configure(configure_predicate_test), + ) + .await; + + let req = + test::TestRequest::with_uri("/html").insert_header((header::ACCEPT_ENCODING, "gzip")); + let res = test::call_service(&app, req.to_request()).await; + assert_successful_gzip_res_with_content_type(&res, "text/html"); + assert_ne!(test::read_body(res).await, HTML_DATA.as_bytes()); + + let req = + test::TestRequest::with_uri("/image").insert_header((header::ACCEPT_ENCODING, "gzip")); + let res = test::call_service(&app, req.to_request()).await; + assert_successful_identity_res_with_content_type(&res, "image/jpeg"); + assert_eq!(test::read_body(res).await, TEXT_DATA.as_bytes()); + } } From 67cee2915d9bb89b9778f72f5981345deb476977 Mon Sep 17 00:00:00 2001 From: Vasiliy Taranov Date: Thu, 20 Jul 2023 01:37:48 +0300 Subject: [PATCH 19/57] set up dependabot (#3019) Co-authored-by: Rob Ede --- .github/dependabot.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..1a54090f0 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: "monthly" + open-pull-requests-limit: 10 + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + open-pull-requests-limit: 10 From 6d452d497795652fde51263db8a49ba7b8ba065d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jul 2023 23:42:40 +0100 Subject: [PATCH 20/57] Bump codecov/codecov-action from 1 to 3 (#3077) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Rob Ede --- .github/workflows/coverage.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index d537031c3..42f16450d 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -29,5 +29,6 @@ jobs: cargo install cargo-tarpaulin --vers "^0.13" cargo tarpaulin --workspace --features=rustls,openssl --out Xml --verbose - name: Upload to Codecov - uses: codecov/codecov-action@v1 - with: { file: cobertura.xml } + uses: codecov/codecov-action@v3.1.4 + with: + file: cobertura.xml From e25f3f8f1d48cde9f5938dd7cc65c2cd683821a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jul 2023 23:43:25 +0100 Subject: [PATCH 21/57] Bump JamesIves/github-pages-deploy-action from 4.4.1 to 4.4.3 (#3076) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/upload-doc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/upload-doc.yml b/.github/workflows/upload-doc.yml index 743e14412..05b81411d 100644 --- a/.github/workflows/upload-doc.yml +++ b/.github/workflows/upload-doc.yml @@ -32,7 +32,7 @@ jobs: run: echo '' > target/doc/index.html - name: Deploy to GitHub Pages - uses: JamesIves/github-pages-deploy-action@v4.4.1 + uses: JamesIves/github-pages-deploy-action@v4.4.3 with: folder: target/doc single-commit: true From d22c9f9fb12db30ee1cb7183ce8cf395c707f30d Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 20 Jul 2023 10:49:01 +0100 Subject: [PATCH 22/57] update syn to 2 in web codegen (#3081) --- actix-multipart-derive/CHANGES.md | 1 + actix-multipart-derive/Cargo.toml | 4 +- actix-router/src/resource.rs | 3 +- actix-web-codegen/CHANGES.md | 1 + actix-web-codegen/Cargo.toml | 4 +- actix-web-codegen/src/route.rs | 223 ++++++++++-------- .../trybuild/routes-missing-args-fail.stderr | 12 +- .../tests/trybuild/simple-fail.stderr | 32 ++- 8 files changed, 164 insertions(+), 116 deletions(-) diff --git a/actix-multipart-derive/CHANGES.md b/actix-multipart-derive/CHANGES.md index caf75aeb3..8a78900ec 100644 --- a/actix-multipart-derive/CHANGES.md +++ b/actix-multipart-derive/CHANGES.md @@ -2,6 +2,7 @@ ## Unreleased +- Update `syn` dependency to `2`. - Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. ## 0.6.0 - 2023-02-26 diff --git a/actix-multipart-derive/Cargo.toml b/actix-multipart-derive/Cargo.toml index aca6de84a..41e687e50 100644 --- a/actix-multipart-derive/Cargo.toml +++ b/actix-multipart-derive/Cargo.toml @@ -17,11 +17,11 @@ all-features = true proc-macro = true [dependencies] -darling = "0.14" +darling = "0.20" parse-size = "1" proc-macro2 = "1" quote = "1" -syn = "1" +syn = "2" [dev-dependencies] actix-multipart = "0.6" diff --git a/actix-router/src/resource.rs b/actix-router/src/resource.rs index 860993a37..b8aa6c224 100644 --- a/actix-router/src/resource.rs +++ b/actix-router/src/resource.rs @@ -252,7 +252,7 @@ impl ResourceDef { /// Multi-pattern resources can be constructed by providing a slice (or vec) of patterns. /// /// # Panics - /// Panics if path pattern is malformed. + /// Panics if any path patterns are malformed. /// /// # Examples /// ``` @@ -838,6 +838,7 @@ impl ResourceDef { fn construct(paths: T, is_prefix: bool) -> Self { let patterns = paths.patterns(); + let (pat_type, segments) = match &patterns { Patterns::Single(pattern) => ResourceDef::parse(pattern, is_prefix, false), diff --git a/actix-web-codegen/CHANGES.md b/actix-web-codegen/CHANGES.md index b9e4b0aad..2c5f17226 100644 --- a/actix-web-codegen/CHANGES.md +++ b/actix-web-codegen/CHANGES.md @@ -2,6 +2,7 @@ ## Unreleased - 2023-xx-xx +- Update `syn` dependency to `2`. - Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. ## 4.2.0 - 2023-02-26 diff --git a/actix-web-codegen/Cargo.toml b/actix-web-codegen/Cargo.toml index 4f2fdc566..c202c5d6e 100644 --- a/actix-web-codegen/Cargo.toml +++ b/actix-web-codegen/Cargo.toml @@ -18,10 +18,10 @@ proc-macro = true actix-router = "0.5" proc-macro2 = "1" quote = "1" -syn = { version = "1", features = ["full", "extra-traits"] } +syn = { version = "2", features = ["full", "extra-traits"] } [dev-dependencies] -actix-macros = "0.2.3" +actix-macros = "0.2.4" actix-rt = "2.2" actix-test = "0.1" actix-utils = "3" diff --git a/actix-web-codegen/src/route.rs b/actix-web-codegen/src/route.rs index e87d37941..525a1c8ba 100644 --- a/actix-web-codegen/src/route.rs +++ b/actix-web-codegen/src/route.rs @@ -4,7 +4,54 @@ use actix_router::ResourceDef; use proc_macro::TokenStream; use proc_macro2::{Span, TokenStream as TokenStream2}; use quote::{quote, ToTokens, TokenStreamExt}; -use syn::{parse_macro_input, AttributeArgs, Ident, LitStr, Meta, NestedMeta, Path}; +use syn::{punctuated::Punctuated, Ident, LitStr, Path, Token}; + +#[derive(Debug)] +pub struct RouteArgs { + path: syn::LitStr, + options: Punctuated, +} + +impl syn::parse::Parse for RouteArgs { + fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result { + // path to match: "/foo" + let path = input.parse::().map_err(|mut err| { + err.combine(syn::Error::new( + err.span(), + r#"invalid service definition, expected #[("")]"#, + )); + + err + })?; + + // verify that path pattern is valid + let _ = ResourceDef::new(path.value()); + + // if there's no comma, assume that no options are provided + if !input.peek(Token![,]) { + return Ok(Self { + path, + options: Punctuated::new(), + }); + } + + // advance past comma separator + input.parse::()?; + + // if next char is a literal, assume that it is a string and show multi-path error + if input.cursor().literal().is_some() { + return Err(syn::Error::new( + Span::call_site(), + r#"Multiple paths specified! There should be only one."#, + )); + } + + // zero or more options: name = "foo" + let options = input.parse_terminated(syn::MetaNameValue::parse, Token![,])?; + + Ok(Self { path, options }) + } +} macro_rules! standard_method_type { ( @@ -182,111 +229,90 @@ struct Args { } impl Args { - fn new(args: AttributeArgs, method: Option) -> syn::Result { - let mut path = None; + fn new(args: RouteArgs, method: Option) -> syn::Result { let mut resource_name = None; let mut guards = Vec::new(); let mut wrappers = Vec::new(); let mut methods = HashSet::new(); - if args.is_empty() { - return Err(syn::Error::new( - Span::call_site(), - format!( - r#"invalid service definition, expected #[{}("")]"#, - method - .map_or("route", |it| it.as_str()) - .to_ascii_lowercase() - ), - )); - } - let is_route_macro = method.is_none(); if let Some(method) = method { methods.insert(MethodTypeExt::Standard(method)); } - for arg in args { - match arg { - NestedMeta::Lit(syn::Lit::Str(lit)) => match path { - None => { - let _ = ResourceDef::new(lit.value()); - path = Some(lit); - } - _ => { - return Err(syn::Error::new_spanned( - lit, - "Multiple paths specified! Should be only one!", - )); - } - }, - - NestedMeta::Meta(syn::Meta::NameValue(nv)) => { - if nv.path.is_ident("name") { - if let syn::Lit::Str(lit) = nv.lit { - resource_name = Some(lit); - } else { - return Err(syn::Error::new_spanned( - nv.lit, - "Attribute name expects literal string!", - )); - } - } else if nv.path.is_ident("guard") { - if let syn::Lit::Str(lit) = nv.lit { - guards.push(lit.parse::()?); - } else { - return Err(syn::Error::new_spanned( - nv.lit, - "Attribute guard expects literal string!", - )); - } - } else if nv.path.is_ident("wrap") { - if let syn::Lit::Str(lit) = nv.lit { - wrappers.push(lit.parse()?); - } else { - return Err(syn::Error::new_spanned( - nv.lit, - "Attribute wrap expects type", - )); - } - } else if nv.path.is_ident("method") { - if !is_route_macro { - return Err(syn::Error::new_spanned( + for nv in args.options { + if nv.path.is_ident("name") { + if let syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Str(lit), + .. + }) = nv.value + { + resource_name = Some(lit); + } else { + return Err(syn::Error::new_spanned( + nv.value, + "Attribute name expects literal string!", + )); + } + } else if nv.path.is_ident("guard") { + if let syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Str(lit), + .. + }) = nv.value + { + guards.push(lit.parse::()?); + } else { + return Err(syn::Error::new_spanned( + nv.value, + "Attribute guard expects literal string!", + )); + } + } else if nv.path.is_ident("wrap") { + if let syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Str(lit), + .. + }) = nv.value + { + wrappers.push(lit.parse()?); + } else { + return Err(syn::Error::new_spanned( + nv.value, + "Attribute wrap expects type", + )); + } + } else if nv.path.is_ident("method") { + if !is_route_macro { + return Err(syn::Error::new_spanned( &nv, "HTTP method forbidden here. To handle multiple methods, use `route` instead", )); - } else if let syn::Lit::Str(ref lit) = nv.lit { - if !methods.insert(MethodTypeExt::try_from(lit)?) { - return Err(syn::Error::new_spanned( - &nv.lit, - format!( - "HTTP method defined more than once: `{}`", - lit.value() - ), - )); - } - } else { - return Err(syn::Error::new_spanned( - nv.lit, - "Attribute method expects literal string!", - )); - } - } else { + } else if let syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Str(lit), + .. + }) = nv.value.clone() + { + if !methods.insert(MethodTypeExt::try_from(&lit)?) { return Err(syn::Error::new_spanned( - nv.path, - "Unknown attribute key is specified. Allowed: guard, method and wrap", + nv.value, + format!("HTTP method defined more than once: `{}`", lit.value()), )); } + } else { + return Err(syn::Error::new_spanned( + nv.value, + "Attribute method expects literal string!", + )); } - - arg => { - return Err(syn::Error::new_spanned(arg, "Unknown attribute.")); - } + } else { + return Err(syn::Error::new_spanned( + nv.path, + "Unknown attribute key is specified. Allowed: guard, method and wrap", + )); } } Ok(Args { - path: path.unwrap(), + path: args.path, resource_name, guards, wrappers, @@ -312,11 +338,7 @@ pub struct Route { } impl Route { - pub fn new( - args: AttributeArgs, - ast: syn::ItemFn, - method: Option, - ) -> syn::Result { + pub fn new(args: RouteArgs, ast: syn::ItemFn, method: Option) -> syn::Result { let name = ast.sig.ident.clone(); // Try and pull out the doc comments so that we can reapply them to the generated struct. @@ -324,7 +346,7 @@ impl Route { let doc_attributes = ast .attrs .iter() - .filter(|attr| attr.path.is_ident("doc")) + .filter(|attr| attr.path().is_ident("doc")) .cloned() .collect(); @@ -360,7 +382,7 @@ impl Route { let doc_attributes = ast .attrs .iter() - .filter(|attr| attr.path.is_ident("doc")) + .filter(|attr| attr.path().is_ident("doc")) .cloned() .collect(); @@ -455,7 +477,11 @@ pub(crate) fn with_method( args: TokenStream, input: TokenStream, ) -> TokenStream { - let args = parse_macro_input!(args as syn::AttributeArgs); + let args = match syn::parse(args) { + Ok(args) => args, + // on parse error, make IDEs happy; see fn docs + Err(err) => return input_and_compile_error(input, err), + }; let ast = match syn::parse::(input.clone()) { Ok(ast) => ast, @@ -480,7 +506,7 @@ pub(crate) fn with_methods(input: TokenStream) -> TokenStream { let (methods, others) = ast .attrs .into_iter() - .map(|attr| match MethodType::from_path(&attr.path) { + .map(|attr| match MethodType::from_path(attr.path()) { Ok(method) => Ok((method, attr)), Err(_) => Err(attr), }) @@ -492,13 +518,8 @@ pub(crate) fn with_methods(input: TokenStream) -> TokenStream { .into_iter() .map(Result::unwrap) .map(|(method, attr)| { - attr.parse_meta().and_then(|args| { - if let Meta::List(args) = args { - Args::new(args.nested.into_iter().collect(), Some(method)) - } else { - Err(syn::Error::new_spanned(attr, "Invalid input for macro")) - } - }) + attr.parse_args() + .and_then(|args| Args::new(args, Some(method))) }) .collect::, _>>() { diff --git a/actix-web-codegen/tests/trybuild/routes-missing-args-fail.stderr b/actix-web-codegen/tests/trybuild/routes-missing-args-fail.stderr index e845241a4..2e84c296a 100644 --- a/actix-web-codegen/tests/trybuild/routes-missing-args-fail.stderr +++ b/actix-web-codegen/tests/trybuild/routes-missing-args-fail.stderr @@ -1,4 +1,4 @@ -error: invalid service definition, expected #[get("")] +error: unexpected end of input, expected string literal --> tests/trybuild/routes-missing-args-fail.rs:4:1 | 4 | #[get] @@ -6,11 +6,19 @@ error: invalid service definition, expected #[get("")] | = note: this error originates in the attribute macro `get` (in Nightly builds, run with -Z macro-backtrace for more info) -error: Invalid input for macro +error: invalid service definition, expected #[("")] --> tests/trybuild/routes-missing-args-fail.rs:4:1 | 4 | #[get] | ^^^^^^ + | + = note: this error originates in the attribute macro `get` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected attribute arguments in parentheses: #[get(...)] + --> tests/trybuild/routes-missing-args-fail.rs:4:3 + | +4 | #[get] + | ^^^ error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied --> tests/trybuild/routes-missing-args-fail.rs:13:55 diff --git a/actix-web-codegen/tests/trybuild/simple-fail.stderr b/actix-web-codegen/tests/trybuild/simple-fail.stderr index cffc81ff8..3b3f9d850 100644 --- a/actix-web-codegen/tests/trybuild/simple-fail.stderr +++ b/actix-web-codegen/tests/trybuild/simple-fail.stderr @@ -1,26 +1,42 @@ -error: Unknown attribute. - --> $DIR/simple-fail.rs:3:15 +error: expected `=` + --> $DIR/simple-fail.rs:3:1 | 3 | #[get("/one", other)] - | ^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the attribute macro `get` (in Nightly builds, run with -Z macro-backtrace for more info) -error: expected identifier or literal +error: expected string literal --> $DIR/simple-fail.rs:8:8 | 8 | #[post(/two)] | ^ -error: Unknown attribute. +error: invalid service definition, expected #[("")] + --> $DIR/simple-fail.rs:8:8 + | +8 | #[post(/two)] + | ^ + +error: expected string literal --> $DIR/simple-fail.rs:15:9 | 15 | #[patch(PATCH_PATH)] | ^^^^^^^^^^ -error: Multiple paths specified! Should be only one! - --> $DIR/simple-fail.rs:20:19 +error: invalid service definition, expected #[("")] + --> $DIR/simple-fail.rs:15:9 + | +15 | #[patch(PATCH_PATH)] + | ^^^^^^^^^^ + +error: Multiple paths specified! There should be only one. + --> $DIR/simple-fail.rs:20:1 | 20 | #[delete("/four", "/five")] - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the attribute macro `delete` (in Nightly builds, run with -Z macro-backtrace for more info) error: HTTP method forbidden here. To handle multiple methods, use `route` instead --> $DIR/simple-fail.rs:25:19 From 1040bc3d17e491d133da733c419c00d727846600 Mon Sep 17 00:00:00 2001 From: cyqsimon <28627918+cyqsimon@users.noreply.github.com> Date: Thu, 20 Jul 2023 18:36:49 +0800 Subject: [PATCH 23/57] Add missing status code constructor methods on `HttpResponse` (#3042) --- actix-web/CHANGES.md | 1 + actix-web/src/response/http_codes.rs | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 35d695328..e96f852e5 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -6,6 +6,7 @@ - Add `HttpServer::{bind, listen}_auto_h2c()` method behind new `http2` crate feature. - Add `Resource::{get, post, etc...}` methods for more concisely adding routes that don't need additional guards. +- Add several missing convenience methods on `HttpResponse` for their respective status codes. ### Changed diff --git a/actix-web/src/response/http_codes.rs b/actix-web/src/response/http_codes.rs index 2ac83046a..db5f392c9 100644 --- a/actix-web/src/response/http_codes.rs +++ b/actix-web/src/response/http_codes.rs @@ -25,12 +25,12 @@ impl HttpResponse { NonAuthoritativeInformation, StatusCode::NON_AUTHORITATIVE_INFORMATION ); - static_resp!(NoContent, StatusCode::NO_CONTENT); static_resp!(ResetContent, StatusCode::RESET_CONTENT); static_resp!(PartialContent, StatusCode::PARTIAL_CONTENT); static_resp!(MultiStatus, StatusCode::MULTI_STATUS); static_resp!(AlreadyReported, StatusCode::ALREADY_REPORTED); + static_resp!(ImUsed, StatusCode::IM_USED); static_resp!(MultipleChoices, StatusCode::MULTIPLE_CHOICES); static_resp!(MovedPermanently, StatusCode::MOVED_PERMANENTLY); @@ -42,10 +42,10 @@ impl HttpResponse { static_resp!(PermanentRedirect, StatusCode::PERMANENT_REDIRECT); static_resp!(BadRequest, StatusCode::BAD_REQUEST); - static_resp!(NotFound, StatusCode::NOT_FOUND); static_resp!(Unauthorized, StatusCode::UNAUTHORIZED); static_resp!(PaymentRequired, StatusCode::PAYMENT_REQUIRED); static_resp!(Forbidden, StatusCode::FORBIDDEN); + static_resp!(NotFound, StatusCode::NOT_FOUND); static_resp!(MethodNotAllowed, StatusCode::METHOD_NOT_ALLOWED); static_resp!(NotAcceptable, StatusCode::NOT_ACCEPTABLE); static_resp!( @@ -57,13 +57,18 @@ impl HttpResponse { static_resp!(Gone, StatusCode::GONE); static_resp!(LengthRequired, StatusCode::LENGTH_REQUIRED); static_resp!(PreconditionFailed, StatusCode::PRECONDITION_FAILED); - static_resp!(PreconditionRequired, StatusCode::PRECONDITION_REQUIRED); static_resp!(PayloadTooLarge, StatusCode::PAYLOAD_TOO_LARGE); static_resp!(UriTooLong, StatusCode::URI_TOO_LONG); static_resp!(UnsupportedMediaType, StatusCode::UNSUPPORTED_MEDIA_TYPE); static_resp!(RangeNotSatisfiable, StatusCode::RANGE_NOT_SATISFIABLE); static_resp!(ExpectationFailed, StatusCode::EXPECTATION_FAILED); + static_resp!(ImATeapot, StatusCode::IM_A_TEAPOT); + static_resp!(MisdirectedRequest, StatusCode::MISDIRECTED_REQUEST); static_resp!(UnprocessableEntity, StatusCode::UNPROCESSABLE_ENTITY); + static_resp!(Locked, StatusCode::LOCKED); + static_resp!(FailedDependency, StatusCode::FAILED_DEPENDENCY); + static_resp!(UpgradeRequired, StatusCode::UPGRADE_REQUIRED); + static_resp!(PreconditionRequired, StatusCode::PRECONDITION_REQUIRED); static_resp!(TooManyRequests, StatusCode::TOO_MANY_REQUESTS); static_resp!( RequestHeaderFieldsTooLarge, @@ -83,6 +88,11 @@ impl HttpResponse { static_resp!(VariantAlsoNegotiates, StatusCode::VARIANT_ALSO_NEGOTIATES); static_resp!(InsufficientStorage, StatusCode::INSUFFICIENT_STORAGE); static_resp!(LoopDetected, StatusCode::LOOP_DETECTED); + static_resp!(NotExtended, StatusCode::NOT_EXTENDED); + static_resp!( + NetworkAuthenticationRequired, + StatusCode::NETWORK_AUTHENTICATION_REQUIRED + ); } #[cfg(test)] From 3eb5a059ade249dae4468a8bb6eb5784e1dfdb10 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 20 Jul 2023 11:02:15 +0100 Subject: [PATCH 24/57] chore: address clippy warnings --- actix-http/src/encoding/mod.rs | 2 +- actix-http/src/ws/mask.rs | 2 +- actix-http/tests/test_server.rs | 8 ++--- actix-router/src/resource.rs | 7 +++- actix-web/src/http/header/accept.rs | 8 ++--- actix-web/src/http/header/accept_charset.rs | 2 +- actix-web/src/http/header/accept_encoding.rs | 14 ++++---- actix-web/src/http/header/accept_language.rs | 12 +++---- actix-web/src/http/header/allow.rs | 6 ++-- actix-web/src/http/header/cache_control.rs | 12 +++---- actix-web/src/http/header/content_language.rs | 4 +-- actix-web/src/http/header/content_range.rs | 36 ++++++++----------- actix-web/src/http/header/content_type.rs | 4 +-- actix-web/src/http/header/date.rs | 2 +- actix-web/src/http/header/etag.rs | 30 ++++++++-------- actix-web/src/http/header/expires.rs | 2 +- actix-web/src/http/header/if_match.rs | 6 ++-- .../src/http/header/if_modified_since.rs | 2 +- actix-web/src/http/header/if_none_match.rs | 10 +++--- actix-web/src/http/header/if_range.rs | 6 ++-- .../src/http/header/if_unmodified_since.rs | 2 +- actix-web/src/http/header/last_modified.rs | 2 +- 22 files changed, 87 insertions(+), 92 deletions(-) diff --git a/actix-http/src/encoding/mod.rs b/actix-http/src/encoding/mod.rs index 7823f3979..6801b5fb0 100644 --- a/actix-http/src/encoding/mod.rs +++ b/actix-http/src/encoding/mod.rs @@ -12,7 +12,7 @@ pub use self::{decoder::Decoder, encoder::Encoder}; /// Special-purpose writer for streaming (de-)compression. /// /// Pre-allocates 8KiB of capacity. -pub(self) struct Writer { +struct Writer { buf: BytesMut, } diff --git a/actix-http/src/ws/mask.rs b/actix-http/src/ws/mask.rs index be72e5631..115a8cf9b 100644 --- a/actix-http/src/ws/mask.rs +++ b/actix-http/src/ws/mask.rs @@ -50,7 +50,7 @@ mod tests { #[test] fn test_apply_mask() { let mask = [0x6d, 0xb6, 0xb2, 0x80]; - let unmasked = vec![ + let unmasked = [ 0xf3, 0x00, 0x01, 0x02, 0x03, 0x80, 0x81, 0x82, 0xff, 0xfe, 0x00, 0x17, 0x74, 0xf9, 0x12, 0x03, ]; diff --git a/actix-http/tests/test_server.rs b/actix-http/tests/test_server.rs index cfb4d17b8..f55b1b36c 100644 --- a/actix-http/tests/test_server.rs +++ b/actix-http/tests/test_server.rs @@ -1,5 +1,3 @@ -#![allow(clippy::uninlined_format_args)] - use std::{ convert::Infallible, io::{Read, Write}, @@ -139,7 +137,7 @@ async fn expect_continue_h1() { #[actix_rt::test] async fn chunked_payload() { - let chunk_sizes = vec![32768, 32, 32768]; + let chunk_sizes = [32768, 32, 32768]; let total_size: usize = chunk_sizes.iter().sum(); let mut srv = test_server(|| { @@ -402,7 +400,7 @@ async fn content_length() { let mut srv = test_server(|| { HttpService::build() .h1(|req: Request| { - let indx: usize = req.uri().path()[1..].parse().unwrap(); + let idx: usize = req.uri().path()[1..].parse().unwrap(); let statuses = [ StatusCode::NO_CONTENT, StatusCode::CONTINUE, @@ -411,7 +409,7 @@ async fn content_length() { StatusCode::OK, StatusCode::NOT_FOUND, ]; - ok::<_, Infallible>(Response::new(statuses[indx])) + ok::<_, Infallible>(Response::new(statuses[idx])) }) .tcp() }) diff --git a/actix-router/src/resource.rs b/actix-router/src/resource.rs index b8aa6c224..a3e89a1fe 100644 --- a/actix-router/src/resource.rs +++ b/actix-router/src/resource.rs @@ -1529,7 +1529,12 @@ mod tests { assert!(!resource.resource_path_from_iter(&mut s, &mut ["item"].iter())); let mut s = String::new(); - assert!(resource.resource_path_from_iter(&mut s, &mut vec!["item", "item2"].iter())); + + assert!(resource.resource_path_from_iter( + &mut s, + #[allow(clippy::useless_vec)] + &mut vec!["item", "item2"].iter() + )); assert_eq!(s, "/user/item/item2/"); } diff --git a/actix-web/src/http/header/accept.rs b/actix-web/src/http/header/accept.rs index 1be136b19..99c95175f 100644 --- a/actix-web/src/http/header/accept.rs +++ b/actix-web/src/http/header/accept.rs @@ -78,7 +78,7 @@ common_header! { // Tests from the RFC crate::http::header::common_header_test!( test1, - vec![b"audio/*; q=0.2, audio/basic"], + [b"audio/*; q=0.2, audio/basic"], Some(Accept(vec![ QualityItem::new("audio/*".parse().unwrap(), q(0.2)), QualityItem::max("audio/basic".parse().unwrap()), @@ -86,7 +86,7 @@ common_header! { crate::http::header::common_header_test!( test2, - vec![b"text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c"], + [b"text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c"], Some(Accept(vec![ QualityItem::new(mime::TEXT_PLAIN, q(0.5)), QualityItem::max(mime::TEXT_HTML), @@ -99,13 +99,13 @@ common_header! { // Custom tests crate::http::header::common_header_test!( test3, - vec![b"text/plain; charset=utf-8"], + [b"text/plain; charset=utf-8"], Some(Accept(vec![ QualityItem::max(mime::TEXT_PLAIN_UTF_8), ]))); crate::http::header::common_header_test!( test4, - vec![b"text/plain; charset=utf-8; q=0.5"], + [b"text/plain; charset=utf-8; q=0.5"], Some(Accept(vec![ QualityItem::new(mime::TEXT_PLAIN_UTF_8, q(0.5)), ]))); diff --git a/actix-web/src/http/header/accept_charset.rs b/actix-web/src/http/header/accept_charset.rs index c7f7e1a68..43a7861fe 100644 --- a/actix-web/src/http/header/accept_charset.rs +++ b/actix-web/src/http/header/accept_charset.rs @@ -57,6 +57,6 @@ common_header! { test_parse_and_format { // Test case from RFC - common_header_test!(test1, vec![b"iso-8859-5, unicode-1-1;q=0.8"]); + common_header_test!(test1, [b"iso-8859-5, unicode-1-1;q=0.8"]); } } diff --git a/actix-web/src/http/header/accept_encoding.rs b/actix-web/src/http/header/accept_encoding.rs index 715126a03..cc80e7bb0 100644 --- a/actix-web/src/http/header/accept_encoding.rs +++ b/actix-web/src/http/header/accept_encoding.rs @@ -50,31 +50,31 @@ common_header! { (AcceptEncoding, header::ACCEPT_ENCODING) => (QualityItem>)* test_parse_and_format { - common_header_test!(no_headers, vec![b""; 0], Some(AcceptEncoding(vec![]))); - common_header_test!(empty_header, vec![b""; 1], Some(AcceptEncoding(vec![]))); + common_header_test!(no_headers, [b""; 0], Some(AcceptEncoding(vec![]))); + common_header_test!(empty_header, [b""; 1], Some(AcceptEncoding(vec![]))); common_header_test!( order_of_appearance, - vec![b"br, gzip"], + [b"br, gzip"], Some(AcceptEncoding(vec![ QualityItem::max(Preference::Specific(Encoding::brotli())), QualityItem::max(Preference::Specific(Encoding::gzip())), ])) ); - common_header_test!(any, vec![b"*"], Some(AcceptEncoding(vec![ + common_header_test!(any, [b"*"], Some(AcceptEncoding(vec![ QualityItem::max(Preference::Any), ]))); // Note: Removed quality 1 from gzip - common_header_test!(implicit_quality, vec![b"gzip, identity; q=0.5, *;q=0"]); + common_header_test!(implicit_quality, [b"gzip, identity; q=0.5, *;q=0"]); // Note: Removed quality 1 from gzip - common_header_test!(implicit_quality_out_of_order, vec![b"compress;q=0.5, gzip"]); + common_header_test!(implicit_quality_out_of_order, [b"compress;q=0.5, gzip"]); common_header_test!( only_gzip_no_identity, - vec![b"gzip, *; q=0"], + [b"gzip, *; q=0"], Some(AcceptEncoding(vec![ QualityItem::max(Preference::Specific(Encoding::gzip())), QualityItem::zero(Preference::Any), diff --git a/actix-web/src/http/header/accept_language.rs b/actix-web/src/http/header/accept_language.rs index 9943e121f..b1d588f8d 100644 --- a/actix-web/src/http/header/accept_language.rs +++ b/actix-web/src/http/header/accept_language.rs @@ -58,19 +58,19 @@ common_header! { (AcceptLanguage, header::ACCEPT_LANGUAGE) => (QualityItem>)* test_parse_and_format { - common_header_test!(no_headers, vec![b""; 0], Some(AcceptLanguage(vec![]))); + common_header_test!(no_headers, [b""; 0], Some(AcceptLanguage(vec![]))); - common_header_test!(empty_header, vec![b""; 1], Some(AcceptLanguage(vec![]))); + common_header_test!(empty_header, [b""; 1], Some(AcceptLanguage(vec![]))); common_header_test!( example_from_rfc, - vec![b"da, en-gb;q=0.8, en;q=0.7"] + [b"da, en-gb;q=0.8, en;q=0.7"] ); common_header_test!( not_ordered_by_weight, - vec![b"en-US, en; q=0.5, fr"], + [b"en-US, en; q=0.5, fr"], Some(AcceptLanguage(vec![ QualityItem::max("en-US".parse().unwrap()), QualityItem::new("en".parse().unwrap(), q(0.5)), @@ -80,7 +80,7 @@ common_header! { common_header_test!( has_wildcard, - vec![b"fr-CH, fr; q=0.9, en; q=0.8, de; q=0.7, *; q=0.5"], + [b"fr-CH, fr; q=0.9, en; q=0.8, de; q=0.7, *; q=0.5"], Some(AcceptLanguage(vec![ QualityItem::max("fr-CH".parse().unwrap()), QualityItem::new("fr".parse().unwrap(), q(0.9)), @@ -137,7 +137,7 @@ impl AcceptLanguage { b.quality.cmp(&a.quality) }); - types.into_iter().map(|qitem| qitem.item).collect() + types.into_iter().map(|q_item| q_item.item).collect() } } diff --git a/actix-web/src/http/header/allow.rs b/actix-web/src/http/header/allow.rs index d0ef96486..1ae8f00dc 100644 --- a/actix-web/src/http/header/allow.rs +++ b/actix-web/src/http/header/allow.rs @@ -51,12 +51,12 @@ crate::http::header::common_header! { // From the RFC crate::http::header::common_header_test!( test1, - vec![b"GET, HEAD, PUT"], + [b"GET, HEAD, PUT"], Some(HeaderField(vec![Method::GET, Method::HEAD, Method::PUT]))); // Own tests crate::http::header::common_header_test!( test2, - vec![b"OPTIONS, GET, PUT, POST, DELETE, HEAD, TRACE, CONNECT, PATCH"], + [b"OPTIONS, GET, PUT, POST, DELETE, HEAD, TRACE, CONNECT, PATCH"], Some(HeaderField(vec![ Method::OPTIONS, Method::GET, @@ -69,7 +69,7 @@ crate::http::header::common_header! { Method::PATCH]))); crate::http::header::common_header_test!( test3, - vec![b""], + [b""], Some(HeaderField(Vec::::new()))); } } diff --git a/actix-web/src/http/header/cache_control.rs b/actix-web/src/http/header/cache_control.rs index 37629313e..77e22d1c3 100644 --- a/actix-web/src/http/header/cache_control.rs +++ b/actix-web/src/http/header/cache_control.rs @@ -47,13 +47,13 @@ common_header! { (CacheControl, header::CACHE_CONTROL) => (CacheDirective)+ test_parse_and_format { - common_header_test!(no_headers, vec![b""; 0], None); - common_header_test!(empty_header, vec![b""; 1], None); - common_header_test!(bad_syntax, vec![b"foo="], None); + common_header_test!(no_headers, [b""; 0], None); + common_header_test!(empty_header, [b""; 1], None); + common_header_test!(bad_syntax, [b"foo="], None); common_header_test!( multiple_headers, - vec![&b"no-cache"[..], &b"private"[..]], + [&b"no-cache"[..], &b"private"[..]], Some(CacheControl(vec![ CacheDirective::NoCache, CacheDirective::Private, @@ -62,7 +62,7 @@ common_header! { common_header_test!( argument, - vec![b"max-age=100, private"], + [b"max-age=100, private"], Some(CacheControl(vec![ CacheDirective::MaxAge(100), CacheDirective::Private, @@ -71,7 +71,7 @@ common_header! { common_header_test!( extension, - vec![b"foo, bar=baz"], + [b"foo, bar=baz"], Some(CacheControl(vec![ CacheDirective::Extension("foo".to_owned(), None), CacheDirective::Extension("bar".to_owned(), Some("baz".to_owned())), diff --git a/actix-web/src/http/header/content_language.rs b/actix-web/src/http/header/content_language.rs index ff317e1de..5b0797ef3 100644 --- a/actix-web/src/http/header/content_language.rs +++ b/actix-web/src/http/header/content_language.rs @@ -48,7 +48,7 @@ common_header! { (ContentLanguage, CONTENT_LANGUAGE) => (QualityItem)+ test_parse_and_format { - crate::http::header::common_header_test!(test1, vec![b"da"]); - crate::http::header::common_header_test!(test2, vec![b"mi, en"]); + crate::http::header::common_header_test!(test1, [b"da"]); + crate::http::header::common_header_test!(test2, [b"mi, en"]); } } diff --git a/actix-web/src/http/header/content_range.rs b/actix-web/src/http/header/content_range.rs index 8befffd95..884926195 100644 --- a/actix-web/src/http/header/content_range.rs +++ b/actix-web/src/http/header/content_range.rs @@ -13,59 +13,59 @@ crate::http::header::common_header! { test_parse_and_format { crate::http::header::common_header_test!(test_bytes, - vec![b"bytes 0-499/500"], + [b"bytes 0-499/500"], Some(ContentRange(ContentRangeSpec::Bytes { range: Some((0, 499)), instance_length: Some(500) }))); crate::http::header::common_header_test!(test_bytes_unknown_len, - vec![b"bytes 0-499/*"], + [b"bytes 0-499/*"], Some(ContentRange(ContentRangeSpec::Bytes { range: Some((0, 499)), instance_length: None }))); crate::http::header::common_header_test!(test_bytes_unknown_range, - vec![b"bytes */500"], + [b"bytes */500"], Some(ContentRange(ContentRangeSpec::Bytes { range: None, instance_length: Some(500) }))); crate::http::header::common_header_test!(test_unregistered, - vec![b"seconds 1-2"], + [b"seconds 1-2"], Some(ContentRange(ContentRangeSpec::Unregistered { unit: "seconds".to_owned(), resp: "1-2".to_owned() }))); crate::http::header::common_header_test!(test_no_len, - vec![b"bytes 0-499"], + [b"bytes 0-499"], None::); crate::http::header::common_header_test!(test_only_unit, - vec![b"bytes"], + [b"bytes"], None::); crate::http::header::common_header_test!(test_end_less_than_start, - vec![b"bytes 499-0/500"], + [b"bytes 499-0/500"], None::); crate::http::header::common_header_test!(test_blank, - vec![b""], + [b""], None::); crate::http::header::common_header_test!(test_bytes_many_spaces, - vec![b"bytes 1-2/500 3"], + [b"bytes 1-2/500 3"], None::); crate::http::header::common_header_test!(test_bytes_many_slashes, - vec![b"bytes 1-2/500/600"], + [b"bytes 1-2/500/600"], None::); crate::http::header::common_header_test!(test_bytes_many_dashes, - vec![b"bytes 1-2-3/500"], + [b"bytes 1-2-3/500"], None::); } @@ -113,21 +113,13 @@ pub enum ContentRangeSpec { }, } -fn split_in_two(s: &str, separator: char) -> Option<(&str, &str)> { - let mut iter = s.splitn(2, separator); - match (iter.next(), iter.next()) { - (Some(a), Some(b)) => Some((a, b)), - _ => None, - } -} - impl FromStr for ContentRangeSpec { type Err = ParseError; fn from_str(s: &str) -> Result { - let res = match split_in_two(s, ' ') { + let res = match s.split_once(' ') { Some(("bytes", resp)) => { - let (range, instance_length) = split_in_two(resp, '/').ok_or(ParseError::Header)?; + let (range, instance_length) = resp.split_once('/').ok_or(ParseError::Header)?; let instance_length = if instance_length == "*" { None @@ -139,7 +131,7 @@ impl FromStr for ContentRangeSpec { None } else { let (first_byte, last_byte) = - split_in_two(range, '-').ok_or(ParseError::Header)?; + range.split_once('-').ok_or(ParseError::Header)?; let first_byte = first_byte.parse().map_err(|_| ParseError::Header)?; let last_byte = last_byte.parse().map_err(|_| ParseError::Header)?; if last_byte < first_byte { diff --git a/actix-web/src/http/header/content_type.rs b/actix-web/src/http/header/content_type.rs index bf86afffa..c43ef8a2f 100644 --- a/actix-web/src/http/header/content_type.rs +++ b/actix-web/src/http/header/content_type.rs @@ -45,11 +45,11 @@ crate::http::header::common_header! { test_parse_and_format { crate::http::header::common_header_test!( test_text_html, - vec![b"text/html"], + [b"text/html"], Some(HeaderField(mime::TEXT_HTML))); crate::http::header::common_header_test!( test_image_star, - vec![b"image/*"], + [b"image/*"], Some(HeaderField(mime::IMAGE_STAR))); } diff --git a/actix-web/src/http/header/date.rs b/actix-web/src/http/header/date.rs index a8ac65660..ac30424f0 100644 --- a/actix-web/src/http/header/date.rs +++ b/actix-web/src/http/header/date.rs @@ -32,7 +32,7 @@ crate::http::header::common_header! { (Date, DATE) => [HttpDate] test_parse_and_format { - crate::http::header::common_header_test!(test1, vec![b"Tue, 15 Nov 1994 08:12:31 GMT"]); + crate::http::header::common_header_test!(test1, [b"Tue, 15 Nov 1994 08:12:31 GMT"]); } } diff --git a/actix-web/src/http/header/etag.rs b/actix-web/src/http/header/etag.rs index 78f5447b3..b82208288 100644 --- a/actix-web/src/http/header/etag.rs +++ b/actix-web/src/http/header/etag.rs @@ -49,50 +49,50 @@ crate::http::header::common_header! { test_parse_and_format { // From the RFC crate::http::header::common_header_test!(test1, - vec![b"\"xyzzy\""], + [b"\"xyzzy\""], Some(ETag(EntityTag::new_strong("xyzzy".to_owned())))); crate::http::header::common_header_test!(test2, - vec![b"W/\"xyzzy\""], + [b"W/\"xyzzy\""], Some(ETag(EntityTag::new_weak("xyzzy".to_owned())))); crate::http::header::common_header_test!(test3, - vec![b"\"\""], + [b"\"\""], Some(ETag(EntityTag::new_strong("".to_owned())))); // Own tests crate::http::header::common_header_test!(test4, - vec![b"\"foobar\""], + [b"\"foobar\""], Some(ETag(EntityTag::new_strong("foobar".to_owned())))); crate::http::header::common_header_test!(test5, - vec![b"\"\""], + [b"\"\""], Some(ETag(EntityTag::new_strong("".to_owned())))); crate::http::header::common_header_test!(test6, - vec![b"W/\"weak-etag\""], + [b"W/\"weak-etag\""], Some(ETag(EntityTag::new_weak("weak-etag".to_owned())))); crate::http::header::common_header_test!(test7, - vec![b"W/\"\x65\x62\""], + [b"W/\"\x65\x62\""], Some(ETag(EntityTag::new_weak("\u{0065}\u{0062}".to_owned())))); crate::http::header::common_header_test!(test8, - vec![b"W/\"\""], + [b"W/\"\""], Some(ETag(EntityTag::new_weak("".to_owned())))); crate::http::header::common_header_test!(test9, - vec![b"no-dquotes"], + [b"no-dquotes"], None::); crate::http::header::common_header_test!(test10, - vec![b"w/\"the-first-w-is-case-sensitive\""], + [b"w/\"the-first-w-is-case-sensitive\""], None::); crate::http::header::common_header_test!(test11, - vec![b""], + [b""], None::); crate::http::header::common_header_test!(test12, - vec![b"\"unmatched-dquotes1"], + [b"\"unmatched-dquotes1"], None::); crate::http::header::common_header_test!(test13, - vec![b"unmatched-dquotes2\""], + [b"unmatched-dquotes2\""], None::); crate::http::header::common_header_test!(test14, - vec![b"matched-\"dquotes\""], + [b"matched-\"dquotes\""], None::); crate::http::header::common_header_test!(test15, - vec![b"\""], + [b"\""], None::); } } diff --git a/actix-web/src/http/header/expires.rs b/actix-web/src/http/header/expires.rs index 55fe5acc5..b677ab527 100644 --- a/actix-web/src/http/header/expires.rs +++ b/actix-web/src/http/header/expires.rs @@ -36,6 +36,6 @@ crate::http::header::common_header! { test_parse_and_format { // Test case from RFC - crate::http::header::common_header_test!(test1, vec![b"Thu, 01 Dec 1994 16:00:00 GMT"]); + crate::http::header::common_header_test!(test1, [b"Thu, 01 Dec 1994 16:00:00 GMT"]); } } diff --git a/actix-web/src/http/header/if_match.rs b/actix-web/src/http/header/if_match.rs index e299d30fe..e0b46a6c3 100644 --- a/actix-web/src/http/header/if_match.rs +++ b/actix-web/src/http/header/if_match.rs @@ -52,17 +52,17 @@ common_header! { test_parse_and_format { crate::http::header::common_header_test!( test1, - vec![b"\"xyzzy\""], + [b"\"xyzzy\""], Some(HeaderField::Items( vec![EntityTag::new_strong("xyzzy".to_owned())]))); crate::http::header::common_header_test!( test2, - vec![b"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\""], + [b"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\""], Some(HeaderField::Items( vec![EntityTag::new_strong("xyzzy".to_owned()), EntityTag::new_strong("r2d2xxxx".to_owned()), EntityTag::new_strong("c3piozzzz".to_owned())]))); - crate::http::header::common_header_test!(test3, vec![b"*"], Some(IfMatch::Any)); + crate::http::header::common_header_test!(test3, [b"*"], Some(IfMatch::Any)); } } diff --git a/actix-web/src/http/header/if_modified_since.rs b/actix-web/src/http/header/if_modified_since.rs index 897210944..8547ff490 100644 --- a/actix-web/src/http/header/if_modified_since.rs +++ b/actix-web/src/http/header/if_modified_since.rs @@ -35,6 +35,6 @@ crate::http::header::common_header! { test_parse_and_format { // Test case from RFC - crate::http::header::common_header_test!(test1, vec![b"Sat, 29 Oct 1994 19:43:31 GMT"]); + crate::http::header::common_header_test!(test1, [b"Sat, 29 Oct 1994 19:43:31 GMT"]); } } diff --git a/actix-web/src/http/header/if_none_match.rs b/actix-web/src/http/header/if_none_match.rs index 86d7da9b2..1a424df96 100644 --- a/actix-web/src/http/header/if_none_match.rs +++ b/actix-web/src/http/header/if_none_match.rs @@ -52,11 +52,11 @@ crate::http::header::common_header! { (IfNoneMatch, IF_NONE_MATCH) => {Any / (EntityTag)+} test_parse_and_format { - crate::http::header::common_header_test!(test1, vec![b"\"xyzzy\""]); - crate::http::header::common_header_test!(test2, vec![b"W/\"xyzzy\""]); - crate::http::header::common_header_test!(test3, vec![b"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\""]); - crate::http::header::common_header_test!(test4, vec![b"W/\"xyzzy\", W/\"r2d2xxxx\", W/\"c3piozzzz\""]); - crate::http::header::common_header_test!(test5, vec![b"*"]); + crate::http::header::common_header_test!(test1, [b"\"xyzzy\""]); + crate::http::header::common_header_test!(test2, [b"W/\"xyzzy\""]); + crate::http::header::common_header_test!(test3, [b"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\""]); + crate::http::header::common_header_test!(test4, [b"W/\"xyzzy\", W/\"r2d2xxxx\", W/\"c3piozzzz\""]); + crate::http::header::common_header_test!(test5, [b"*"]); } } diff --git a/actix-web/src/http/header/if_range.rs b/actix-web/src/http/header/if_range.rs index d7375c4c5..3e8727ab0 100644 --- a/actix-web/src/http/header/if_range.rs +++ b/actix-web/src/http/header/if_range.rs @@ -111,7 +111,7 @@ mod test_parse_and_format { use super::IfRange as HeaderField; use crate::http::header::*; - crate::http::header::common_header_test!(test1, vec![b"Sat, 29 Oct 1994 19:43:31 GMT"]); - crate::http::header::common_header_test!(test2, vec![b"\"abc\""]); - crate::http::header::common_header_test!(test3, vec![b"this-is-invalid"], None::); + crate::http::header::common_header_test!(test1, [b"Sat, 29 Oct 1994 19:43:31 GMT"]); + crate::http::header::common_header_test!(test2, [b"\"abc\""]); + crate::http::header::common_header_test!(test3, [b"this-is-invalid"], None::); } diff --git a/actix-web/src/http/header/if_unmodified_since.rs b/actix-web/src/http/header/if_unmodified_since.rs index 2ee3160b4..afa4eb8e5 100644 --- a/actix-web/src/http/header/if_unmodified_since.rs +++ b/actix-web/src/http/header/if_unmodified_since.rs @@ -35,6 +35,6 @@ crate::http::header::common_header! { test_parse_and_format { // Test case from RFC - crate::http::header::common_header_test!(test1, vec![b"Sat, 29 Oct 1994 19:43:31 GMT"]); + crate::http::header::common_header_test!(test1, [b"Sat, 29 Oct 1994 19:43:31 GMT"]); } } diff --git a/actix-web/src/http/header/last_modified.rs b/actix-web/src/http/header/last_modified.rs index 59e649bea..724a38bbc 100644 --- a/actix-web/src/http/header/last_modified.rs +++ b/actix-web/src/http/header/last_modified.rs @@ -34,6 +34,6 @@ crate::http::header::common_header! { test_parse_and_format { // Test case from RFC - crate::http::header::common_header_test!(test1, vec![b"Sat, 29 Oct 1994 19:43:31 GMT"]); + crate::http::header::common_header_test!(test1, [b"Sat, 29 Oct 1994 19:43:31 GMT"]); } } From 146011018ef4c71ca9cee1538684a784c619ffac Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 22 Jul 2023 02:02:29 +0100 Subject: [PATCH 25/57] add payload to_bytes helpers (#3083) --- actix-http/src/body/body_stream.rs | 5 +- actix-web/CHANGES.md | 3 +- actix-web/src/types/payload.rs | 116 ++++++++++++++++++++++++++++- 3 files changed, 117 insertions(+), 7 deletions(-) diff --git a/actix-http/src/body/body_stream.rs b/actix-http/src/body/body_stream.rs index 5a12c1e40..4574b2519 100644 --- a/actix-http/src/body/body_stream.rs +++ b/actix-http/src/body/body_stream.rs @@ -47,9 +47,8 @@ where /// Attempts to pull out the next value of the underlying [`Stream`]. /// - /// Empty values are skipped to prevent [`BodyStream`]'s transmission being - /// ended on a zero-length chunk, but rather proceed until the underlying - /// [`Stream`] ends. + /// Empty values are skipped to prevent [`BodyStream`]'s transmission being ended on a + /// zero-length chunk, but rather proceed until the underlying [`Stream`] ends. fn poll_next( mut self: Pin<&mut Self>, cx: &mut Context<'_>, diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index e96f852e5..f22a815c3 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -6,7 +6,8 @@ - Add `HttpServer::{bind, listen}_auto_h2c()` method behind new `http2` crate feature. - Add `Resource::{get, post, etc...}` methods for more concisely adding routes that don't need additional guards. -- Add several missing convenience methods on `HttpResponse` for their respective status codes. +- Add `web::Payload::to_bytes[_limited]()` helper methods. +- Add missing constructors on `HttpResponse` for several status codes. ### Changed diff --git a/actix-web/src/types/payload.rs b/actix-web/src/types/payload.rs index 1d9c6aba5..abb4e6b7f 100644 --- a/actix-web/src/types/payload.rs +++ b/actix-web/src/types/payload.rs @@ -16,7 +16,8 @@ use futures_core::{ready, stream::Stream}; use mime::Mime; use crate::{ - dev, error::ErrorBadRequest, http::header, web, Error, FromRequest, HttpMessage, HttpRequest, + body, dev, error::ErrorBadRequest, http::header, web, Error, FromRequest, HttpMessage, + HttpRequest, }; /// Extract a request's raw payload stream. @@ -50,6 +51,72 @@ impl Payload { pub fn into_inner(self) -> dev::Payload { self.0 } + + /// Buffers payload from request up to `limit` bytes. + /// + /// This method is preferred over [`Payload::to_bytes()`] since it will not lead to unexpected + /// memory exhaustion from massive payloads. Note that the other primitive extractors such as + /// [`Bytes`] and [`String`], as well as extractors built on top of them, already have this sort + /// of protection according to the configured (or default) [`PayloadConfig`]. + /// + /// # Errors + /// + /// - The outer error type, [`BodyLimitExceeded`](body::BodyLimitExceeded), is returned when the + /// payload is larger than `limit`. + /// - The inner error type is [the normal Actix Web error](crate::Error) and is only returned if + /// the payload stream yields an error for some reason. Such cases are usually caused by + /// unrecoverable connection issues. + /// + /// # Examples + /// + /// ``` + /// use actix_web::{error, web::Payload, Responder}; + /// + /// async fn limited_payload_handler(pl: Payload) -> actix_web::Result { + /// match pl.to_bytes_limited(5).await { + /// Ok(res) => res, + /// Err(err) => Err(error::ErrorPayloadTooLarge(err)), + /// } + /// } + /// ``` + pub async fn to_bytes_limited( + self, + limit: usize, + ) -> Result, body::BodyLimitExceeded> { + let stream = body::BodyStream::new(self.0); + + match body::to_bytes_limited(stream, limit).await { + Ok(Ok(body)) => Ok(Ok(body)), + Ok(Err(err)) => Ok(Err(err.into())), + Err(err) => Err(err), + } + } + + /// Buffers entire payload from request. + /// + /// Use of this method is discouraged unless you know for certain that requests will not be + /// large enough to exhaust memory. If this is not known, prefer [`Payload::to_bytes_limited()`] + /// or one of the higher level extractors like [`Bytes`] or [`String`] that implement size + /// limits according to the configured (or default) [`PayloadConfig`]. + /// + /// # Errors + /// + /// An error is only returned if the payload stream yields an error for some reason. Such cases + /// are usually caused by unrecoverable connection issues. + /// + /// # Examples + /// + /// ``` + /// use actix_web::{error, web::Payload, Responder}; + /// + /// async fn payload_handler(pl: Payload) -> actix_web::Result { + /// pl.to_bytes().await + /// } + /// ``` + pub async fn to_bytes(self) -> crate::Result { + let stream = body::BodyStream::new(self.0); + Ok(body::to_bytes(stream).await?) + } } impl Stream for Payload { @@ -64,7 +131,7 @@ impl Stream for Payload { /// See [here](#Examples) for example of usage as an extractor. impl FromRequest for Payload { type Error = Error; - type Future = Ready>; + type Future = Ready>; #[inline] fn from_request(_: &HttpRequest, payload: &mut dev::Payload) -> Self::Future { @@ -378,10 +445,53 @@ mod tests { use super::*; use crate::{ http::{header, StatusCode}, - test::{call_service, init_service, TestRequest}, + test::{call_service, init_service, read_body, TestRequest}, web, App, Responder, }; + #[actix_rt::test] + async fn payload_to_bytes() { + async fn payload_handler(pl: Payload) -> crate::Result { + pl.to_bytes().await + } + + async fn limited_payload_handler(pl: Payload) -> crate::Result { + match pl.to_bytes_limited(5).await { + Ok(res) => res, + Err(_limited) => Err(ErrorBadRequest("too big")), + } + } + + let srv = init_service( + App::new() + .route("/all", web::to(payload_handler)) + .route("limited", web::to(limited_payload_handler)), + ) + .await; + + let req = TestRequest::with_uri("/all") + .set_payload("1234567890") + .to_request(); + let res = call_service(&srv, req).await; + assert_eq!(res.status(), StatusCode::OK); + let body = read_body(res).await; + assert_eq!(body, "1234567890"); + + let req = TestRequest::with_uri("/limited") + .set_payload("1234567890") + .to_request(); + let res = call_service(&srv, req).await; + assert_eq!(res.status(), StatusCode::BAD_REQUEST); + + let req = TestRequest::with_uri("/limited") + .set_payload("12345") + .to_request(); + let res = call_service(&srv, req).await; + assert_eq!(res.status(), StatusCode::OK); + let body = read_body(res).await; + assert_eq!(body, "12345"); + } + #[actix_rt::test] async fn test_payload_config() { let req = TestRequest::default().to_http_request(); From 8cdbab3416ecc562a6ca5aad6b7bba5b3dce1dfd Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 22 Jul 2023 01:57:44 +0100 Subject: [PATCH 26/57] refactor: remove web dev dep from http-test --- actix-http-test/Cargo.toml | 1 - actix-http-test/src/lib.rs | 25 +++++++++++-------------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/actix-http-test/Cargo.toml b/actix-http-test/Cargo.toml index 87422551d..7f00ba30a 100644 --- a/actix-http-test/Cargo.toml +++ b/actix-http-test/Cargo.toml @@ -50,5 +50,4 @@ tls-openssl = { version = "0.10.55", package = "openssl", optional = true } tokio = { version = "1.24.2", features = ["sync"] } [dev-dependencies] -actix-web = { version = "4", default-features = false, features = ["cookies"] } actix-http = "3" diff --git a/actix-http-test/src/lib.rs b/actix-http-test/src/lib.rs index 8dcbe759d..2f1725d1c 100644 --- a/actix-http-test/src/lib.rs +++ b/actix-http-test/src/lib.rs @@ -31,24 +31,20 @@ use tokio::sync::mpsc; /// for HTTP applications. /// /// # Examples -/// ```no_run -/// use actix_http::HttpService; +/// +/// ``` +/// use actix_http::{HttpService, Response, Error, StatusCode}; /// use actix_http_test::test_server; -/// use actix_service::map_config; -/// use actix_service::ServiceFactoryExt; -/// use actix_web::{dev::AppConfig, web, App, Error, HttpResponse}; +/// use actix_service::{fn_service, map_config, ServiceFactoryExt as _}; /// -/// async fn my_handler() -> Result { -/// Ok(HttpResponse::Ok().into()) -/// } -/// -/// #[actix_web::test] +/// #[actix_rt::test] +/// # async fn hidden_test() {} /// async fn test_example() { /// let srv = test_server(|| { -/// let app = App::new().service(web::resource("/").to(my_handler)); -/// /// HttpService::build() -/// .h1(map_config(app, |_| AppConfig::default())) +/// .h1(fn_service(|req| async move { +/// Ok::<_, Error>(Response::ok()) +/// })) /// .tcp() /// .map_err(|_| ()) /// }) @@ -57,8 +53,9 @@ use tokio::sync::mpsc; /// let req = srv.get("/"); /// let response = req.send().await.unwrap(); /// -/// assert!(response.status().is_success()); +/// assert_eq!(response.status(), StatusCode::OK); /// } +/// # actix_rt::System::new().block_on(test_example()); /// ``` pub async fn test_server>(factory: F) -> TestServer { let tcp = net::TcpListener::bind("127.0.0.1:0").unwrap(); From 6a0ea51b15fc8df2cdbf3438c334486def7a8eda Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 22 Jul 2023 03:16:01 +0100 Subject: [PATCH 27/57] add `ContentLength` typed header (#2490) --- actix-web/CHANGES.md | 1 + actix-web/src/http/header/allow.rs | 8 ++- actix-web/src/http/header/content_length.rs | 56 +++++++++++++++++++++ actix-web/src/http/header/content_range.rs | 1 - actix-web/src/http/header/mod.rs | 2 + actix-web/src/types/json.rs | 8 +-- 6 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 actix-web/src/http/header/content_length.rs diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index f22a815c3..39535d41f 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -8,6 +8,7 @@ - Add `Resource::{get, post, etc...}` methods for more concisely adding routes that don't need additional guards. - Add `web::Payload::to_bytes[_limited]()` helper methods. - Add missing constructors on `HttpResponse` for several status codes. +- Add `http::header::ContentLength` typed header. ### Changed diff --git a/actix-web/src/http/header/allow.rs b/actix-web/src/http/header/allow.rs index 1ae8f00dc..b1c35c3d7 100644 --- a/actix-web/src/http/header/allow.rs +++ b/actix-web/src/http/header/allow.rs @@ -48,12 +48,15 @@ crate::http::header::common_header! { (Allow, header::ALLOW) => (Method)* test_parse_and_format { - // From the RFC + // from the RFC + crate::http::header::common_header_test!( test1, [b"GET, HEAD, PUT"], Some(HeaderField(vec![Method::GET, Method::HEAD, Method::PUT]))); - // Own tests + + // other tests + crate::http::header::common_header_test!( test2, [b"OPTIONS, GET, PUT, POST, DELETE, HEAD, TRACE, CONNECT, PATCH"], @@ -67,6 +70,7 @@ crate::http::header::common_header! { Method::TRACE, Method::CONNECT, Method::PATCH]))); + crate::http::header::common_header_test!( test3, [b""], diff --git a/actix-web/src/http/header/content_length.rs b/actix-web/src/http/header/content_length.rs new file mode 100644 index 000000000..b2769e5fa --- /dev/null +++ b/actix-web/src/http/header/content_length.rs @@ -0,0 +1,56 @@ +use super::common_header; +use crate::http::header; + +common_header! { + /// `Content-Length` header, defined in [RFC 7230 §3.3.2]. + /// + /// The Content-Length + /// + /// # ABNF + /// + /// ```plain + /// Content-Length = 1*DIGIT + /// ``` + /// + /// # Example Values + /// + /// - `0` + /// - `3495` + /// + /// # Examples + /// + /// ``` + /// use actix_web::{http::header::ContentLength, HttpResponse}; + /// + /// let res_empty = HttpResponse::Ok() + /// .insert_header(ContentLength(0)); + /// + /// let res_fake_cl = HttpResponse::Ok() + /// .insert_header(ContentLength(3_495)); + /// ``` + /// + /// [RFC 7230 §3.3.2]: https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2 + (ContentLength, header::CONTENT_LENGTH) => [usize] + + test_parse_and_format { + common_header_test!(no_header, [b""; 0], None); + common_header_test!(empty_header, [b""; 1], None); + + common_header_test!(zero, [b"0"], Some(ContentLength(0))); + common_header_test!(one, [b"1"], Some(ContentLength(1))); + common_header_test!(one_two_three, [b"123"], Some(ContentLength(123))); + common_header_test!( + thirty_two_power_plus_one, + [b"4294967297"], + Some(ContentLength(4_294_967_297)) + ); + common_header_test!( + sixty_four_power_minus_one, + [b"18446744073709551615"], + Some(ContentLength(18_446_744_073_709_551_615)) + ); + + common_header_test!(invalid1, [b"123,567"], None); + common_header_test!(invalid2, [b"123_567"], None); + } +} diff --git a/actix-web/src/http/header/content_range.rs b/actix-web/src/http/header/content_range.rs index 884926195..2604f9ba2 100644 --- a/actix-web/src/http/header/content_range.rs +++ b/actix-web/src/http/header/content_range.rs @@ -67,7 +67,6 @@ crate::http::header::common_header! { crate::http::header::common_header_test!(test_bytes_many_dashes, [b"bytes 1-2-3/500"], None::); - } } diff --git a/actix-web/src/http/header/mod.rs b/actix-web/src/http/header/mod.rs index 65c5c88a0..51ac4fcfd 100644 --- a/actix-web/src/http/header/mod.rs +++ b/actix-web/src/http/header/mod.rs @@ -24,6 +24,7 @@ mod allow; mod cache_control; mod content_disposition; mod content_language; +mod content_length; mod content_range; mod content_type; mod date; @@ -53,6 +54,7 @@ pub use self::{ cache_control::{CacheControl, CacheDirective}, content_disposition::{ContentDisposition, DispositionParam, DispositionType}, content_language::ContentLanguage, + content_length::ContentLength, content_range::{ContentRange, ContentRangeSpec}, content_type::ContentType, date::Date, diff --git a/actix-web/src/types/json.rs b/actix-web/src/types/json.rs index 2523e55f2..59c95da4c 100644 --- a/actix-web/src/types/json.rs +++ b/actix-web/src/types/json.rs @@ -21,7 +21,7 @@ use crate::{ body::EitherBody, error::{Error, JsonPayloadError}, extract::FromRequest, - http::header::CONTENT_LENGTH, + http::header::{ContentLength, Header as _}, request::HttpRequest, web, HttpMessage, HttpResponse, Responder, }; @@ -342,11 +342,7 @@ impl JsonBody { return JsonBody::Error(Some(JsonPayloadError::ContentType)); } - let length = req - .headers() - .get(&CONTENT_LENGTH) - .and_then(|l| l.to_str().ok()) - .and_then(|s| s.parse::().ok()); + let length = ContentLength::parse(req).ok().map(|x| x.0); // Notice the content-length is not checked against limit of json config here. // As the internal usage always call JsonBody::limit after JsonBody::new. From ff8fd2f7b54dce405ede595fae568561a8465d48 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 22 Jul 2023 18:01:59 +0100 Subject: [PATCH 28/57] modernize ContentLength --- actix-web/src/http/header/content_length.rs | 282 ++++++++++++++++---- 1 file changed, 232 insertions(+), 50 deletions(-) diff --git a/actix-web/src/http/header/content_length.rs b/actix-web/src/http/header/content_length.rs index b2769e5fa..ad16dc409 100644 --- a/actix-web/src/http/header/content_length.rs +++ b/actix-web/src/http/header/content_length.rs @@ -1,56 +1,238 @@ -use super::common_header; -use crate::http::header; +use std::{convert::Infallible, str}; -common_header! { - /// `Content-Length` header, defined in [RFC 7230 §3.3.2]. - /// - /// The Content-Length - /// - /// # ABNF - /// - /// ```plain - /// Content-Length = 1*DIGIT - /// ``` - /// - /// # Example Values - /// - /// - `0` - /// - `3495` - /// - /// # Examples - /// - /// ``` - /// use actix_web::{http::header::ContentLength, HttpResponse}; - /// - /// let res_empty = HttpResponse::Ok() - /// .insert_header(ContentLength(0)); - /// - /// let res_fake_cl = HttpResponse::Ok() - /// .insert_header(ContentLength(3_495)); - /// ``` - /// - /// [RFC 7230 §3.3.2]: https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2 - (ContentLength, header::CONTENT_LENGTH) => [usize] +use derive_more::{Deref, DerefMut}; - test_parse_and_format { - common_header_test!(no_header, [b""; 0], None); - common_header_test!(empty_header, [b""; 1], None); +use crate::{ + error::ParseError, + http::header::{ + from_one_raw_str, Header, HeaderName, HeaderValue, TryIntoHeaderValue, CONTENT_LENGTH, + }, + HttpMessage, +}; - common_header_test!(zero, [b"0"], Some(ContentLength(0))); - common_header_test!(one, [b"1"], Some(ContentLength(1))); - common_header_test!(one_two_three, [b"123"], Some(ContentLength(123))); - common_header_test!( - thirty_two_power_plus_one, - [b"4294967297"], - Some(ContentLength(4_294_967_297)) - ); - common_header_test!( - sixty_four_power_minus_one, - [b"18446744073709551615"], - Some(ContentLength(18_446_744_073_709_551_615)) - ); +/// `Content-Length` header, defined in [RFC 9110 §8.6]. +/// +/// The Content-Length +/// +/// # ABNF +/// +/// ```plain +/// Content-Length = 1*DIGIT +/// ``` +/// +/// # Example Values +/// +/// - `0` +/// - `3495` +/// +/// # Examples +/// +/// ``` +/// use actix_web::{http::header::ContentLength, HttpResponse}; +/// +/// let res_empty = HttpResponse::Ok() +/// .insert_header(ContentLength(0)); +/// +/// let res_fake_cl = HttpResponse::Ok() +/// .insert_header(ContentLength(3_495)); +/// ``` +/// +/// [RFC 9110 §8.6]: https://www.rfc-editor.org/rfc/rfc9110#name-content-length +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Deref, DerefMut)] +pub struct ContentLength(pub usize); - common_header_test!(invalid1, [b"123,567"], None); - common_header_test!(invalid2, [b"123_567"], None); +impl ContentLength { + /// Returns Content-Length value. + pub fn into_inner(&self) -> usize { + self.0 + } +} + +impl str::FromStr for ContentLength { + type Err = ::Err; + + #[inline] + fn from_str(val: &str) -> Result { + let val = val.trim(); + + // decoder prevents this case + debug_assert!(!val.starts_with('+')); + + val.parse().map(Self) + } +} + +impl TryIntoHeaderValue for ContentLength { + type Error = Infallible; + + fn try_into_value(self) -> Result { + Ok(HeaderValue::from(self.0)) + } +} + +impl Header for ContentLength { + fn name() -> HeaderName { + CONTENT_LENGTH + } + + fn parse(msg: &M) -> Result { + let val = from_one_raw_str(msg.headers().get(Self::name()))?; + + // decoder prevents multiple CL headers + debug_assert_eq!(msg.headers().get_all(Self::name()).count(), 1); + + Ok(val) + } +} + +impl From for usize { + fn from(ContentLength(len): ContentLength) -> Self { + len + } +} + +impl From for ContentLength { + fn from(len: usize) -> Self { + ContentLength(len) + } +} + +impl PartialEq for ContentLength { + fn eq(&self, other: &usize) -> bool { + self.0 == *other + } +} + +impl PartialEq for usize { + fn eq(&self, other: &ContentLength) -> bool { + *self == other.0 + } +} + +impl PartialOrd for ContentLength { + fn partial_cmp(&self, other: &usize) -> Option { + self.0.partial_cmp(other) + } +} + +impl PartialOrd for usize { + fn partial_cmp(&self, other: &ContentLength) -> Option { + self.partial_cmp(&other.0) + } +} + +#[cfg(test)] +mod tests { + use std::fmt; + + use super::*; + use crate::{http::header::Header, test::TestRequest, HttpRequest}; + + fn req_from_raw_headers, V: AsRef<[u8]>>( + header_lines: I, + ) -> HttpRequest { + header_lines + .into_iter() + .fold(TestRequest::default(), |req, item| { + req.append_header((H::name(), item.as_ref().to_vec())) + }) + .to_http_request() + } + + #[track_caller] + pub(crate) fn assert_parse_fail< + H: Header + fmt::Debug, + I: IntoIterator, + V: AsRef<[u8]>, + >( + headers: I, + ) { + let req = req_from_raw_headers::(headers); + H::parse(&req).unwrap_err(); + } + + #[track_caller] + pub(crate) fn assert_parse_eq< + H: Header + fmt::Debug + PartialEq, + I: IntoIterator, + V: AsRef<[u8]>, + >( + headers: I, + expect: H, + ) { + let req = req_from_raw_headers::(headers); + assert_eq!(H::parse(&req).unwrap(), expect); + } + + #[test] + fn missing_header() { + assert_parse_fail::([""; 0]); + assert_parse_fail::([""]); + } + + #[test] + fn bad_header() { + assert_parse_fail::(["-123"]); + assert_parse_fail::(["123_456"]); + assert_parse_fail::(["123.456"]); + + // too large for u64 (2^64, 2^64 + 1) + assert_parse_fail::(["18446744073709551616"]); + assert_parse_fail::(["18446744073709551617"]); + + // hex notation + assert_parse_fail::(["0x123"]); + + // multi-value + assert_parse_fail::(["0, 123"]); + } + + #[test] + #[should_panic] + fn bad_header_plus() { + // prevented by HTTP decoder anyway + assert_parse_fail::(["+123"]); + } + + #[test] + #[should_panic] + fn bad_multiple_value() { + // prevented by HTTP decoder anyway + assert_parse_fail::(["0", "123"]); + } + + #[test] + fn good_header() { + assert_parse_eq::(["0"], ContentLength(0)); + assert_parse_eq::(["1"], ContentLength(1)); + assert_parse_eq::(["123"], ContentLength(123)); + + // value that looks like octal notation is not interpreted as such + assert_parse_eq::(["0123"], ContentLength(123)); + + // whitespace variations + assert_parse_eq::([" 0"], ContentLength(0)); + assert_parse_eq::(["0 "], ContentLength(0)); + assert_parse_eq::([" 0 "], ContentLength(0)); + + // large value (2^64 - 1) + assert_parse_eq::( + ["18446744073709551615"], + ContentLength(18_446_744_073_709_551_615), + ); + } + + #[test] + fn equality() { + assert!(ContentLength(0) == ContentLength(0)); + assert!(ContentLength(0) == 0); + assert!(0 != ContentLength(123)); + } + + #[test] + fn ordering() { + assert!(ContentLength(0) < ContentLength(123)); + assert!(ContentLength(0) < 123); + assert!(0 < ContentLength(123)); } } From 75a97f6b329911387a915f29d34a4e7f1ba8d460 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 24 Jul 2023 03:29:56 +0100 Subject: [PATCH 29/57] chore: remove clippy config file --- .github/workflows/ci-post-merge.yml | 5 +++-- .github/workflows/ci.yml | 3 ++- .prettierrc.yaml | 1 - .prettierrc.yml | 5 +++++ actix-web-codegen/src/lib.rs | 2 +- clippy.toml | 1 - 6 files changed, 11 insertions(+), 6 deletions(-) delete mode 100644 .prettierrc.yaml create mode 100644 .prettierrc.yml delete mode 100644 clippy.toml diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index d293fea95..06669e31e 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -5,7 +5,7 @@ on: branches: [master] permissions: - contents: read # to fetch code (actions/checkout) + contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -16,10 +16,11 @@ jobs: strategy: fail-fast: false matrix: + # prettier-ignore target: - { name: Linux, os: ubuntu-latest, triple: x86_64-unknown-linux-gnu } - { name: macOS, os: macos-latest, triple: x86_64-apple-darwin } - - { name: Windows, os: windows-2022, triple: x86_64-pc-windows-msvc } + - { name: Windows, os: windows-latest, triple: x86_64-pc-windows-msvc } version: - nightly diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f85548505..468c9b1df 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: branches: [master] permissions: - contents: read # to fetch code (actions/checkout) + contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -18,6 +18,7 @@ jobs: strategy: fail-fast: false matrix: + # prettier-ignore target: - { name: Linux, os: ubuntu-latest, triple: x86_64-unknown-linux-gnu } - { name: macOS, os: macos-latest, triple: x86_64-apple-darwin } diff --git a/.prettierrc.yaml b/.prettierrc.yaml deleted file mode 100644 index 7b5590248..000000000 --- a/.prettierrc.yaml +++ /dev/null @@ -1 +0,0 @@ -proseWrap: never diff --git a/.prettierrc.yml b/.prettierrc.yml new file mode 100644 index 000000000..b61fd8974 --- /dev/null +++ b/.prettierrc.yml @@ -0,0 +1,5 @@ +overrides: + - files: '*.md' + options: + printWidth: 9999 + proseWrap: never diff --git a/actix-web-codegen/src/lib.rs b/actix-web-codegen/src/lib.rs index 6d6f4f79d..6d6c9ab5c 100644 --- a/actix-web-codegen/src/lib.rs +++ b/actix-web-codegen/src/lib.rs @@ -221,7 +221,7 @@ pub fn main(_: TokenStream, item: TokenStream) -> TokenStream { output } -/// Marks async test functions to use the actix system entry-point. +/// Marks async test functions to use the Actix Web system entry-point. /// /// # Examples /// ``` diff --git a/clippy.toml b/clippy.toml deleted file mode 100644 index 04371125d..000000000 --- a/clippy.toml +++ /dev/null @@ -1 +0,0 @@ -msrv = "1.65" From 605cd7c540e196efa50d3e96e9ed3f32b556dd03 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 1 Aug 2023 18:06:59 +0100 Subject: [PATCH 30/57] add startup logging to basic example --- actix-web/examples/basic.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actix-web/examples/basic.rs b/actix-web/examples/basic.rs index 60715f477..b8bc09821 100644 --- a/actix-web/examples/basic.rs +++ b/actix-web/examples/basic.rs @@ -1,5 +1,3 @@ -#![allow(clippy::uninlined_format_args)] - use actix_web::{get, middleware, web, App, HttpRequest, HttpResponse, HttpServer}; #[get("/resource1/{name}/index.html")] @@ -22,6 +20,8 @@ async fn no_params() -> &'static str { async fn main() -> std::io::Result<()> { env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); + log::info!("starting HTTP server at http://localhost:8080"); + HttpServer::new(|| { App::new() .wrap(middleware::DefaultHeaders::new().add(("X-Version", "0.2"))) From b4fcdffdc3243f41236da8d20743a685f0b45045 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 1 Aug 2023 19:33:32 +0100 Subject: [PATCH 31/57] chore: update msrv to 1.68 (#3094) --- .github/workflows/bench.yml | 3 +-- .github/workflows/ci.yml | 4 +++- actix-files/CHANGES.md | 2 +- actix-files/README.md | 4 ++-- actix-http-test/CHANGES.md | 2 +- actix-http-test/README.md | 4 ++-- actix-http/CHANGES.md | 2 +- actix-http/README.md | 4 ++-- actix-multipart-derive/CHANGES.md | 2 +- actix-multipart-derive/README.md | 4 ++-- actix-multipart-derive/tests/trybuild.rs | 2 +- actix-multipart/CHANGES.md | 2 +- actix-multipart/README.md | 4 ++-- actix-router/CHANGES.md | 2 +- actix-router/src/resource.rs | 7 ++++++- actix-test/CHANGES.md | 2 +- actix-web-actors/CHANGES.md | 2 +- actix-web-actors/README.md | 4 ++-- actix-web-codegen/CHANGES.md | 2 +- actix-web-codegen/README.md | 4 ++-- actix-web-codegen/tests/trybuild.rs | 2 +- actix-web/CHANGES.md | 2 +- actix-web/README.md | 4 ++-- awc/CHANGES.md | 2 +- awc/README.md | 2 +- 25 files changed, 40 insertions(+), 34 deletions(-) diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index f8bf2abda..f0e4cc8b3 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -2,8 +2,7 @@ name: Benchmark on: push: - branches: - - master + branches: [master] permissions: contents: read # to fetch code (actions/checkout) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 468c9b1df..f073f6afe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,6 +3,8 @@ name: CI on: pull_request: types: [opened, synchronize, reopened] + merge_group: + types: [checks_requested] push: branches: [master] @@ -24,7 +26,7 @@ jobs: - { name: macOS, os: macos-latest, triple: x86_64-apple-darwin } - { name: Windows, os: windows-latest, triple: x86_64-pc-windows-msvc } version: - - 1.65.0 # MSRV + - 1.68.0 # MSRV - stable name: ${{ matrix.target.name }} / ${{ matrix.version }} diff --git a/actix-files/CHANGES.md b/actix-files/CHANGES.md index 4e45ce517..31c0499ed 100644 --- a/actix-files/CHANGES.md +++ b/actix-files/CHANGES.md @@ -2,7 +2,7 @@ ## Unreleased - 2023-xx-xx -- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. +- Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. ## 0.6.3 - 2023-01-21 diff --git a/actix-files/README.md b/actix-files/README.md index f01fc8566..3e656c431 100644 --- a/actix-files/README.md +++ b/actix-files/README.md @@ -4,7 +4,7 @@ [![crates.io](https://img.shields.io/crates/v/actix-files?label=latest)](https://crates.io/crates/actix-files) [![Documentation](https://docs.rs/actix-files/badge.svg?version=0.6.3)](https://docs.rs/actix-files/0.6.3) -![Version](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) +![Version](https://img.shields.io/badge/rustc-1.68+-ab6000.svg) ![License](https://img.shields.io/crates/l/actix-files.svg)
[![dependency status](https://deps.rs/crate/actix-files/0.6.3/status.svg)](https://deps.rs/crate/actix-files/0.6.3) @@ -15,4 +15,4 @@ - [API Documentation](https://docs.rs/actix-files) - [Example Project](https://github.com/actix/examples/tree/master/basics/static-files) -- Minimum Supported Rust Version (MSRV): 1.65 +- Minimum Supported Rust Version (MSRV): 1.68 diff --git a/actix-http-test/CHANGES.md b/actix-http-test/CHANGES.md index 3b8c83b3c..0fc89214d 100644 --- a/actix-http-test/CHANGES.md +++ b/actix-http-test/CHANGES.md @@ -2,7 +2,7 @@ ## Unreleased - 2023-xx-xx -- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. +- Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. ## 3.1.0 - 2023-01-21 diff --git a/actix-http-test/README.md b/actix-http-test/README.md index 935be407f..4b286e603 100644 --- a/actix-http-test/README.md +++ b/actix-http-test/README.md @@ -4,7 +4,7 @@ [![crates.io](https://img.shields.io/crates/v/actix-http-test?label=latest)](https://crates.io/crates/actix-http-test) [![Documentation](https://docs.rs/actix-http-test/badge.svg?version=3.1.0)](https://docs.rs/actix-http-test/3.1.0) -![Version](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) +![Version](https://img.shields.io/badge/rustc-1.68+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-http-test)
[![Dependency Status](https://deps.rs/crate/actix-http-test/3.1.0/status.svg)](https://deps.rs/crate/actix-http-test/3.1.0) @@ -14,4 +14,4 @@ ## Documentation & Resources - [API Documentation](https://docs.rs/actix-http-test) -- Minimum Supported Rust Version (MSRV): 1.65 +- Minimum Supported Rust Version (MSRV): 1.68 diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index a105c02c1..0dedd2c74 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -9,7 +9,7 @@ ### Changed -- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. +- Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. ## 3.3.1 - 2023-03-02 diff --git a/actix-http/README.md b/actix-http/README.md index 0c5fcb6b6..ce2e5cb32 100644 --- a/actix-http/README.md +++ b/actix-http/README.md @@ -4,7 +4,7 @@ [![crates.io](https://img.shields.io/crates/v/actix-http?label=latest)](https://crates.io/crates/actix-http) [![Documentation](https://docs.rs/actix-http/badge.svg?version=3.3.1)](https://docs.rs/actix-http/3.3.1) -![Version](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) +![Version](https://img.shields.io/badge/rustc-1.68+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-http.svg)
[![dependency status](https://deps.rs/crate/actix-http/3.3.1/status.svg)](https://deps.rs/crate/actix-http/3.3.1) @@ -14,7 +14,7 @@ ## Documentation & Resources - [API Documentation](https://docs.rs/actix-http) -- Minimum Supported Rust Version (MSRV): 1.65 +- Minimum Supported Rust Version (MSRV): 1.68 ## Example diff --git a/actix-multipart-derive/CHANGES.md b/actix-multipart-derive/CHANGES.md index 8a78900ec..f90b9e3cf 100644 --- a/actix-multipart-derive/CHANGES.md +++ b/actix-multipart-derive/CHANGES.md @@ -3,7 +3,7 @@ ## Unreleased - Update `syn` dependency to `2`. -- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. +- Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. ## 0.6.0 - 2023-02-26 diff --git a/actix-multipart-derive/README.md b/actix-multipart-derive/README.md index b077d355c..2737410f6 100644 --- a/actix-multipart-derive/README.md +++ b/actix-multipart-derive/README.md @@ -4,7 +4,7 @@ [![crates.io](https://img.shields.io/crates/v/actix-multipart-derive?label=latest)](https://crates.io/crates/actix-multipart-derive) [![Documentation](https://docs.rs/actix-multipart-derive/badge.svg?version=0.5.0)](https://docs.rs/actix-multipart-derive/0.5.0) -![Version](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) +![Version](https://img.shields.io/badge/rustc-1.68+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-multipart-derive.svg)
[![dependency status](https://deps.rs/crate/actix-multipart-derive/0.5.0/status.svg)](https://deps.rs/crate/actix-multipart-derive/0.5.0) @@ -14,4 +14,4 @@ ## Documentation & Resources - [API Documentation](https://docs.rs/actix-multipart-derive) -- Minimum Supported Rust Version (MSRV): 1.65 +- Minimum Supported Rust Version (MSRV): 1.68 diff --git a/actix-multipart-derive/tests/trybuild.rs b/actix-multipart-derive/tests/trybuild.rs index 829c1d771..88aa619c6 100644 --- a/actix-multipart-derive/tests/trybuild.rs +++ b/actix-multipart-derive/tests/trybuild.rs @@ -1,4 +1,4 @@ -#[rustversion::stable(1.65)] // MSRV +#[rustversion::stable(1.68)] // MSRV #[test] fn compile_macros() { let t = trybuild::TestCases::new(); diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index 410c8af17..1ad5865ec 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -2,7 +2,7 @@ ## Unreleased - 2023-xx-xx -- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. +- Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. ## 0.6.0 - 2023-02-26 diff --git a/actix-multipart/README.md b/actix-multipart/README.md index 3e2a7a127..66550668d 100644 --- a/actix-multipart/README.md +++ b/actix-multipart/README.md @@ -4,7 +4,7 @@ [![crates.io](https://img.shields.io/crates/v/actix-multipart?label=latest)](https://crates.io/crates/actix-multipart) [![Documentation](https://docs.rs/actix-multipart/badge.svg?version=0.6.0)](https://docs.rs/actix-multipart/0.6.0) -![Version](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) +![Version](https://img.shields.io/badge/rustc-1.68+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-multipart.svg)
[![dependency status](https://deps.rs/crate/actix-multipart/0.6.0/status.svg)](https://deps.rs/crate/actix-multipart/0.6.0) @@ -14,4 +14,4 @@ ## Documentation & Resources - [API Documentation](https://docs.rs/actix-multipart) -- Minimum Supported Rust Version (MSRV): 1.65 +- Minimum Supported Rust Version (MSRV): 1.68 diff --git a/actix-router/CHANGES.md b/actix-router/CHANGES.md index 1f5552193..786ee12d9 100644 --- a/actix-router/CHANGES.md +++ b/actix-router/CHANGES.md @@ -2,7 +2,7 @@ ## Unreleased - 2023-xx-xx -- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. +- Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. ## 0.5.1 - 2022-09-19 diff --git a/actix-router/src/resource.rs b/actix-router/src/resource.rs index a3e89a1fe..80c0a2d68 100644 --- a/actix-router/src/resource.rs +++ b/actix-router/src/resource.rs @@ -501,7 +501,12 @@ impl ResourceDef { let patterns = self .pattern_iter() .flat_map(move |this| other.pattern_iter().map(move |other| (this, other))) - .map(|(this, other)| [this, other].join("")) + .map(|(this, other)| { + let mut pattern = String::with_capacity(this.len() + other.len()); + pattern.push_str(this); + pattern.push_str(other); + pattern + }) .collect::>(); match patterns.len() { diff --git a/actix-test/CHANGES.md b/actix-test/CHANGES.md index aba27dbfc..fae8201d2 100644 --- a/actix-test/CHANGES.md +++ b/actix-test/CHANGES.md @@ -3,7 +3,7 @@ ## Unreleased - 2023-xx-xx - Add `TestServerConfig::workers()` setter method. -- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. +- Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. ## 0.1.1 - 2023-02-26 diff --git a/actix-web-actors/CHANGES.md b/actix-web-actors/CHANGES.md index 4799c7b67..cff27a16d 100644 --- a/actix-web-actors/CHANGES.md +++ b/actix-web-actors/CHANGES.md @@ -2,7 +2,7 @@ ## Unreleased - 2023-xx-xx -- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. +- Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. ## 4.2.0 - 2023-01-21 diff --git a/actix-web-actors/README.md b/actix-web-actors/README.md index fe6122115..b2c30b954 100644 --- a/actix-web-actors/README.md +++ b/actix-web-actors/README.md @@ -4,7 +4,7 @@ [![crates.io](https://img.shields.io/crates/v/actix-web-actors?label=latest)](https://crates.io/crates/actix-web-actors) [![Documentation](https://docs.rs/actix-web-actors/badge.svg?version=4.2.0)](https://docs.rs/actix-web-actors/4.2.0) -![Version](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) +![Version](https://img.shields.io/badge/rustc-1.68+-ab6000.svg) ![License](https://img.shields.io/crates/l/actix-web-actors.svg)
[![dependency status](https://deps.rs/crate/actix-web-actors/4.2.0/status.svg)](https://deps.rs/crate/actix-web-actors/4.2.0) @@ -14,4 +14,4 @@ ## Documentation & Resources - [API Documentation](https://docs.rs/actix-web-actors) -- Minimum Supported Rust Version (MSRV): 1.65 +- Minimum Supported Rust Version (MSRV): 1.68 diff --git a/actix-web-codegen/CHANGES.md b/actix-web-codegen/CHANGES.md index 2c5f17226..9ff1edf6e 100644 --- a/actix-web-codegen/CHANGES.md +++ b/actix-web-codegen/CHANGES.md @@ -3,7 +3,7 @@ ## Unreleased - 2023-xx-xx - Update `syn` dependency to `2`. -- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. +- Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. ## 4.2.0 - 2023-02-26 diff --git a/actix-web-codegen/README.md b/actix-web-codegen/README.md index 531f44a5d..e6df8164e 100644 --- a/actix-web-codegen/README.md +++ b/actix-web-codegen/README.md @@ -4,7 +4,7 @@ [![crates.io](https://img.shields.io/crates/v/actix-web-codegen?label=latest)](https://crates.io/crates/actix-web-codegen) [![Documentation](https://docs.rs/actix-web-codegen/badge.svg?version=4.2.0)](https://docs.rs/actix-web-codegen/4.2.0) -![Version](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) +![Version](https://img.shields.io/badge/rustc-1.68+-ab6000.svg) ![License](https://img.shields.io/crates/l/actix-web-codegen.svg)
[![dependency status](https://deps.rs/crate/actix-web-codegen/4.2.0/status.svg)](https://deps.rs/crate/actix-web-codegen/4.2.0) @@ -14,7 +14,7 @@ ## Documentation & Resources - [API Documentation](https://docs.rs/actix-web-codegen) -- Minimum Supported Rust Version (MSRV): 1.65 +- Minimum Supported Rust Version (MSRV): 1.68 ## Compile Testing diff --git a/actix-web-codegen/tests/trybuild.rs b/actix-web-codegen/tests/trybuild.rs index 9f0aa02f4..8e1f58a4c 100644 --- a/actix-web-codegen/tests/trybuild.rs +++ b/actix-web-codegen/tests/trybuild.rs @@ -1,4 +1,4 @@ -#[rustversion::stable(1.65)] // MSRV +#[rustversion::stable(1.68)] // MSRV #[test] fn compile_macros() { let t = trybuild::TestCases::new(); diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 39535d41f..518a02507 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -15,7 +15,7 @@ - Handler functions can now receive up to 16 extractor parameters. - The `Compress` middleware no longer compresses image or video content. - Hide sensitive header values in `HttpRequest`'s `Debug` output. -- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. +- Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. ## 4.3.1 - 2023-02-26 diff --git a/actix-web/README.md b/actix-web/README.md index cc2d9abe0..565f2b0f3 100644 --- a/actix-web/README.md +++ b/actix-web/README.md @@ -5,7 +5,7 @@

-[![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=4.3.1)](https://docs.rs/actix-web/4.3.1) ![MSRV](https://img.shields.io/badge/rustc-1.65+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-web.svg) [![Dependency Status](https://deps.rs/crate/actix-web/4.3.1/status.svg)](https://deps.rs/crate/actix-web/4.3.1)
[![CI](https://github.com/actix/actix-web/actions/workflows/ci.yml/badge.svg)](https://github.com/actix/actix-web/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web) ![downloads](https://img.shields.io/crates/d/actix-web.svg) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) +[![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=4.3.1)](https://docs.rs/actix-web/4.3.1) ![MSRV](https://img.shields.io/badge/rustc-1.68+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-web.svg) [![Dependency Status](https://deps.rs/crate/actix-web/4.3.1/status.svg)](https://deps.rs/crate/actix-web/4.3.1)
[![CI](https://github.com/actix/actix-web/actions/workflows/ci.yml/badge.svg)](https://github.com/actix/actix-web/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web) ![downloads](https://img.shields.io/crates/d/actix-web.svg) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)

@@ -24,7 +24,7 @@ - SSL support using OpenSSL or Rustls - Middlewares ([Logger, Session, CORS, etc](https://actix.rs/docs/middleware/)) - Integrates with the [`awc` HTTP client](https://docs.rs/awc/) -- Runs on stable Rust 1.65+ +- Runs on stable Rust 1.68+ ## Documentation diff --git a/awc/CHANGES.md b/awc/CHANGES.md index f5bddd04d..3429a84d7 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -2,7 +2,7 @@ ## Unreleased - 2023-xx-xx -- Minimum supported Rust version (MSRV) is now 1.65 due to transitive `time` dependency. +- Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. ## 3.1.1 - 2023-02-26 diff --git a/awc/README.md b/awc/README.md index 1a480df12..f2a9c7559 100644 --- a/awc/README.md +++ b/awc/README.md @@ -12,7 +12,7 @@ - [API Documentation](https://docs.rs/awc) - [Example Project](https://github.com/actix/examples/tree/master/https-tls/awc-https) -- Minimum Supported Rust Version (MSRV): 1.65 +- Minimum Supported Rust Version (MSRV): 1.68 ## Example From 1c60978a895d736c53025f2aab88340fb0b3e464 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 3 Aug 2023 06:28:45 +0100 Subject: [PATCH 32/57] chore: move codecov file --- codecov.yml => .codecov.yml | 0 actix-web/README.md | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) rename codecov.yml => .codecov.yml (100%) diff --git a/codecov.yml b/.codecov.yml similarity index 100% rename from codecov.yml rename to .codecov.yml diff --git a/actix-web/README.md b/actix-web/README.md index 565f2b0f3..74b4924d4 100644 --- a/actix-web/README.md +++ b/actix-web/README.md @@ -5,7 +5,20 @@

-[![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=4.3.1)](https://docs.rs/actix-web/4.3.1) ![MSRV](https://img.shields.io/badge/rustc-1.68+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-web.svg) [![Dependency Status](https://deps.rs/crate/actix-web/4.3.1/status.svg)](https://deps.rs/crate/actix-web/4.3.1)
[![CI](https://github.com/actix/actix-web/actions/workflows/ci.yml/badge.svg)](https://github.com/actix/actix-web/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web) ![downloads](https://img.shields.io/crates/d/actix-web.svg) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) + + +[![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=4.3.1)](https://docs.rs/actix-web/4.3.1) +![MSRV](https://img.shields.io/badge/rustc-1.68+-ab6000.svg) +![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-web.svg) +[![Dependency Status](https://deps.rs/crate/actix-web/4.3.1/status.svg)](https://deps.rs/crate/actix-web/4.3.1) +
+[![CI](https://github.com/actix/actix-web/actions/workflows/ci.yml/badge.svg)](https://github.com/actix/actix-web/actions/workflows/ci.yml) +[![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web) +![downloads](https://img.shields.io/crates/d/actix-web.svg) +[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) + +

From 12dbda986ee89726d62edc609f7928307ce5390c Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 3 Aug 2023 06:54:50 +0100 Subject: [PATCH 33/57] test: fix test_h2_connection_drop spurious hang fixes #3061 --- awc/src/client/connection.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/awc/src/client/connection.rs b/awc/src/client/connection.rs index 64075eae8..12d00914a 100644 --- a/awc/src/client/connection.rs +++ b/awc/src/client/connection.rs @@ -394,6 +394,8 @@ mod test { #[actix_rt::test] async fn test_h2_connection_drop() { + env_logger::try_init().ok(); + let addr = "127.0.0.1:0".parse::().unwrap(); let listener = net::TcpListener::bind(addr).unwrap(); let local = listener.local_addr().unwrap(); @@ -428,11 +430,18 @@ mod test { if this.start_from.elapsed() > Duration::from_secs(10) { panic!("connection should be gone and can not be ready"); } else { - let _ = this.interval.poll_tick(cx); - Poll::Pending + match this.interval.poll_tick(cx) { + Poll::Ready(_) => { + // prevents spurious test hang + this.interval.reset(); + + Poll::Pending + } + Poll::Pending => Poll::Pending, + } } } - Err(_) => Poll::Ready(()), + Err(err) => Poll::Ready(()), } } } From eaabe7e6869872384dcc6c85fe021f60b25f3f8a Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 3 Aug 2023 06:58:31 +0100 Subject: [PATCH 34/57] ci: reinstate coverage --- .github/workflows/coverage.yml | 26 ++++++++++++++------------ .gitignore | 3 +++ awc/src/client/connection.rs | 2 +- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 42f16450d..1e450d491 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -1,5 +1,3 @@ -# disabled because `cargo tarpaulin` currently segfaults - name: Coverage on: @@ -14,21 +12,25 @@ concurrency: cancel-in-progress: true jobs: - # job currently (1st Feb 2022) segfaults coverage: - name: coverage runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + - name: Install Rust + uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 + with: + components: llvm-tools-preview - - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: { toolchain: nightly } + - name: Install cargo-llvm-cov + uses: taiki-e/install-action@v2.13.4 + with: + tool: cargo-llvm-cov - - name: Generate coverage file - run: | - cargo install cargo-tarpaulin --vers "^0.13" - cargo tarpaulin --workspace --features=rustls,openssl --out Xml --verbose - - name: Upload to Codecov + - name: Generate code coverage + run: cargo llvm-cov --workspace --all-features --codecov --output-path codecov.json + + - name: Upload coverage to Codecov uses: codecov/codecov-action@v3.1.4 with: - file: cobertura.xml + files: codecov.json + fail_ci_if_error: true diff --git a/.gitignore b/.gitignore index 543403267..91930acf8 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,6 @@ guide/build/ # Configuration directory generated by VSCode .vscode + +# code coverage +/codecov.json diff --git a/awc/src/client/connection.rs b/awc/src/client/connection.rs index 12d00914a..5ed965bed 100644 --- a/awc/src/client/connection.rs +++ b/awc/src/client/connection.rs @@ -441,7 +441,7 @@ mod test { } } } - Err(err) => Poll::Ready(()), + Err(_) => Poll::Ready(()), } } } From d8df60bf4c04c3cbb99bcf19a141c202223e07ea Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 3 Aug 2023 07:03:42 +0100 Subject: [PATCH 35/57] build: add justfile --- .cargo/config.toml | 3 --- .github/workflows/coverage.yml | 2 +- justfile | 11 +++++++++++ 3 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 justfile diff --git a/.cargo/config.toml b/.cargo/config.toml index deb300749..931b20b2c 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -12,6 +12,3 @@ ci-check-all-feature-powerset-linux="hack --workspace --feature-powerset --skip= # testing ci-doctest-default = "test --workspace --doc --no-fail-fast -- --nocapture" ci-doctest = "test --workspace --all-features --doc --no-fail-fast -- --nocapture" - -# compile docs as docs.rs would -# RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly doc --no-deps --workspace diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 1e450d491..1feae0432 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -5,7 +5,7 @@ on: branches: [master] permissions: - contents: read # to fetch code (actions/checkout) + contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/justfile b/justfile new file mode 100644 index 000000000..f2e449d85 --- /dev/null +++ b/justfile @@ -0,0 +1,11 @@ +_list: + @just --list + +# Document crates in workspace. +doc: + RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly doc --no-deps --workspace --features=rustls,openssl + +# Document crates in workspace and watch for changes. +doc-watch: + RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly doc --no-deps --workspace --features=rustls,openssl --open + cargo watch -- RUSTDOCFLAGS="--cfg=docsrs" cargo +nightly doc --no-deps --workspace --features=rustls,openssl From 14355b94421716dd2a70b7bfe1d863f80c768be8 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 26 Aug 2023 18:19:32 +0100 Subject: [PATCH 36/57] ci: name msrv jobs (#3114) --- .github/workflows/ci-post-merge.yml | 8 ++++---- .github/workflows/ci.yml | 17 +++++++++-------- .gitignore | 1 + 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 06669e31e..5460eeec4 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -22,9 +22,9 @@ jobs: - { name: macOS, os: macos-latest, triple: x86_64-apple-darwin } - { name: Windows, os: windows-latest, triple: x86_64-pc-windows-msvc } version: - - nightly + - { name: nightly, version: nightly } - name: ${{ matrix.target.name }} / ${{ matrix.version }} + name: ${{ matrix.target.name }} / ${{ matrix.version.name }} runs-on: ${{ matrix.target.os }} steps: @@ -39,10 +39,10 @@ jobs: echo 'OPENSSL_DIR=C:\Program Files\OpenSSL-Win64' | Out-File -FilePath $env:GITHUB_ENV -Append echo 'OPENSSL_DIR=C:\Program Files\OpenSSL' | Out-File -FilePath $env:GITHUB_ENV -Append - - name: Install Rust (${{ matrix.version }}) + - name: Install Rust (${{ matrix.version.name }}) uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: ${{ matrix.version }} + toolchain: ${{ matrix.version.version }} - name: Install cargo-hack uses: taiki-e/install-action@cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f073f6afe..f12202017 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,10 +26,10 @@ jobs: - { name: macOS, os: macos-latest, triple: x86_64-apple-darwin } - { name: Windows, os: windows-latest, triple: x86_64-pc-windows-msvc } version: - - 1.68.0 # MSRV - - stable + - { name: msrv, version: 1.68.0 } + - { name: stable, version: stable } - name: ${{ matrix.target.name }} / ${{ matrix.version }} + name: ${{ matrix.target.name }} / ${{ matrix.version.name }} runs-on: ${{ matrix.target.os }} steps: @@ -44,17 +44,18 @@ jobs: echo 'OPENSSL_DIR=C:\Program Files\OpenSSL-Win64' | Out-File -FilePath $env:GITHUB_ENV -Append echo 'OPENSSL_DIR=C:\Program Files\OpenSSL' | Out-File -FilePath $env:GITHUB_ENV -Append - - name: Install Rust (${{ matrix.version }}) + - name: Install Rust (${{ matrix.version.name }}) uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: ${{ matrix.version }} + toolchain: ${{ matrix.version.version }} - name: Install cargo-hack uses: taiki-e/install-action@cargo-hack - # - name: workaround MSRV issues - # if: matrix.version != 'stable' - # run: | + - name: workaround MSRV issues + if: matrix.version.name != 'stable' + run: | + cargo update -p=clap --precise=4.3.24 - name: check minimal run: cargo ci-check-min diff --git a/.gitignore b/.gitignore index 91930acf8..48ccccb92 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,5 @@ guide/build/ .vscode # code coverage +/lcov.info /codecov.json From 55c15f5bbf96518738bb440cea84c25551296bec Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 27 Aug 2023 00:07:11 +0100 Subject: [PATCH 37/57] minimum viable rustls v0.21 support (#3112) --- .github/workflows/ci.yml | 1 + Cargo.toml | 5 ++ actix-http/CHANGES.md | 2 + actix-http/Cargo.toml | 29 ++++++--- actix-http/examples/tls_rustls.rs | 73 +++++++++++++++++++++ actix-http/examples/ws.rs | 6 +- actix-http/src/h1/service.rs | 69 ++++++++++++++++++-- actix-http/src/h2/service.rs | 57 +++++++++++++++- actix-http/src/lib.rs | 2 +- actix-http/src/service.rs | 104 ++++++++++++++++++++++++++++-- actix-http/tests/test_rustls.rs | 45 +++++++------ actix-web/Cargo.toml | 3 +- awc/Cargo.toml | 2 +- 13 files changed, 350 insertions(+), 48 deletions(-) create mode 100644 actix-http/examples/tls_rustls.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f12202017..fdd6f0f9a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,6 +56,7 @@ jobs: if: matrix.version.name != 'stable' run: | cargo update -p=clap --precise=4.3.24 + cargo update -p=clap_lex --precise=0.5.0 - name: check minimal run: cargo ci-check-min diff --git a/Cargo.toml b/Cargo.toml index 65e3c6ae8..58fd96935 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,11 @@ members = [ "awc", ] +[workspace.package] +license = "MIT OR Apache-2.0" +edition = "2021" +rust-version = "1.68" + [profile.dev] # Disabling debug info speeds up builds a bunch and we don't rely on it for debugging that much. debug = 0 diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 0dedd2c74..7078adb7e 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -4,6 +4,8 @@ ### Added +- Add `rustls-0_20` crate feature. +- Add `{H1Service, H2Service, HttpService}::rustls_021()` and `HttpService::rustls_021_with_config()` service constructors. - Add `body::to_body_limit()` function. - Add `body::BodyLimitExceeded` error type. diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 6909b785f..61fba4bce 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -15,8 +15,9 @@ categories = [ "web-programming::http-server", "web-programming::websocket", ] -license = "MIT OR Apache-2.0" -edition = "2021" +license.workspace = true +edition.workspace = true +rust-version.workspace = true [package.metadata.docs.rs] # features that docs.rs will build with @@ -43,15 +44,21 @@ ws = [ # TLS via OpenSSL openssl = ["actix-tls/accept", "actix-tls/openssl"] -# TLS via Rustls -rustls = ["actix-tls/accept", "actix-tls/rustls"] +# TLS via Rustls v0.20 +rustls = ["rustls-0_20"] + +# TLS via Rustls v0.20 +rustls-0_20 = ["actix-tls/accept", "actix-tls/rustls-0_20"] + +# TLS via Rustls v0.21 +rustls-0_21 = ["actix-tls/accept", "actix-tls/rustls-0_21"] # Compression codecs compress-brotli = ["__compress", "brotli"] compress-gzip = ["__compress", "flate2"] compress-zstd = ["__compress", "zstd"] -# Internal (PRIVATE!) features used to aid testing and cheking feature status. +# Internal (PRIVATE!) features used to aid testing and checking feature status. # Don't rely on these whatsoever. They are semver-exempt and may disappear at anytime. __compress = [] @@ -91,7 +98,7 @@ rand = { version = "0.8", optional = true } sha1 = { version = "0.10", optional = true } # openssl/rustls -actix-tls = { version = "3", default-features = false, optional = true } +actix-tls = { version = "3.1", default-features = false, optional = true } # compress-* brotli = { version = "3.3.3", optional = true } @@ -101,7 +108,7 @@ zstd = { version = "0.12", optional = true } [dev-dependencies] actix-http-test = { version = "3", features = ["openssl"] } actix-server = "2" -actix-tls = { version = "3", features = ["openssl"] } +actix-tls = { version = "3.1", features = ["openssl"] } actix-web = "4" async-stream = "0.3" @@ -118,12 +125,16 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" static_assertions = "1" tls-openssl = { package = "openssl", version = "0.10.55" } -tls-rustls = { package = "rustls", version = "0.20" } +tls-rustls_021 = { package = "rustls", version = "0.21" } tokio = { version = "1.24.2", features = ["net", "rt", "macros"] } [[example]] name = "ws" -required-features = ["ws", "rustls"] +required-features = ["ws", "rustls-0_21"] + +[[example]] +name = "tls_rustls" +required-features = ["http2", "rustls-0_21"] [[bench]] name = "response-body-compression" diff --git a/actix-http/examples/tls_rustls.rs b/actix-http/examples/tls_rustls.rs new file mode 100644 index 000000000..fbb55c6a4 --- /dev/null +++ b/actix-http/examples/tls_rustls.rs @@ -0,0 +1,73 @@ +//! Demonstrates TLS configuration (via Rustls) for HTTP/1.1 and HTTP/2 connections. +//! +//! Test using cURL: +//! +//! ```console +//! $ curl --insecure https://127.0.0.1:8443 +//! Hello World! +//! Protocol: HTTP/2.0 +//! +//! $ curl --insecure --http1.1 https://127.0.0.1:8443 +//! Hello World! +//! Protocol: HTTP/1.1 +//! ``` + +extern crate tls_rustls_021 as rustls; + +use std::io; + +use actix_http::{Error, HttpService, Request, Response}; +use actix_utils::future::ok; + +#[actix_rt::main] +async fn main() -> io::Result<()> { + env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); + + tracing::info!("starting HTTP server at https://127.0.0.1:8443"); + + actix_server::Server::build() + .bind("echo", ("127.0.0.1", 8443), || { + HttpService::build() + .finish(|req: Request| { + let body = format!( + "Hello World!\n\ + Protocol: {:?}", + req.head().version + ); + ok::<_, Error>(Response::ok().set_body(body)) + }) + .rustls_021(rustls_config()) + })? + .run() + .await +} + +fn rustls_config() -> rustls::ServerConfig { + let cert = rcgen::generate_simple_self_signed(vec!["localhost".to_owned()]).unwrap(); + let cert_file = cert.serialize_pem().unwrap(); + let key_file = cert.serialize_private_key_pem(); + + let cert_file = &mut io::BufReader::new(cert_file.as_bytes()); + let key_file = &mut io::BufReader::new(key_file.as_bytes()); + + let cert_chain = rustls_pemfile::certs(cert_file) + .unwrap() + .into_iter() + .map(rustls::Certificate) + .collect(); + let mut keys = rustls_pemfile::pkcs8_private_keys(key_file).unwrap(); + + let mut config = rustls::ServerConfig::builder() + .with_safe_defaults() + .with_no_client_auth() + .with_single_cert(cert_chain, rustls::PrivateKey(keys.remove(0))) + .unwrap(); + + const H1_ALPN: &[u8] = b"http/1.1"; + const H2_ALPN: &[u8] = b"h2"; + + config.alpn_protocols.push(H2_ALPN.to_vec()); + config.alpn_protocols.push(H1_ALPN.to_vec()); + + config +} diff --git a/actix-http/examples/ws.rs b/actix-http/examples/ws.rs index 6af6d5095..241175ae2 100644 --- a/actix-http/examples/ws.rs +++ b/actix-http/examples/ws.rs @@ -1,7 +1,7 @@ //! Sets up a WebSocket server over TCP and TLS. //! Sends a heartbeat message every 4 seconds but does not respond to any incoming frames. -extern crate tls_rustls as rustls; +extern crate tls_rustls_021 as rustls; use std::{ io, @@ -28,7 +28,9 @@ async fn main() -> io::Result<()> { HttpService::build().h1(handler).tcp() })? .bind("tls", ("127.0.0.1", 8443), || { - HttpService::build().finish(handler).rustls(tls_config()) + HttpService::build() + .finish(handler) + .rustls_021(tls_config()) })? .run() .await diff --git a/actix-http/src/h1/service.rs b/actix-http/src/h1/service.rs index fbda7138e..3b27e3db5 100644 --- a/actix-http/src/h1/service.rs +++ b/actix-http/src/h1/service.rs @@ -152,13 +152,13 @@ mod openssl { } } -#[cfg(feature = "rustls")] -mod rustls { +#[cfg(feature = "rustls-0_20")] +mod rustls_020 { use std::io; use actix_service::ServiceFactoryExt as _; use actix_tls::accept::{ - rustls::{reexports::ServerConfig, Acceptor, TlsStream}, + rustls_0_20::{reexports::ServerConfig, Acceptor, TlsStream}, TlsError, }; @@ -188,7 +188,7 @@ mod rustls { U::Error: fmt::Display + Into>, U::InitError: fmt::Debug, { - /// Create Rustls based service. + /// Create Rustls v0.20 based service. pub fn rustls( self, config: ServerConfig, @@ -213,6 +213,67 @@ mod rustls { } } +#[cfg(feature = "rustls-0_21")] +mod rustls_021 { + use std::io; + + use actix_service::ServiceFactoryExt as _; + use actix_tls::accept::{ + rustls_0_21::{reexports::ServerConfig, Acceptor, TlsStream}, + TlsError, + }; + + use super::*; + + impl H1Service, S, B, X, U> + where + S: ServiceFactory, + S::Future: 'static, + S::Error: Into>, + S::InitError: fmt::Debug, + S::Response: Into>, + + B: MessageBody, + + X: ServiceFactory, + X::Future: 'static, + X::Error: Into>, + X::InitError: fmt::Debug, + + U: ServiceFactory< + (Request, Framed, Codec>), + Config = (), + Response = (), + >, + U::Future: 'static, + U::Error: fmt::Display + Into>, + U::InitError: fmt::Debug, + { + /// Create Rustls v0.21 based service. + pub fn rustls_021( + self, + config: ServerConfig, + ) -> impl ServiceFactory< + TcpStream, + Config = (), + Response = (), + Error = TlsError, + InitError = (), + > { + Acceptor::new(config) + .map_init_err(|_| { + unreachable!("TLS acceptor service factory does not error on init") + }) + .map_err(TlsError::into_service_error) + .map(|io: TlsStream| { + let peer_addr = io.get_ref().0.peer_addr().ok(); + (io, peer_addr) + }) + .and_then(self.map_err(TlsError::Service)) + } + } +} + impl H1Service where S: ServiceFactory, diff --git a/actix-http/src/h2/service.rs b/actix-http/src/h2/service.rs index 3f742135a..0ae7ea682 100644 --- a/actix-http/src/h2/service.rs +++ b/actix-http/src/h2/service.rs @@ -140,8 +140,8 @@ mod openssl { } } -#[cfg(feature = "rustls")] -mod rustls { +#[cfg(feature = "rustls-0_20")] +mod rustls_020 { use std::io; use actix_service::ServiceFactoryExt as _; @@ -162,7 +162,7 @@ mod rustls { B: MessageBody + 'static, { - /// Create Rustls based service. + /// Create Rustls v0.20 based service. pub fn rustls( self, mut config: ServerConfig, @@ -191,6 +191,57 @@ mod rustls { } } +#[cfg(feature = "rustls-0_21")] +mod rustls_021 { + use std::io; + + use actix_service::ServiceFactoryExt as _; + use actix_tls::accept::{ + rustls_0_21::{reexports::ServerConfig, Acceptor, TlsStream}, + TlsError, + }; + + use super::*; + + impl H2Service, S, B> + where + S: ServiceFactory, + S::Future: 'static, + S::Error: Into> + 'static, + S::Response: Into> + 'static, + >::Future: 'static, + + B: MessageBody + 'static, + { + /// Create Rustls v0.21 based service. + pub fn rustls_021( + self, + mut config: ServerConfig, + ) -> impl ServiceFactory< + TcpStream, + Config = (), + Response = (), + Error = TlsError, + InitError = S::InitError, + > { + let mut protos = vec![b"h2".to_vec()]; + protos.extend_from_slice(&config.alpn_protocols); + config.alpn_protocols = protos; + + Acceptor::new(config) + .map_init_err(|_| { + unreachable!("TLS acceptor service factory does not error on init") + }) + .map_err(TlsError::into_service_error) + .map(|io: TlsStream| { + let peer_addr = io.get_ref().0.peer_addr().ok(); + (io, peer_addr) + }) + .and_then(self.map_err(TlsError::Service)) + } + } +} + impl ServiceFactory<(T, Option)> for H2Service where T: AsyncRead + AsyncWrite + Unpin + 'static, diff --git a/actix-http/src/lib.rs b/actix-http/src/lib.rs index 8b755f2f4..382295fbc 100644 --- a/actix-http/src/lib.rs +++ b/actix-http/src/lib.rs @@ -58,7 +58,7 @@ pub mod ws; #[allow(deprecated)] pub use self::payload::PayloadStream; -#[cfg(any(feature = "openssl", feature = "rustls"))] +#[cfg(any(feature = "openssl", feature = "rustls-0_20", feature = "rustls-0_21"))] pub use self::service::TlsAcceptorConfig; pub use self::{ builder::HttpServiceBuilder, diff --git a/actix-http/src/service.rs b/actix-http/src/service.rs index e118d8361..bb0fda8c4 100644 --- a/actix-http/src/service.rs +++ b/actix-http/src/service.rs @@ -241,13 +241,13 @@ where } /// Configuration options used when accepting TLS connection. -#[cfg(any(feature = "openssl", feature = "rustls"))] +#[cfg(any(feature = "openssl", feature = "rustls-0_20", feature = "rustls-0_21"))] #[derive(Debug, Default)] pub struct TlsAcceptorConfig { pub(crate) handshake_timeout: Option, } -#[cfg(any(feature = "openssl", feature = "rustls"))] +#[cfg(any(feature = "openssl", feature = "rustls", feature = "rustls-0_21"))] impl TlsAcceptorConfig { /// Set TLS handshake timeout duration. pub fn handshake_timeout(self, dur: std::time::Duration) -> Self { @@ -352,8 +352,8 @@ mod openssl { } } -#[cfg(feature = "rustls")] -mod rustls { +#[cfg(feature = "rustls-0_20")] +mod rustls_020 { use std::io; use actix_service::ServiceFactoryExt as _; @@ -448,6 +448,102 @@ mod rustls { } } +#[cfg(feature = "rustls-0_21")] +mod rustls_021 { + use std::io; + + use actix_service::ServiceFactoryExt as _; + use actix_tls::accept::{ + rustls_0_21::{reexports::ServerConfig, Acceptor, TlsStream}, + TlsError, + }; + + use super::*; + + impl HttpService, S, B, X, U> + where + S: ServiceFactory, + S::Future: 'static, + S::Error: Into> + 'static, + S::InitError: fmt::Debug, + S::Response: Into> + 'static, + >::Future: 'static, + + B: MessageBody + 'static, + + X: ServiceFactory, + X::Future: 'static, + X::Error: Into>, + X::InitError: fmt::Debug, + + U: ServiceFactory< + (Request, Framed, h1::Codec>), + Config = (), + Response = (), + >, + U::Future: 'static, + U::Error: fmt::Display + Into>, + U::InitError: fmt::Debug, + { + /// Create Rustls based service. + pub fn rustls_021( + self, + config: ServerConfig, + ) -> impl ServiceFactory< + TcpStream, + Config = (), + Response = (), + Error = TlsError, + InitError = (), + > { + self.rustls_021_with_config(config, TlsAcceptorConfig::default()) + } + + /// Create Rustls based service with custom TLS acceptor configuration. + pub fn rustls_021_with_config( + self, + mut config: ServerConfig, + tls_acceptor_config: TlsAcceptorConfig, + ) -> impl ServiceFactory< + TcpStream, + Config = (), + Response = (), + Error = TlsError, + InitError = (), + > { + let mut protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; + protos.extend_from_slice(&config.alpn_protocols); + config.alpn_protocols = protos; + + let mut acceptor = Acceptor::new(config); + + if let Some(handshake_timeout) = tls_acceptor_config.handshake_timeout { + acceptor.set_handshake_timeout(handshake_timeout); + } + + acceptor + .map_init_err(|_| { + unreachable!("TLS acceptor service factory does not error on init") + }) + .map_err(TlsError::into_service_error) + .and_then(|io: TlsStream| async { + let proto = if let Some(protos) = io.get_ref().1.alpn_protocol() { + if protos.windows(2).any(|window| window == b"h2") { + Protocol::Http2 + } else { + Protocol::Http1 + } + } else { + Protocol::Http1 + }; + let peer_addr = io.get_ref().0.peer_addr().ok(); + Ok((io, proto, peer_addr)) + }) + .and_then(self.map_err(TlsError::Service)) + } + } +} + impl ServiceFactory<(T, Protocol, Option)> for HttpService where diff --git a/actix-http/tests/test_rustls.rs b/actix-http/tests/test_rustls.rs index 3d9a39cbd..c94e579e5 100644 --- a/actix-http/tests/test_rustls.rs +++ b/actix-http/tests/test_rustls.rs @@ -1,7 +1,6 @@ -#![cfg(feature = "rustls")] -#![allow(clippy::uninlined_format_args)] +#![cfg(feature = "rustls-0_21")] -extern crate tls_rustls as rustls; +extern crate tls_rustls_021 as rustls; use std::{ convert::Infallible, @@ -21,7 +20,7 @@ use actix_http::{ use actix_http_test::test_server; use actix_rt::pin; use actix_service::{fn_factory_with_config, fn_service}; -use actix_tls::connect::rustls::webpki_roots_cert_store; +use actix_tls::connect::rustls_0_21::webpki_roots_cert_store; use actix_utils::future::{err, ok, poll_fn}; use bytes::{Bytes, BytesMut}; use derive_more::{Display, Error}; @@ -110,7 +109,7 @@ async fn h1() -> io::Result<()> { let srv = test_server(move || { HttpService::build() .h1(|_| ok::<_, Error>(Response::ok())) - .rustls(tls_config()) + .rustls_021(tls_config()) }) .await; @@ -124,7 +123,7 @@ async fn h2() -> io::Result<()> { let srv = test_server(move || { HttpService::build() .h2(|_| ok::<_, Error>(Response::ok())) - .rustls(tls_config()) + .rustls_021(tls_config()) }) .await; @@ -142,7 +141,7 @@ async fn h1_1() -> io::Result<()> { assert_eq!(req.version(), Version::HTTP_11); ok::<_, Error>(Response::ok()) }) - .rustls(tls_config()) + .rustls_021(tls_config()) }) .await; @@ -160,7 +159,7 @@ async fn h2_1() -> io::Result<()> { assert_eq!(req.version(), Version::HTTP_2); ok::<_, Error>(Response::ok()) }) - .rustls_with_config( + .rustls_021_with_config( tls_config(), TlsAcceptorConfig::default().handshake_timeout(Duration::from_secs(5)), ) @@ -181,7 +180,7 @@ async fn h2_body1() -> io::Result<()> { let body = load_body(req.take_payload()).await?; Ok::<_, Error>(Response::ok().set_body(body)) }) - .rustls(tls_config()) + .rustls_021(tls_config()) }) .await; @@ -207,7 +206,7 @@ async fn h2_content_length() { ]; ok::<_, Infallible>(Response::new(statuses[indx])) }) - .rustls(tls_config()) + .rustls_021(tls_config()) }) .await; @@ -279,7 +278,7 @@ async fn h2_headers() { } ok::<_, Infallible>(config.body(data.clone())) }) - .rustls(tls_config()) + .rustls_021(tls_config()) }) .await; @@ -318,7 +317,7 @@ async fn h2_body2() { let mut srv = test_server(move || { HttpService::build() .h2(|_| ok::<_, Infallible>(Response::ok().set_body(STR))) - .rustls(tls_config()) + .rustls_021(tls_config()) }) .await; @@ -335,7 +334,7 @@ async fn h2_head_empty() { let mut srv = test_server(move || { HttpService::build() .finish(|_| ok::<_, Infallible>(Response::ok().set_body(STR))) - .rustls(tls_config()) + .rustls_021(tls_config()) }) .await; @@ -361,7 +360,7 @@ async fn h2_head_binary() { let mut srv = test_server(move || { HttpService::build() .h2(|_| ok::<_, Infallible>(Response::ok().set_body(STR))) - .rustls(tls_config()) + .rustls_021(tls_config()) }) .await; @@ -386,7 +385,7 @@ async fn h2_head_binary2() { let srv = test_server(move || { HttpService::build() .h2(|_| ok::<_, Infallible>(Response::ok().set_body(STR))) - .rustls(tls_config()) + .rustls_021(tls_config()) }) .await; @@ -412,7 +411,7 @@ async fn h2_body_length() { Response::ok().set_body(SizedStream::new(STR.len() as u64, body)), ) }) - .rustls(tls_config()) + .rustls_021(tls_config()) }) .await; @@ -436,7 +435,7 @@ async fn h2_body_chunked_explicit() { .body(BodyStream::new(body)), ) }) - .rustls(tls_config()) + .rustls_021(tls_config()) }) .await; @@ -465,7 +464,7 @@ async fn h2_response_http_error_handling() { ) })) })) - .rustls(tls_config()) + .rustls_021(tls_config()) }) .await; @@ -495,7 +494,7 @@ async fn h2_service_error() { let mut srv = test_server(move || { HttpService::build() .h2(|_| err::, _>(BadRequest)) - .rustls(tls_config()) + .rustls_021(tls_config()) }) .await; @@ -512,7 +511,7 @@ async fn h1_service_error() { let mut srv = test_server(move || { HttpService::build() .h1(|_| err::, _>(BadRequest)) - .rustls(tls_config()) + .rustls_021(tls_config()) }) .await; @@ -535,7 +534,7 @@ async fn alpn_h1() -> io::Result<()> { config.alpn_protocols.push(CUSTOM_ALPN_PROTOCOL.to_vec()); HttpService::build() .h1(|_| ok::<_, Error>(Response::ok())) - .rustls(config) + .rustls_021(config) }) .await; @@ -557,7 +556,7 @@ async fn alpn_h2() -> io::Result<()> { config.alpn_protocols.push(CUSTOM_ALPN_PROTOCOL.to_vec()); HttpService::build() .h2(|_| ok::<_, Error>(Response::ok())) - .rustls(config) + .rustls_021(config) }) .await; @@ -583,7 +582,7 @@ async fn alpn_h2_1() -> io::Result<()> { config.alpn_protocols.push(CUSTOM_ALPN_PROTOCOL.to_vec()); HttpService::build() .finish(|_| ok::<_, Error>(Response::ok())) - .rustls(config) + .rustls_021(config) }) .await; diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index 4322fb871..7dbaa2a29 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -16,7 +16,8 @@ categories = [ homepage = "https://actix.rs" repository = "https://github.com/actix/actix-web.git" license = "MIT OR Apache-2.0" -edition = "2021" +edition.workspace = true +rust-version.workspace = true [package.metadata.docs.rs] # features that docs.rs will build with diff --git a/awc/Cargo.toml b/awc/Cargo.toml index daec84ab9..2a09a52c4 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -45,7 +45,7 @@ cookies = ["cookie"] # trust-dns as dns resolver trust-dns = ["trust-dns-resolver"] -# Internal (PRIVATE!) features used to aid testing and cheking feature status. +# Internal (PRIVATE!) features used to aid testing and checking feature status. # Don't rely on these whatsoever. They may disappear at anytime. __compress = [] From cbf5e948db5237c0efc359fac19e116ec4c1d561 Mon Sep 17 00:00:00 2001 From: Wyatt Herkamp Date: Sun, 27 Aug 2023 18:47:05 -0400 Subject: [PATCH 38/57] Implement Deserialize and Default for actix_web::Data (#3109) * Implement Default and Deserialize for Data * FMT * Change Log * tweak changelog * chore: whitespace --------- Co-authored-by: Rob Ede --- actix-web/CHANGES.md | 2 ++ actix-web/src/data.rs | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 518a02507..97bf4ed04 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -9,6 +9,8 @@ - Add `web::Payload::to_bytes[_limited]()` helper methods. - Add missing constructors on `HttpResponse` for several status codes. - Add `http::header::ContentLength` typed header. +- Implement `Default` for `web::Data`. +- Implement `serde::Deserialize` for `web::Data`. ### Changed diff --git a/actix-web/src/data.rs b/actix-web/src/data.rs index 423dd598c..449a24a64 100644 --- a/actix-web/src/data.rs +++ b/actix-web/src/data.rs @@ -3,7 +3,7 @@ use std::{any::type_name, ops::Deref, sync::Arc}; use actix_http::Extensions; use actix_utils::future::{err, ok, Ready}; use futures_core::future::LocalBoxFuture; -use serde::Serialize; +use serde::{de, Serialize}; use crate::{dev::Payload, error, Error, FromRequest, HttpRequest}; @@ -128,6 +128,12 @@ impl From> for Data { } } +impl Default for Data { + fn default() -> Self { + Data::new(T::default()) + } +} + impl Serialize for Data where T: Serialize, @@ -139,6 +145,17 @@ where self.0.serialize(serializer) } } +impl<'de, T> de::Deserialize<'de> for Data +where + T: de::Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + Ok(Data::new(T::deserialize(deserializer)?)) + } +} impl FromRequest for Data { type Error = Error; From 905c30af865924b8853eba7149cddd17c114d171 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 29 Aug 2023 01:11:11 +0100 Subject: [PATCH 39/57] Actix Web Rustls v0.21 support (#3116) --- .github/workflows/ci.yml | 2 +- .github/workflows/clippy-fmt.yml | 5 +- actix-files/src/lib.rs | 7 +- actix-http/Cargo.toml | 2 +- actix-http/src/h1/payload.rs | 7 +- actix-http/src/service.rs | 2 +- actix-multipart/src/server.rs | 4 +- actix-router/benches/quoter.rs | 9 +- actix-router/src/url.rs | 8 +- actix-test/CHANGES.md | 4 +- actix-test/Cargo.toml | 13 ++- actix-test/src/lib.rs | 75 +++++++++++--- actix-web/CHANGES.md | 4 +- actix-web/Cargo.toml | 16 +-- actix-web/src/app_service.rs | 6 +- actix-web/src/handler.rs | 2 +- actix-web/src/route.rs | 2 +- actix-web/src/server.rs | 126 +++++++++++++++++++---- actix-web/tests/test_server.rs | 6 +- awc/CHANGES.md | 2 + awc/Cargo.toml | 27 +++-- awc/src/client/connector.rs | 167 ++++++++++++++++++++++++------- awc/tests/test_rustls_client.rs | 10 +- 23 files changed, 382 insertions(+), 124 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fdd6f0f9a..f071ec8f3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,7 +69,7 @@ jobs: run: | cargo test --lib --tests -p=actix-router --all-features cargo test --lib --tests -p=actix-http --all-features - cargo test --lib --tests -p=actix-web --features=rustls,openssl -- --skip=test_reading_deflate_encoding_large_random_rustls + cargo test --lib --tests -p=actix-web --features=rustls-0_20,rustls-0_21,openssl -- --skip=test_reading_deflate_encoding_large_random_rustls cargo test --lib --tests -p=actix-web-codegen --all-features cargo test --lib --tests -p=awc --all-features cargo test --lib --tests -p=actix-http-test --all-features diff --git a/.github/workflows/clippy-fmt.yml b/.github/workflows/clippy-fmt.yml index 109165ce0..25c05bcbc 100644 --- a/.github/workflows/clippy-fmt.yml +++ b/.github/workflows/clippy-fmt.yml @@ -39,7 +39,7 @@ jobs: with: reporter: 'github-pr-check' github_token: ${{ secrets.GITHUB_TOKEN }} - clippy_flags: --workspace --all-features --tests --examples --bins -- -Dclippy::todo + clippy_flags: --workspace --all-features --tests --examples --bins -- -Dclippy::todo -Aunknown_lints lint-docs: runs-on: ubuntu-latest @@ -63,8 +63,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions-rust-lang/setup-rust-toolchain@v1 - # temp: unpin once https://github.com/rust-lang/rust/issues/113152 is fixed - with: { toolchain: nightly-2023-06-28 } + with: { toolchain: nightly-2023-08-25 } - uses: taiki-e/cache-cargo-install-action@v1 with: { tool: cargo-public-api } diff --git a/actix-files/src/lib.rs b/actix-files/src/lib.rs index 1d8609889..7871905f6 100644 --- a/actix-files/src/lib.rs +++ b/actix-files/src/lib.rs @@ -66,6 +66,7 @@ type PathFilter = dyn Fn(&Path, &RequestHead) -> bool; #[cfg(test)] mod tests { use std::{ + fmt::Write as _, fs::{self}, ops::Add, time::{Duration, SystemTime}, @@ -848,8 +849,10 @@ mod tests { let filename_encoded = filename .as_bytes() .iter() - .map(|c| format!("%{:02X}", c)) - .collect::(); + .fold(String::new(), |mut buf, c| { + write!(&mut buf, "%{:02X}", c).unwrap(); + buf + }); std::fs::File::create(tmpdir.path().join(filename)).unwrap(); let srv = test::init_service(App::new().service(Files::new("", tmpdir.path()))).await; diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 61fba4bce..6aaaecfd4 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -21,7 +21,7 @@ rust-version.workspace = true [package.metadata.docs.rs] # features that docs.rs will build with -features = ["http2", "ws", "openssl", "rustls", "compress-brotli", "compress-gzip", "compress-zstd"] +features = ["http2", "ws", "openssl", "rustls-0_20", "rustls-0_21", "compress-brotli", "compress-gzip", "compress-zstd"] [lib] name = "actix_http" diff --git a/actix-http/src/h1/payload.rs b/actix-http/src/h1/payload.rs index 1ed785a1b..2ad3a14a3 100644 --- a/actix-http/src/h1/payload.rs +++ b/actix-http/src/h1/payload.rs @@ -117,6 +117,7 @@ impl PayloadSender { } } + #[allow(clippy::needless_pass_by_ref_mut)] #[inline] pub fn need_read(&self, cx: &mut Context<'_>) -> PayloadStatus { // we check need_read only if Payload (other side) is alive, @@ -174,7 +175,7 @@ impl Inner { /// Register future waiting data from payload. /// Waker would be used in `Inner::wake` - fn register(&mut self, cx: &mut Context<'_>) { + fn register(&mut self, cx: &Context<'_>) { if self .task .as_ref() @@ -186,7 +187,7 @@ impl Inner { // Register future feeding data to payload. /// Waker would be used in `Inner::wake_io` - fn register_io(&mut self, cx: &mut Context<'_>) { + fn register_io(&mut self, cx: &Context<'_>) { if self .io_task .as_ref() @@ -221,7 +222,7 @@ impl Inner { fn poll_next( mut self: Pin<&mut Self>, - cx: &mut Context<'_>, + cx: &Context<'_>, ) -> Poll>> { if let Some(data) = self.items.pop_front() { self.len -= data.len(); diff --git a/actix-http/src/service.rs b/actix-http/src/service.rs index bb0fda8c4..fb38ba636 100644 --- a/actix-http/src/service.rs +++ b/actix-http/src/service.rs @@ -247,7 +247,7 @@ pub struct TlsAcceptorConfig { pub(crate) handshake_timeout: Option, } -#[cfg(any(feature = "openssl", feature = "rustls", feature = "rustls-0_21"))] +#[cfg(any(feature = "openssl", feature = "rustls-0_20", feature = "rustls-0_21"))] impl TlsAcceptorConfig { /// Set TLS handshake timeout duration. pub fn handshake_timeout(self, dur: std::time::Duration) -> Self { diff --git a/actix-multipart/src/server.rs b/actix-multipart/src/server.rs index b20429040..c08031eba 100644 --- a/actix-multipart/src/server.rs +++ b/actix-multipart/src/server.rs @@ -252,7 +252,7 @@ impl InnerMultipart { fn poll( &mut self, safety: &Safety, - cx: &mut Context<'_>, + cx: &Context<'_>, ) -> Poll>> { if self.state == InnerState::Eof { Poll::Ready(None) @@ -740,7 +740,7 @@ impl Safety { self.clean.get() } - fn clone(&self, cx: &mut Context<'_>) -> Safety { + fn clone(&self, cx: &Context<'_>) -> Safety { let payload = Rc::clone(&self.payload); let s = Safety { task: LocalWaker::new(), diff --git a/actix-router/benches/quoter.rs b/actix-router/benches/quoter.rs index 2065fd563..c78240809 100644 --- a/actix-router/benches/quoter.rs +++ b/actix-router/benches/quoter.rs @@ -1,6 +1,6 @@ #![allow(clippy::uninlined_format_args)] -use std::borrow::Cow; +use std::{borrow::Cow, fmt::Write as _}; use criterion::{black_box, criterion_group, criterion_main, Criterion}; @@ -8,9 +8,10 @@ fn compare_quoters(c: &mut Criterion) { let mut group = c.benchmark_group("Compare Quoters"); let quoter = actix_router::Quoter::new(b"", b""); - let path_quoted = (0..=0x7f) - .map(|c| format!("%{:02X}", c)) - .collect::(); + let path_quoted = (0..=0x7f).fold(String::new(), |mut buf, c| { + write!(&mut buf, "%{:02X}", c).unwrap(); + buf + }); let path_unquoted = ('\u{00}'..='\u{7f}').collect::(); group.bench_function("quoter_unquoted", |b| { diff --git a/actix-router/src/url.rs b/actix-router/src/url.rs index 2920e271d..b3d9e1121 100644 --- a/actix-router/src/url.rs +++ b/actix-router/src/url.rs @@ -62,6 +62,8 @@ impl ResourcePath for Url { #[cfg(test)] mod tests { + use std::fmt::Write as _; + use http::Uri; use super::*; @@ -78,7 +80,11 @@ mod tests { } fn percent_encode(data: &[u8]) -> String { - data.iter().map(|c| format!("%{:02X}", c)).collect() + data.iter() + .fold(String::with_capacity(data.len() * 3), |mut buf, c| { + write!(&mut buf, "%{:02X}", c).unwrap(); + buf + }) } #[test] diff --git a/actix-test/CHANGES.md b/actix-test/CHANGES.md index fae8201d2..477ed4c04 100644 --- a/actix-test/CHANGES.md +++ b/actix-test/CHANGES.md @@ -2,7 +2,9 @@ ## Unreleased - 2023-xx-xx -- Add `TestServerConfig::workers()` setter method. +- Add `TestServerConfig::rustls_021()` method for Rustls v0.21 support behind new `rustls-0_21` crate feature. +- Add `TestServerConfig::workers()` method. +- Add `rustls-0_20` crate feature, which the existing `rustls` feature now aliases. - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. ## 0.1.1 - 2023-02-26 diff --git a/actix-test/Cargo.toml b/actix-test/Cargo.toml index 9cf5aa76c..dd96084b3 100644 --- a/actix-test/Cargo.toml +++ b/actix-test/Cargo.toml @@ -21,10 +21,14 @@ edition = "2021" [features] default = [] -# rustls -rustls = ["tls-rustls", "actix-http/rustls", "awc/rustls"] +# TLS via Rustls v0.20 +rustls = ["rustls-0_20"] +# TLS via Rustls v0.20 +rustls-0_20 = ["tls-rustls-0_20", "actix-http/rustls-0_20", "awc/rustls-0_20"] +# TLS via Rustls v0.21 +rustls-0_21 = ["tls-rustls-0_21", "actix-http/rustls-0_21", "awc/rustls-0_21"] -# openssl +# TLS via OpenSSL openssl = ["tls-openssl", "actix-http/openssl", "awc/openssl"] [dependencies] @@ -44,5 +48,6 @@ serde = { version = "1", features = ["derive"] } serde_json = "1" serde_urlencoded = "0.7" tls-openssl = { package = "openssl", version = "0.10.55", optional = true } -tls-rustls = { package = "rustls", version = "0.20", optional = true } +tls-rustls-0_20 = { package = "rustls", version = "0.20", optional = true } +tls-rustls-0_21 = { package = "rustls", version = "0.21", optional = true } tokio = { version = "1.24.2", features = ["sync"] } diff --git a/actix-test/src/lib.rs b/actix-test/src/lib.rs index 751ab3161..e570bb266 100644 --- a/actix-test/src/lib.rs +++ b/actix-test/src/lib.rs @@ -34,8 +34,6 @@ #[cfg(feature = "openssl")] extern crate tls_openssl as openssl; -#[cfg(feature = "rustls")] -extern crate tls_rustls as rustls; use std::{fmt, net, thread, time::Duration}; @@ -141,8 +139,10 @@ where StreamType::Tcp => false, #[cfg(feature = "openssl")] StreamType::Openssl(_) => true, - #[cfg(feature = "rustls")] - StreamType::Rustls(_) => true, + #[cfg(feature = "rustls-0_20")] + StreamType::Rustls020(_) => true, + #[cfg(feature = "rustls-0_21")] + StreamType::Rustls021(_) => true, }; // run server in separate orphaned thread @@ -243,8 +243,8 @@ where .openssl(acceptor.clone()) }), }, - #[cfg(feature = "rustls")] - StreamType::Rustls(config) => match cfg.tp { + #[cfg(feature = "rustls-0_20")] + StreamType::Rustls020(config) => match cfg.tp { HttpVer::Http1 => builder.listen("test", tcp, move || { let app_cfg = AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); @@ -285,6 +285,48 @@ where .rustls(config.clone()) }), }, + #[cfg(feature = "rustls-0_21")] + StreamType::Rustls021(config) => match cfg.tp { + HttpVer::Http1 => builder.listen("test", tcp, move || { + let app_cfg = + AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); + + let fac = factory() + .into_factory() + .map_err(|err| err.into().error_response()); + + HttpService::build() + .client_request_timeout(timeout) + .h1(map_config(fac, move |_| app_cfg.clone())) + .rustls_021(config.clone()) + }), + HttpVer::Http2 => builder.listen("test", tcp, move || { + let app_cfg = + AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); + + let fac = factory() + .into_factory() + .map_err(|err| err.into().error_response()); + + HttpService::build() + .client_request_timeout(timeout) + .h2(map_config(fac, move |_| app_cfg.clone())) + .rustls_021(config.clone()) + }), + HttpVer::Both => builder.listen("test", tcp, move || { + let app_cfg = + AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr); + + let fac = factory() + .into_factory() + .map_err(|err| err.into().error_response()); + + HttpService::build() + .client_request_timeout(timeout) + .finish(map_config(fac, move |_| app_cfg.clone())) + .rustls_021(config.clone()) + }), + }, } .expect("test server could not be created"); @@ -316,7 +358,7 @@ where builder.set_verify(SslVerifyMode::NONE); let _ = builder .set_alpn_protos(b"\x02h2\x08http/1.1") - .map_err(|e| log::error!("Can not set alpn protocol: {:?}", e)); + .map_err(|err| log::error!("Can not set alpn protocol: {err:?}")); Connector::new() .conn_lifetime(Duration::from_secs(0)) .timeout(Duration::from_millis(30000)) @@ -355,8 +397,10 @@ enum StreamType { Tcp, #[cfg(feature = "openssl")] Openssl(openssl::ssl::SslAcceptor), - #[cfg(feature = "rustls")] - Rustls(rustls::ServerConfig), + #[cfg(feature = "rustls-0_20")] + Rustls020(tls_rustls_0_20::ServerConfig), + #[cfg(feature = "rustls-0_21")] + Rustls021(tls_rustls_0_21::ServerConfig), } /// Create default test server config. @@ -411,9 +455,16 @@ impl TestServerConfig { } /// Accept secure connections via Rustls. - #[cfg(feature = "rustls")] - pub fn rustls(mut self, config: rustls::ServerConfig) -> Self { - self.stream = StreamType::Rustls(config); + #[cfg(feature = "rustls-0_20")] + pub fn rustls(mut self, config: tls_rustls_0_20::ServerConfig) -> Self { + self.stream = StreamType::Rustls020(config); + self + } + + /// Accept secure connections via Rustls. + #[cfg(feature = "rustls-0_21")] + pub fn rustls_021(mut self, config: tls_rustls_0_21::ServerConfig) -> Self { + self.stream = StreamType::Rustls021(config); self } diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 97bf4ed04..aaa262e63 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -4,13 +4,15 @@ ### Added -- Add `HttpServer::{bind, listen}_auto_h2c()` method behind new `http2` crate feature. +- Add `HttpServer::{bind, listen}_auto_h2c()` methods behind new `http2` crate feature. +- Add `HttpServer::{bind, listen}_rustls_021()` methods for Rustls v0.21 support behind new `rustls-0_21` crate feature. - Add `Resource::{get, post, etc...}` methods for more concisely adding routes that don't need additional guards. - Add `web::Payload::to_bytes[_limited]()` helper methods. - Add missing constructors on `HttpResponse` for several status codes. - Add `http::header::ContentLength` typed header. - Implement `Default` for `web::Data`. - Implement `serde::Deserialize` for `web::Data`. +- Add `rustls-0_20` crate feature, which the existing `rustls` feature now aliases. ### Changed diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index 7dbaa2a29..e85a0c90e 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -21,7 +21,7 @@ rust-version.workspace = true [package.metadata.docs.rs] # features that docs.rs will build with -features = ["macros", "openssl", "rustls", "compress-brotli", "compress-gzip", "compress-zstd", "cookies", "secure-cookies"] +features = ["macros", "openssl", "rustls-0_20", "rustls-0_21", "compress-brotli", "compress-gzip", "compress-zstd", "cookies", "secure-cookies"] rustdoc-args = ["--cfg", "docsrs"] [lib] @@ -52,8 +52,12 @@ http2 = ["actix-http/http2"] # TLS via OpenSSL openssl = ["http2", "actix-http/openssl", "actix-tls/accept", "actix-tls/openssl"] -# TLS via Rustls -rustls = ["http2", "actix-http/rustls", "actix-tls/accept", "actix-tls/rustls"] +# TLS via Rustls v0.20 +rustls = ["rustls-0_20"] +# TLS via Rustls v0.20 +rustls-0_20 = ["http2", "actix-http/rustls-0_20", "actix-tls/accept", "actix-tls/rustls-0_20"] +# TLS via Rustls v0.21 +rustls-0_21 = ["http2", "actix-http/rustls-0_21", "actix-tls/accept", "actix-tls/rustls-0_21"] # Internal (PRIVATE!) features used to aid testing and checking feature status. # Don't rely on these whatsoever. They may disappear at anytime. @@ -69,7 +73,7 @@ actix-rt = { version = "2.6", default-features = false } actix-server = "2" actix-service = "2" actix-utils = "3" -actix-tls = { version = "3", default-features = false, optional = true } +actix-tls = { version = "3.1", default-features = false, optional = true } actix-http = { version = "3.3", features = ["ws"] } actix-router = "0.5" @@ -101,7 +105,7 @@ url = "2.1" [dev-dependencies] actix-files = "0.6" -actix-test = { version = "0.1", features = ["openssl", "rustls"] } +actix-test = { version = "0.1", features = ["openssl", "rustls-0_21"] } awc = { version = "3", features = ["openssl"] } brotli = "3.3.3" @@ -116,7 +120,7 @@ rustls-pemfile = "1" serde = { version = "1.0", features = ["derive"] } static_assertions = "1" tls-openssl = { package = "openssl", version = "0.10.55" } -tls-rustls = { package = "rustls", version = "0.20" } +tls-rustls = { package = "rustls", version = "0.21" } tokio = { version = "1.24.2", features = ["rt-multi-thread", "macros"] } zstd = "0.12" diff --git a/actix-web/src/app_service.rs b/actix-web/src/app_service.rs index 513e7a8a1..f2dca954c 100644 --- a/actix-web/src/app_service.rs +++ b/actix-web/src/app_service.rs @@ -112,11 +112,7 @@ where let endpoint_fut = self.endpoint.new_service(()); // take extensions or create new one as app data container. - let mut app_data = self - .extensions - .borrow_mut() - .take() - .unwrap_or_else(Extensions::new); + let mut app_data = self.extensions.borrow_mut().take().unwrap_or_default(); Box::pin(async move { // async data factories diff --git a/actix-web/src/handler.rs b/actix-web/src/handler.rs index 0c5e58e28..3d6b7f039 100644 --- a/actix-web/src/handler.rs +++ b/actix-web/src/handler.rs @@ -167,7 +167,7 @@ mod tests { async fn handler_min() {} #[rustfmt::skip] - #[allow(clippy::too_many_arguments, clippy::just_underscores_and_digits)] + #[allow(clippy::too_many_arguments, clippy::just_underscores_and_digits, clippy::let_unit_value)] async fn handler_max( _01: (), _02: (), _03: (), _04: (), _05: (), _06: (), _07: (), _08: (), _09: (), _10: (), _11: (), _12: (), diff --git a/actix-web/src/route.rs b/actix-web/src/route.rs index 674d0082a..a46c1fdd4 100644 --- a/actix-web/src/route.rs +++ b/actix-web/src/route.rs @@ -92,7 +92,7 @@ pub struct RouteService { } impl RouteService { - // TODO: does this need to take &mut ? + #[allow(clippy::needless_pass_by_ref_mut)] pub fn check(&self, req: &mut ServiceRequest) -> bool { let guard_ctx = req.guard_ctx(); diff --git a/actix-web/src/server.rs b/actix-web/src/server.rs index a540da7c8..879b269a0 100644 --- a/actix-web/src/server.rs +++ b/actix-web/src/server.rs @@ -7,7 +7,7 @@ use std::{ time::Duration, }; -#[cfg(any(feature = "openssl", feature = "rustls"))] +#[cfg(any(feature = "openssl", feature = "rustls-0_20", feature = "rustls-0_21"))] use actix_http::TlsAcceptorConfig; use actix_http::{body::MessageBody, Extensions, HttpService, KeepAlive, Request, Response}; use actix_server::{Server, ServerBuilder}; @@ -16,8 +16,6 @@ use actix_service::{ }; #[cfg(feature = "openssl")] use actix_tls::accept::openssl::reexports::{AlpnError, SslAcceptor, SslAcceptorBuilder}; -#[cfg(feature = "rustls")] -use actix_tls::accept::rustls::reexports::ServerConfig as RustlsServerConfig; use crate::{config::AppConfig, Error}; @@ -31,7 +29,7 @@ struct Config { keep_alive: KeepAlive, client_request_timeout: Duration, client_disconnect_timeout: Duration, - #[cfg(any(feature = "openssl", feature = "rustls"))] + #[allow(dead_code)] // only dead when no TLS features are enabled tls_handshake_timeout: Option, } @@ -109,7 +107,6 @@ where keep_alive: KeepAlive::default(), client_request_timeout: Duration::from_secs(5), client_disconnect_timeout: Duration::from_secs(1), - #[cfg(any(feature = "rustls", feature = "openssl"))] tls_handshake_timeout: None, })), backlog: 1024, @@ -170,7 +167,7 @@ where /// By default max connections is set to a 256. #[allow(unused_variables)] pub fn max_connection_rate(self, num: usize) -> Self { - #[cfg(any(feature = "rustls", feature = "openssl"))] + #[cfg(any(feature = "rustls-0_20", feature = "rustls-0_21", feature = "openssl"))] actix_tls::accept::max_concurrent_tls_connect(num); self } @@ -222,8 +219,8 @@ where /// Defines a timeout for TLS handshake. If the TLS handshake does not complete within this /// time, the connection is closed. /// - /// By default handshake timeout is set to 3000 milliseconds. - #[cfg(any(feature = "openssl", feature = "rustls"))] + /// By default, the handshake timeout is 3 seconds. + #[cfg(any(feature = "openssl", feature = "rustls-0_20", feature = "rustls-0_21"))] pub fn tls_handshake_timeout(self, dur: Duration) -> Self { self.config .lock() @@ -247,7 +244,10 @@ where /// /// # Connection Types /// - `actix_tls::accept::openssl::TlsStream` when using OpenSSL. - /// - `actix_tls::accept::rustls::TlsStream` when using Rustls. + /// - `actix_tls::accept::rustls_0_20::TlsStream` when using + /// Rustls v0.20. + /// - `actix_tls::accept::rustls_0_21::TlsStream` when using + /// Rustls v0.21. /// - `actix_web::rt::net::TcpStream` when no encryption is used. /// /// See the `on_connect` example for additional details. @@ -368,20 +368,39 @@ where } /// Resolves socket address(es) and binds server to created listener(s) for TLS connections - /// using Rustls. + /// using Rustls v0.20. /// /// See [`bind()`](Self::bind) for more details on `addrs` argument. /// /// ALPN protocols "h2" and "http/1.1" are added to any configured ones. - #[cfg(feature = "rustls")] + #[cfg(feature = "rustls-0_20")] pub fn bind_rustls( mut self, addrs: A, - config: RustlsServerConfig, + config: actix_tls::accept::rustls_0_20::reexports::ServerConfig, ) -> io::Result { let sockets = bind_addrs(addrs, self.backlog)?; for lst in sockets { - self = self.listen_rustls_inner(lst, config.clone())?; + self = self.listen_rustls_0_20_inner(lst, config.clone())?; + } + Ok(self) + } + + /// Resolves socket address(es) and binds server to created listener(s) for TLS connections + /// using Rustls v0.21. + /// + /// See [`bind()`](Self::bind) for more details on `addrs` argument. + /// + /// ALPN protocols "h2" and "http/1.1" are added to any configured ones. + #[cfg(feature = "rustls-0_21")] + pub fn bind_rustls_021( + mut self, + addrs: A, + config: actix_tls::accept::rustls_0_21::reexports::ServerConfig, + ) -> io::Result { + let sockets = bind_addrs(addrs, self.backlog)?; + for lst in sockets { + self = self.listen_rustls_0_21_inner(lst, config.clone())?; } Ok(self) } @@ -497,25 +516,41 @@ where Ok(self) } - /// Binds to existing listener for accepting incoming TLS connection requests using Rustls. + /// Binds to existing listener for accepting incoming TLS connection requests using Rustls + /// v0.20. /// /// See [`listen()`](Self::listen) for more details on the `lst` argument. /// /// ALPN protocols "h2" and "http/1.1" are added to any configured ones. - #[cfg(feature = "rustls")] + #[cfg(feature = "rustls-0_20")] pub fn listen_rustls( self, lst: net::TcpListener, - config: RustlsServerConfig, + config: actix_tls::accept::rustls_0_20::reexports::ServerConfig, ) -> io::Result { - self.listen_rustls_inner(lst, config) + self.listen_rustls_0_20_inner(lst, config) } - #[cfg(feature = "rustls")] - fn listen_rustls_inner( + /// Binds to existing listener for accepting incoming TLS connection requests using Rustls + /// v0.21. + /// + /// See [`listen()`](Self::listen) for more details on the `lst` argument. + /// + /// ALPN protocols "h2" and "http/1.1" are added to any configured ones. + #[cfg(feature = "rustls-0_21")] + pub fn listen_rustls_0_21( + self, + lst: net::TcpListener, + config: actix_tls::accept::rustls_0_21::reexports::ServerConfig, + ) -> io::Result { + self.listen_rustls_0_21_inner(lst, config) + } + + #[cfg(feature = "rustls-0_20")] + fn listen_rustls_0_20_inner( mut self, lst: net::TcpListener, - config: RustlsServerConfig, + config: actix_tls::accept::rustls_0_20::reexports::ServerConfig, ) -> io::Result { let factory = self.factory.clone(); let cfg = self.config.clone(); @@ -562,6 +597,57 @@ where Ok(self) } + #[cfg(feature = "rustls-0_21")] + fn listen_rustls_0_21_inner( + mut self, + lst: net::TcpListener, + config: actix_tls::accept::rustls_0_21::reexports::ServerConfig, + ) -> io::Result { + let factory = self.factory.clone(); + let cfg = self.config.clone(); + let addr = lst.local_addr().unwrap(); + self.sockets.push(Socket { + addr, + scheme: "https", + }); + + let on_connect_fn = self.on_connect_fn.clone(); + + self.builder = + self.builder + .listen(format!("actix-web-service-{}", addr), lst, move || { + let c = cfg.lock().unwrap(); + let host = c.host.clone().unwrap_or_else(|| format!("{}", addr)); + + let svc = HttpService::build() + .keep_alive(c.keep_alive) + .client_request_timeout(c.client_request_timeout) + .client_disconnect_timeout(c.client_disconnect_timeout); + + let svc = if let Some(handler) = on_connect_fn.clone() { + svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext)) + } else { + svc + }; + + let fac = factory() + .into_factory() + .map_err(|err| err.into().error_response()); + + let acceptor_config = match c.tls_handshake_timeout { + Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur), + None => TlsAcceptorConfig::default(), + }; + + svc.finish(map_config(fac, move |_| { + AppConfig::new(true, host.clone(), addr) + })) + .rustls_021_with_config(config.clone(), acceptor_config) + })?; + + Ok(self) + } + /// Binds to existing listener for accepting incoming TLS connection requests using OpenSSL. /// /// See [`listen()`](Self::listen) for more details on the `lst` argument. diff --git a/actix-web/tests/test_server.rs b/actix-web/tests/test_server.rs index 8ce889396..a268cb6e3 100644 --- a/actix-web/tests/test_server.rs +++ b/actix-web/tests/test_server.rs @@ -1,6 +1,6 @@ #[cfg(feature = "openssl")] extern crate tls_openssl as openssl; -#[cfg(feature = "rustls")] +#[cfg(feature = "rustls-0_21")] extern crate tls_rustls as rustls; use std::{ @@ -704,7 +704,7 @@ async fn test_brotli_encoding_large_openssl() { srv.stop().await; } -#[cfg(feature = "rustls")] +#[cfg(feature = "rustls-0_21")] mod plus_rustls { use std::io::BufReader; @@ -743,7 +743,7 @@ mod plus_rustls { .map(char::from) .collect::(); - let srv = actix_test::start_with(actix_test::config().rustls(tls_config()), || { + let srv = actix_test::start_with(actix_test::config().rustls_021(tls_config()), || { App::new().service(web::resource("/").route(web::to(|bytes: Bytes| async { // echo decompressed request body back in response HttpResponse::Ok() diff --git a/awc/CHANGES.md b/awc/CHANGES.md index 3429a84d7..c998cd97a 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased - 2023-xx-xx +- Add `awc::Connector::rustls_021()` method for Rustls v0.21 support behind new `rustls-0_21` crate feature. +- Add `rustls-0_20` crate feature, which the existing `rustls` feature now aliases. - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. ## 3.1.1 - 2023-02-26 diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 2a09a52c4..67d6b06f5 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -21,16 +21,20 @@ path = "src/lib.rs" [package.metadata.docs.rs] # features that docs.rs will build with -features = ["openssl", "rustls", "compress-brotli", "compress-gzip", "compress-zstd", "cookies"] +features = ["openssl", "rustls-0_20", "rustls-0_21", "compress-brotli", "compress-gzip", "compress-zstd", "cookies"] [features] default = ["compress-brotli", "compress-gzip", "compress-zstd", "cookies"] -# openssl +# TLS via OpenSSL openssl = ["tls-openssl", "actix-tls/openssl"] -# rustls -rustls = ["tls-rustls", "actix-tls/rustls"] +# TLS via Rustls v0.20 +rustls = ["rustls-0_20"] +# TLS via Rustls v0.20 +rustls-0_20 = ["tls-rustls-0_20", "actix-tls/rustls-0_20"] +# TLS via Rustls v0.21 +rustls-0_21 = ["tls-rustls-0_21", "actix-tls/rustls-0_21"] # Brotli algorithm content-encoding support compress-brotli = ["actix-http/compress-brotli", "__compress"] @@ -39,10 +43,10 @@ compress-gzip = ["actix-http/compress-gzip", "__compress"] # Zstd algorithm content-encoding support compress-zstd = ["actix-http/compress-zstd", "__compress"] -# cookie parsing and cookie jar +# Cookie parsing and cookie jar cookies = ["cookie"] -# trust-dns as dns resolver +# Use `trust-dns-resolver` crate as DNS resolver trust-dns = ["trust-dns-resolver"] # Internal (PRIVATE!) features used to aid testing and checking feature status. @@ -59,7 +63,7 @@ actix-codec = "0.5" actix-service = "2" actix-http = { version = "3.3", features = ["http2", "ws"] } actix-rt = { version = "2.1", default-features = false } -actix-tls = { version = "3", features = ["connect", "uri"] } +actix-tls = { version = "3.1", features = ["connect", "uri"] } actix-utils = "3" base64 = "0.21" @@ -84,7 +88,8 @@ tokio = { version = "1.24.2", features = ["sync"] } cookie = { version = "0.16", features = ["percent-encode"], optional = true } tls-openssl = { package = "openssl", version = "0.10.55", optional = true } -tls-rustls = { package = "rustls", version = "0.20", optional = true, features = ["dangerous_configuration"] } +tls-rustls-0_20 = { package = "rustls", version = "0.20", optional = true, features = ["dangerous_configuration"] } +tls-rustls-0_21 = { package = "rustls", version = "0.21", optional = true, features = ["dangerous_configuration"] } trust-dns-resolver = { version = "0.22", optional = true } @@ -92,8 +97,8 @@ trust-dns-resolver = { version = "0.22", optional = true } actix-http = { version = "3", features = ["openssl"] } actix-http-test = { version = "3", features = ["openssl"] } actix-server = "2" -actix-test = { version = "0.1", features = ["openssl", "rustls"] } -actix-tls = { version = "3", features = ["openssl", "rustls"] } +actix-test = { version = "0.1", features = ["openssl", "rustls-0_21"] } +actix-tls = { version = "3", features = ["openssl", "rustls-0_21"] } actix-utils = "3" actix-web = { version = "4", features = ["openssl"] } @@ -110,4 +115,4 @@ zstd = "0.12" [[example]] name = "client" -required-features = ["rustls"] +required-features = ["rustls-0_21"] diff --git a/awc/src/client/connector.rs b/awc/src/client/connector.rs index 1ecaf9947..538b64ffd 100644 --- a/awc/src/client/connector.rs +++ b/awc/src/client/connector.rs @@ -43,20 +43,22 @@ enum OurTlsConnector { #[allow(dead_code)] // false positive; used in build_ssl OpensslBuilder(actix_tls::connect::openssl::reexports::SslConnectorBuilder), - #[cfg(feature = "rustls")] - Rustls(std::sync::Arc), + #[cfg(feature = "rustls-0_20")] + Rustls020(std::sync::Arc), + + #[cfg(feature = "rustls-0_21")] + Rustls021(std::sync::Arc), } /// Manages HTTP client network connectivity. /// -/// The `Connector` type uses a builder-like combinator pattern for service -/// construction that finishes by calling the `.finish()` method. +/// The `Connector` type uses a builder-like combinator pattern for service construction that +/// finishes by calling the `.finish()` method. /// -/// ```ignore +/// ```no_run /// use std::time::Duration; -/// use actix_http::client::Connector; /// -/// let connector = Connector::new() +/// let connector = awc::Connector::new() /// .timeout(Duration::from_secs(5)) /// .finish(); /// ``` @@ -80,22 +82,22 @@ impl Connector<()> { Connector { connector: TcpConnector::new(resolver::resolver()).service(), config: ConnectorConfig::default(), - tls: Self::build_ssl(vec![b"h2".to_vec(), b"http/1.1".to_vec()]), + tls: Self::build_tls(vec![b"h2".to_vec(), b"http/1.1".to_vec()]), } } /// Provides an empty TLS connector when no TLS feature is enabled. - #[cfg(not(any(feature = "openssl", feature = "rustls")))] - fn build_ssl(_: Vec>) -> OurTlsConnector { + #[cfg(not(any(feature = "openssl", feature = "rustls-0_20", feature = "rustls-0_21")))] + fn build_tls(_: Vec>) -> OurTlsConnector { OurTlsConnector::None } - /// Build TLS connector with rustls, based on supplied ALPN protocols + /// Build TLS connector with Rustls v0.21, based on supplied ALPN protocols /// - /// Note that if both `openssl` and `rustls` features are enabled, rustls will be used. - #[cfg(feature = "rustls")] - fn build_ssl(protocols: Vec>) -> OurTlsConnector { - use actix_tls::connect::rustls::{reexports::ClientConfig, webpki_roots_cert_store}; + /// Note that if other TLS crate features are enabled, Rustls v0.21 will be used. + #[cfg(feature = "rustls-0_21")] + fn build_tls(protocols: Vec>) -> OurTlsConnector { + use actix_tls::connect::rustls_0_21::{reexports::ClientConfig, webpki_roots_cert_store}; let mut config = ClientConfig::builder() .with_safe_defaults() @@ -104,12 +106,55 @@ impl Connector<()> { config.alpn_protocols = protocols; - OurTlsConnector::Rustls(std::sync::Arc::new(config)) + OurTlsConnector::Rustls021(std::sync::Arc::new(config)) } - /// Build TLS connector with openssl, based on supplied ALPN protocols - #[cfg(all(feature = "openssl", not(feature = "rustls")))] - fn build_ssl(protocols: Vec>) -> OurTlsConnector { + /// Build TLS connector with Rustls v0.21, based on supplied ALPN protocols + /// + /// Note that if other TLS crate features are enabled, Rustls v0.21 will be used. + #[cfg(all( + all(feature = "rustls-0_20", feature = "openssl"), + not(feature = "rustls-0_21"), + ))] + fn build_tls(protocols: Vec>) -> OurTlsConnector { + use actix_tls::connect::rustls_0_20::{reexports::ClientConfig, webpki_roots_cert_store}; + + let mut config = ClientConfig::builder() + .with_safe_defaults() + .with_root_certificates(webpki_roots_cert_store()) + .with_no_client_auth(); + + config.alpn_protocols = protocols; + + OurTlsConnector::Rustls020(std::sync::Arc::new(config)) + } + + /// Build TLS connector with Rustls v0.20, based on supplied ALPN protocols + /// + /// Note that if other TLS crate features are enabled, Rustls v0.21 will be used. + #[cfg(all( + feature = "rustls-0_20", + not(any(feature = "rustls-0_21", feature = "openssl")), + ))] + fn build_tls(protocols: Vec>) -> OurTlsConnector { + use actix_tls::connect::rustls_0_20::{reexports::ClientConfig, webpki_roots_cert_store}; + + let mut config = ClientConfig::builder() + .with_safe_defaults() + .with_root_certificates(webpki_roots_cert_store()) + .with_no_client_auth(); + + config.alpn_protocols = protocols; + + OurTlsConnector::Rustls020(std::sync::Arc::new(config)) + } + + /// Build TLS connector with OpenSSL, based on supplied ALPN protocols + #[cfg(all( + feature = "openssl", + not(any(feature = "rustls-0_20", feature = "rustls-0_21")), + ))] + fn build_tls(protocols: Vec>) -> OurTlsConnector { use actix_tls::connect::openssl::reexports::{SslConnector, SslMethod}; use bytes::{BufMut, BytesMut}; @@ -129,7 +174,7 @@ impl Connector<()> { } impl Connector { - /// Use custom connector. + /// Sets custom connector. pub fn connector(self, connector: S1) -> Connector where Io1: ActixStream + fmt::Debug + 'static, @@ -158,21 +203,28 @@ where + Clone + 'static, { - /// Tcp connection timeout, i.e. max time to connect to remote host including dns name - /// resolution. Set to 5 second by default. + /// Sets TCP connection timeout. + /// + /// This is the max time allowed to connect to remote host, including DNS name resolution. + /// + /// By default, the timeout is 5 seconds. pub fn timeout(mut self, timeout: Duration) -> Self { self.config.timeout = timeout; self } - /// Tls handshake timeout, i.e. max time to do tls handshake with remote host after tcp - /// connection established. Set to 5 second by default. + /// Sets TLS handshake timeout. + /// + /// This is the max time allowed to perform the TLS handshake with remote host after TCP + /// connection is established. + /// + /// By default, the timeout is 5 seconds. pub fn handshake_timeout(mut self, timeout: Duration) -> Self { self.config.handshake_timeout = timeout; self } - /// Use custom OpenSSL `SslConnector` instance. + /// Sets custom OpenSSL `SslConnector` instance. #[cfg(feature = "openssl")] pub fn openssl( mut self, @@ -191,13 +243,23 @@ where self } - /// Use custom Rustls `ClientConfig` instance. - #[cfg(feature = "rustls")] + /// Sets custom Rustls v0.20 `ClientConfig` instance. + #[cfg(feature = "rustls-0_20")] pub fn rustls( mut self, - connector: std::sync::Arc, + connector: std::sync::Arc, ) -> Self { - self.tls = OurTlsConnector::Rustls(connector); + self.tls = OurTlsConnector::Rustls020(connector); + self + } + + /// Sets custom Rustls v0.21 `ClientConfig` instance. + #[cfg(feature = "rustls-0_21")] + pub fn rustls_021( + mut self, + connector: std::sync::Arc, + ) -> Self { + self.tls = OurTlsConnector::Rustls021(connector); self } @@ -212,12 +274,12 @@ where unimplemented!("actix-http client only supports versions http/1.1 & http/2") } }; - self.tls = Connector::build_ssl(versions); + self.tls = Connector::build_tls(versions); self } - /// Sets the initial window size (in octets) for HTTP/2 stream-level flow control for - /// received data. + /// Sets the initial window size (in bytes) for HTTP/2 stream-level flow control for received + /// data. /// /// The default value is 65,535 and is good for APIs, but not for big objects. pub fn initial_window_size(mut self, size: u32) -> Self { @@ -225,7 +287,7 @@ where self } - /// Sets the initial window size (in octets) for HTTP/2 connection-level flow control for + /// Sets the initial window size (in bytes) for HTTP/2 connection-level flow control for /// received data. /// /// The default value is 65,535 and is good for APIs, but not for big objects. @@ -405,11 +467,44 @@ where unreachable!("OpenSSL builder is built before this match."); } - #[cfg(feature = "rustls")] - OurTlsConnector::Rustls(tls) => { + #[cfg(feature = "rustls-0_20")] + OurTlsConnector::Rustls020(tls) => { const H2: &[u8] = b"h2"; - use actix_tls::connect::rustls::{reexports::AsyncTlsStream, TlsConnector}; + use actix_tls::connect::rustls_0_20::{reexports::AsyncTlsStream, TlsConnector}; + + impl IntoConnectionIo for TcpConnection> { + fn into_connection_io(self) -> (Box, Protocol) { + let sock = self.into_parts().0; + let h2 = sock + .get_ref() + .1 + .alpn_protocol() + .map_or(false, |protos| protos.windows(2).any(|w| w == H2)); + if h2 { + (Box::new(sock), Protocol::Http2) + } else { + (Box::new(sock), Protocol::Http1) + } + } + } + + let handshake_timeout = self.config.handshake_timeout; + + let tls_service = TlsConnectorService { + tcp_service: tcp_service_inner, + tls_service: TlsConnector::service(tls), + timeout: handshake_timeout, + }; + + Some(actix_service::boxed::rc_service(tls_service)) + } + + #[cfg(feature = "rustls-0_21")] + OurTlsConnector::Rustls021(tls) => { + const H2: &[u8] = b"h2"; + + use actix_tls::connect::rustls_0_21::{reexports::AsyncTlsStream, TlsConnector}; impl IntoConnectionIo for TcpConnection> { fn into_connection_io(self) -> (Box, Protocol) { diff --git a/awc/tests/test_rustls_client.rs b/awc/tests/test_rustls_client.rs index 652997de6..d758f93d8 100644 --- a/awc/tests/test_rustls_client.rs +++ b/awc/tests/test_rustls_client.rs @@ -1,6 +1,6 @@ -#![cfg(feature = "rustls")] +#![cfg(feature = "rustls-0_21")] -extern crate tls_rustls as rustls; +extern crate tls_rustls_0_21 as rustls; use std::{ io::BufReader, @@ -14,7 +14,7 @@ use std::{ use actix_http::HttpService; use actix_http_test::test_server; use actix_service::{fn_service, map_config, ServiceFactoryExt}; -use actix_tls::connect::rustls::webpki_roots_cert_store; +use actix_tls::connect::rustls_0_21::webpki_roots_cert_store; use actix_utils::future::ok; use actix_web::{dev::AppConfig, http::Version, web, App, HttpResponse}; use rustls::{ @@ -82,7 +82,7 @@ async fn test_connection_reuse_h2() { App::new().service(web::resource("/").route(web::to(HttpResponse::Ok))), |_| AppConfig::default(), )) - .rustls(tls_config()) + .rustls_021(tls_config()) .map_err(|_| ()), ) }) @@ -102,7 +102,7 @@ async fn test_connection_reuse_h2() { .set_certificate_verifier(Arc::new(danger::NoCertificateVerification)); let client = awc::Client::builder() - .connector(awc::Connector::new().rustls(Arc::new(config))) + .connector(awc::Connector::new().rustls_021(Arc::new(config))) .finish(); // req 1 From 384ca0a2cd60e2023852579c69b0c56e099c06b7 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 28 Aug 2023 23:44:35 +0100 Subject: [PATCH 40/57] chore: remove dates from changelogs --- actix-files/CHANGES.md | 88 ++++++++--------- actix-http-test/CHANGES.md | 64 ++++++------- actix-http/CHANGES.md | 152 +++++++++++++++--------------- actix-multipart-derive/CHANGES.md | 2 +- actix-multipart/CHANGES.md | 62 ++++++------ actix-router/CHANGES.md | 52 +++++----- actix-test/CHANGES.md | 32 +++---- actix-web-actors/CHANGES.md | 60 ++++++------ actix-web-codegen/CHANGES.md | 54 +++++------ actix-web/CHANGES.md | 152 +++++++++++++++--------------- awc/CHANGES.md | 110 ++++++++++----------- 11 files changed, 414 insertions(+), 414 deletions(-) diff --git a/actix-files/CHANGES.md b/actix-files/CHANGES.md index 31c0499ed..15c2958f0 100644 --- a/actix-files/CHANGES.md +++ b/actix-files/CHANGES.md @@ -1,10 +1,10 @@ # Changes -## Unreleased - 2023-xx-xx +## Unreleased - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. -## 0.6.3 - 2023-01-21 +## 0.6.3 - XHTML files now use `Content-Disposition: inline` instead of `attachment`. [#2903] - Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency. @@ -12,14 +12,14 @@ [#2903]: https://github.com/actix/actix-web/pull/2903 -## 0.6.2 - 2022-07-23 +## 0.6.2 - Allow partial range responses for video content to start streaming sooner. [#2817] - Minimum supported Rust version (MSRV) is now 1.57 due to transitive `time` dependency. [#2817]: https://github.com/actix/actix-web/pull/2817 -## 0.6.1 - 2022-06-11 +## 0.6.1 - Add `NamedFile::{modified, metadata, content_type, content_disposition, encoding}()` getters. [#2021] - Update `tokio-uring` dependency to `0.3`. @@ -29,25 +29,25 @@ [#2021]: https://github.com/actix/actix-web/pull/2021 [#2645]: https://github.com/actix/actix-web/pull/2645 -## 0.6.0 - 2022-02-25 +## 0.6.0 - No significant changes since `0.6.0-beta.16`. -## 0.6.0-beta.16 - 2022-01-31 +## 0.6.0-beta.16 - No significant changes since `0.6.0-beta.15`. -## 0.6.0-beta.15 - 2022-01-21 +## 0.6.0-beta.15 - No significant changes since `0.6.0-beta.14`. -## 0.6.0-beta.14 - 2022-01-14 +## 0.6.0-beta.14 - The `prefer_utf8` option introduced in `0.4.0` is now true by default. [#2583] [#2583]: https://github.com/actix/actix-web/pull/2583 -## 0.6.0-beta.13 - 2022-01-04 +## 0.6.0-beta.13 - The `Files` service now rejects requests with URL paths that include `%2F` (decoded: `/`). [#2398] - The `Files` service now correctly decodes `%25` in the URL path to `%` for the file path. [#2398] @@ -55,19 +55,19 @@ [#2398]: https://github.com/actix/actix-web/pull/2398 -## 0.6.0-beta.12 - 2021-12-29 +## 0.6.0-beta.12 - No significant changes since `0.6.0-beta.11`. -## 0.6.0-beta.11 - 2021-12-27 +## 0.6.0-beta.11 - No significant changes since `0.6.0-beta.10`. -## 0.6.0-beta.10 - 2021-12-11 +## 0.6.0-beta.10 - No significant changes since `0.6.0-beta.9`. -## 0.6.0-beta.9 - 2021-11-22 +## 0.6.0-beta.9 - Add crate feature `experimental-io-uring`, enabling async file I/O to be utilized. This feature is only available on Linux OSes with recent kernel versions. This feature is semver-exempt. [#2408] - Add `NamedFile::open_async`. [#2408] @@ -79,15 +79,15 @@ [#2408]: https://github.com/actix/actix-web/pull/2408 [#2453]: https://github.com/actix/actix-web/pull/2453 -## 0.6.0-beta.8 - 2021-10-20 +## 0.6.0-beta.8 - Minimum supported Rust version (MSRV) is now 1.52. -## 0.6.0-beta.7 - 2021-09-09 +## 0.6.0-beta.7 - Minimum supported Rust version (MSRV) is now 1.51. -## 0.6.0-beta.6 - 2021-06-26 +## 0.6.0-beta.6 - Added `Files::path_filter()`. [#2274] - `Files::show_files_listing()` can now be used with `Files::index_file()` to show files listing as a fallback when the index file is not found. [#2228] @@ -95,7 +95,7 @@ [#2274]: https://github.com/actix/actix-web/pull/2274 [#2228]: https://github.com/actix/actix-web/pull/2228 -## 0.6.0-beta.5 - 2021-06-17 +## 0.6.0-beta.5 - `NamedFile` now implements `ServiceFactory` and `HttpServiceFactory` making it much more useful in routing. For example, it can be used directly as a default service. [#2135] - For symbolic links, `Content-Disposition` header no longer shows the filename of the original file. [#2156] @@ -107,17 +107,17 @@ [#2225]: https://github.com/actix/actix-web/pull/2225 [#2257]: https://github.com/actix/actix-web/pull/2257 -## 0.6.0-beta.4 - 2021-04-02 +## 0.6.0-beta.4 - Add support for `.guard` in `Files` to selectively filter `Files` services. [#2046] [#2046]: https://github.com/actix/actix-web/pull/2046 -## 0.6.0-beta.3 - 2021-03-09 +## 0.6.0-beta.3 - No notable changes. -## 0.6.0-beta.2 - 2021-02-10 +## 0.6.0-beta.2 - Fix If-Modified-Since and If-Unmodified-Since to not compare using sub-second timestamps. [#1887] - Replace `v_htmlescape` with `askama_escape`. [#1953] @@ -125,39 +125,39 @@ [#1887]: https://github.com/actix/actix-web/pull/1887 [#1953]: https://github.com/actix/actix-web/pull/1953 -## 0.6.0-beta.1 - 2021-01-07 +## 0.6.0-beta.1 - `HttpRange::parse` now has its own error type. - Update `bytes` to `1.0`. [#1813] [#1813]: https://github.com/actix/actix-web/pull/1813 -## 0.5.0 - 2020-12-26 +## 0.5.0 - Optionally support hidden files/directories. [#1811] [#1811]: https://github.com/actix/actix-web/pull/1811 -## 0.4.1 - 2020-11-24 +## 0.4.1 - Clarify order of parameters in `Files::new` and improve docs. -## 0.4.0 - 2020-10-06 +## 0.4.0 - Add `Files::prefer_utf8` option that adds UTF-8 charset on certain response types. [#1714] [#1714]: https://github.com/actix/actix-web/pull/1714 -## 0.3.0 - 2020-09-11 +## 0.3.0 - No significant changes from 0.3.0-beta.1. -## 0.3.0-beta.1 - 2020-07-15 +## 0.3.0-beta.1 - Update `v_htmlescape` to 0.10 - Update `actix-web` and `actix-http` dependencies to beta.1 -## 0.3.0-alpha.1 - 2020-05-23 +## 0.3.0-alpha.1 - Update `actix-web` and `actix-http` dependencies to alpha - Fix some typos in the docs @@ -166,73 +166,73 @@ [#1384]: https://github.com/actix/actix-web/pull/1384 -## 0.2.1 - 2019-12-22 +## 0.2.1 - Use the same format for file URLs regardless of platforms -## 0.2.0 - 2019-12-20 +## 0.2.0 - Fix BodyEncoding trait import #1220 -## 0.2.0-alpha.1 - 2019-12-07 +## 0.2.0-alpha.1 - Migrate to `std::future` -## 0.1.7 - 2019-11-06 +## 0.1.7 - Add an additional `filename*` param in the `Content-Disposition` header of `actix_files::NamedFile` to be more compatible. (#1151) -## 0.1.6 - 2019-10-14 +## 0.1.6 - Add option to redirect to a slash-ended path `Files` #1132 -## 0.1.5 - 2019-10-08 +## 0.1.5 - Bump up `mime_guess` crate version to 2.0.1 - Bump up `percent-encoding` crate version to 2.1 - Allow user defined request guards for `Files` #1113 -## 0.1.4 - 2019-07-20 +## 0.1.4 - Allow to disable `Content-Disposition` header #686 -## 0.1.3 - 2019-06-28 +## 0.1.3 - Do not set `Content-Length` header, let actix-http set it #930 -## 0.1.2 - 2019-06-13 +## 0.1.2 - Content-Length is 0 for NamedFile HEAD request #914 - Fix ring dependency from actix-web default features for #741 -## 0.1.1 - 2019-06-01 +## 0.1.1 - Static files are incorrectly served as both chunked and with length #812 -## 0.1.0 - 2019-05-25 +## 0.1.0 - NamedFile last-modified check always fails due to nano-seconds in file modified date #820 -## 0.1.0-beta.4 - 2019-05-12 +## 0.1.0-beta.4 - Update actix-web to beta.4 -## 0.1.0-beta.1 - 2019-04-20 +## 0.1.0-beta.1 - Update actix-web to beta.1 -## 0.1.0-alpha.6 - 2019-04-14 +## 0.1.0-alpha.6 - Update actix-web to alpha6 -## 0.1.0-alpha.4 - 2019-04-08 +## 0.1.0-alpha.4 - Update actix-web to alpha4 -## 0.1.0-alpha.2 - 2019-04-02 +## 0.1.0-alpha.2 - Add default handler support -## 0.1.0-alpha.1 - 2019-03-28 +## 0.1.0-alpha.1 - Initial impl diff --git a/actix-http-test/CHANGES.md b/actix-http-test/CHANGES.md index 0fc89214d..065141b20 100644 --- a/actix-http-test/CHANGES.md +++ b/actix-http-test/CHANGES.md @@ -1,14 +1,14 @@ # Changes -## Unreleased - 2023-xx-xx +## Unreleased - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. -## 3.1.0 - 2023-01-21 +## 3.1.0 - Minimum supported Rust version (MSRV) is now 1.59. -## 3.0.0 - 2022-07-24 +## 3.0.0 - `TestServer::stop` is now async and will wait for the server and system to shutdown. [#2442] - Added `TestServer::client_headers` method. [#2097] @@ -24,41 +24,41 @@
3.0.0 Pre-Releases -## 3.0.0-beta.13 - 2022-02-16 +## 3.0.0-beta.13 - No significant changes since `3.0.0-beta.12`. -## 3.0.0-beta.12 - 2022-01-31 +## 3.0.0-beta.12 - No significant changes since `3.0.0-beta.11`. -## 3.0.0-beta.11 - 2022-01-04 +## 3.0.0-beta.11 - Minimum supported Rust version (MSRV) is now 1.54. -## 3.0.0-beta.10 - 2021-12-27 +## 3.0.0-beta.10 - Update `actix-server` to `2.0.0-rc.2`. [#2550] [#2550]: https://github.com/actix/actix-web/pull/2550 -## 3.0.0-beta.9 - 2021-12-11 +## 3.0.0-beta.9 - No significant changes since `3.0.0-beta.8`. -## 3.0.0-beta.8 - 2021-11-30 +## 3.0.0-beta.8 - Update `actix-tls` to `3.0.0-rc.1`. [#2474] [#2474]: https://github.com/actix/actix-web/pull/2474 -## 3.0.0-beta.7 - 2021-11-22 +## 3.0.0-beta.7 - Fix compatibility with experimental `io-uring` feature of `actix-rt`. [#2408] [#2408]: https://github.com/actix/actix-web/pull/2408 -## 3.0.0-beta.6 - 2021-11-15 +## 3.0.0-beta.6 - `TestServer::stop` is now async and will wait for the server and system to shutdown. [#2442] - Update `actix-server` to `2.0.0-beta.9`. [#2442] @@ -66,25 +66,25 @@ [#2442]: https://github.com/actix/actix-web/pull/2442 -## 3.0.0-beta.5 - 2021-09-09 +## 3.0.0-beta.5 - Minimum supported Rust version (MSRV) is now 1.51. -## 3.0.0-beta.4 - 2021-04-02 +## 3.0.0-beta.4 - Added `TestServer::client_headers` method. [#2097] [#2097]: https://github.com/actix/actix-web/pull/2097 -## 3.0.0-beta.3 - 2021-03-09 +## 3.0.0-beta.3 - No notable changes. -## 3.0.0-beta.2 - 2021-02-10 +## 3.0.0-beta.2 - No notable changes. -## 3.0.0-beta.1 - 2021-01-07 +## 3.0.0-beta.1 - Update `bytes` to `1.0`. [#1813] @@ -92,7 +92,7 @@
-## 2.1.0 - 2020-11-25 +## 2.1.0 - Add ability to set address for `TestServer`. [#1645] - Upgrade `base64` to `0.13`. @@ -101,11 +101,11 @@ [#1773]: https://github.com/actix/actix-web/pull/1773 [#1645]: https://github.com/actix/actix-web/pull/1645 -## 2.0.0 - 2020-09-11 +## 2.0.0 - Update actix-codec and actix-utils dependencies. -## 2.0.0-alpha.1 - 2020-05-23 +## 2.0.0-alpha.1 - Update the `time` dependency to 0.2.7 - Update `actix-connect` dependency to 2.0.0-alpha.2 @@ -115,57 +115,57 @@ - Update `base64` dependency to 0.12 - Update `env_logger` dependency to 0.7 -## 1.0.0 - 2019-12-13 +## 1.0.0 - Replaced `TestServer::start()` with `test_server()` -## 1.0.0-alpha.3 - 2019-12-07 +## 1.0.0-alpha.3 - Migrate to `std::future` -## 0.2.5 - 2019-09-17 +## 0.2.5 - Update serde_urlencoded to "0.6.1" - Increase TestServerRuntime timeouts from 500ms to 3000ms - Do not override current `System` -## 0.2.4 - 2019-07-18 +## 0.2.4 - Update actix-server to 0.6 -## 0.2.3 - 2019-07-16 +## 0.2.3 - Add `delete`, `options`, `patch` methods to `TestServerRunner` -## 0.2.2 - 2019-06-16 +## 0.2.2 - Add .put() and .sput() methods -## 0.2.1 - 2019-06-05 +## 0.2.1 - Add license files -## 0.2.0 - 2019-05-12 +## 0.2.0 - Update awc and actix-http deps -## 0.1.1 - 2019-04-24 +## 0.1.1 - Always make new connection for http client -## 0.1.0 - 2019-04-16 +## 0.1.0 - No changes -## 0.1.0-alpha.3 - 2019-04-02 +## 0.1.0-alpha.3 - Request functions accept path #743 -## 0.1.0-alpha.2 - 2019-03-29 +## 0.1.0-alpha.2 - Added TestServerRuntime::load_body() method - Update actix-http and awc libraries -## 0.1.0-alpha.1 - 2019-03-28 +## 0.1.0-alpha.1 - Initial impl diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 7078adb7e..5252f3fbf 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -1,6 +1,6 @@ # Changes -## Unreleased - 2023-xx-xx +## Unreleased ### Added @@ -13,13 +13,13 @@ - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. -## 3.3.1 - 2023-03-02 +## 3.3.1 ### Fixed - Use correct `http` version requirement to ensure support for const `HeaderName` definitions. -## 3.3.0 - 2023-01-21 +## 3.3.0 ### Added @@ -55,7 +55,7 @@ [#2956]: https://github.com/actix/actix-web/pull/2956 [#2968]: https://github.com/actix/actix-web/pull/2968 -## 3.2.2 - 2022-09-11 +## 3.2.2 ### Changed @@ -67,7 +67,7 @@ [#2369]: https://github.com/actix/actix-web/pull/2369 -## 3.2.1 - 2022-07-02 +## 3.2.1 ### Fixed @@ -75,7 +75,7 @@ [#2794]: https://github.com/actix/actix-web/pull/2794 -## 3.2.0 - 2022-06-30 +## 3.2.0 ### Changed @@ -89,7 +89,7 @@ [#2790]: https://github.com/actix/actix-web/pull/2790 [#2798]: https://github.com/actix/actix-web/pull/2798 -## 3.1.0 - 2022-06-11 +## 3.1.0 ### Changed @@ -103,13 +103,13 @@ [#2357]: https://github.com/actix/actix-web/issues/2357 [#2779]: https://github.com/actix/actix-web/pull/2779 -## 3.0.4 - 2022-03-09 +## 3.0.4 ### Fixed - Document on docs.rs with `ws` feature enabled. -## 3.0.3 - 2022-03-08 +## 3.0.3 ### Fixed @@ -117,7 +117,7 @@ [#2684]: https://github.com/actix/actix-web/pull/2684 -## 3.0.2 - 2022-03-05 +## 3.0.2 ### Fixed @@ -125,13 +125,13 @@ [#2683]: https://github.com/actix/actix-web/pull/2683 -## 3.0.1 - 2022-03-04 +## 3.0.1 - Fix panic in H1 dispatcher when pipelining is used with keep-alive. [#2678] [#2678]: https://github.com/actix/actix-web/issues/2678 -## 3.0.0 - 2022-02-25 +## 3.0.0 ### Dependencies @@ -419,7 +419,7 @@
3.0.0 Pre-Releases -## 3.0.0-rc.4 - 2022-02-22 +## 3.0.0-rc.4 ### Fixed @@ -427,11 +427,11 @@ [1ce58ecb]: https://github.com/actix/actix-web/commit/1ce58ecb305c60e51db06e6c913b7a1344e229ca -## 3.0.0-rc.3 - 2022-02-16 +## 3.0.0-rc.3 - No significant changes since `3.0.0-rc.2`. -## 3.0.0-rc.2 - 2022-02-08 +## 3.0.0-rc.2 ### Added @@ -448,7 +448,7 @@ [#2624]: https://github.com/actix/actix-web/pull/2624 [#2625]: https://github.com/actix/actix-web/pull/2625 -## 3.0.0-rc.1 - 2022-01-31 +## 3.0.0-rc.1 ### Added @@ -484,7 +484,7 @@ [#2611]: https://github.com/actix/actix-web/pull/2611 [#2618]: https://github.com/actix/actix-web/pull/2618 -## 3.0.0-beta.19 - 2022-01-21 +## 3.0.0-beta.19 ### Added @@ -504,7 +504,7 @@ [#2585]: https://github.com/actix/actix-web/pull/2585 [#2587]: https://github.com/actix/actix-web/pull/2587 -## 3.0.0-beta.18 - 2022-01-04 +## 3.0.0-beta.18 ### Added @@ -535,7 +535,7 @@ [#2501]: https://github.com/actix/actix-web/pull/2501 [#2565]: https://github.com/actix/actix-web/pull/2565 -## 3.0.0-beta.17 - 2021-12-27 +## 3.0.0-beta.17 ### Changed @@ -553,7 +553,7 @@ [#2527]: https://github.com/actix/actix-web/pull/2527 [#2545]: https://github.com/actix/actix-web/pull/2545 -## 3.0.0-beta.16 - 2021-12-17 +## 3.0.0-beta.16 ### Added @@ -572,7 +572,7 @@ [#2510]: https://github.com/actix/actix-web/pull/2510 [#2522]: https://github.com/actix/actix-web/pull/2522 -## 3.0.0-beta.15 - 2021-12-11 +## 3.0.0-beta.15 ### Added @@ -626,7 +626,7 @@ [#2497]: https://github.com/actix/actix-web/pull/2497 [#2520]: https://github.com/actix/actix-web/pull/2520 -## 3.0.0-beta.14 - 2021-11-30 +## 3.0.0-beta.14 ### Changed @@ -639,7 +639,7 @@ [#2470]: https://github.com/actix/actix-web/pull/2470 [#2474]: https://github.com/actix/actix-web/pull/2474 -## 3.0.0-beta.13 - 2021-11-22 +## 3.0.0-beta.13 ### Added @@ -668,7 +668,7 @@ [#2448]: https://github.com/actix/actix-web/pull/2448 [#2456]: https://github.com/actix/actix-web/pull/2456 -## 3.0.0-beta.12 - 2021-11-15 +## 3.0.0-beta.12 ### Changed @@ -682,7 +682,7 @@ [#2425]: https://github.com/actix/actix-web/pull/2425 [#2442]: https://github.com/actix/actix-web/pull/2442 -## 3.0.0-beta.11 - 2021-10-20 +## 3.0.0-beta.11 ### Changed @@ -691,7 +691,7 @@ [#2414]: https://github.com/actix/actix-web/pull/2414 -## 3.0.0-beta.10 - 2021-09-09 +## 3.0.0-beta.10 ### Changed @@ -709,13 +709,13 @@ [#2344]: https://github.com/actix/actix-web/pull/2344 [#2377]: https://github.com/actix/actix-web/pull/2377 -## 3.0.0-beta.9 - 2021-08-09 +## 3.0.0-beta.9 ### Fixed - Potential HTTP request smuggling vulnerabilities. [RUSTSEC-2021-0081](https://github.com/rustsec/advisory-db/pull/977) -## 3.0.0-beta.8 - 2021-06-26 +## 3.0.0-beta.8 ### Changed @@ -728,7 +728,7 @@ [#2291]: https://github.com/actix/actix-web/pull/2291 [#2250]: https://github.com/actix/actix-web/pull/2250 -## 3.0.0-beta.7 - 2021-06-17 +## 3.0.0-beta.7 ### Added @@ -775,7 +775,7 @@ [#2253]: https://github.com/actix/actix-web/pull/2253 [#2244]: https://github.com/actix/actix-web/pull/2244 -## 3.0.0-beta.6 - 2021-04-17 +## 3.0.0-beta.6 ### Added @@ -810,7 +810,7 @@ [#2158]: https://github.com/actix/actix-web/pull/2158 [#2161]: https://github.com/actix/actix-web/pull/2161 -## 3.0.0-beta.5 - 2021-04-02 +## 3.0.0-beta.5 ### Added @@ -832,7 +832,7 @@ [#2094]: https://github.com/actix/actix-web/pull/2094 [#2127]: https://github.com/actix/actix-web/pull/2127 -## 3.0.0-beta.4 - 2021-03-08 +## 3.0.0-beta.4 ### Changed @@ -850,11 +850,11 @@ [#2035]: https://github.com/actix/actix-web/pull/2035 [#2052]: https://github.com/actix/actix-web/pull/2052 -## 3.0.0-beta.3 - 2021-02-10 +## 3.0.0-beta.3 - No notable changes. -## 3.0.0-beta.2 - 2021-02-10 +## 3.0.0-beta.2 ### Added @@ -906,7 +906,7 @@ [#1964]: https://github.com/actix/actix-web/pull/1964 [#1969]: https://github.com/actix/actix-web/pull/1969 -## 3.0.0-beta.1 - 2021-01-07 +## 3.0.0-beta.1 ### Added @@ -934,7 +934,7 @@
-## 2.2.2 - 2022-01-21 +## 2.2.2 ### Changed @@ -942,13 +942,13 @@ [ad7e3c06]: https://github.com/actix/actix-web/commit/ad7e3c06 -## 2.2.1 - 2021-08-09 +## 2.2.1 ### Fixed - Potential HTTP request smuggling vulnerabilities. [RUSTSEC-2021-0081](https://github.com/rustsec/advisory-db/pull/977) -## 2.2.0 - 2020-11-25 +## 2.2.0 ### Added @@ -970,7 +970,7 @@ [#1793]: https://github.com/actix/actix-web/pull/1793 [#1797]: https://github.com/actix/actix-web/pull/1797 -## 2.1.0 - 2020-10-30 +## 2.1.0 ### Added @@ -987,18 +987,18 @@ [#1733]: https://github.com/actix/actix-web/pull/1733 [#1744]: https://github.com/actix/actix-web/pull/1744 -## 2.0.0 - 2020-09-11 +## 2.0.0 - No significant changes from `2.0.0-beta.4`. -## 2.0.0-beta.4 - 2020-09-09 +## 2.0.0-beta.4 ### Changed - Update actix-codec and actix-utils dependencies. - Update actix-connect and actix-tls dependencies. -## 2.0.0-beta.3 - 2020-08-14 +## 2.0.0-beta.3 ### Fixed @@ -1006,7 +1006,7 @@ [#1626]: https://github.com/actix/actix-web/pull/1626 -## 2.0.0-beta.2 - 2020-07-21 +## 2.0.0-beta.2 ### Fixed @@ -1019,7 +1019,7 @@ [#1614]: https://github.com/actix/actix-web/pull/1614 [#1615]: https://github.com/actix/actix-web/pull/1615 -## 2.0.0-beta.1 - 2020-07-11 +## 2.0.0-beta.1 ### Changed @@ -1032,7 +1032,7 @@ [#1586]: https://github.com/actix/actix-web/pull/1586 [#1580]: https://github.com/actix/actix-web/pull/1580 -## 2.0.0-alpha.4 - 2020-05-21 +## 2.0.0-alpha.4 ### Changed @@ -1048,7 +1048,7 @@ [#1439]: https://github.com/actix/actix-web/pull/1439 [#1503]: https://github.com/actix/actix-web/pull/1503 -## 2.0.0-alpha.3 - 2020-05-08 +## 2.0.0-alpha.3 ### Fixed @@ -1063,7 +1063,7 @@ [#1422]: https://github.com/actix/actix-web/pull/1422 [#1487]: https://github.com/actix/actix-web/pull/1487 -## 2.0.0-alpha.2 - 2020-03-07 +## 2.0.0-alpha.2 ### Changed @@ -1075,7 +1075,7 @@ [#1394]: https://github.com/actix/actix-web/pull/1394 [#1395]: https://github.com/actix/actix-web/pull/1395 -## 2.0.0-alpha.1 - 2020-02-27 +## 2.0.0-alpha.1 ### Changed @@ -1088,14 +1088,14 @@ - Allow `SameSite=None` cookies to be sent in a response. -## 1.0.1 - 2019-12-20 +## 1.0.1 ### Fixed - Poll upgrade service's readiness from HTTP service handlers - Replace brotli with brotli2 #1224 -## 1.0.0 - 2019-12-13 +## 1.0.0 ### Added @@ -1105,7 +1105,7 @@ - Replace `flate2-xxx` features with `compress` -## 1.0.0-alpha.5 - 2019-12-09 +## 1.0.0-alpha.5 ### Fixed @@ -1116,7 +1116,7 @@ - Websockets: Ping and Pong should have binary data #1049 -## 1.0.0-alpha.4 - 2019-12-08 +## 1.0.0-alpha.4 ### Added @@ -1126,14 +1126,14 @@ - Use rust based brotli compression library -## 1.0.0-alpha.3 - 2019-12-07 +## 1.0.0-alpha.3 ### Changed - Migrate to tokio 0.2 - Migrate to `std::future` -## 0.2.11 - 2019-11-06 +## 0.2.11 ### Added @@ -1147,7 +1147,7 @@ [#1878]: https://github.com/actix/actix-web/pull/1878 -## 0.2.10 - 2019-09-11 +## 0.2.10 ### Added @@ -1158,7 +1158,7 @@ - h2 will use error response #1080 - on_connect result isn't added to request extensions for http2 requests #1009 -## 0.2.9 - 2019-08-13 +## 0.2.9 ### Changed @@ -1170,7 +1170,7 @@ - Fixed a panic in the HTTP2 handshake in client HTTP requests (#1031) -## 0.2.8 - 2019-08-01 +## 0.2.8 ### Added @@ -1182,20 +1182,20 @@ - awc client panic #1016 - Invalid response with compression middleware enabled, but compression-related features disabled #997 -## 0.2.7 - 2019-07-18 +## 0.2.7 ### Added - Add support for downcasting response errors #986 -## 0.2.6 - 2019-07-17 +## 0.2.6 ### Changed - Replace `ClonableService` with local copy - Upgrade `rand` dependency version to 0.7 -## 0.2.5 - 2019-06-28 +## 0.2.5 ### Added @@ -1206,13 +1206,13 @@ - Use `encoding_rs` crate instead of unmaintained `encoding` crate - Add `Copy` and `Clone` impls for `ws::Codec` -## 0.2.4 - 2019-06-16 +## 0.2.4 ### Fixed - Do not compress NoContent (204) responses #918 -## 0.2.3 - 2019-06-02 +## 0.2.3 ### Added @@ -1223,19 +1223,19 @@ - SizedStream uses u64 -## 0.2.2 - 2019-05-29 +## 0.2.2 ### Fixed - Parse incoming stream before closing stream on disconnect #868 -## 0.2.1 - 2019-05-25 +## 0.2.1 ### Fixed - Handle socket read disconnect -## 0.2.0 - 2019-05-12 +## 0.2.0 ### Changed @@ -1246,13 +1246,13 @@ - `OneRequest` service -## 0.1.5 - 2019-05-04 +## 0.1.5 ### Fixed - Clean up response extensions in response pool #817 -## 0.1.4 - 2019-04-24 +## 0.1.4 ### Added @@ -1262,20 +1262,20 @@ - Read until eof for http/1.0 responses #771 -## 0.1.3 - 2019-04-23 +## 0.1.3 ### Fixed - Fix http client pool management - Fix http client wait queue management #794 -## 0.1.2 - 2019-04-23 +## 0.1.2 ### Fixed - Fix BorrowMutError panic in client connector #793 -## 0.1.1 - 2019-04-19 +## 0.1.1 ### Changed @@ -1283,7 +1283,7 @@ - Cookie::max_age_time() accepts value in time::Duration - Allow to specify server address for client connector -## 0.1.0 - 2019-04-16 +## 0.1.0 ### Added @@ -1294,7 +1294,7 @@ - `actix_http::encoding` always available - use trust-dns-resolver 0.11.0 -## 0.1.0-alpha.5 - 2019-04-12 +## 0.1.0-alpha.5 ### Added @@ -1306,7 +1306,7 @@ - MessageBody::length() renamed to MessageBody::size() for consistency - ws handshake verification functions take RequestHead instead of Request -## 0.1.0-alpha.4 - 2019-04-08 +## 0.1.0-alpha.4 ### Added @@ -1323,7 +1323,7 @@ - Removed PayloadBuffer -## 0.1.0-alpha.3 - 2019-04-02 +## 0.1.0-alpha.3 ### Added @@ -1335,7 +1335,7 @@ - Preallocate read buffer for h1 codec - Detect socket disconnection during protocol selection -## 0.1.0-alpha.2 - 2019-03-29 +## 0.1.0-alpha.2 ### Added @@ -1345,6 +1345,6 @@ - Do not use thread pool for decompression if chunk size is smaller than 2048. -## 0.1.0-alpha.1 - 2019-03-28 +## 0.1.0-alpha.1 - Initial impl diff --git a/actix-multipart-derive/CHANGES.md b/actix-multipart-derive/CHANGES.md index f90b9e3cf..04f31e0f3 100644 --- a/actix-multipart-derive/CHANGES.md +++ b/actix-multipart-derive/CHANGES.md @@ -5,6 +5,6 @@ - Update `syn` dependency to `2`. - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. -## 0.6.0 - 2023-02-26 +## 0.6.0 - Add `MultipartForm` derive macro. diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index 1ad5865ec..dc4cb8373 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -1,49 +1,49 @@ # Changes -## Unreleased - 2023-xx-xx +## Unreleased - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. -## 0.6.0 - 2023-02-26 +## 0.6.0 - Added `MultipartForm` typed data extractor. [#2883] [#2883]: https://github.com/actix/actix-web/pull/2883 -## 0.5.0 - 2023-01-21 +## 0.5.0 - `Field::content_type()` now returns `Option<&mime::Mime>`. [#2885] - Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency. [#2885]: https://github.com/actix/actix-web/pull/2885 -## 0.4.0 - 2022-02-25 +## 0.4.0 - No significant changes since `0.4.0-beta.13`. -## 0.4.0-beta.13 - 2022-01-31 +## 0.4.0-beta.13 - No significant changes since `0.4.0-beta.12`. -## 0.4.0-beta.12 - 2022-01-04 +## 0.4.0-beta.12 - Minimum supported Rust version (MSRV) is now 1.54. -## 0.4.0-beta.11 - 2021-12-27 +## 0.4.0-beta.11 - No significant changes since `0.4.0-beta.10`. -## 0.4.0-beta.10 - 2021-12-11 +## 0.4.0-beta.10 - No significant changes since `0.4.0-beta.9`. -## 0.4.0-beta.9 - 2021-12-01 +## 0.4.0-beta.9 - Polling `Field` after dropping `Multipart` now fails immediately instead of hanging forever. [#2463] [#2463]: https://github.com/actix/actix-web/pull/2463 -## 0.4.0-beta.8 - 2021-11-22 +## 0.4.0-beta.8 - Ensure a correct Content-Disposition header is included in every part of a multipart message. [#2451] - Added `MultipartError::NoContentDisposition` variant. [#2451] @@ -54,31 +54,31 @@ [#2451]: https://github.com/actix/actix-web/pull/2451 -## 0.4.0-beta.7 - 2021-10-20 +## 0.4.0-beta.7 - Minimum supported Rust version (MSRV) is now 1.52. -## 0.4.0-beta.6 - 2021-09-09 +## 0.4.0-beta.6 - Minimum supported Rust version (MSRV) is now 1.51. -## 0.4.0-beta.5 - 2021-06-17 +## 0.4.0-beta.5 - No notable changes. -## 0.4.0-beta.4 - 2021-04-02 +## 0.4.0-beta.4 - No notable changes. -## 0.4.0-beta.3 - 2021-03-09 +## 0.4.0-beta.3 - No notable changes. -## 0.4.0-beta.2 - 2021-02-10 +## 0.4.0-beta.2 - No notable changes. -## 0.4.0-beta.1 - 2021-01-07 +## 0.4.0-beta.1 - Fix multipart consuming payload before header checks. [#1513] - Update `bytes` to `1.0`. [#1813] @@ -86,19 +86,19 @@ [#1813]: https://github.com/actix/actix-web/pull/1813 [#1513]: https://github.com/actix/actix-web/pull/1513 -## 0.3.0 - 2020-09-11 +## 0.3.0 - No significant changes from `0.3.0-beta.2`. -## 0.3.0-beta.2 - 2020-09-10 +## 0.3.0-beta.2 - Update `actix-*` dependencies to latest versions. -## 0.3.0-beta.1 - 2020-07-15 +## 0.3.0-beta.1 - Update `actix-web` to 3.0.0-beta.1 -## 0.3.0-alpha.1 - 2020-05-25 +## 0.3.0-alpha.1 - Update `actix-web` to 3.0.0-alpha.3 - Bump minimum supported Rust version to 1.40 @@ -106,45 +106,45 @@ - Remove the unused `time` dependency - Fix missing `std::error::Error` implement for `MultipartError`. -## [0.2.0] - 2019-12-20 +## [0.2.0] - Release -## [0.2.0-alpha.4] - 2019-12-xx +## [0.2.0-alpha.4] - Multipart handling now handles Pending during read of boundary #1205 -## [0.2.0-alpha.2] - 2019-12-03 +## [0.2.0-alpha.2] - Migrate to `std::future` -## [0.1.4] - 2019-09-12 +## [0.1.4] - Multipart handling now parses requests which do not end in CRLF #1038 -## [0.1.3] - 2019-08-18 +## [0.1.3] - Fix ring dependency from actix-web default features for #741. -## [0.1.2] - 2019-06-02 +## [0.1.2] - Fix boundary parsing #876 -## [0.1.1] - 2019-05-25 +## [0.1.1] - Fix disconnect handling #834 -## [0.1.0] - 2019-05-18 +## [0.1.0] - Release -## [0.1.0-beta.4] - 2019-05-12 +## [0.1.0-beta.4] - Handle cancellation of uploads #736 - Upgrade to actix-web 1.0.0-beta.4 -## [0.1.0-beta.1] - 2019-04-21 +## [0.1.0-beta.1] - Do not support nested multipart diff --git a/actix-router/CHANGES.md b/actix-router/CHANGES.md index 786ee12d9..31316ff47 100644 --- a/actix-router/CHANGES.md +++ b/actix-router/CHANGES.md @@ -1,17 +1,17 @@ # Changes -## Unreleased - 2023-xx-xx +## Unreleased - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. -## 0.5.1 - 2022-09-19 +## 0.5.1 - Correct typo in error string for `i32` deserialization. [#2876] - Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency. [#2876]: https://github.com/actix/actix-web/pull/2876 -## 0.5.0 - 2022-02-22 +## 0.5.0 ### Added @@ -86,7 +86,7 @@
0.5.0 Pre-Releases -## 0.5.0-rc.3 - 2022-01-31 +## 0.5.0-rc.3 - Remove unused `ResourceInfo`. [#2612] - Add `RouterBuilder::push`. [#2612] @@ -98,32 +98,32 @@ [#2612]: https://github.com/actix/actix-web/pull/2612 [#2613]: https://github.com/actix/actix-web/pull/2613 -## 0.5.0-rc.2 - 2022-01-21 +## 0.5.0-rc.2 - Add `Path::as_str`. [#2590] - Deprecate `Path::path`. [#2590] [#2590]: https://github.com/actix/actix-web/pull/2590 -## 0.5.0-rc.1 - 2022-01-14 +## 0.5.0-rc.1 - `Resource` trait now have an associated type, `Path`, instead of the generic parameter. [#2568] - `Resource` is now implemented for `&mut Path<_>` and `RefMut>`. [#2568] [#2568]: https://github.com/actix/actix-web/pull/2568 -## 0.5.0-beta.4 - 2022-01-04 +## 0.5.0-beta.4 - `PathDeserializer` now decodes all percent encoded characters in dynamic segments. [#2566] - Minimum supported Rust version (MSRV) is now 1.54. [#2566]: https://github.com/actix/actix-net/pull/2566 -## 0.5.0-beta.3 - 2021-12-17 +## 0.5.0-beta.3 - Minimum supported Rust version (MSRV) is now 1.52. -## 0.5.0-beta.2 - 2021-09-09 +## 0.5.0-beta.2 - Introduce `ResourceDef::join`. [#380][net#380] - Disallow prefix routes with tail segments. [#379][net#379] @@ -143,7 +143,7 @@ [#2355]: https://github.com/actix/actix-web/pull/2355 [#2356]: https://github.com/actix/actix-web/pull/2356 -## 0.5.0-beta.1 - 2021-07-20 +## 0.5.0-beta.1 - Fix a bug in multi-patterns where static patterns are interpreted as regex. [#366][net#366] - Introduce `ResourceDef::pattern_iter` to get an iterator over all patterns in a multi-pattern resource. [#373][net#373] @@ -173,7 +173,7 @@
-## 0.4.0 - 2021-06-06 +## 0.4.0 - When matching path parameters, `%25` is now kept in the percent-encoded form; no longer decoded to `%`. [#357][net#357] - Path tail patterns now match new lines (`\n`) in request URL. [#360][net#360] @@ -185,70 +185,70 @@ [net#359]: https://github.com/actix/actix-net/pull/359 [net#360]: https://github.com/actix/actix-net/pull/360 -## 0.3.0 - 2019-12-31 +## 0.3.0 - Version was yanked previously. See https://crates.io/crates/actix-router/0.3.0 -## 0.2.7 - 2021-02-06 +## 0.2.7 - Add `Router::recognize_checked` [#247][net#247] [net#247]: https://github.com/actix/actix-net/pull/247 -## 0.2.6 - 2021-01-09 +## 0.2.6 - Use `bytestring` version range compatible with Bytes v1.0. [#246][net#246] [net#246]: https://github.com/actix/actix-net/pull/246 -## 0.2.5 - 2020-09-20 +## 0.2.5 - Fix `from_hex()` method -## 0.2.4 - 2019-12-31 +## 0.2.4 - Add `ResourceDef::resource_path_named()` path generation method -## 0.2.3 - 2019-12-25 +## 0.2.3 - Add impl `IntoPattern` for `&String` -## 0.2.2 - 2019-12-25 +## 0.2.2 - Use `IntoPattern` for `RouterBuilder::path()` -## 0.2.1 - 2019-12-25 +## 0.2.1 - Add `IntoPattern` trait - Add multi-pattern resources -## 0.2.0 - 2019-12-07 +## 0.2.0 - Update http to 0.2 - Update regex to 1.3 - Use bytestring instead of string -## 0.1.5 - 2019-05-15 +## 0.1.5 - Remove debug prints -## 0.1.4 - 2019-05-15 +## 0.1.4 - Fix checked resource match -## 0.1.3 - 2019-04-22 +## 0.1.3 - Added support for `remainder match` (i.e "/path/{tail}\*") -## 0.1.2 - 2019-04-07 +## 0.1.2 - Export `Quoter` type - Allow to reset `Path` instance -## 0.1.1 - 2019-04-03 +## 0.1.1 - Get dynamic segment by name instead of iterator. -## 0.1.0 - 2019-03-09 +## 0.1.0 - Initial release diff --git a/actix-test/CHANGES.md b/actix-test/CHANGES.md index 477ed4c04..c33927fa4 100644 --- a/actix-test/CHANGES.md +++ b/actix-test/CHANGES.md @@ -1,80 +1,80 @@ # Changes -## Unreleased - 2023-xx-xx +## Unreleased - Add `TestServerConfig::rustls_021()` method for Rustls v0.21 support behind new `rustls-0_21` crate feature. - Add `TestServerConfig::workers()` method. - Add `rustls-0_20` crate feature, which the existing `rustls` feature now aliases. - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. -## 0.1.1 - 2023-02-26 +## 0.1.1 - Add `TestServerConfig::port()` setter method. - Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency. -## 0.1.0 - 2022-07-24 +## 0.1.0 - Minimum supported Rust version (MSRV) is now 1.57 due to transitive `time` dependency. -## 0.1.0-beta.13 - 2022-02-16 +## 0.1.0-beta.13 - No significant changes since `0.1.0-beta.12`. -## 0.1.0-beta.12 - 2022-01-31 +## 0.1.0-beta.12 - Rename `TestServerConfig::{client_timeout => client_request_timeout}`. [#2611] [#2611]: https://github.com/actix/actix-web/pull/2611 -## 0.1.0-beta.11 - 2022-01-04 +## 0.1.0-beta.11 - Minimum supported Rust version (MSRV) is now 1.54. -## 0.1.0-beta.10 - 2021-12-27 +## 0.1.0-beta.10 - No significant changes since `0.1.0-beta.9`. -## 0.1.0-beta.9 - 2021-12-17 +## 0.1.0-beta.9 - Re-export `actix_http::body::to_bytes`. [#2518] - Update `actix_web::test` re-exports. [#2518] [#2518]: https://github.com/actix/actix-web/pull/2518 -## 0.1.0-beta.8 - 2021-12-11 +## 0.1.0-beta.8 - No significant changes since `0.1.0-beta.7`. -## 0.1.0-beta.7 - 2021-11-22 +## 0.1.0-beta.7 - Fix compatibility with experimental `io-uring` feature of `actix-rt`. [#2408] [#2408]: https://github.com/actix/actix-web/pull/2408 -## 0.1.0-beta.6 - 2021-11-15 +## 0.1.0-beta.6 - No significant changes from `0.1.0-beta.5`. -## 0.1.0-beta.5 - 2021-10-20 +## 0.1.0-beta.5 - Updated rustls to v0.20. [#2414] - Minimum supported Rust version (MSRV) is now 1.52. [#2414]: https://github.com/actix/actix-web/pull/2414 -## 0.1.0-beta.4 - 2021-09-09 +## 0.1.0-beta.4 - Minimum supported Rust version (MSRV) is now 1.51. -## 0.1.0-beta.3 - 2021-06-20 +## 0.1.0-beta.3 - No significant changes from `0.1.0-beta.2`. -## 0.1.0-beta.2 - 2021-04-17 +## 0.1.0-beta.2 - No significant changes from `0.1.0-beta.1`. -## 0.1.0-beta.1 - 2021-04-02 +## 0.1.0-beta.1 - Move integration testing structs from `actix-web`. [#2112] diff --git a/actix-web-actors/CHANGES.md b/actix-web-actors/CHANGES.md index cff27a16d..563bc210f 100644 --- a/actix-web-actors/CHANGES.md +++ b/actix-web-actors/CHANGES.md @@ -1,40 +1,40 @@ # Changes -## Unreleased - 2023-xx-xx +## Unreleased - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. -## 4.2.0 - 2023-01-21 +## 4.2.0 - Minimum supported Rust version (MSRV) is now 1.57 due to transitive `time` dependency. -## 4.1.0 - 2022-03-02 +## 4.1.0 - Add support for `actix` version `0.13`. [#2675] [#2675]: https://github.com/actix/actix-web/pull/2675 -## 4.0.0 - 2022-02-25 +## 4.0.0 - No significant changes since `4.0.0-beta.12`. -## 4.0.0-beta.12 - 2022-02-16 +## 4.0.0-beta.12 - No significant changes since `4.0.0-beta.11`. -## 4.0.0-beta.11 - 2022-01-31 +## 4.0.0-beta.11 - No significant changes since `4.0.0-beta.10`. -## 4.0.0-beta.10 - 2022-01-04 +## 4.0.0-beta.10 - Minimum supported Rust version (MSRV) is now 1.54. -## 4.0.0-beta.9 - 2021-12-27 +## 4.0.0-beta.9 - No significant changes since `4.0.0-beta.8`. -## 4.0.0-beta.8 - 2021-12-11 +## 4.0.0-beta.8 - Add `ws:WsResponseBuilder` for building WebSocket session response. [#1920] - Deprecate `ws::{start_with_addr, start_with_protocols}`. [#1920] @@ -42,33 +42,33 @@ [#1920]: https://github.com/actix/actix-web/pull/1920 -## 4.0.0-beta.7 - 2021-09-09 +## 4.0.0-beta.7 - Minimum supported Rust version (MSRV) is now 1.51. -## 4.0.0-beta.6 - 2021-06-26 +## 4.0.0-beta.6 - Update `actix` to `0.12`. [#2277] [#2277]: https://github.com/actix/actix-web/pull/2277 -## 4.0.0-beta.5 - 2021-06-17 +## 4.0.0-beta.5 - No notable changes. -## 4.0.0-beta.4 - 2021-04-02 +## 4.0.0-beta.4 - No notable changes. -## 4.0.0-beta.3 - 2021-03-09 +## 4.0.0-beta.3 - No notable changes. -## 4.0.0-beta.2 - 2021-02-10 +## 4.0.0-beta.2 - No notable changes. -## 4.0.0-beta.1 - 2021-01-07 +## 4.0.0-beta.1 - Update `pin-project` to `1.0`. - Update `bytes` to `1.0`. [#1813] @@ -77,63 +77,63 @@ [#1813]: https://github.com/actix/actix-web/pull/1813 [#1864]: https://github.com/actix/actix-web/pull/1864 -## 3.0.0 - 2020-09-11 +## 3.0.0 - No significant changes from `3.0.0-beta.2`. -## 3.0.0-beta.2 - 2020-09-10 +## 3.0.0-beta.2 - Update `actix-*` dependencies to latest versions. -## [3.0.0-beta.1] - 2020-xx-xx +## [3.0.0-beta.1] - Update `actix-web` & `actix-http` dependencies to beta.1 - Bump minimum supported Rust version to 1.40 -## [3.0.0-alpha.1] - 2020-05-08 +## [3.0.0-alpha.1] - Update the actix-web dependency to 3.0.0-alpha.1 - Update the actix dependency to 0.10.0-alpha.2 - Update the actix-http dependency to 2.0.0-alpha.3 -## [2.0.0] - 2019-12-20 +## [2.0.0] - Release -## [2.0.0-alpha.1] - 2019-12-15 +## [2.0.0-alpha.1] - Migrate to actix-web 2.0.0 -## [1.0.4] - 2019-12-07 +## [1.0.4] - Allow comma-separated websocket subprotocols without spaces (#1172) -## [1.0.3] - 2019-11-14 +## [1.0.3] - Update actix-web and actix-http dependencies -## [1.0.2] - 2019-07-20 +## [1.0.2] - Add `ws::start_with_addr()`, returning the address of the created actor, along with the `HttpResponse`. - Add support for specifying protocols on websocket handshake #835 -## [1.0.1] - 2019-06-28 +## [1.0.1] - Allow to use custom ws codec with `WebsocketContext` #925 -## [1.0.0] - 2019-05-29 +## [1.0.0] - Update actix-http and actix-web -## [0.1.0-alpha.3] - 2019-04-02 +## [0.1.0-alpha.3] - Update actix-http and actix-web -## [0.1.0-alpha.2] - 2019-03-29 +## [0.1.0-alpha.2] - Update actix-http and actix-web -## [0.1.0-alpha.1] - 2019-03-28 +## [0.1.0-alpha.1] - Initial impl diff --git a/actix-web-codegen/CHANGES.md b/actix-web-codegen/CHANGES.md index 9ff1edf6e..4b3205d7c 100644 --- a/actix-web-codegen/CHANGES.md +++ b/actix-web-codegen/CHANGES.md @@ -1,52 +1,52 @@ # Changes -## Unreleased - 2023-xx-xx +## Unreleased - Update `syn` dependency to `2`. - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. -## 4.2.0 - 2023-02-26 +## 4.2.0 - Add support for custom methods with the `#[route]` macro. [#2969] [#2969]: https://github.com/actix/actix-web/pull/2969 -## 4.1.0 - 2022-09-11 +## 4.1.0 - Add `#[routes]` macro to support multiple paths for one handler. [#2718] - Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency. [#2718]: https://github.com/actix/actix-web/pull/2718 -## 4.0.1 - 2022-06-11 +## 4.0.1 - Fix support for guard paths in route handler macros. [#2771] - Minimum supported Rust version (MSRV) is now 1.56 due to transitive `hashbrown` dependency. [#2771]: https://github.com/actix/actix-web/pull/2771 -## 4.0.0 - 2022-02-24 +## 4.0.0 - Version aligned with `actix-web` and will remain in sync going forward. - No significant changes since `0.5.0`. -## 0.5.0 - 2022-02-24 +## 0.5.0 - No significant changes since `0.5.0-rc.2`. -## 0.5.0-rc.2 - 2022-02-01 +## 0.5.0-rc.2 - No significant changes since `0.5.0-rc.1`. -## 0.5.0-rc.1 - 2022-01-04 +## 0.5.0-rc.1 - Minimum supported Rust version (MSRV) is now 1.54. -## 0.5.0-beta.6 - 2021-12-11 +## 0.5.0-beta.6 - No significant changes since `0.5.0-beta.5`. -## 0.5.0-beta.5 - 2021-10-20 +## 0.5.0-beta.5 - Improve error recovery potential when macro input is invalid. [#2410] - Add `#[actix_web::test]` macro for setting up tests with a runtime. [#2409] @@ -55,18 +55,18 @@ [#2410]: https://github.com/actix/actix-web/pull/2410 [#2409]: https://github.com/actix/actix-web/pull/2409 -## 0.5.0-beta.4 - 2021-09-09 +## 0.5.0-beta.4 - In routing macros, paths are now validated at compile time. [#2350] - Minimum supported Rust version (MSRV) is now 1.51. [#2350]: https://github.com/actix/actix-web/pull/2350 -## 0.5.0-beta.3 - 2021-06-17 +## 0.5.0-beta.3 - No notable changes. -## 0.5.0-beta.2 - 2021-03-09 +## 0.5.0-beta.2 - Preserve doc comments when using route macros. [#2022] - Add `name` attribute to `route` macro. [#1934] @@ -74,11 +74,11 @@ [#2022]: https://github.com/actix/actix-web/pull/2022 [#1934]: https://github.com/actix/actix-web/pull/1934 -## 0.5.0-beta.1 - 2021-02-10 +## 0.5.0-beta.1 - Use new call signature for `System::new`. -## 0.4.0 - 2020-09-20 +## 0.4.0 - Added compile success and failure testing. [#1677] - Add `route` macro for supporting multiple HTTP methods guards. [#1674] @@ -86,23 +86,23 @@ [#1677]: https://github.com/actix/actix-web/pull/1677 [#1674]: https://github.com/actix/actix-web/pull/1674 -## 0.3.0 - 2020-09-11 +## 0.3.0 - No significant changes from `0.3.0-beta.1`. -## 0.3.0-beta.1 - 2020-07-14 +## 0.3.0-beta.1 - Add main entry-point macro that uses re-exported runtime. [#1559] [#1559]: https://github.com/actix/actix-web/pull/1559 -## 0.2.2 - 2020-05-23 +## 0.2.2 - Add resource middleware on actix-web-codegen [#1467] [#1467]: https://github.com/actix/actix-web/pull/1467 -## 0.2.1 - 2020-02-25 +## 0.2.1 - Add `#[allow(missing_docs)]` attribute to generated structs [#1368] - Allow the handler function to be named as `config` [#1290] @@ -110,35 +110,35 @@ [#1368]: https://github.com/actix/actix-web/issues/1368 [#1290]: https://github.com/actix/actix-web/issues/1290 -## 0.2.0 - 2019-12-13 +## 0.2.0 - Generate code for actix-web 2.0 -## 0.1.3 - 2019-10-14 +## 0.1.3 - Bump up `syn` & `quote` to 1.0 - Provide better error message -## 0.1.2 - 2019-06-04 +## 0.1.2 - Add macros for head, options, trace, connect and patch http methods -## 0.1.1 - 2019-06-01 +## 0.1.1 - Add syn "extra-traits" feature -## 0.1.0 - 2019-05-18 +## 0.1.0 - Release -## 0.1.0-beta.1 - 2019-04-20 +## 0.1.0-beta.1 - Gen code for actix-web 1.0.0-beta.1 -## 0.1.0-alpha.6 - 2019-04-14 +## 0.1.0-alpha.6 - Gen code for actix-web 1.0.0-alpha.6 -## 0.1.0-alpha.1 - 2019-03-28 +## 0.1.0-alpha.1 - Initial impl diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index aaa262e63..289f8698f 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased - 2023-xx-xx +## Unreleased ### Added @@ -21,7 +21,7 @@ - Hide sensitive header values in `HttpRequest`'s `Debug` output. - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. -## 4.3.1 - 2023-02-26 +## 4.3.1 ### Added @@ -29,7 +29,7 @@ [#2969]: https://github.com/actix/actix-web/pull/2969 -## 4.3.0 - 2023-01-21 +## 4.3.0 ### Added @@ -52,7 +52,7 @@ [#2949]: https://github.com/actix/actix-web/pull/2949 [#2961]: https://github.com/actix/actix-web/pull/2961 -## 4.2.1 - 2022-09-12 +## 4.2.1 ### Fixed @@ -60,7 +60,7 @@ [#2871]: https://github.com/actix/actix-web/pull/2871 -## 4.2.0 - 2022-09-11 +## 4.2.0 ### Added @@ -76,7 +76,7 @@ [#2752]: https://github.com/actix/actix-web/pull/2752 [#2786]: https://github.com/actix/actix-web/pull/2786 -## 4.1.0 - 2022-06-11 +## 4.1.0 ### Added @@ -99,13 +99,13 @@ [#2742]: https://github.com/actix/actix-web/pull/2742 [#2743]: https://github.com/actix/actix-web/pull/2743 -## 4.0.1 - 2022-02-25 +## 4.0.1 ### Fixed - Use stable version in readme example. -## 4.0.0 - 2022-02-25 +## 4.0.0 ### Dependencies @@ -383,7 +383,7 @@
4.0.0 Pre-Releases -## 4.0.0-rc.3 - 2022-02-08 +## 4.0.0-rc.3 ### Changed @@ -397,7 +397,7 @@ [#2625]: https://github.com/actix/actix-web/pull/2625 [#2635]: https://github.com/actix/actix-web/pull/2635 -## 4.0.0-rc.2 - 2022-02-02 +## 4.0.0-rc.2 ### Added @@ -409,7 +409,7 @@ [#2619]: https://github.com/actix/actix-web/pull/2619 -## 4.0.0-rc.1 - 2022-01-31 +## 4.0.0-rc.1 ### Changed @@ -423,7 +423,7 @@ [#2601]: https://github.com/actix/actix-web/pull/2601 [#2611]: https://github.com/actix/actix-web/pull/2611 -## 4.0.0-beta.21 - 2022-01-21 +## 4.0.0-beta.21 ### Added @@ -440,7 +440,7 @@ [#2591]: https://github.com/actix/actix-web/pull/2591 [#2594]: https://github.com/actix/actix-web/pull/2594 -## 4.0.0-beta.20 - 2022-01-14 +## 4.0.0-beta.20 ### Added @@ -462,7 +462,7 @@ [#2582]: https://github.com/actix/actix-web/pull/2582 [#2584]: https://github.com/actix/actix-web/pull/2584 -## 4.0.0-beta.19 - 2022-01-04 +## 4.0.0-beta.19 ### Added @@ -487,7 +487,7 @@ [#2501]: https://github.com/actix/actix-web/pull/2501 [#2565]: https://github.com/actix/actix-web/pull/2565 -## 4.0.0-beta.18 - 2021-12-29 +## 4.0.0-beta.18 ### Changed @@ -501,7 +501,7 @@ [#2555]: https://github.com/actix/actix-web/pull/2555 [`rustsec-2020-0071`]: https://rustsec.org/advisories/RUSTSEC-2020-0071.html -## 4.0.0-beta.17 - 2021-12-29 +## 4.0.0-beta.17 ### Added @@ -524,7 +524,7 @@ [#2552]: https://github.com/actix/actix-web/pull/2552 [#2554]: https://github.com/actix/actix-web/pull/2554 -## 4.0.0-beta.16 - 2021-12-27 +## 4.0.0-beta.16 ### Changed @@ -534,7 +534,7 @@ [#2523]: https://github.com/actix/actix-web/pull/2523 [#2526]: https://github.com/actix/actix-web/pull/2526 -## 4.0.0-beta.15 - 2021-12-17 +## 4.0.0-beta.15 ### Added @@ -562,7 +562,7 @@ [#2516]: https://github.com/actix/actix-web/pull/2516 [#2518]: https://github.com/actix/actix-web/pull/2518 -## 4.0.0-beta.14 - 2021-12-11 +## 4.0.0-beta.14 ### Added @@ -607,7 +607,7 @@ [#2493]: https://github.com/actix/actix-web/pull/2493 [#2499]: https://github.com/actix/actix-web/pull/2499 -## 4.0.0-beta.13 - 2021-11-30 +## 4.0.0-beta.13 ### Changed @@ -615,7 +615,7 @@ [#2474]: https://github.com/actix/actix-web/pull/2474 -## 4.0.0-beta.12 - 2021-11-22 +## 4.0.0-beta.12 ### Changed @@ -632,7 +632,7 @@ [#2446]: https://github.com/actix/actix-web/pull/2446 [#2448]: https://github.com/actix/actix-web/pull/2448 -## 4.0.0-beta.11 - 2021-11-15 +## 4.0.0-beta.11 ### Added @@ -646,7 +646,7 @@ [#2423]: https://github.com/actix/actix-web/pull/2423 [#2442]: https://github.com/actix/actix-web/pull/2442 -## 4.0.0-beta.10 - 2021-10-20 +## 4.0.0-beta.10 ### Added @@ -673,7 +673,7 @@ [#2409]: https://github.com/actix/actix-web/pull/2409 [#2414]: https://github.com/actix/actix-web/pull/2414 -## 4.0.0-beta.9 - 2021-09-09 +## 4.0.0-beta.9 ### Added @@ -696,7 +696,7 @@ [#2344]: https://github.com/actix/actix-web/pull/2344 [#2379]: https://github.com/actix/actix-web/pull/2379 -## 4.0.0-beta.8 - 2021-06-26 +## 4.0.0-beta.8 ### Added @@ -723,7 +723,7 @@ [#2282]: https://github.com/actix/actix-web/pull/2282 [#2288]: https://github.com/actix/actix-web/pull/2288 -## 4.0.0-beta.7 - 2021-06-17 +## 4.0.0-beta.7 ### Added @@ -752,7 +752,7 @@ [#2253]: https://github.com/actix/actix-web/pull/2253 [#2246]: https://github.com/actix/actix-web/pull/2246 -## 4.0.0-beta.6 - 2021-04-17 +## 4.0.0-beta.6 ### Added @@ -766,7 +766,7 @@ [#2065]: https://github.com/actix/actix-web/pull/2065 [#2148]: https://github.com/actix/actix-web/pull/2148 -## 4.0.0-beta.5 - 2021-04-02 +## 4.0.0-beta.5 ### Added @@ -792,7 +792,7 @@ [#2097]: https://github.com/actix/actix-web/pull/2097 [#2112]: https://github.com/actix/actix-web/pull/2112 -## 4.0.0-beta.4 - 2021-03-09 +## 4.0.0-beta.4 ### Changed @@ -802,11 +802,11 @@ [#1981]: https://github.com/actix/actix-web/pull/1981 [#2010]: https://github.com/actix/actix-web/pull/2010 -## 4.0.0-beta.3 - 2021-02-10 +## 4.0.0-beta.3 - Update `actix-web-codegen` to `0.5.0-beta.1`. -## 4.0.0-beta.2 - 2021-02-10 +## 4.0.0-beta.2 ### Added @@ -844,7 +844,7 @@ [#1933]: https://github.com/actix/actix-web/pull/1933 [#1957]: https://github.com/actix/actix-web/pull/1957 -## 4.0.0-beta.1 - 2021-01-07 +## 4.0.0-beta.1 ### Added @@ -878,7 +878,7 @@
-## 3.3.3 - 2021-12-18 +## 3.3.3 ### Changed @@ -886,7 +886,7 @@ [#2529]: https://github.com/actix/actix-web/pull/2529 -## 3.3.2 - 2020-12-01 +## 3.3.2 ### Fixed @@ -898,11 +898,11 @@ [#1798]: https://github.com/actix/actix-web/pull/1798 [#1803]: https://github.com/actix/actix-web/pull/1803 -## 3.3.1 - 2020-11-29 +## 3.3.1 - Ensure `actix-http` dependency uses same `serde_urlencoded`. -## 3.3.0 - 2020-11-25 +## 3.3.0 ### Added @@ -915,7 +915,7 @@ [#1773]: https://github.com/actix/actix-web/pull/1773 [#1788]: https://github.com/actix/actix-web/pull/1788 -## 3.2.0 - 2020-10-30 +## 3.2.0 ### Added @@ -940,7 +940,7 @@ [#1757]: https://github.com/actix/actix-web/pull/1757 [#1749]: https://github.com/actix/actix-web/pull/1749 -## 3.1.0 - 2020-09-29 +## 3.1.0 ### Changed @@ -955,7 +955,7 @@ [#1708]: https://github.com/actix/actix-web/pull/1708 [#1710]: https://github.com/actix/actix-web/pull/1710 -## 3.0.2 - 2020-09-15 +## 3.0.2 ### Fixed @@ -963,7 +963,7 @@ [#1678]: https://github.com/actix/actix-web/pull/1678 -## 3.0.1 - 2020-09-13 +## 3.0.1 ### Changed @@ -971,11 +971,11 @@ [#1673]: https://github.com/actix/actix-web/pull/1673 -## 3.0.0 - 2020-09-11 +## 3.0.0 - No significant changes from `3.0.0-beta.4`. -## 3.0.0-beta.4 - 2020-09-09 +## 3.0.0-beta.4 ### Added @@ -993,13 +993,13 @@ [#1634]: https://github.com/actix/actix-web/pull/1634 [#1655]: https://github.com/actix/actix-web/pull/1655 -## 3.0.0-beta.3 - 2020-08-17 +## 3.0.0-beta.3 ### Changed - Update `rustls` to 0.18 -## 3.0.0-beta.2 - 2020-08-17 +## 3.0.0-beta.2 ### Changed @@ -1019,7 +1019,7 @@ [#1618]: https://github.com/actix/actix-web/pull/1618 [#1621]: https://github.com/actix/actix-web/pull/1621 -## 3.0.0-beta.1 - 2020-07-13 +## 3.0.0-beta.1 ### Added @@ -1037,7 +1037,7 @@ - `NormalizePath` improved consistency when path needs slashes added _and_ removed. -## 3.0.0-alpha.3 - 2020-05-21 +## 3.0.0-alpha.3 ### Added @@ -1053,7 +1053,7 @@ [#1485]: https://github.com/actix/actix-web/pull/1485 [#1509]: https://github.com/actix/actix-web/pull/1509 -## [3.0.0-alpha.2] - 2020-05-08 +## [3.0.0-alpha.2] ### Changed @@ -1067,7 +1067,7 @@ [#1452]: https://github.com/actix/actix-web/pull/1452 [#1486]: https://github.com/actix/actix-web/pull/1486 -## [3.0.0-alpha.1] - 2020-03-11 +## [3.0.0-alpha.1] ### Added @@ -1084,7 +1084,7 @@ [#1308]: https://github.com/actix/actix-web/pull/1308 -## [2.0.0] - 2019-12-25 +## [2.0.0] ### Changed @@ -1094,7 +1094,7 @@ - Allow to specify multi-patterns for resources -## [2.0.0-rc] - 2019-12-20 +## [2.0.0-rc] ### Changed @@ -1112,31 +1112,31 @@ - Fix `AppConfig::secure()` is always false. #1202 -## [2.0.0-alpha.6] - 2019-12-15 +## [2.0.0-alpha.6] ### Fixed - Fixed compilation with default features off -## [2.0.0-alpha.5] - 2019-12-13 +## [2.0.0-alpha.5] ### Added - Add test server, `test::start()` and `test::start_with()` -## [2.0.0-alpha.4] - 2019-12-08 +## [2.0.0-alpha.4] ### Deleted - Delete HttpServer::run(), it is not useful with async/await -## [2.0.0-alpha.3] - 2019-12-07 +## [2.0.0-alpha.3] ### Changed - Migrate to tokio 0.2 -## [2.0.0-alpha.1] - 2019-11-22 +## [2.0.0-alpha.1] ### Changed @@ -1144,7 +1144,7 @@ - Remove implementation of `Responder` for `()`. (#1167) -## [1.0.9] - 2019-11-14 +## [1.0.9] ### Added @@ -1154,7 +1154,7 @@ - Support `Host` guards when the `Host` header is unset (e.g. HTTP/2 requests) (#1129) -## [1.0.8] - 2019-09-25 +## [1.0.8] ### Added @@ -1172,13 +1172,13 @@ - Use actix-testing for testing utils -## [1.0.7] - 2019-08-29 +## [1.0.7] ### Fixed - Request Extensions leak #1062 -## [1.0.6] - 2019-08-28 +## [1.0.6] ### Added @@ -1200,7 +1200,7 @@ - Update url to 2.1 -## [1.0.5] - 2019-07-18 +## [1.0.5] ### Added @@ -1212,7 +1212,7 @@ - Restored logging of errors through the `Logger` middleware -## [1.0.4] - 2019-07-17 +## [1.0.4] ### Added @@ -1224,7 +1224,7 @@ - Upgrade `rand` dependency version to 0.7 -## [1.0.3] - 2019-06-28 +## [1.0.3] ### Added @@ -1234,7 +1234,7 @@ - Use `encoding_rs` crate instead of unmaintained `encoding` crate -## [1.0.2] - 2019-06-17 +## [1.0.2] ### Changed @@ -1242,7 +1242,7 @@ - Move identity middleware to `actix-identity` crate. -## [1.0.1] - 2019-06-17 +## [1.0.1] ### Added @@ -1266,7 +1266,7 @@ - HttpRequest::url_for is broken with nested scopes #915 -## [1.0.0] - 2019-06-05 +## [1.0.0] ### Added @@ -1288,7 +1288,7 @@ - Clear http requests pool on app service drop #860 -## [1.0.0-rc] - 2019-05-18 +## [1.0.0-rc] ### Added @@ -1303,7 +1303,7 @@ - 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] ### Added @@ -1314,7 +1314,7 @@ - `App::configure` take an `FnOnce` instead of `Fn` - Upgrade actix-net crates -## [1.0.0-beta.3] - 2019-05-04 +## [1.0.0-beta.3] ### Added @@ -1338,7 +1338,7 @@ - `App::data_factory()` is deleted. -## [1.0.0-beta.2] - 2019-04-24 +## [1.0.0-beta.2] ### Added @@ -1360,7 +1360,7 @@ - Fix async web::Data factory handling -## [1.0.0-beta.1] - 2019-04-20 +## [1.0.0-beta.1] ### Added @@ -1384,7 +1384,7 @@ - Fixed `TestRequest::app_data()` -## [1.0.0-alpha.6] - 2019-04-14 +## [1.0.0-alpha.6] ### Changed @@ -1396,7 +1396,7 @@ - Make extractor config type explicit. Add `FromRequest::Config` associated type. -## [1.0.0-alpha.5] - 2019-04-12 +## [1.0.0-alpha.5] ### Added @@ -1406,7 +1406,7 @@ - Removed native-tls support -## [1.0.0-alpha.4] - 2019-04-08 +## [1.0.0-alpha.4] ### Added @@ -1428,7 +1428,7 @@ - Fix body propagation in Response::from_error. #760 -## [1.0.0-alpha.3] - 2019-04-02 +## [1.0.0-alpha.3] ### Changed @@ -1442,7 +1442,7 @@ - Removed unused `actix_web::web::md()` -## [1.0.0-alpha.2] - 2019-03-29 +## [1.0.0-alpha.2] ### Added @@ -1454,7 +1454,7 @@ - Multipart::Field renamed to MultipartField -## [1.0.0-alpha.1] - 2019-03-28 +## [1.0.0-alpha.1] ### Changed diff --git a/awc/CHANGES.md b/awc/CHANGES.md index c998cd97a..606199131 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -1,24 +1,24 @@ # Changes -## Unreleased - 2023-xx-xx +## Unreleased - Add `awc::Connector::rustls_021()` method for Rustls v0.21 support behind new `rustls-0_21` crate feature. - Add `rustls-0_20` crate feature, which the existing `rustls` feature now aliases. - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. -## 3.1.1 - 2023-02-26 +## 3.1.1 ### Changed - `client::Connect` is now public to allow tunneling connection with `client::Connector`. -## 3.1.0 - 2023-01-21 +## 3.1.0 ### Changed - Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency. -## 3.0.1 - 2022-08-25 +## 3.0.1 ### Changed @@ -30,7 +30,7 @@ [#2840]: https://github.com/actix/actix-web/pull/2840 -## 3.0.0 - 2022-03-07 +## 3.0.0 ### Dependencies @@ -132,23 +132,23 @@
3.0.0 Pre-Releases -## 3.0.0-beta.21 - 2022-02-16 +## 3.0.0-beta.21 - No significant changes since `3.0.0-beta.20`. -## 3.0.0-beta.20 - 2022-01-31 +## 3.0.0-beta.20 - No significant changes since `3.0.0-beta.19`. -## 3.0.0-beta.19 - 2022-01-21 +## 3.0.0-beta.19 - No significant changes since `3.0.0-beta.18`. -## 3.0.0-beta.18 - 2022-01-04 +## 3.0.0-beta.18 - Minimum supported Rust version (MSRV) is now 1.54. -## 3.0.0-beta.17 - 2021-12-29 +## 3.0.0-beta.17 ### Changed @@ -161,7 +161,7 @@ [#2555]: https://github.com/actix/actix-web/pull/2555 [`rustsec-2020-0071`]: https://rustsec.org/advisories/RUSTSEC-2020-0071.html -## 3.0.0-beta.16 - 2021-12-29 +## 3.0.0-beta.16 - `*::send_json` and `*::send_form` methods now receive `impl Serialize`. [#2553] - `FrozenClientRequest::extra_header` now uses receives an `impl TryIntoHeaderPair`. [#2553] @@ -169,7 +169,7 @@ [#2553]: https://github.com/actix/actix-web/pull/2553 -## 3.0.0-beta.15 - 2021-12-27 +## 3.0.0-beta.15 - Rename `Connector::{ssl => openssl}`. [#2503] - Improve `Client` instantiation efficiency when using `openssl` by only building connectors once. [#2503] @@ -182,37 +182,37 @@ [#2503]: https://github.com/actix/actix-web/pull/2503 [#2546]: https://github.com/actix/actix-web/pull/2546 -## 3.0.0-beta.14 - 2021-12-17 +## 3.0.0-beta.14 - Add `ClientBuilder::add_default_header` and deprecate `ClientBuilder::header`. [#2510] [#2510]: https://github.com/actix/actix-web/pull/2510 -## 3.0.0-beta.13 - 2021-12-11 +## 3.0.0-beta.13 - No significant changes since `3.0.0-beta.12`. -## 3.0.0-beta.12 - 2021-11-30 +## 3.0.0-beta.12 - Update `actix-tls` to `3.0.0-rc.1`. [#2474] [#2474]: https://github.com/actix/actix-web/pull/2474 -## 3.0.0-beta.11 - 2021-11-22 +## 3.0.0-beta.11 - No significant changes from `3.0.0-beta.10`. -## 3.0.0-beta.10 - 2021-11-15 +## 3.0.0-beta.10 - No significant changes from `3.0.0-beta.9`. -## 3.0.0-beta.9 - 2021-10-20 +## 3.0.0-beta.9 - Updated rustls to v0.20. [#2414] [#2414]: https://github.com/actix/actix-web/pull/2414 -## 3.0.0-beta.8 - 2021-09-09 +## 3.0.0-beta.8 ### Changed @@ -220,7 +220,7 @@ [#2310]: https://github.com/actix/actix-web/pull/2310 -## 3.0.0-beta.7 - 2021-06-26 +## 3.0.0-beta.7 ### Changed @@ -228,11 +228,11 @@ [#2250]: https://github.com/actix/actix-web/pull/2250 -## 3.0.0-beta.6 - 2021-06-17 +## 3.0.0-beta.6 - No significant changes since 3.0.0-beta.5. -## 3.0.0-beta.5 - 2021-04-17 +## 3.0.0-beta.5 ### Removed @@ -240,7 +240,7 @@ [#2148]: https://github.com/actix/actix-web/pull/2148 -## 3.0.0-beta.4 - 2021-04-02 +## 3.0.0-beta.4 ### Added @@ -257,7 +257,7 @@ [#2114]: https://github.com/actix/actix-web/pull/2114 [#2116]: https://github.com/actix/actix-web/pull/2116 -## 3.0.0-beta.3 - 2021-03-08 +## 3.0.0-beta.3 ### Added @@ -280,7 +280,7 @@ [#2024]: https://github.com/actix/actix-web/pull/2024 [#2050]: https://github.com/actix/actix-web/pull/2050 -## 3.0.0-beta.2 - 2021-02-10 +## 3.0.0-beta.2 ### Added @@ -303,7 +303,7 @@ [#1905]: https://github.com/actix/actix-web/pull/1905 [#1969]: https://github.com/actix/actix-web/pull/1969 -## 3.0.0-beta.1 - 2021-01-07 +## 3.0.0-beta.1 ### Changed @@ -315,13 +315,13 @@
-## 2.0.3 - 2020-11-29 +## 2.0.3 ### Fixed - Ensure `actix-http` dependency uses same `serde_urlencoded`. -## 2.0.2 - 2020-11-25 +## 2.0.2 ### Changed @@ -329,7 +329,7 @@ [#1773]: https://github.com/actix/actix-web/pull/1773 -## 2.0.1 - 2020-10-30 +## 2.0.1 ### Changed @@ -344,37 +344,37 @@ [#1760]: https://github.com/actix/actix-web/pull/1760 [#1744]: https://github.com/actix/actix-web/pull/1744 -## 2.0.0 - 2020-09-11 +## 2.0.0 ### Changed - `Client::build` was renamed to `Client::builder`. -## 2.0.0-beta.4 - 2020-09-09 +## 2.0.0-beta.4 ### Changed - Update actix-codec & actix-tls dependencies. -## 2.0.0-beta.3 - 2020-08-17 +## 2.0.0-beta.3 ### Changed - Update `rustls` to 0.18 -## 2.0.0-beta.2 - 2020-07-21 +## 2.0.0-beta.2 ### Changed - Update `actix-http` dependency to 2.0.0-beta.2 -## [2.0.0-beta.1] - 2020-07-14 +## [2.0.0-beta.1] ### Changed - Update `actix-http` dependency to 2.0.0-beta.1 -## [2.0.0-alpha.2] - 2020-05-21 +## [2.0.0-alpha.2] ### Changed @@ -384,18 +384,18 @@ [#1422]: https://github.com/actix/actix-web/pull/1422 -## [2.0.0-alpha.1] - 2020-03-11 +## [2.0.0-alpha.1] - Update `actix-http` dependency to 2.0.0-alpha.2 - Update `rustls` dependency to 0.17 - ClientBuilder accepts initial_window_size and initial_connection_window_size HTTP2 configuration - ClientBuilder allowing to set max_http_version to limit HTTP version to be used -## [1.0.1] - 2019-12-15 +## [1.0.1] - Fix compilation with default features off -## [1.0.0] - 2019-12-13 +## [1.0.0] - Release @@ -403,23 +403,23 @@ - Migrate to `std::future` -## [0.2.8] - 2019-11-06 +## [0.2.8] - Add support for setting query from Serialize type for client request. -## [0.2.7] - 2019-09-25 +## [0.2.7] ### Added - Remaining getter methods for `ClientRequest`'s private `head` field #1101 -## [0.2.6] - 2019-09-12 +## [0.2.6] ### Added - Export frozen request related types. -## [0.2.5] - 2019-09-11 +## [0.2.5] ### Added @@ -429,7 +429,7 @@ - Ensure that the `Host` header is set when initiating a WebSocket client connection. -## [0.2.4] - 2019-08-13 +## [0.2.4] ### Changed @@ -437,13 +437,13 @@ - Update serde_urlencoded to "0.6.1" -## [0.2.3] - 2019-08-01 +## [0.2.3] ### Added - Add `rustls` support -## [0.2.2] - 2019-07-01 +## [0.2.2] ### Changed @@ -451,13 +451,13 @@ - Upgrade `rand` dependency version to 0.7 -## [0.2.1] - 2019-06-05 +## [0.2.1] ### Added - Add license files -## [0.2.0] - 2019-05-12 +## [0.2.0] ### Added @@ -467,7 +467,7 @@ - Upgrade actix-http dependency. -## [0.1.1] - 2019-04-19 +## [0.1.1] ### Added @@ -477,17 +477,17 @@ - `ClientRequest::if_true()` and `ClientRequest::if_some()` use instance instead of ref -## [0.1.0] - 2019-04-16 +## [0.1.0] - No changes -## [0.1.0-alpha.6] - 2019-04-14 +## [0.1.0-alpha.6] ### Changed - Do not set default headers for websocket request -## [0.1.0-alpha.5] - 2019-04-12 +## [0.1.0-alpha.5] ### Changed @@ -497,13 +497,13 @@ - Add Debug impl for BoxedSocket -## [0.1.0-alpha.4] - 2019-04-08 +## [0.1.0-alpha.4] ### Changed - Update actix-http dependency -## [0.1.0-alpha.3] - 2019-04-02 +## [0.1.0-alpha.3] ### Added @@ -519,7 +519,7 @@ - Renamed `ClientRequest::close_connection()` to `ClientRequest::force_close()` -## [0.1.0-alpha.2] - 2019-03-29 +## [0.1.0-alpha.2] ### Added @@ -537,6 +537,6 @@ - Export `ws` sub-module with websockets related types -## [0.1.0-alpha.1] - 2019-03-28 +## [0.1.0-alpha.1] - Initial impl From 84eb8b306c8be989339b513600a5c09838cd97ec Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 28 Aug 2023 23:46:02 +0100 Subject: [PATCH 41/57] chore: remove broken links from changelogs --- actix-multipart/CHANGES.md | 20 ++++++------- actix-web-actors/CHANGES.md | 24 +++++++-------- actix-web/CHANGES.md | 60 ++++++++++++++++++------------------- awc/CHANGES.md | 46 ++++++++++++++-------------- 4 files changed, 75 insertions(+), 75 deletions(-) diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index dc4cb8373..e5a746e8c 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -106,45 +106,45 @@ - Remove the unused `time` dependency - Fix missing `std::error::Error` implement for `MultipartError`. -## [0.2.0] +## 0.2.0 - Release -## [0.2.0-alpha.4] +## 0.2.0-alpha.4 - Multipart handling now handles Pending during read of boundary #1205 -## [0.2.0-alpha.2] +## 0.2.0-alpha.2 - Migrate to `std::future` -## [0.1.4] +## 0.1.4 - Multipart handling now parses requests which do not end in CRLF #1038 -## [0.1.3] +## 0.1.3 - Fix ring dependency from actix-web default features for #741. -## [0.1.2] +## 0.1.2 - Fix boundary parsing #876 -## [0.1.1] +## 0.1.1 - Fix disconnect handling #834 -## [0.1.0] +## 0.1.0 - Release -## [0.1.0-beta.4] +## 0.1.0-beta.4 - Handle cancellation of uploads #736 - Upgrade to actix-web 1.0.0-beta.4 -## [0.1.0-beta.1] +## 0.1.0-beta.1 - Do not support nested multipart diff --git a/actix-web-actors/CHANGES.md b/actix-web-actors/CHANGES.md index 563bc210f..5c516db56 100644 --- a/actix-web-actors/CHANGES.md +++ b/actix-web-actors/CHANGES.md @@ -85,55 +85,55 @@ - Update `actix-*` dependencies to latest versions. -## [3.0.0-beta.1] +## 3.0.0-beta.1 - Update `actix-web` & `actix-http` dependencies to beta.1 - Bump minimum supported Rust version to 1.40 -## [3.0.0-alpha.1] +## 3.0.0-alpha.1 - Update the actix-web dependency to 3.0.0-alpha.1 - Update the actix dependency to 0.10.0-alpha.2 - Update the actix-http dependency to 2.0.0-alpha.3 -## [2.0.0] +## 2.0.0 - Release -## [2.0.0-alpha.1] +## 2.0.0-alpha.1 - Migrate to actix-web 2.0.0 -## [1.0.4] +## 1.0.4 - Allow comma-separated websocket subprotocols without spaces (#1172) -## [1.0.3] +## 1.0.3 - Update actix-web and actix-http dependencies -## [1.0.2] +## 1.0.2 - Add `ws::start_with_addr()`, returning the address of the created actor, along with the `HttpResponse`. - Add support for specifying protocols on websocket handshake #835 -## [1.0.1] +## 1.0.1 - Allow to use custom ws codec with `WebsocketContext` #925 -## [1.0.0] +## 1.0.0 - Update actix-http and actix-web -## [0.1.0-alpha.3] +## 0.1.0-alpha.3 - Update actix-http and actix-web -## [0.1.0-alpha.2] +## 0.1.0-alpha.2 - Update actix-http and actix-web -## [0.1.0-alpha.1] +## 0.1.0-alpha.1 - Initial impl diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 289f8698f..dcf6279fb 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -1053,7 +1053,7 @@ [#1485]: https://github.com/actix/actix-web/pull/1485 [#1509]: https://github.com/actix/actix-web/pull/1509 -## [3.0.0-alpha.2] +## 3.0.0-alpha.2 ### Changed @@ -1067,7 +1067,7 @@ [#1452]: https://github.com/actix/actix-web/pull/1452 [#1486]: https://github.com/actix/actix-web/pull/1486 -## [3.0.0-alpha.1] +## 3.0.0-alpha.1 ### Added @@ -1084,7 +1084,7 @@ [#1308]: https://github.com/actix/actix-web/pull/1308 -## [2.0.0] +## 2.0.0 ### Changed @@ -1094,7 +1094,7 @@ - Allow to specify multi-patterns for resources -## [2.0.0-rc] +## 2.0.0-rc ### Changed @@ -1112,31 +1112,31 @@ - Fix `AppConfig::secure()` is always false. #1202 -## [2.0.0-alpha.6] +## 2.0.0-alpha.6 ### Fixed - Fixed compilation with default features off -## [2.0.0-alpha.5] +## 2.0.0-alpha.5 ### Added - Add test server, `test::start()` and `test::start_with()` -## [2.0.0-alpha.4] +## 2.0.0-alpha.4 ### Deleted - Delete HttpServer::run(), it is not useful with async/await -## [2.0.0-alpha.3] +## 2.0.0-alpha.3 ### Changed - Migrate to tokio 0.2 -## [2.0.0-alpha.1] +## 2.0.0-alpha.1 ### Changed @@ -1144,7 +1144,7 @@ - Remove implementation of `Responder` for `()`. (#1167) -## [1.0.9] +## 1.0.9 ### Added @@ -1154,7 +1154,7 @@ - Support `Host` guards when the `Host` header is unset (e.g. HTTP/2 requests) (#1129) -## [1.0.8] +## 1.0.8 ### Added @@ -1172,13 +1172,13 @@ - Use actix-testing for testing utils -## [1.0.7] +## 1.0.7 ### Fixed - Request Extensions leak #1062 -## [1.0.6] +## 1.0.6 ### Added @@ -1200,7 +1200,7 @@ - Update url to 2.1 -## [1.0.5] +## 1.0.5 ### Added @@ -1212,7 +1212,7 @@ - Restored logging of errors through the `Logger` middleware -## [1.0.4] +## 1.0.4 ### Added @@ -1224,7 +1224,7 @@ - Upgrade `rand` dependency version to 0.7 -## [1.0.3] +## 1.0.3 ### Added @@ -1234,7 +1234,7 @@ - Use `encoding_rs` crate instead of unmaintained `encoding` crate -## [1.0.2] +## 1.0.2 ### Changed @@ -1242,7 +1242,7 @@ - Move identity middleware to `actix-identity` crate. -## [1.0.1] +## 1.0.1 ### Added @@ -1266,7 +1266,7 @@ - HttpRequest::url_for is broken with nested scopes #915 -## [1.0.0] +## 1.0.0 ### Added @@ -1288,7 +1288,7 @@ - Clear http requests pool on app service drop #860 -## [1.0.0-rc] +## 1.0.0-rc ### Added @@ -1303,7 +1303,7 @@ - Codegen with parameters in the path only resolves the first registered endpoint #841 -## [1.0.0-beta.4] +## 1.0.0-beta.4 ### Added @@ -1314,7 +1314,7 @@ - `App::configure` take an `FnOnce` instead of `Fn` - Upgrade actix-net crates -## [1.0.0-beta.3] +## 1.0.0-beta.3 ### Added @@ -1338,7 +1338,7 @@ - `App::data_factory()` is deleted. -## [1.0.0-beta.2] +## 1.0.0-beta.2 ### Added @@ -1360,7 +1360,7 @@ - Fix async web::Data factory handling -## [1.0.0-beta.1] +## 1.0.0-beta.1 ### Added @@ -1384,7 +1384,7 @@ - Fixed `TestRequest::app_data()` -## [1.0.0-alpha.6] +## 1.0.0-alpha.6 ### Changed @@ -1396,7 +1396,7 @@ - Make extractor config type explicit. Add `FromRequest::Config` associated type. -## [1.0.0-alpha.5] +## 1.0.0-alpha.5 ### Added @@ -1406,7 +1406,7 @@ - Removed native-tls support -## [1.0.0-alpha.4] +## 1.0.0-alpha.4 ### Added @@ -1428,7 +1428,7 @@ - Fix body propagation in Response::from_error. #760 -## [1.0.0-alpha.3] +## 1.0.0-alpha.3 ### Changed @@ -1442,7 +1442,7 @@ - Removed unused `actix_web::web::md()` -## [1.0.0-alpha.2] +## 1.0.0-alpha.2 ### Added @@ -1454,7 +1454,7 @@ - Multipart::Field renamed to MultipartField -## [1.0.0-alpha.1] +## 1.0.0-alpha.1 ### Changed diff --git a/awc/CHANGES.md b/awc/CHANGES.md index 606199131..8b1248733 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -368,13 +368,13 @@ - Update `actix-http` dependency to 2.0.0-beta.2 -## [2.0.0-beta.1] +## 2.0.0-beta.1 ### Changed - Update `actix-http` dependency to 2.0.0-beta.1 -## [2.0.0-alpha.2] +## 2.0.0-alpha.2 ### Changed @@ -384,42 +384,42 @@ [#1422]: https://github.com/actix/actix-web/pull/1422 -## [2.0.0-alpha.1] +## 2.0.0-alpha.1 - Update `actix-http` dependency to 2.0.0-alpha.2 - Update `rustls` dependency to 0.17 - ClientBuilder accepts initial_window_size and initial_connection_window_size HTTP2 configuration - ClientBuilder allowing to set max_http_version to limit HTTP version to be used -## [1.0.1] +## 1.0.1 - Fix compilation with default features off -## [1.0.0] +## 1.0.0 - Release -## [1.0.0-alpha.3] +## 1.0.0-alpha.3 - Migrate to `std::future` -## [0.2.8] +## 0.2.8 - Add support for setting query from Serialize type for client request. -## [0.2.7] +## 0.2.7 ### Added - Remaining getter methods for `ClientRequest`'s private `head` field #1101 -## [0.2.6] +## 0.2.6 ### Added - Export frozen request related types. -## [0.2.5] +## 0.2.5 ### Added @@ -429,7 +429,7 @@ - Ensure that the `Host` header is set when initiating a WebSocket client connection. -## [0.2.4] +## 0.2.4 ### Changed @@ -437,13 +437,13 @@ - Update serde_urlencoded to "0.6.1" -## [0.2.3] +## 0.2.3 ### Added - Add `rustls` support -## [0.2.2] +## 0.2.2 ### Changed @@ -451,13 +451,13 @@ - Upgrade `rand` dependency version to 0.7 -## [0.2.1] +## 0.2.1 ### Added - Add license files -## [0.2.0] +## 0.2.0 ### Added @@ -467,7 +467,7 @@ - Upgrade actix-http dependency. -## [0.1.1] +## 0.1.1 ### Added @@ -477,17 +477,17 @@ - `ClientRequest::if_true()` and `ClientRequest::if_some()` use instance instead of ref -## [0.1.0] +## 0.1.0 - No changes -## [0.1.0-alpha.6] +## 0.1.0-alpha.6 ### Changed - Do not set default headers for websocket request -## [0.1.0-alpha.5] +## 0.1.0-alpha.5 ### Changed @@ -497,13 +497,13 @@ - Add Debug impl for BoxedSocket -## [0.1.0-alpha.4] +## 0.1.0-alpha.4 ### Changed - Update actix-http dependency -## [0.1.0-alpha.3] +## 0.1.0-alpha.3 ### Added @@ -519,7 +519,7 @@ - Renamed `ClientRequest::close_connection()` to `ClientRequest::force_close()` -## [0.1.0-alpha.2] +## 0.1.0-alpha.2 ### Added @@ -537,6 +537,6 @@ - Export `ws` sub-module with websockets related types -## [0.1.0-alpha.1] +## 0.1.0-alpha.1 - Initial impl From ac95362340c195b60639e48a610e9d7f3677ba18 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 29 Aug 2023 01:14:54 +0100 Subject: [PATCH 42/57] refactor: simplify connector feature combos --- .github/workflows/ci-post-merge.yml | 2 +- awc/src/client/connector.rs | 25 +------------------------ 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 5460eeec4..a34dd27ba 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -58,7 +58,7 @@ jobs: run: | cargo test --lib --tests -p=actix-router --all-features cargo test --lib --tests -p=actix-http --all-features - cargo test --lib --tests -p=actix-web --features=rustls,openssl -- --skip=test_reading_deflate_encoding_large_random_rustls + cargo test --lib --tests -p=actix-web --features=rustls-0_20,rustls-0_21,openssl -- --skip=test_reading_deflate_encoding_large_random_rustls cargo test --lib --tests -p=actix-web-codegen --all-features cargo test --lib --tests -p=awc --all-features cargo test --lib --tests -p=actix-http-test --all-features diff --git a/awc/src/client/connector.rs b/awc/src/client/connector.rs index 538b64ffd..1a8715bf9 100644 --- a/awc/src/client/connector.rs +++ b/awc/src/client/connector.rs @@ -109,33 +109,10 @@ impl Connector<()> { OurTlsConnector::Rustls021(std::sync::Arc::new(config)) } - /// Build TLS connector with Rustls v0.21, based on supplied ALPN protocols - /// - /// Note that if other TLS crate features are enabled, Rustls v0.21 will be used. - #[cfg(all( - all(feature = "rustls-0_20", feature = "openssl"), - not(feature = "rustls-0_21"), - ))] - fn build_tls(protocols: Vec>) -> OurTlsConnector { - use actix_tls::connect::rustls_0_20::{reexports::ClientConfig, webpki_roots_cert_store}; - - let mut config = ClientConfig::builder() - .with_safe_defaults() - .with_root_certificates(webpki_roots_cert_store()) - .with_no_client_auth(); - - config.alpn_protocols = protocols; - - OurTlsConnector::Rustls020(std::sync::Arc::new(config)) - } - /// Build TLS connector with Rustls v0.20, based on supplied ALPN protocols /// /// Note that if other TLS crate features are enabled, Rustls v0.21 will be used. - #[cfg(all( - feature = "rustls-0_20", - not(any(feature = "rustls-0_21", feature = "openssl")), - ))] + #[cfg(all(feature = "rustls-0_20", not(feature = "rustls-0_21")))] fn build_tls(protocols: Vec>) -> OurTlsConnector { use actix_tls::connect::rustls_0_20::{reexports::ClientConfig, webpki_roots_cert_store}; From 4ed61466e79776ca4e4b7df3b8365dcc023f45ff Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 29 Aug 2023 01:17:32 +0100 Subject: [PATCH 43/57] chore(actix-multipart-derive): prepare release 0.6.1 --- actix-multipart-derive/CHANGES.md | 2 ++ actix-multipart-derive/Cargo.toml | 2 +- actix-multipart/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/actix-multipart-derive/CHANGES.md b/actix-multipart-derive/CHANGES.md index 04f31e0f3..e36a13d04 100644 --- a/actix-multipart-derive/CHANGES.md +++ b/actix-multipart-derive/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.6.1 + - Update `syn` dependency to `2`. - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. diff --git a/actix-multipart-derive/Cargo.toml b/actix-multipart-derive/Cargo.toml index 41e687e50..75b4c723b 100644 --- a/actix-multipart-derive/Cargo.toml +++ b/actix-multipart-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-multipart-derive" -version = "0.6.0" +version = "0.6.1" authors = ["Jacob Halsey "] description = "Multipart form derive macro for Actix Web" keywords = ["http", "web", "framework", "async", "futures"] diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index 9220e793c..31c792fc0 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -22,7 +22,7 @@ derive = ["actix-multipart-derive"] tempfile = ["dep:tempfile", "tokio/fs"] [dependencies] -actix-multipart-derive = { version = "=0.6.0", optional = true } +actix-multipart-derive = { version = "=0.6.1", optional = true } actix-utils = "3" actix-web = { version = "4", default-features = false } From b422745b6c2fa8c8b68da501c112bf1bd0420d1e Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 29 Aug 2023 01:18:37 +0100 Subject: [PATCH 44/57] chore(actix-multipart): prepare release 0.6.1 --- actix-multipart/CHANGES.md | 2 ++ actix-multipart/Cargo.toml | 2 +- actix-multipart/README.md | 4 ++-- scripts/bump | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index e5a746e8c..50faf7cfa 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.6.1 + - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. ## 0.6.0 diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index 31c792fc0..455d7db78 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-multipart" -version = "0.6.0" +version = "0.6.1" authors = [ "Nikolay Kim ", "Jacob Halsey ", diff --git a/actix-multipart/README.md b/actix-multipart/README.md index 66550668d..8fe0328ab 100644 --- a/actix-multipart/README.md +++ b/actix-multipart/README.md @@ -3,11 +3,11 @@ > Multipart form support for Actix Web. [![crates.io](https://img.shields.io/crates/v/actix-multipart?label=latest)](https://crates.io/crates/actix-multipart) -[![Documentation](https://docs.rs/actix-multipart/badge.svg?version=0.6.0)](https://docs.rs/actix-multipart/0.6.0) +[![Documentation](https://docs.rs/actix-multipart/badge.svg?version=0.6.1)](https://docs.rs/actix-multipart/0.6.1) ![Version](https://img.shields.io/badge/rustc-1.68+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-multipart.svg)
-[![dependency status](https://deps.rs/crate/actix-multipart/0.6.0/status.svg)](https://deps.rs/crate/actix-multipart/0.6.0) +[![dependency status](https://deps.rs/crate/actix-multipart/0.6.1/status.svg)](https://deps.rs/crate/actix-multipart/0.6.1) [![Download](https://img.shields.io/crates/d/actix-multipart.svg)](https://crates.io/crates/actix-multipart) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) diff --git a/scripts/bump b/scripts/bump index b09d9d196..baf3fb4d8 100755 --- a/scripts/bump +++ b/scripts/bump @@ -128,11 +128,11 @@ if [ "$UPDATE_REFERENCES" = 'y' ] || [ "$UPDATE_REFERENCES" = 'Y' ]; then fi if [ $MACOS ]; then - printf "prepare $PACKAGE_NAME release $NEW_VERSION" | pbcopy + printf "chore($PACKAGE_NAME): prepare release $NEW_VERSION" | pbcopy else echo echo "commit message:" - echo "prepare $PACKAGE_NAME release $NEW_VERSION" + echo "chore($PACKAGE_NAME): prepare release $NEW_VERSION" fi SHORT_PACKAGE_NAME="$(echo $PACKAGE_NAME | sed 's/^actix-web-//' | sed 's/^actix-//')" From a12d39c93edc83d32fb62a53b14c4422e1b4774d Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 29 Aug 2023 01:19:56 +0100 Subject: [PATCH 45/57] chore(actix-web-codegen): prepare release 4.2.1 --- actix-web-codegen/CHANGES.md | 2 ++ actix-web-codegen/Cargo.toml | 2 +- actix-web-codegen/README.md | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/actix-web-codegen/CHANGES.md b/actix-web-codegen/CHANGES.md index 4b3205d7c..d5a3f5d31 100644 --- a/actix-web-codegen/CHANGES.md +++ b/actix-web-codegen/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.2.1 + - Update `syn` dependency to `2`. - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. diff --git a/actix-web-codegen/Cargo.toml b/actix-web-codegen/Cargo.toml index c202c5d6e..0eee5004a 100644 --- a/actix-web-codegen/Cargo.toml +++ b/actix-web-codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-web-codegen" -version = "4.2.0" +version = "4.2.1" description = "Routing and runtime macros for Actix Web" homepage = "https://actix.rs" repository = "https://github.com/actix/actix-web.git" diff --git a/actix-web-codegen/README.md b/actix-web-codegen/README.md index e6df8164e..a53159e03 100644 --- a/actix-web-codegen/README.md +++ b/actix-web-codegen/README.md @@ -3,11 +3,11 @@ > Routing and runtime macros for Actix Web. [![crates.io](https://img.shields.io/crates/v/actix-web-codegen?label=latest)](https://crates.io/crates/actix-web-codegen) -[![Documentation](https://docs.rs/actix-web-codegen/badge.svg?version=4.2.0)](https://docs.rs/actix-web-codegen/4.2.0) +[![Documentation](https://docs.rs/actix-web-codegen/badge.svg?version=4.2.1)](https://docs.rs/actix-web-codegen/4.2.1) ![Version](https://img.shields.io/badge/rustc-1.68+-ab6000.svg) ![License](https://img.shields.io/crates/l/actix-web-codegen.svg)
-[![dependency status](https://deps.rs/crate/actix-web-codegen/4.2.0/status.svg)](https://deps.rs/crate/actix-web-codegen/4.2.0) +[![dependency status](https://deps.rs/crate/actix-web-codegen/4.2.1/status.svg)](https://deps.rs/crate/actix-web-codegen/4.2.1) [![Download](https://img.shields.io/crates/d/actix-web-codegen.svg)](https://crates.io/crates/actix-web-codegen) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) From 45fdc08788b8c0294e399f856027066476e6e4f9 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 29 Aug 2023 01:51:54 +0100 Subject: [PATCH 46/57] chore(actix-http): prepare release 3.4.0 --- actix-http/CHANGES.md | 4 +++- actix-http/Cargo.toml | 2 +- actix-http/README.md | 4 ++-- actix-web/Cargo.toml | 2 +- awc/Cargo.toml | 4 ++-- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 5252f3fbf..f3720b784 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -2,10 +2,12 @@ ## Unreleased +## 3.4.0 + ### Added - Add `rustls-0_20` crate feature. -- Add `{H1Service, H2Service, HttpService}::rustls_021()` and `HttpService::rustls_021_with_config()` service constructors. +- Add `{h1::H1Service, h2::H2Service, HttpService}::rustls_021()` and `HttpService::rustls_021_with_config()` service constructors. - Add `body::to_body_limit()` function. - Add `body::BodyLimitExceeded` error type. diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 6aaaecfd4..c19ce0161 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-http" -version = "3.3.1" +version = "3.4.0" authors = [ "Nikolay Kim ", "Rob Ede ", diff --git a/actix-http/README.md b/actix-http/README.md index ce2e5cb32..049de9278 100644 --- a/actix-http/README.md +++ b/actix-http/README.md @@ -3,11 +3,11 @@ > HTTP primitives for the Actix ecosystem. [![crates.io](https://img.shields.io/crates/v/actix-http?label=latest)](https://crates.io/crates/actix-http) -[![Documentation](https://docs.rs/actix-http/badge.svg?version=3.3.1)](https://docs.rs/actix-http/3.3.1) +[![Documentation](https://docs.rs/actix-http/badge.svg?version=3.4.0)](https://docs.rs/actix-http/3.4.0) ![Version](https://img.shields.io/badge/rustc-1.68+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-http.svg)
-[![dependency status](https://deps.rs/crate/actix-http/3.3.1/status.svg)](https://deps.rs/crate/actix-http/3.3.1) +[![dependency status](https://deps.rs/crate/actix-http/3.4.0/status.svg)](https://deps.rs/crate/actix-http/3.4.0) [![Download](https://img.shields.io/crates/d/actix-http.svg)](https://crates.io/crates/actix-http) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index e85a0c90e..8221aaa90 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -75,7 +75,7 @@ actix-service = "2" actix-utils = "3" actix-tls = { version = "3.1", default-features = false, optional = true } -actix-http = { version = "3.3", features = ["ws"] } +actix-http = { version = "3.4", features = ["ws"] } actix-router = "0.5" actix-web-codegen = { version = "4.2", optional = true } diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 67d6b06f5..a0f933b40 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -61,7 +61,7 @@ dangerous-h2c = [] [dependencies] actix-codec = "0.5" actix-service = "2" -actix-http = { version = "3.3", features = ["http2", "ws"] } +actix-http = { version = "3.4", features = ["http2", "ws"] } actix-rt = { version = "2.1", default-features = false } actix-tls = { version = "3.1", features = ["connect", "uri"] } actix-utils = "3" @@ -94,7 +94,7 @@ tls-rustls-0_21 = { package = "rustls", version = "0.21", optional = true, featu trust-dns-resolver = { version = "0.22", optional = true } [dev-dependencies] -actix-http = { version = "3", features = ["openssl"] } +actix-http = { version = "3.4", features = ["openssl"] } actix-http-test = { version = "3", features = ["openssl"] } actix-server = "2" actix-test = { version = "0.1", features = ["openssl", "rustls-0_21"] } From d2c0d472e97f0baaa0b2b734f99b32e0d4c43615 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 29 Aug 2023 01:53:14 +0100 Subject: [PATCH 47/57] chore(awc): prepare release 3.2.0 --- awc/CHANGES.md | 2 ++ awc/Cargo.toml | 2 +- awc/README.md | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/awc/CHANGES.md b/awc/CHANGES.md index 8b1248733..f649a37c8 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.2.0 + - Add `awc::Connector::rustls_021()` method for Rustls v0.21 support behind new `rustls-0_21` crate feature. - Add `rustls-0_20` crate feature, which the existing `rustls` feature now aliases. - Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency. diff --git a/awc/Cargo.toml b/awc/Cargo.toml index a0f933b40..22f87ae3e 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "awc" -version = "3.1.1" +version = "3.2.0" authors = ["Nikolay Kim "] description = "Async HTTP and WebSocket client library" keywords = ["actix", "http", "framework", "async", "web"] diff --git a/awc/README.md b/awc/README.md index f2a9c7559..1f31167eb 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=3.1.1)](https://docs.rs/awc/3.1.1) +[![Documentation](https://docs.rs/awc/badge.svg?version=3.2.0)](https://docs.rs/awc/3.2.0) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/awc) -[![Dependency Status](https://deps.rs/crate/awc/3.1.1/status.svg)](https://deps.rs/crate/awc/3.1.1) +[![Dependency Status](https://deps.rs/crate/awc/3.2.0/status.svg)](https://deps.rs/crate/awc/3.2.0) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) ## Documentation & Resources From 2b40033a9cd3c8dbc813bc6ee4a385a44236994d Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 29 Aug 2023 01:54:40 +0100 Subject: [PATCH 48/57] chore(actix-web): prepare release 4.4.0 --- actix-web/CHANGES.md | 2 ++ actix-web/Cargo.toml | 2 +- actix-web/README.md | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index dcf6279fb..6ed97b671 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.4.0 + ### Added - Add `HttpServer::{bind, listen}_auto_h2c()` methods behind new `http2` crate feature. diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index 8221aaa90..19ac6c8ae 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-web" -version = "4.3.1" +version = "4.4.0" authors = [ "Nikolay Kim ", "Rob Ede ", diff --git a/actix-web/README.md b/actix-web/README.md index 74b4924d4..e83397657 100644 --- a/actix-web/README.md +++ b/actix-web/README.md @@ -8,10 +8,10 @@ [![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=4.3.1)](https://docs.rs/actix-web/4.3.1) +[![Documentation](https://docs.rs/actix-web/badge.svg?version=4.4.0)](https://docs.rs/actix-web/4.4.0) ![MSRV](https://img.shields.io/badge/rustc-1.68+-ab6000.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-web.svg) -[![Dependency Status](https://deps.rs/crate/actix-web/4.3.1/status.svg)](https://deps.rs/crate/actix-web/4.3.1) +[![Dependency Status](https://deps.rs/crate/actix-web/4.4.0/status.svg)](https://deps.rs/crate/actix-web/4.4.0)
[![CI](https://github.com/actix/actix-web/actions/workflows/ci.yml/badge.svg)](https://github.com/actix/actix-web/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web) From e6636f1279510a8f0b1d62c2981288bb845f8ef5 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 29 Aug 2023 01:55:17 +0100 Subject: [PATCH 49/57] chore(actix-test): prepare release 0.1.2 --- actix-test/CHANGES.md | 2 ++ actix-test/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/actix-test/CHANGES.md b/actix-test/CHANGES.md index c33927fa4..a3ca7fe10 100644 --- a/actix-test/CHANGES.md +++ b/actix-test/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.1.2 + - Add `TestServerConfig::rustls_021()` method for Rustls v0.21 support behind new `rustls-0_21` crate feature. - Add `TestServerConfig::workers()` method. - Add `rustls-0_20` crate feature, which the existing `rustls` feature now aliases. diff --git a/actix-test/Cargo.toml b/actix-test/Cargo.toml index dd96084b3..38b40ccfa 100644 --- a/actix-test/Cargo.toml +++ b/actix-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-test" -version = "0.1.1" +version = "0.1.2" authors = [ "Nikolay Kim ", "Rob Ede ", From 39abe3ae5e318c11135bb36cfc29472a33e60af2 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 29 Aug 2023 01:57:19 +0100 Subject: [PATCH 50/57] docs: fix -http changelog --- actix-http/CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index f3720b784..860ee3b6c 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -8,7 +8,7 @@ - Add `rustls-0_20` crate feature. - Add `{h1::H1Service, h2::H2Service, HttpService}::rustls_021()` and `HttpService::rustls_021_with_config()` service constructors. -- Add `body::to_body_limit()` function. +- Add `body::to_bytes_limited()` function. - Add `body::BodyLimitExceeded` error type. ### Changed From 76f6106f8fe8b8d4827698d8132624080ae189aa Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 29 Aug 2023 21:27:36 +0100 Subject: [PATCH 51/57] fix: wrap attribute codegen regression when using expression (#3119) --- actix-web-codegen/CHANGES.md | 4 ++++ actix-web-codegen/Cargo.toml | 2 +- actix-web-codegen/README.md | 4 ++-- actix-web-codegen/src/route.rs | 16 ++++++++-------- actix-web-codegen/tests/test_macro.rs | 13 +++++++++++++ .../tests/trybuild/simple-fail.stderr | 2 +- 6 files changed, 29 insertions(+), 12 deletions(-) diff --git a/actix-web-codegen/CHANGES.md b/actix-web-codegen/CHANGES.md index d5a3f5d31..00e36b037 100644 --- a/actix-web-codegen/CHANGES.md +++ b/actix-web-codegen/CHANGES.md @@ -2,6 +2,10 @@ ## Unreleased +## 4.2.2 + +- Fix regression when declaring `wrap` attribute using an expression. + ## 4.2.1 - Update `syn` dependency to `2`. diff --git a/actix-web-codegen/Cargo.toml b/actix-web-codegen/Cargo.toml index 0eee5004a..748984b49 100644 --- a/actix-web-codegen/Cargo.toml +++ b/actix-web-codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-web-codegen" -version = "4.2.1" +version = "4.2.2" description = "Routing and runtime macros for Actix Web" homepage = "https://actix.rs" repository = "https://github.com/actix/actix-web.git" diff --git a/actix-web-codegen/README.md b/actix-web-codegen/README.md index a53159e03..e9a1f9c7e 100644 --- a/actix-web-codegen/README.md +++ b/actix-web-codegen/README.md @@ -3,11 +3,11 @@ > Routing and runtime macros for Actix Web. [![crates.io](https://img.shields.io/crates/v/actix-web-codegen?label=latest)](https://crates.io/crates/actix-web-codegen) -[![Documentation](https://docs.rs/actix-web-codegen/badge.svg?version=4.2.1)](https://docs.rs/actix-web-codegen/4.2.1) +[![Documentation](https://docs.rs/actix-web-codegen/badge.svg?version=4.2.2)](https://docs.rs/actix-web-codegen/4.2.2) ![Version](https://img.shields.io/badge/rustc-1.68+-ab6000.svg) ![License](https://img.shields.io/crates/l/actix-web-codegen.svg)
-[![dependency status](https://deps.rs/crate/actix-web-codegen/4.2.1/status.svg)](https://deps.rs/crate/actix-web-codegen/4.2.1) +[![dependency status](https://deps.rs/crate/actix-web-codegen/4.2.2/status.svg)](https://deps.rs/crate/actix-web-codegen/4.2.2) [![Download](https://img.shields.io/crates/d/actix-web-codegen.svg)](https://crates.io/crates/actix-web-codegen) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) diff --git a/actix-web-codegen/src/route.rs b/actix-web-codegen/src/route.rs index 525a1c8ba..7a2dfc051 100644 --- a/actix-web-codegen/src/route.rs +++ b/actix-web-codegen/src/route.rs @@ -224,7 +224,7 @@ struct Args { path: syn::LitStr, resource_name: Option, guards: Vec, - wrappers: Vec, + wrappers: Vec, methods: HashSet, } @@ -251,7 +251,7 @@ impl Args { } else { return Err(syn::Error::new_spanned( nv.value, - "Attribute name expects literal string!", + "Attribute name expects literal string", )); } } else if nv.path.is_ident("guard") { @@ -264,7 +264,7 @@ impl Args { } else { return Err(syn::Error::new_spanned( nv.value, - "Attribute guard expects literal string!", + "Attribute guard expects literal string", )); } } else if nv.path.is_ident("wrap") { @@ -283,9 +283,9 @@ impl Args { } else if nv.path.is_ident("method") { if !is_route_macro { return Err(syn::Error::new_spanned( - &nv, - "HTTP method forbidden here. To handle multiple methods, use `route` instead", - )); + &nv, + "HTTP method forbidden here; to handle multiple methods, use `route` instead", + )); } else if let syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Str(lit), .. @@ -300,13 +300,13 @@ impl Args { } else { return Err(syn::Error::new_spanned( nv.value, - "Attribute method expects literal string!", + "Attribute method expects literal string", )); } } else { return Err(syn::Error::new_spanned( nv.path, - "Unknown attribute key is specified. Allowed: guard, method and wrap", + "Unknown attribute key is specified; allowed: guard, method and wrap", )); } } diff --git a/actix-web-codegen/tests/test_macro.rs b/actix-web-codegen/tests/test_macro.rs index f28654cd9..fb50d4ae0 100644 --- a/actix-web-codegen/tests/test_macro.rs +++ b/actix-web-codegen/tests/test_macro.rs @@ -212,6 +212,19 @@ async fn get_wrap(_: web::Path) -> impl Responder { HttpResponse::Ok() } +/// Using expression, not just path to type, in wrap attribute. +/// +/// Regression from . +#[route( + "/catalog", + method = "GET", + method = "HEAD", + wrap = "actix_web::middleware::Compress::default()" +)] +async fn get_catalog() -> impl Responder { + HttpResponse::Ok().body("123123123") +} + #[actix_rt::test] async fn test_params() { let srv = actix_test::start(|| { diff --git a/actix-web-codegen/tests/trybuild/simple-fail.stderr b/actix-web-codegen/tests/trybuild/simple-fail.stderr index 3b3f9d850..ab81599ed 100644 --- a/actix-web-codegen/tests/trybuild/simple-fail.stderr +++ b/actix-web-codegen/tests/trybuild/simple-fail.stderr @@ -38,7 +38,7 @@ error: Multiple paths specified! There should be only one. | = note: this error originates in the attribute macro `delete` (in Nightly builds, run with -Z macro-backtrace for more info) -error: HTTP method forbidden here. To handle multiple methods, use `route` instead +error: HTTP method forbidden here; to handle multiple methods, use `route` instead --> $DIR/simple-fail.rs:25:19 | 25 | #[delete("/five", method="GET")] From d4457429741d46abad0b726fd884d7301691ada2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 3 Sep 2023 04:40:41 +0000 Subject: [PATCH 52/57] Update trust-dns-resolver requirement from 0.22 to 0.23 (#3121) * Update trust-dns-resolver requirement from 0.22 to 0.23 Updates the requirements on [trust-dns-resolver](https://github.com/bluejekyll/trust-dns) to permit the latest version. - [Release notes](https://github.com/bluejekyll/trust-dns/releases) - [Changelog](https://github.com/bluejekyll/trust-dns/blob/main/CHANGELOG.md) - [Commits](https://github.com/bluejekyll/trust-dns/compare/v0.22.0...v0.23.0) --- updated-dependencies: - dependency-name: trust-dns-resolver dependency-type: direct:production ... Signed-off-by: dependabot[bot] * fixup post-upgrade --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Rob Ede --- awc/CHANGES.md | 2 ++ awc/Cargo.toml | 2 +- awc/src/client/connector.rs | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/awc/CHANGES.md b/awc/CHANGES.md index f649a37c8..1032e196c 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +- Update `trust-dns-resolver` dependency to `0.23`. + ## 3.2.0 - Add `awc::Connector::rustls_021()` method for Rustls v0.21 support behind new `rustls-0_21` crate feature. diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 22f87ae3e..027bb161e 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -91,7 +91,7 @@ tls-openssl = { package = "openssl", version = "0.10.55", optional = true } tls-rustls-0_20 = { package = "rustls", version = "0.20", optional = true, features = ["dangerous_configuration"] } tls-rustls-0_21 = { package = "rustls", version = "0.21", optional = true, features = ["dangerous_configuration"] } -trust-dns-resolver = { version = "0.22", optional = true } +trust-dns-resolver = { version = "0.23", optional = true } [dev-dependencies] actix-http = { version = "3.4", features = ["openssl"] } diff --git a/awc/src/client/connector.rs b/awc/src/client/connector.rs index 1a8715bf9..de39e1a4a 100644 --- a/awc/src/client/connector.rs +++ b/awc/src/client/connector.rs @@ -915,7 +915,7 @@ mod resolver { } }; - let resolver = TokioAsyncResolver::tokio(cfg, opts).unwrap(); + let resolver = TokioAsyncResolver::tokio(cfg, opts); // box trust dns resolver and put it in thread local. let resolver = Resolver::custom(TrustDnsResolver(resolver)); From 215a52f56535a8ab104159c84d02461841d5d340 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 3 Sep 2023 19:09:42 +0100 Subject: [PATCH 53/57] chore: avoid single char error bindings --- actix-http/src/encoding/decoder.rs | 16 ++++++++-------- actix-http/src/h1/decoder.rs | 2 +- actix-http/src/responses/builder.rs | 6 +++--- actix-http/src/ws/codec.rs | 2 +- actix-http/tests/test_server.rs | 2 +- actix-web-actors/src/ws.rs | 4 ++-- actix-web/Cargo.toml | 2 +- actix-web/src/app.rs | 4 ++-- actix-web/src/extract.rs | 10 +++++----- actix-web/src/middleware/logger.rs | 2 +- actix-web/src/response/builder.rs | 6 +++--- actix-web/src/server.rs | 2 +- actix-web/src/types/header.rs | 6 +++--- awc/src/client/connector.rs | 4 ++-- awc/src/client/h1proto.rs | 2 +- awc/src/client/h2proto.rs | 18 +++++++++--------- awc/src/request.rs | 24 ++++++++++++------------ awc/src/sender.rs | 16 ++++++++-------- awc/src/ws.rs | 18 +++++++++--------- 19 files changed, 73 insertions(+), 73 deletions(-) diff --git a/actix-http/src/encoding/decoder.rs b/actix-http/src/encoding/decoder.rs index e9aba25e7..cda534d60 100644 --- a/actix-http/src/encoding/decoder.rs +++ b/actix-http/src/encoding/decoder.rs @@ -191,7 +191,7 @@ impl ContentDecoder { Ok(None) } } - Err(e) => Err(e), + Err(err) => Err(err), }, #[cfg(feature = "compress-gzip")] @@ -205,7 +205,7 @@ impl ContentDecoder { Ok(None) } } - Err(e) => Err(e), + Err(err) => Err(err), }, #[cfg(feature = "compress-gzip")] @@ -218,7 +218,7 @@ impl ContentDecoder { Ok(None) } } - Err(e) => Err(e), + Err(err) => Err(err), }, #[cfg(feature = "compress-zstd")] @@ -231,7 +231,7 @@ impl ContentDecoder { Ok(None) } } - Err(e) => Err(e), + Err(err) => Err(err), }, } } @@ -250,7 +250,7 @@ impl ContentDecoder { Ok(None) } } - Err(e) => Err(e), + Err(err) => Err(err), }, #[cfg(feature = "compress-gzip")] @@ -265,7 +265,7 @@ impl ContentDecoder { Ok(None) } } - Err(e) => Err(e), + Err(err) => Err(err), }, #[cfg(feature = "compress-gzip")] @@ -280,7 +280,7 @@ impl ContentDecoder { Ok(None) } } - Err(e) => Err(e), + Err(err) => Err(err), }, #[cfg(feature = "compress-zstd")] @@ -295,7 +295,7 @@ impl ContentDecoder { Ok(None) } } - Err(e) => Err(e), + Err(err) => Err(err), }, } } diff --git a/actix-http/src/h1/decoder.rs b/actix-http/src/h1/decoder.rs index 9e9b253d6..5c26515f7 100644 --- a/actix-http/src/h1/decoder.rs +++ b/actix-http/src/h1/decoder.rs @@ -532,7 +532,7 @@ impl Decoder for PayloadDecoder { *state = match state.step(src, size, &mut buf) { Poll::Pending => return Ok(None), Poll::Ready(Ok(state)) => state, - Poll::Ready(Err(e)) => return Err(e), + Poll::Ready(Err(err)) => return Err(err), }; if *state == ChunkedState::End { diff --git a/actix-http/src/responses/builder.rs b/actix-http/src/responses/builder.rs index 063af92da..91c69ba54 100644 --- a/actix-http/src/responses/builder.rs +++ b/actix-http/src/responses/builder.rs @@ -93,7 +93,7 @@ impl ResponseBuilder { Ok((key, value)) => { parts.headers.insert(key, value); } - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), }; } @@ -119,7 +119,7 @@ impl ResponseBuilder { if let Some(parts) = self.inner() { match header.try_into_pair() { Ok((key, value)) => parts.headers.append(key, value), - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), }; } @@ -193,7 +193,7 @@ impl ResponseBuilder { Ok(value) => { parts.headers.insert(header::CONTENT_TYPE, value); } - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), }; } self diff --git a/actix-http/src/ws/codec.rs b/actix-http/src/ws/codec.rs index 681649a7e..ad487e400 100644 --- a/actix-http/src/ws/codec.rs +++ b/actix-http/src/ws/codec.rs @@ -296,7 +296,7 @@ impl Decoder for Codec { } } Ok(None) => Ok(None), - Err(e) => Err(e), + Err(err) => Err(err), } } } diff --git a/actix-http/tests/test_server.rs b/actix-http/tests/test_server.rs index f55b1b36c..4ba64a53c 100644 --- a/actix-http/tests/test_server.rs +++ b/actix-http/tests/test_server.rs @@ -147,7 +147,7 @@ async fn chunked_payload() { .take_payload() .map(|res| match res { Ok(pl) => pl, - Err(e) => panic!("Error reading payload: {}", e), + Err(err) => panic!("Error reading payload: {err}"), }) .fold(0usize, |acc, chunk| ready(acc + chunk.len())) .map(|req_size| { diff --git a/actix-web-actors/src/ws.rs b/actix-web-actors/src/ws.rs index 6ce3e69a1..04dbf5e17 100644 --- a/actix-web-actors/src/ws.rs +++ b/actix-web-actors/src/ws.rs @@ -775,10 +775,10 @@ where break; } Poll::Pending => break, - Poll::Ready(Some(Err(e))) => { + Poll::Ready(Some(Err(err))) => { return Poll::Ready(Some(Err(ProtocolError::Io(io::Error::new( io::ErrorKind::Other, - format!("{}", e), + format!("{err}"), ))))); } } diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index 19ac6c8ae..0f874d3f8 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "actix-web" version = "4.4.0" +description = "Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust" authors = [ "Nikolay Kim ", "Rob Ede ", ] -description = "Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust" keywords = ["actix", "http", "web", "framework", "async"] categories = [ "network-programming", diff --git a/actix-web/src/app.rs b/actix-web/src/app.rs index a4cd8d819..06b66f62c 100644 --- a/actix-web/src/app.rs +++ b/actix-web/src/app.rs @@ -141,8 +141,8 @@ where let fut = data(); async move { match fut.await { - Err(e) => { - log::error!("Can not construct data instance: {:?}", e); + Err(err) => { + log::error!("Can not construct data instance: {err:?}"); Err(()) } Ok(data) => { diff --git a/actix-web/src/extract.rs b/actix-web/src/extract.rs index a2afd3827..249b56114 100644 --- a/actix-web/src/extract.rs +++ b/actix-web/src/extract.rs @@ -175,8 +175,8 @@ where let res = ready!(this.fut.poll(cx)); match res { Ok(t) => Poll::Ready(Ok(Some(t))), - Err(e) => { - log::debug!("Error for Option extractor: {}", e.into()); + Err(err) => { + log::debug!("Error for Option extractor: {}", err.into()); Poll::Ready(Ok(None)) } } @@ -217,8 +217,8 @@ where /// /// extract `Thing` from request /// async fn index(supplied_thing: Result) -> String { /// match supplied_thing { -/// Ok(thing) => format!("Got thing: {:?}", thing), -/// Err(e) => format!("Error extracting thing: {}", e) +/// Ok(thing) => format!("Got thing: {thing:?}"), +/// Err(err) => format!("Error extracting thing: {err}"), /// } /// } /// @@ -355,7 +355,7 @@ mod tuple_from_req { Poll::Ready(Ok(output)) => { let _ = this.$T.as_mut().project_replace(ExtractFuture::Done { output }); }, - Poll::Ready(Err(e)) => return Poll::Ready(Err(e.into())), + Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())), Poll::Pending => ready = false, }, ExtractProj::Done { .. } => {}, diff --git a/actix-web/src/middleware/logger.rs b/actix-web/src/middleware/logger.rs index 06d26617a..ce2caacd9 100644 --- a/actix-web/src/middleware/logger.rs +++ b/actix-web/src/middleware/logger.rs @@ -356,7 +356,7 @@ where let res = match ready!(this.fut.poll(cx)) { Ok(res) => res, - Err(e) => return Poll::Ready(Err(e)), + Err(err) => return Poll::Ready(Err(err)), }; if let Some(error) = res.response().error() { diff --git a/actix-web/src/response/builder.rs b/actix-web/src/response/builder.rs index 2c06941cd..28a0adffd 100644 --- a/actix-web/src/response/builder.rs +++ b/actix-web/src/response/builder.rs @@ -64,7 +64,7 @@ impl HttpResponseBuilder { Ok((key, value)) => { parts.headers.insert(key, value); } - Err(e) => self.error = Some(e.into()), + Err(err) => self.error = Some(err.into()), }; } @@ -86,7 +86,7 @@ impl HttpResponseBuilder { if let Some(parts) = self.inner() { match header.try_into_pair() { Ok((key, value)) => parts.headers.append(key, value), - Err(e) => self.error = Some(e.into()), + Err(err) => self.error = Some(err.into()), }; } @@ -210,7 +210,7 @@ impl HttpResponseBuilder { Ok(value) => { parts.headers.insert(header::CONTENT_TYPE, value); } - Err(e) => self.error = Some(e.into()), + Err(err) => self.error = Some(err.into()), }; } self diff --git a/actix-web/src/server.rs b/actix-web/src/server.rs index 879b269a0..e92985d39 100644 --- a/actix-web/src/server.rs +++ b/actix-web/src/server.rs @@ -853,7 +853,7 @@ fn bind_addrs(addrs: impl net::ToSocketAddrs, backlog: u32) -> io::Result err = Some(e), + Err(error) => err = Some(error), } } diff --git a/actix-web/src/types/header.rs b/actix-web/src/types/header.rs index 8b1740e6c..977dc032e 100644 --- a/actix-web/src/types/header.rs +++ b/actix-web/src/types/header.rs @@ -2,7 +2,7 @@ use std::{fmt, ops}; -use actix_utils::future::{err, ok, Ready}; +use actix_utils::future::{ready, Ready}; use crate::{ dev::Payload, error::ParseError, extract::FromRequest, http::header::Header as ParseHeader, @@ -66,8 +66,8 @@ where #[inline] fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future { match ParseHeader::parse(req) { - Ok(header) => ok(Header(header)), - Err(e) => err(e), + Ok(header) => ready(Ok(Header(header))), + Err(err) => ready(Err(err)), } } } diff --git a/awc/src/client/connector.rs b/awc/src/client/connector.rs index de39e1a4a..879d1895b 100644 --- a/awc/src/client/connector.rs +++ b/awc/src/client/connector.rs @@ -909,8 +909,8 @@ mod resolver { None => { let (cfg, opts) = match read_system_conf() { Ok((cfg, opts)) => (cfg, opts), - Err(e) => { - log::error!("TRust-DNS can not load system config: {}", e); + Err(err) => { + log::error!("Trust-DNS can not load system config: {err}"); (ResolverConfig::default(), ResolverOpts::default()) } }; diff --git a/awc/src/client/h1proto.rs b/awc/src/client/h1proto.rs index c756179a4..3f4c9f979 100644 --- a/awc/src/client/h1proto.rs +++ b/awc/src/client/h1proto.rs @@ -56,7 +56,7 @@ where headers.insert(HOST, value); } }, - Err(e) => log::error!("Can not set HOST header {}", e), + Err(err) => log::error!("Can not set HOST header {err}"), } } } diff --git a/awc/src/client/h2proto.rs b/awc/src/client/h2proto.rs index d18db1410..c3f801f20 100644 --- a/awc/src/client/h2proto.rs +++ b/awc/src/client/h2proto.rs @@ -106,9 +106,9 @@ where } let res = poll_fn(|cx| io.poll_ready(cx)).await; - if let Err(e) = res { - io.on_release(e.is_io()); - return Err(SendRequestError::from(e)); + if let Err(err) = res { + io.on_release(err.is_io()); + return Err(SendRequestError::from(err)); } let resp = match io.send_request(req, eof) { @@ -120,9 +120,9 @@ where } fut.await.map_err(SendRequestError::from)? } - Err(e) => { - io.on_release(e.is_io()); - return Err(e.into()); + Err(err) => { + io.on_release(err.is_io()); + return Err(err.into()); } }; @@ -169,8 +169,8 @@ where let len = b.len(); let bytes = b.split_to(std::cmp::min(cap, len)); - if let Err(e) = send.send_data(bytes, false) { - return Err(e.into()); + if let Err(err) = send.send_data(bytes, false) { + return Err(err.into()); } if !b.is_empty() { send.reserve_capacity(b.len()); @@ -179,7 +179,7 @@ where } continue; } - Some(Err(e)) => return Err(e.into()), + Some(Err(err)) => return Err(err.into()), } } } diff --git a/awc/src/request.rs b/awc/src/request.rs index 4e34e5771..28ed8b5f5 100644 --- a/awc/src/request.rs +++ b/awc/src/request.rs @@ -83,7 +83,7 @@ impl ClientRequest { { match Uri::try_from(uri) { Ok(uri) => self.head.uri = uri, - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), } self } @@ -152,7 +152,7 @@ impl ClientRequest { Ok((key, value)) => { self.head.headers.insert(key, value); } - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), }; self @@ -166,7 +166,7 @@ impl ClientRequest { self.head.headers.insert(key, value); } } - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), }; self @@ -185,7 +185,7 @@ impl ClientRequest { pub fn append_header(mut self, header: impl TryIntoHeaderPair) -> Self { match header.try_into_pair() { Ok((key, value)) => self.head.headers.append(key, value), - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), }; self @@ -217,7 +217,7 @@ impl ClientRequest { Ok(value) => { self.head.headers.insert(header::CONTENT_TYPE, value); } - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), } self } @@ -299,7 +299,7 @@ impl ClientRequest { match Uri::from_parts(parts) { Ok(uri) => self.head.uri = uri, - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), } } @@ -311,7 +311,7 @@ impl ClientRequest { pub fn freeze(self) -> Result { let slf = match self.prep_for_sending() { Ok(slf) => slf, - Err(e) => return Err(e.into()), + Err(err) => return Err(err.into()), }; let request = FrozenClientRequest { @@ -332,7 +332,7 @@ impl ClientRequest { { let slf = match self.prep_for_sending() { Ok(slf) => slf, - Err(e) => return e.into(), + Err(err) => return err.into(), }; RequestSender::Owned(slf.head).send_body( @@ -348,7 +348,7 @@ impl ClientRequest { pub fn send_json(self, value: &T) -> SendClientRequest { let slf = match self.prep_for_sending() { Ok(slf) => slf, - Err(e) => return e.into(), + Err(err) => return err.into(), }; RequestSender::Owned(slf.head).send_json( @@ -366,7 +366,7 @@ impl ClientRequest { pub fn send_form(self, value: &T) -> SendClientRequest { let slf = match self.prep_for_sending() { Ok(slf) => slf, - Err(e) => return e.into(), + Err(err) => return err.into(), }; RequestSender::Owned(slf.head).send_form( @@ -386,7 +386,7 @@ impl ClientRequest { { let slf = match self.prep_for_sending() { Ok(slf) => slf, - Err(e) => return e.into(), + Err(err) => return err.into(), }; RequestSender::Owned(slf.head).send_stream( @@ -402,7 +402,7 @@ impl ClientRequest { pub fn send(self) -> SendClientRequest { let slf = match self.prep_for_sending() { Ok(slf) => slf, - Err(e) => return e.into(), + Err(err) => return err.into(), }; RequestSender::Owned(slf.head).send( diff --git a/awc/src/sender.rs b/awc/src/sender.rs index c2191d11b..8de1033a3 100644 --- a/awc/src/sender.rs +++ b/awc/src/sender.rs @@ -122,8 +122,8 @@ impl Future for SendClientRequest { Poll::Ready(res) } - SendClientRequest::Err(ref mut e) => match e.take() { - Some(e) => Poll::Ready(Err(e)), + SendClientRequest::Err(ref mut err) => match err.take() { + Some(err) => Poll::Ready(Err(err)), None => panic!("Attempting to call completed future"), }, } @@ -147,8 +147,8 @@ impl Future for SendClientRequest { .poll(cx) .map_ok(|res| res.into_client_response()._timeout(delay.take())) } - SendClientRequest::Err(ref mut e) => match e.take() { - Some(e) => Poll::Ready(Err(e)), + SendClientRequest::Err(ref mut err) => match err.take() { + Some(err) => Poll::Ready(Err(err)), None => panic!("Attempting to call completed future"), }, } @@ -219,8 +219,8 @@ impl RequestSender { Err(err) => return PrepForSendingError::Json(err).into(), }; - if let Err(e) = self.set_header_if_none(header::CONTENT_TYPE, "application/json") { - return e.into(); + if let Err(err) = self.set_header_if_none(header::CONTENT_TYPE, "application/json") { + return err.into(); } self.send_body(addr, response_decompress, timeout, config, body) @@ -291,7 +291,7 @@ impl RequestSender { Ok(value) => { head.headers.insert(key, value); } - Err(e) => return Err(e.into()), + Err(err) => return Err(err.into()), } } } @@ -304,7 +304,7 @@ impl RequestSender { let h = extra_headers.get_or_insert(HeaderMap::new()); h.insert(key, v) } - Err(e) => return Err(e.into()), + Err(err) => return Err(err.into()), }; } } diff --git a/awc/src/ws.rs b/awc/src/ws.rs index 836ff2024..c3340206d 100644 --- a/awc/src/ws.rs +++ b/awc/src/ws.rs @@ -64,7 +64,7 @@ pub struct WebsocketsRequest { } impl WebsocketsRequest { - /// Create new WebSocket connection + /// Create new WebSocket connection. pub(crate) fn new(uri: U, config: ClientConfig) -> Self where Uri: TryFrom, @@ -82,7 +82,7 @@ impl WebsocketsRequest { match Uri::try_from(uri) { Ok(uri) => head.uri = uri, - Err(e) => err = Some(e.into()), + Err(error) => err = Some(error.into()), } WebsocketsRequest { @@ -143,7 +143,7 @@ impl WebsocketsRequest { { match HeaderValue::try_from(origin) { Ok(value) => self.origin = Some(value), - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), } self } @@ -177,9 +177,9 @@ impl WebsocketsRequest { Ok(value) => { self.head.headers.append(key, value); } - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), }, - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), } self } @@ -196,9 +196,9 @@ impl WebsocketsRequest { Ok(value) => { self.head.headers.insert(key, value); } - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), }, - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), } self } @@ -217,11 +217,11 @@ impl WebsocketsRequest { Ok(value) => { self.head.headers.insert(key, value); } - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), } } } - Err(e) => self.err = Some(e.into()), + Err(err) => self.err = Some(err.into()), } self } From a7983351be4aeebfa2baba7e6a8c3a765a25b785 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 12 Sep 2023 04:45:36 +0100 Subject: [PATCH 54/57] docs: fix Data doc --- .github/dependabot.yml | 14 ++++++-------- actix-web/src/data.rs | 4 ++-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1a54090f0..23f6c3ea8 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,12 +1,10 @@ version: 2 updates: - - package-ecosystem: "cargo" - directory: "/" + - package-ecosystem: cargo + directory: / schedule: - interval: "monthly" - open-pull-requests-limit: 10 - - package-ecosystem: "github-actions" - directory: "/" + interval: weekly + - package-ecosystem: github-actions + directory: / schedule: - interval: "monthly" - open-pull-requests-limit: 10 + interval: daily diff --git a/actix-web/src/data.rs b/actix-web/src/data.rs index 449a24a64..ebb98af3f 100644 --- a/actix-web/src/data.rs +++ b/actix-web/src/data.rs @@ -32,8 +32,8 @@ pub(crate) type FnDataFactory = /// Since the Actix Web router layers application data, the returned object will reference the /// "closest" instance of the type. For example, if an `App` stores a `u32`, a nested `Scope` /// also stores a `u32`, and the delegated request handler falls within that `Scope`, then -/// extracting a `web::>` for that handler will return the `Scope`'s instance. -/// However, using the same router set up and a request that does not get captured by the `Scope`, +/// extracting a `web::Data` for that handler will return the `Scope`'s instance. However, +/// using the same router set up and a request that does not get captured by the `Scope`, /// `web::>` would return the `App`'s instance. /// /// If route data is not set for a handler, using `Data` extractor would cause a `500 Internal From d50eccb3f7cdec186b7c9398258748cb91395231 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 12 Sep 2023 05:16:41 +0100 Subject: [PATCH 55/57] ci: workaround anstyle msrv --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f071ec8f3..2d5c879dd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,10 +53,11 @@ jobs: uses: taiki-e/install-action@cargo-hack - name: workaround MSRV issues - if: matrix.version.name != 'stable' + if: matrix.version.name == 'msrv' run: | cargo update -p=clap --precise=4.3.24 cargo update -p=clap_lex --precise=0.5.0 + cargo update -p=anstyle --precise=1.0.2 - name: check minimal run: cargo ci-check-min From 81ac30f3df37c9dee69decb89fe2e80ad55217e7 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 12 Sep 2023 05:24:55 +0100 Subject: [PATCH 56/57] ci: overspecify actions versions --- .github/workflows/ci-post-merge.yml | 18 ++++++++++----- .github/workflows/ci.yml | 16 ++++++++----- .github/workflows/clippy-fmt.yml | 36 +++++++++++++++++------------ .github/workflows/coverage.yml | 1 + .github/workflows/upload-doc.yml | 10 ++++---- 5 files changed, 50 insertions(+), 31 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index a34dd27ba..7acb2b73f 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -40,12 +40,14 @@ jobs: echo 'OPENSSL_DIR=C:\Program Files\OpenSSL' | Out-File -FilePath $env:GITHUB_ENV -Append - name: Install Rust (${{ matrix.version.name }}) - uses: actions-rust-lang/setup-rust-toolchain@v1 + uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 with: toolchain: ${{ matrix.version.version }} - name: Install cargo-hack - uses: taiki-e/install-action@cargo-hack + uses: taiki-e/install-action@v2.18.9 + with: + tool: cargo-hack - name: check minimal run: cargo ci-check-min @@ -80,10 +82,12 @@ jobs: - uses: actions/checkout@v3 - name: Install Rust - uses: actions-rust-lang/setup-rust-toolchain@v1 + uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 - name: Install cargo-hack - uses: taiki-e/install-action@cargo-hack + uses: taiki-e/install-action@v2.18.9 + with: + tool: cargo-hack - name: check feature combinations run: cargo ci-check-all-feature-powerset @@ -99,10 +103,12 @@ jobs: - uses: actions/checkout@v3 - name: Install Rust - uses: actions-rust-lang/setup-rust-toolchain@v1 + uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 - name: Install nextest - uses: taiki-e/install-action@nextest + uses: taiki-e/install-action@v2.18.9 + with: + tool: nextest - name: Test with cargo-nextest run: cargo nextest run diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d5c879dd..c079e10c9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,12 +45,14 @@ jobs: echo 'OPENSSL_DIR=C:\Program Files\OpenSSL' | Out-File -FilePath $env:GITHUB_ENV -Append - name: Install Rust (${{ matrix.version.name }}) - uses: actions-rust-lang/setup-rust-toolchain@v1 + uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 with: toolchain: ${{ matrix.version.version }} - name: Install cargo-hack - uses: taiki-e/install-action@cargo-hack + uses: taiki-e/install-action@v2.18.9 + with: + tool: cargo-hack - name: workaround MSRV issues if: matrix.version.name == 'msrv' @@ -91,8 +93,9 @@ jobs: - uses: actions/checkout@v3 - name: Install Rust - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: { toolchain: nightly } + uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 + with: + toolchain: nightly - name: tests (io-uring) timeout-minutes: 60 @@ -106,8 +109,9 @@ jobs: - uses: actions/checkout@v3 - name: Install Rust (nightly) - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: { toolchain: nightly } + uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 + with: + toolchain: nightly - name: doc tests run: cargo ci-doctest diff --git a/.github/workflows/clippy-fmt.yml b/.github/workflows/clippy-fmt.yml index 25c05bcbc..19b4fe6a3 100644 --- a/.github/workflows/clippy-fmt.yml +++ b/.github/workflows/clippy-fmt.yml @@ -5,7 +5,7 @@ on: types: [opened, synchronize, reopened] permissions: - contents: read # to fetch code (actions/checkout) + contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -17,7 +17,7 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions-rust-lang/setup-rust-toolchain@v1 + - uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 with: toolchain: nightly components: rustfmt @@ -32,12 +32,13 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: { components: clippy } - - - uses: giraffate/clippy-action@v1 + - uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 with: - reporter: 'github-pr-check' + components: clippy + + - uses: giraffate/clippy-action@v1.0.1 + with: + reporter: github-pr-check github_token: ${{ secrets.GITHUB_TOKEN }} clippy_flags: --workspace --all-features --tests --examples --bins -- -Dclippy::todo -Aunknown_lints @@ -46,12 +47,15 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: { components: rust-docs } + - uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 + with: + toolchain: nightly + components: rust-docs - name: Check for broken intra-doc links - env: { RUSTDOCFLAGS: "-D warnings" } - run: cargo doc --no-deps --all-features --workspace + env: + RUSTDOCFLAGS: -D warnings + run: cargo +nightly doc --no-deps --workspace --all-features public-api-diff: runs-on: ubuntu-latest @@ -62,11 +66,13 @@ jobs: - uses: actions/checkout@v3 - - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: { toolchain: nightly-2023-08-25 } + - uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 + with: + toolchain: nightly-2023-08-25 - - uses: taiki-e/cache-cargo-install-action@v1 - with: { tool: cargo-public-api } + - uses: taiki-e/cache-cargo-install-action@v1.2.1 + with: + tool: cargo-public-api - name: generate API diff run: | diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 1feae0432..de31907a9 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -16,6 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + - name: Install Rust uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 with: diff --git a/.github/workflows/upload-doc.yml b/.github/workflows/upload-doc.yml index 05b81411d..0efe36816 100644 --- a/.github/workflows/upload-doc.yml +++ b/.github/workflows/upload-doc.yml @@ -5,8 +5,7 @@ on: branches: [master] permissions: - contents: read # to fetch code (actions/checkout) - + contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -14,14 +13,17 @@ concurrency: jobs: build: permissions: - contents: write # to push changes in repo (jamesives/github-pages-deploy-action) + contents: write runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: dtolnay/rust-toolchain@nightly + - name: Install Rust + uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 + with: + toolchain: nightly - name: Build Docs run: cargo +nightly doc --no-deps --workspace --all-features From 835a57afc61584feecfb73fe0865ccd0b4758ee4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 04:44:47 +0000 Subject: [PATCH 57/57] build(deps): bump actions/checkout from 3 to 4 (#3130) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/bench.yml | 2 +- .github/workflows/ci-post-merge.yml | 6 +++--- .github/workflows/ci.yml | 6 +++--- .github/workflows/clippy-fmt.yml | 10 +++++----- .github/workflows/coverage.yml | 2 +- .github/workflows/upload-doc.yml | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index f0e4cc8b3..910cb24b9 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install Rust run: | diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 7acb2b73f..9f205410e 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -28,7 +28,7 @@ jobs: runs-on: ${{ matrix.target.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install OpenSSL if: matrix.target.os == 'windows-latest' @@ -79,7 +79,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install Rust uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 @@ -100,7 +100,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install Rust uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c079e10c9..4c4977ac8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: runs-on: ${{ matrix.target.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install OpenSSL if: matrix.target.os == 'windows-latest' @@ -90,7 +90,7 @@ jobs: name: io-uring tests runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install Rust uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 @@ -106,7 +106,7 @@ jobs: name: doc tests runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install Rust (nightly) uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 diff --git a/.github/workflows/clippy-fmt.yml b/.github/workflows/clippy-fmt.yml index 19b4fe6a3..4146e5661 100644 --- a/.github/workflows/clippy-fmt.yml +++ b/.github/workflows/clippy-fmt.yml @@ -15,7 +15,7 @@ jobs: fmt: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 with: @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 with: @@ -45,7 +45,7 @@ jobs: lint-docs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 with: @@ -60,11 +60,11 @@ jobs: public-api-diff: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: ref: ${{ github.base_ref }} - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 with: diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index de31907a9..6fc1eabb0 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -15,7 +15,7 @@ jobs: coverage: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install Rust uses: actions-rust-lang/setup-rust-toolchain@v1.5.0 diff --git a/.github/workflows/upload-doc.yml b/.github/workflows/upload-doc.yml index 0efe36816..2037e34f5 100644 --- a/.github/workflows/upload-doc.yml +++ b/.github/workflows/upload-doc.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install Rust uses: actions-rust-lang/setup-rust-toolchain@v1.5.0