From fa74ab3dfb164f7184e4dcea82901ab62e40058f Mon Sep 17 00:00:00 2001 From: Nikolaos Chatzikonstantinou Date: Thu, 13 Jun 2024 21:51:29 -0400 Subject: [PATCH 001/144] remove references to StaticFiles (#3400) --- actix-web/src/app.rs | 1 - actix-web/src/scope.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/actix-web/src/app.rs b/actix-web/src/app.rs index 3d86d1f9b..21a4443cf 100644 --- a/actix-web/src/app.rs +++ b/actix-web/src/app.rs @@ -234,7 +234,6 @@ where /// /// * *Resource* is an entry in resource table which corresponds to requested URL. /// * *Scope* is a set of resources with common root path. - /// * "StaticFiles" is a service for static files support pub fn service(mut self, factory: F) -> Self where F: HttpServiceFactory + 'static, diff --git a/actix-web/src/scope.rs b/actix-web/src/scope.rs index adc9f75d3..81f3615b0 100644 --- a/actix-web/src/scope.rs +++ b/actix-web/src/scope.rs @@ -213,7 +213,6 @@ where /// /// * *Resource* is an entry in resource table which corresponds to requested URL. /// * *Scope* is a set of resources with common root path. - /// * "StaticFiles" is a service for static files support /// /// ``` /// use actix_web::{web, App, HttpRequest}; From 3ecaff5f5bfa8b952dfd6e5110c48ea31c9e58b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 00:28:10 +0000 Subject: [PATCH 002/144] build(deps): bump taiki-e/cache-cargo-install-action from 1.2.2 to 2.0.1 (#3406) Bumps [taiki-e/cache-cargo-install-action](https://github.com/taiki-e/cache-cargo-install-action) from 1.2.2 to 2.0.1. - [Release notes](https://github.com/taiki-e/cache-cargo-install-action/releases) - [Changelog](https://github.com/taiki-e/cache-cargo-install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/cache-cargo-install-action/compare/v1.2.2...v2.0.1) --- updated-dependencies: - dependency-name: taiki-e/cache-cargo-install-action 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/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ca9d2bbeb..1c8841289 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -81,7 +81,7 @@ jobs: tool: just - name: Install cargo-check-external-types - uses: taiki-e/cache-cargo-install-action@v1.2.2 + uses: taiki-e/cache-cargo-install-action@v2.0.1 with: tool: cargo-check-external-types From c076e34b5d88df9ff8975d7608aead544097b2bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 03:27:23 +0100 Subject: [PATCH 003/144] build(deps): bump codecov/codecov-action from 4.4.1 to 4.5.0 (#3405) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.4.1 to 4.5.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4.4.1...v4.5.0) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index ca3115713..60ddb7c10 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -32,7 +32,7 @@ jobs: run: just test-coverage-codecov - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4.4.1 + uses: codecov/codecov-action@v4.5.0 with: files: codecov.json fail_ci_if_error: true From 66905efd7b02a464f0becff59685c8ce58f243c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 02:28:03 +0000 Subject: [PATCH 004/144] build(deps): bump taiki-e/install-action from 2.38.0 to 2.39.1 (#3404) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.38.0 to 2.39.1. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.38.0...v2.39.1) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 1729d9a07..67a6d0f8f 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.38.0 + uses: taiki-e/install-action@v2.39.1 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -80,7 +80,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 - name: Install cargo-hack - uses: taiki-e/install-action@v2.38.0 + uses: taiki-e/install-action@v2.39.1 with: tool: cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b6f7b460..9cb8d7b7e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.38.0 + uses: taiki-e/install-action@v2.39.1 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.38.0 + uses: taiki-e/install-action@v2.39.1 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 60ddb7c10..630c6c864 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.38.0 + uses: taiki-e/install-action@v2.39.1 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1c8841289..49d88df1b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -76,7 +76,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.38.0 + uses: taiki-e/install-action@v2.39.1 with: tool: just @@ -105,7 +105,7 @@ jobs: toolchain: nightly-2024-06-07 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.38.0 + uses: taiki-e/install-action@v2.39.1 with: tool: cargo-public-api From 643d64581a3b4b9f718827168e87703a188e6ace Mon Sep 17 00:00:00 2001 From: Yury Yarashevich Date: Thu, 20 Jun 2024 00:34:49 +0200 Subject: [PATCH 005/144] Fix Rustls 0.22 & 0.23 are limited to 256 handshakes per second. (#3408) --- actix-http/Cargo.toml | 16 ++++++++++------ actix-http/src/lib.rs | 8 +------- actix-http/src/service.rs | 16 ++-------------- actix-web/CHANGES.md | 1 + actix-web/Cargo.toml | 14 +++++++++----- actix-web/src/server.rs | 18 +++--------------- 6 files changed, 26 insertions(+), 47 deletions(-) diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 4dc0f0bd8..25e8b28f5 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -70,22 +70,22 @@ ws = [ ] # TLS via OpenSSL -openssl = ["actix-tls/accept", "actix-tls/openssl"] +openssl = ["__tls", "actix-tls/accept", "actix-tls/openssl"] # TLS via Rustls v0.20 -rustls = ["rustls-0_20"] +rustls = ["__tls", "rustls-0_20"] # TLS via Rustls v0.20 -rustls-0_20 = ["actix-tls/accept", "actix-tls/rustls-0_20"] +rustls-0_20 = ["__tls", "actix-tls/accept", "actix-tls/rustls-0_20"] # TLS via Rustls v0.21 -rustls-0_21 = ["actix-tls/accept", "actix-tls/rustls-0_21"] +rustls-0_21 = ["__tls", "actix-tls/accept", "actix-tls/rustls-0_21"] # TLS via Rustls v0.22 -rustls-0_22 = ["actix-tls/accept", "actix-tls/rustls-0_22"] +rustls-0_22 = ["__tls", "actix-tls/accept", "actix-tls/rustls-0_22"] # TLS via Rustls v0.23 -rustls-0_23 = ["actix-tls/accept", "actix-tls/rustls-0_23"] +rustls-0_23 = ["__tls", "actix-tls/accept", "actix-tls/rustls-0_23"] # Compression codecs compress-brotli = ["__compress", "brotli"] @@ -96,6 +96,10 @@ compress-zstd = ["__compress", "zstd"] # Don't rely on these whatsoever. They are semver-exempt and may disappear at anytime. __compress = [] +# Internal (PRIVATE!) features used to aid checking feature status. +# Don't rely on these whatsoever. They may disappear at anytime. +__tls = [] + [dependencies] actix-service = "2" actix-codec = "0.5" diff --git a/actix-http/src/lib.rs b/actix-http/src/lib.rs index f9697c4d5..b76032ba3 100644 --- a/actix-http/src/lib.rs +++ b/actix-http/src/lib.rs @@ -61,13 +61,7 @@ pub mod ws; #[allow(deprecated)] pub use self::payload::PayloadStream; -#[cfg(any( - feature = "openssl", - feature = "rustls-0_20", - feature = "rustls-0_21", - feature = "rustls-0_22", - feature = "rustls-0_23", -))] +#[cfg(feature = "__tls")] 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 a58be93c7..37cee960f 100644 --- a/actix-http/src/service.rs +++ b/actix-http/src/service.rs @@ -241,25 +241,13 @@ where } /// Configuration options used when accepting TLS connection. -#[cfg(any( - feature = "openssl", - feature = "rustls-0_20", - feature = "rustls-0_21", - feature = "rustls-0_22", - feature = "rustls-0_23", -))] +#[cfg(feature = "__tls")] #[derive(Debug, Default)] pub struct TlsAcceptorConfig { pub(crate) handshake_timeout: Option, } -#[cfg(any( - feature = "openssl", - feature = "rustls-0_20", - feature = "rustls-0_21", - feature = "rustls-0_22", - feature = "rustls-0_23", -))] +#[cfg(feature = "__tls")] impl TlsAcceptorConfig { /// Set TLS handshake timeout duration. pub fn handshake_timeout(self, dur: std::time::Duration) -> Self { diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 54c7045ae..bf63a689e 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -11,6 +11,7 @@ - `ConnectionInfo::realip_remote_addr()` now handles IPv6 addresses from `Forwarded` header correctly. Previously, it sometimes returned the forwarded port as well. - The `UrlencodedError::ContentType` variant (relevant to the `Form` extractor) now uses the 415 (Media Type Unsupported) status code in it's `ResponseError` implementation. +- `HttpServer::method.max_connection_rate` now takes effect on any TLS implementation. Previously, the configuration was missing for rustls versions 0.22 and 0.23. ## 4.7.0 diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index 3827d4400..bc441fd7e 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -93,18 +93,18 @@ secure-cookies = ["cookies", "cookie/secure"] http2 = ["actix-http/http2"] # TLS via OpenSSL -openssl = ["http2", "actix-http/openssl", "actix-tls/accept", "actix-tls/openssl"] +openssl = ["__tls", "http2", "actix-http/openssl", "actix-tls/accept", "actix-tls/openssl"] # 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"] +rustls-0_20 = ["__tls", "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"] +rustls-0_21 = ["__tls", "http2", "actix-http/rustls-0_21", "actix-tls/accept", "actix-tls/rustls-0_21"] # TLS via Rustls v0.22 -rustls-0_22 = ["http2", "actix-http/rustls-0_22", "actix-tls/accept", "actix-tls/rustls-0_22"] +rustls-0_22 = ["__tls", "http2", "actix-http/rustls-0_22", "actix-tls/accept", "actix-tls/rustls-0_22"] # TLS via Rustls v0.23 -rustls-0_23 = ["http2", "actix-http/rustls-0_23", "actix-tls/accept", "actix-tls/rustls-0_23"] +rustls-0_23 = ["__tls", "http2", "actix-http/rustls-0_23", "actix-tls/accept", "actix-tls/rustls-0_23"] # Full unicode support unicode = ["dep:regex", "actix-router/unicode"] @@ -113,6 +113,10 @@ unicode = ["dep:regex", "actix-router/unicode"] # Don't rely on these whatsoever. They may disappear at anytime. __compress = [] +# Internal (PRIVATE!) features used to aid checking feature status. +# Don't rely on these whatsoever. They may disappear at anytime. +__tls = [] + # io-uring feature only available for Linux OSes. experimental-io-uring = ["actix-server/io-uring"] diff --git a/actix-web/src/server.rs b/actix-web/src/server.rs index 33b1e1894..95e15581f 100644 --- a/actix-web/src/server.rs +++ b/actix-web/src/server.rs @@ -7,13 +7,7 @@ use std::{ time::Duration, }; -#[cfg(any( - feature = "openssl", - feature = "rustls-0_20", - feature = "rustls-0_21", - feature = "rustls-0_22", - feature = "rustls-0_23", -))] +#[cfg(feature = "__tls")] use actix_http::TlsAcceptorConfig; use actix_http::{body::MessageBody, Extensions, HttpService, KeepAlive, Request, Response}; use actix_server::{Server, ServerBuilder}; @@ -190,7 +184,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-0_20", feature = "rustls-0_21", feature = "openssl"))] + #[cfg(feature = "__tls")] actix_tls::accept::max_concurrent_tls_connect(num); self } @@ -243,13 +237,7 @@ where /// time, the connection is closed. /// /// By default, the handshake timeout is 3 seconds. - #[cfg(any( - feature = "openssl", - feature = "rustls-0_20", - feature = "rustls-0_21", - feature = "rustls-0_22", - feature = "rustls-0_23", - ))] + #[cfg(feature = "__tls")] pub fn tls_handshake_timeout(self, dur: Duration) -> Self { self.config .lock() From cbb55ba27d98ca24e364f1c26b6fa96b3ade6e32 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Wed, 19 Jun 2024 23:40:22 +0100 Subject: [PATCH 006/144] ci: use just for feature combos check --- .cargo/config.toml | 10 ---------- .github/workflows/ci-post-merge.yml | 14 +++++++------- actix-http/Cargo.toml | 16 ++++++++-------- actix-http/src/lib.rs | 8 ++++---- justfile | 15 ++++++++++++++- 5 files changed, 33 insertions(+), 30 deletions(-) delete mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index a2345e184..000000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,10 +0,0 @@ -[alias] -lint = "clippy --workspace --all-targets -- -Dclippy::todo" -lint-all = "clippy --workspace --all-features --all-targets -- -Dclippy::todo" - -# lib checking -ci-check-min = "hack --workspace check --no-default-features" -ci-check-default = "hack --workspace check" -ci-check-default-tests = "check --workspace --tests" -ci-check-all-feature-powerset="hack --workspace --feature-powerset --depth=4 --skip=__compress,experimental-io-uring check" -ci-check-all-feature-powerset-linux="hack --workspace --feature-powerset --depth=4 --skip=__compress check" diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 67a6d0f8f..59a17e70a 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -76,16 +76,16 @@ jobs: - name: Free Disk Space run: ./scripts/free-disk-space.sh + - name: Setup mold linker + uses: rui314/setup-mold@v1 + - name: Install Rust uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 - - name: Install cargo-hack + - name: Install just, cargo-hack uses: taiki-e/install-action@v2.39.1 with: - tool: cargo-hack + tool: just,cargo-hack - - name: check feature combinations - run: cargo ci-check-all-feature-powerset - - - name: check feature combinations - run: cargo ci-check-all-feature-powerset-linux + - name: Check feature combinations + run: just check-feature-combinations diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 25e8b28f5..5f6a424e8 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -59,14 +59,14 @@ allowed_external_types = [ default = [] # HTTP/2 protocol support -http2 = ["h2"] +http2 = ["dep:h2"] # WebSocket protocol implementation ws = [ - "local-channel", - "base64", - "rand", - "sha1", + "dep:local-channel", + "dep:base64", + "dep:rand", + "dep:sha1", ] # TLS via OpenSSL @@ -88,9 +88,9 @@ rustls-0_22 = ["__tls", "actix-tls/accept", "actix-tls/rustls-0_22"] rustls-0_23 = ["__tls", "actix-tls/accept", "actix-tls/rustls-0_23"] # Compression codecs -compress-brotli = ["__compress", "brotli"] -compress-gzip = ["__compress", "flate2"] -compress-zstd = ["__compress", "zstd"] +compress-brotli = ["__compress", "dep:brotli"] +compress-gzip = ["__compress", "dep:flate2"] +compress-zstd = ["__compress", "dep:zstd"] # 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. diff --git a/actix-http/src/lib.rs b/actix-http/src/lib.rs index b76032ba3..ac79433c6 100644 --- a/actix-http/src/lib.rs +++ b/actix-http/src/lib.rs @@ -6,10 +6,10 @@ //! | ------------------- | ------------------------------------------- | //! | `http2` | HTTP/2 support via [h2]. | //! | `openssl` | TLS support via [OpenSSL]. | -//! | `rustls` | TLS support via [rustls] 0.20. | -//! | `rustls-0_21` | TLS support via [rustls] 0.21. | -//! | `rustls-0_22` | TLS support via [rustls] 0.22. | -//! | `rustls-0_23` | TLS support via [rustls] 0.23. | +//! | `rustls-0_20` | TLS support via rustls 0.20. | +//! | `rustls-0_21` | TLS support via rustls 0.21. | +//! | `rustls-0_22` | TLS support via rustls 0.22. | +//! | `rustls-0_23` | TLS support via [rustls] 0.23. | //! | `compress-brotli` | Payload compression support: Brotli. | //! | `compress-gzip` | Payload compression support: Deflate, Gzip. | //! | `compress-zstd` | Payload compression support: Zstd. | diff --git a/justfile b/justfile index 646c6b44d..985e2b35a 100644 --- a/justfile +++ b/justfile @@ -22,7 +22,7 @@ non_linux_all_features_list := ``` cargo metadata --format-version=1 \ | jq '.packages[] | select(.source == null) | .features | keys' \ | jq -r --slurp \ - --arg exclusions "tokio-uring,io-uring,experimental-io-uring" \ + --arg exclusions "__tls,__compress,tokio-uring,io-uring,experimental-io-uring" \ 'add | unique | . - ($exclusions | split(",")) | join(",")' ``` @@ -93,6 +93,19 @@ update-readmes: && fmt cd ./actix-multipart && cargo rdme --force cd ./actix-test && cargo rdme --force +feature_combo_skip_list := if os() == "linux" { + "__tls,__compress" +} else { + "__tls,__compress,experimental-io-uring" +} + +# Checks compatibility of feature combinations. +check-feature-combinations: + cargo hack --workspace \ + --feature-powerset --depth=4 \ + --skip={{ feature_combo_skip_list }} \ + check + # Check for unintentional external type exposure on all crates in workspace. check-external-types-all toolchain="+nightly": #!/usr/bin/env bash From c612b5ce940588268e55719c24ef78bd8d2691ce Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 20 Jun 2024 00:13:42 +0100 Subject: [PATCH 007/144] ci: fix checks --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- justfile | 8 ++++++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 59a17e70a..e60325bf8 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -54,10 +54,10 @@ jobs: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean - name: check minimal - run: cargo ci-check-min + run: just check-min - name: check default - run: cargo ci-check-default + run: just check-default - name: tests timeout-minutes: 60 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9cb8d7b7e..9ff206ffb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,10 +73,10 @@ jobs: run: just downgrade-for-msrv - name: check minimal - run: cargo ci-check-min + run: just check-min - name: check default - run: cargo ci-check-default + run: just check-default - name: tests timeout-minutes: 60 diff --git a/justfile b/justfile index 985e2b35a..a3e81b271 100644 --- a/justfile +++ b/justfile @@ -32,6 +32,14 @@ all_crate_features := if os() == "linux" { "--features='" + non_linux_all_features_list + "'" } +[private] +check-min: + cargo hack --workspace check --no-default-features + +[private] +check-default: + cargo hack --workspace check + # Run Clippy over workspace. clippy toolchain="": cargo {{ toolchain }} clippy --workspace --all-targets {{ all_crate_features }} From d92a73eacdc575918e6ffaf965c71d6ece02be9e Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 20 Jun 2024 00:18:22 +0100 Subject: [PATCH 008/144] chore(actix-http): prepare release 3.8.0 --- actix-http/CHANGES.md | 2 ++ actix-http/Cargo.toml | 2 +- actix-http/README.md | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 85ba03100..48c730bb2 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.8.0 + ### Added - Add `error::InvalidStatusCode` re-export. diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 5f6a424e8..0a0252e9a 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-http" -version = "3.7.0" +version = "3.8.0" authors = [ "Nikolay Kim ", "Rob Ede ", diff --git a/actix-http/README.md b/actix-http/README.md index 0ba3fdcac..7d56f2517 100644 --- a/actix-http/README.md +++ b/actix-http/README.md @@ -5,11 +5,11 @@ [![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.7.0)](https://docs.rs/actix-http/3.7.0) +[![Documentation](https://docs.rs/actix-http/badge.svg?version=3.8.0)](https://docs.rs/actix-http/3.8.0) ![Version](https://img.shields.io/badge/rustc-1.72+-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.7.0/status.svg)](https://deps.rs/crate/actix-http/3.7.0) +[![dependency status](https://deps.rs/crate/actix-http/3.8.0/status.svg)](https://deps.rs/crate/actix-http/3.8.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) From 4222f92bd35b854cb07ceb9a03862402cf82299d Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 20 Jun 2024 00:23:11 +0100 Subject: [PATCH 009/144] chore(actix-web): prepare release 4.8.0 --- actix-web/CHANGES.md | 6 ++++-- actix-web/Cargo.toml | 2 +- actix-web/README.md | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index bf63a689e..90c7b7e2a 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.8.0 + ### Added - Add `web::Html` responder. @@ -9,9 +11,9 @@ ### Fixed -- `ConnectionInfo::realip_remote_addr()` now handles IPv6 addresses from `Forwarded` header correctly. Previously, it sometimes returned the forwarded port as well. +- Always remove port from return value of `ConnectionInfo::realip_remote_addr()` when handling IPv6 addresses. from the `Forwarded` header. - The `UrlencodedError::ContentType` variant (relevant to the `Form` extractor) now uses the 415 (Media Type Unsupported) status code in it's `ResponseError` implementation. -- `HttpServer::method.max_connection_rate` now takes effect on any TLS implementation. Previously, the configuration was missing for rustls versions 0.22 and 0.23. +- Apply `HttpServer::max_connection_rate()` setting when using rustls v0.22 or v0.23. ## 4.7.0 diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index bc441fd7e..125cfe20f 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-web" -version = "4.7.0" +version = "4.8.0" description = "Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust" authors = [ "Nikolay Kim ", diff --git a/actix-web/README.md b/actix-web/README.md index 3f9d3e0d5..d30d945a4 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.7.0)](https://docs.rs/actix-web/4.7.0) +[![Documentation](https://docs.rs/actix-web/badge.svg?version=4.8.0)](https://docs.rs/actix-web/4.8.0) ![MSRV](https://img.shields.io/badge/rustc-1.72+-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.7.0/status.svg)](https://deps.rs/crate/actix-web/4.7.0) +[![Dependency Status](https://deps.rs/crate/actix-web/4.8.0/status.svg)](https://deps.rs/crate/actix-web/4.8.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 9f45be03e1fdee207b360de40fc2140d3305360f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 10:22:54 +0100 Subject: [PATCH 010/144] build(deps): bump taiki-e/install-action from 2.39.1 to 2.41.2 (#3412) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.39.1 to 2.41.2. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.39.1...v2.41.2) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index e60325bf8..6803fc157 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.39.1 + uses: taiki-e/install-action@v2.41.2 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.39.1 + uses: taiki-e/install-action@v2.41.2 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ff206ffb..48c286f9f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.39.1 + uses: taiki-e/install-action@v2.41.2 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.39.1 + uses: taiki-e/install-action@v2.41.2 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 630c6c864..3865aa51b 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.39.1 + uses: taiki-e/install-action@v2.41.2 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 49d88df1b..dddde3f4f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -76,7 +76,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.39.1 + uses: taiki-e/install-action@v2.41.2 with: tool: just @@ -105,7 +105,7 @@ jobs: toolchain: nightly-2024-06-07 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.39.1 + uses: taiki-e/install-action@v2.41.2 with: tool: cargo-public-api From 4db4251b8ffbcd3852c6b657d5d6df076d3227ae Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 30 Jun 2024 18:45:20 +0100 Subject: [PATCH 011/144] chore: cargo update after version bumps --- scripts/bump | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/bump b/scripts/bump index 6fd879eae..7a57e6ed0 100755 --- a/scripts/bump +++ b/scripts/bump @@ -169,3 +169,5 @@ if [ "$GH_RELEASE" = 'y' ] || [ "$GH_RELEASE" = 'Y' ]; then fi echo + +cargo update >/dev/null 2>&1 || true From 0b193c710677332d56da3a028c3c1e30983502b7 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 30 Jun 2024 18:45:38 +0100 Subject: [PATCH 012/144] build: fix doc-watch recipe --- justfile | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/justfile b/justfile index a3e81b271..5cd56b12e 100644 --- a/justfile +++ b/justfile @@ -3,6 +3,7 @@ _list: # Format workspace. fmt: + just --unstable --fmt cargo +nightly fmt fd --hidden --type=file --extension=md --extension=yml --exec-batch npx -y prettier --write @@ -17,7 +18,6 @@ msrv := ``` | sed -E 's/^1\.([0-9]{2})$/1\.\1\.0/' ``` msrv_rustup := "+" + msrv - non_linux_all_features_list := ``` cargo metadata --format-version=1 \ | jq '.packages[] | select(.source == null) | .features | keys' \ @@ -25,12 +25,7 @@ non_linux_all_features_list := ``` --arg exclusions "__tls,__compress,tokio-uring,io-uring,experimental-io-uring" \ 'add | unique | . - ($exclusions | split(",")) | join(",")' ``` - -all_crate_features := if os() == "linux" { - "--all-features" -} else { - "--features='" + non_linux_all_features_list + "'" -} +all_crate_features := if os() == "linux" { "--all-features" } else { "--features='" + non_linux_all_features_list + "'" } [private] check-min: @@ -84,7 +79,8 @@ doc-set-workspace-crates: #!/usr/bin/env bash ( echo "window.ALL_CRATES =" - cargo metadata --format-version=1 | jq '[.packages[] | select(.source == null) | .name]' + cargo metadata --format-version=1 \ + | jq '[.packages[] | select(.source == null) | .targets | map(select(.doc) | .name)] | flatten' echo ";" ) > "$(cargo metadata --format-version=1 | jq -r '.target_directory')/doc/crates.js" @@ -101,11 +97,7 @@ update-readmes: && fmt cd ./actix-multipart && cargo rdme --force cd ./actix-test && cargo rdme --force -feature_combo_skip_list := if os() == "linux" { - "__tls,__compress" -} else { - "__tls,__compress,experimental-io-uring" -} +feature_combo_skip_list := if os() == "linux" { "__tls,__compress" } else { "__tls,__compress,experimental-io-uring" } # Checks compatibility of feature combinations. check-feature-combinations: @@ -120,7 +112,7 @@ check-external-types-all toolchain="+nightly": set -euo pipefail exit=0 for f in $(find . -mindepth 2 -maxdepth 2 -name Cargo.toml | grep -vE "\-codegen/|\-derive/|\-macros/"); do - if ! just check-external-types-manifest "$f" {{toolchain}}; then exit=1; fi + if ! just check-external-types-manifest "$f" {{ toolchain }}; then exit=1; fi echo echo done @@ -133,9 +125,9 @@ check-external-types-all-table toolchain="+nightly": for f in $(find . -mindepth 2 -maxdepth 2 -name Cargo.toml | grep -vE "\-codegen/|\-derive/|\-macros/"); do echo echo "Checking for $f" - just check-external-types-manifest "$f" {{toolchain}} --output-format=markdown-table + just check-external-types-manifest "$f" {{ toolchain }} --output-format=markdown-table done # Check for unintentional external type exposure on a crate. check-external-types-manifest manifest_path toolchain="+nightly" *extra_args="": - cargo {{toolchain}} check-external-types --manifest-path "{{manifest_path}}" {{extra_args}} + cargo {{ toolchain }} check-external-types --manifest-path "{{ manifest_path }}" {{ extra_args }} From 763c58445af61531b7fe335679e773755cad73d8 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 30 Jun 2024 20:28:11 +0100 Subject: [PATCH 013/144] test: fix tests based on mime-guess inference relates to https://github.com/abonander/mime_guess/pull/86 --- actix-files/src/lib.rs | 4 ++-- actix-http/src/responses/builder.rs | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/actix-files/src/lib.rs b/actix-files/src/lib.rs index 167f996c0..0178c13de 100644 --- a/actix-files/src/lib.rs +++ b/actix-files/src/lib.rs @@ -307,11 +307,11 @@ mod tests { let resp = file.respond_to(&req); assert_eq!( resp.headers().get(header::CONTENT_TYPE).unwrap(), - "application/javascript; charset=utf-8" + "text/javascript", ); assert_eq!( resp.headers().get(header::CONTENT_DISPOSITION).unwrap(), - "inline; filename=\"test.js\"" + "inline; filename=\"test.js\"", ); } diff --git a/actix-http/src/responses/builder.rs b/actix-http/src/responses/builder.rs index 91c69ba54..bb7d0f712 100644 --- a/actix-http/src/responses/builder.rs +++ b/actix-http/src/responses/builder.rs @@ -351,12 +351,9 @@ mod tests { assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "text/plain"); let resp = Response::build(StatusCode::OK) - .content_type(mime::APPLICATION_JAVASCRIPT_UTF_8) + .content_type(mime::TEXT_JAVASCRIPT) .body(Bytes::new()); - assert_eq!( - resp.headers().get(CONTENT_TYPE).unwrap(), - "application/javascript; charset=utf-8" - ); + assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "text/javascript"); } #[test] From 668b8e5745d4b67ba1c88e2dd9f729f124dec4af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 01:55:49 +0100 Subject: [PATCH 014/144] build(deps): bump taiki-e/install-action from 2.41.2 to 2.41.7 (#3419) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.41.2 to 2.41.7. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.41.2...v2.41.7) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 6803fc157..444f1b174 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.41.2 + uses: taiki-e/install-action@v2.41.7 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.41.2 + uses: taiki-e/install-action@v2.41.7 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 48c286f9f..caee78896 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.41.2 + uses: taiki-e/install-action@v2.41.7 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.41.2 + uses: taiki-e/install-action@v2.41.7 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 3865aa51b..260d65e27 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.41.2 + uses: taiki-e/install-action@v2.41.7 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index dddde3f4f..1fd20f221 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -76,7 +76,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.41.2 + uses: taiki-e/install-action@v2.41.7 with: tool: just @@ -105,7 +105,7 @@ jobs: toolchain: nightly-2024-06-07 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.41.2 + uses: taiki-e/install-action@v2.41.7 with: tool: cargo-public-api From 71cd3a31f9b3f4b86afe9c24645a3c8211ec7905 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 1 Jul 2024 03:55:08 +0100 Subject: [PATCH 015/144] fix(multipart): optional content-disposition for non-form-data requests (#3416) --- actix-multipart-derive/src/lib.rs | 6 +- actix-multipart/CHANGES.md | 9 + actix-multipart/Cargo.toml | 2 + actix-multipart/README.md | 12 +- actix-multipart/examples/form.rs | 36 ++ actix-multipart/src/error.rs | 96 +++-- actix-multipart/src/extractor.rs | 6 +- actix-multipart/src/form/bytes.rs | 3 +- actix-multipart/src/form/json.rs | 7 +- actix-multipart/src/form/mod.rs | 83 +++- actix-multipart/src/form/tempfile.rs | 28 +- actix-multipart/src/form/text.rs | 9 +- actix-multipart/src/lib.rs | 16 +- actix-multipart/src/server.rs | 406 +++++++++++------- actix-multipart/src/test.rs | 2 + .../src/http/header/content_disposition.rs | 6 +- 16 files changed, 479 insertions(+), 248 deletions(-) create mode 100644 actix-multipart/examples/form.rs diff --git a/actix-multipart-derive/src/lib.rs b/actix-multipart-derive/src/lib.rs index 9552ad2d9..44db1fa0e 100644 --- a/actix-multipart-derive/src/lib.rs +++ b/actix-multipart-derive/src/lib.rs @@ -138,7 +138,7 @@ struct ParsedField<'t> { /// `#[multipart(duplicate_field = "")]` attribute: /// /// - "ignore": (default) Extra fields are ignored. I.e., the first one is persisted. -/// - "deny": A `MultipartError::UnsupportedField` error response is returned. +/// - "deny": A `MultipartError::UnknownField` error response is returned. /// - "replace": Each field is processed, but only the last one is persisted. /// /// Note that `Vec` fields will ignore this option. @@ -229,7 +229,7 @@ pub fn impl_multipart_form(input: proc_macro::TokenStream) -> proc_macro::TokenS // Return value when a field name is not supported by the form let unknown_field_result = if attrs.deny_unknown_fields { quote!(::std::result::Result::Err( - ::actix_multipart::MultipartError::UnsupportedField(field.name().to_string()) + ::actix_multipart::MultipartError::UnknownField(field.name().unwrap().to_string()) )) } else { quote!(::std::result::Result::Ok(())) @@ -292,7 +292,7 @@ pub fn impl_multipart_form(input: proc_macro::TokenStream) -> proc_macro::TokenS limits: &'t mut ::actix_multipart::form::Limits, state: &'t mut ::actix_multipart::form::State, ) -> ::std::pin::Pin<::std::boxed::Box> + 't>> { - match field.name() { + match field.name().unwrap() { #handle_field_impl _ => return ::std::boxed::Box::pin(::std::future::ready(#unknown_field_result)), } diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index a91edf9c8..dea24ab9d 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -2,6 +2,15 @@ ## Unreleased +- Add `MultipartError::ContentTypeIncompatible` variant. +- Add `MultipartError::ContentDispositionNameMissing` variant. +- Rename `MultipartError::{NoContentDisposition => ContentDispositionMissing}` variant. +- Rename `MultipartError::{NoContentType => ContentTypeMissing}` variant. +- Rename `MultipartError::{ParseContentType => ContentTypeParse}` variant. +- Rename `MultipartError::{Boundary => BoundaryMissing}` variant. +- Rename `MultipartError::{UnsupportedField => UnknownField}` variant. +- Remove top-level re-exports of `test` utilities. + ## 0.6.2 - Add testing utilities under new module `test`. diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index 5e9b78d84..c5ff7dd10 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -63,7 +63,9 @@ actix-multipart-rfc7578 = "0.10" actix-rt = "2.2" actix-test = "0.1" actix-web = "4" +assert_matches = "1" awc = "3" +env_logger = "0.11" futures-util = { version = "0.3.17", default-features = false, features = ["alloc"] } multer = "3" tokio = { version = "1.24.2", features = ["sync"] } diff --git a/actix-multipart/README.md b/actix-multipart/README.md index d61347f32..917dceece 100644 --- a/actix-multipart/README.md +++ b/actix-multipart/README.md @@ -54,15 +54,15 @@ async fn main() -> std::io::Result<()> { } ``` - +cURL request: -[More available in the examples repo →](https://github.com/actix/examples/tree/master/forms/multipart) - -Curl request : - -```bash +```sh curl -v --request POST \ --url http://localhost:8080/videos \ -F 'json={"name": "Cargo.lock"};type=application/json' \ -F file=@./Cargo.lock ``` + + + +[More available in the examples repo →](https://github.com/actix/examples/tree/master/forms/multipart) diff --git a/actix-multipart/examples/form.rs b/actix-multipart/examples/form.rs new file mode 100644 index 000000000..a90aeff96 --- /dev/null +++ b/actix-multipart/examples/form.rs @@ -0,0 +1,36 @@ +use actix_multipart::form::{json::Json as MpJson, tempfile::TempFile, MultipartForm}; +use actix_web::{middleware::Logger, post, App, HttpServer, Responder}; +use serde::Deserialize; + +#[derive(Debug, Deserialize)] +struct Metadata { + name: String, +} + +#[derive(Debug, MultipartForm)] +struct UploadForm { + #[multipart(limit = "100MB")] + file: TempFile, + json: MpJson, +} + +#[post("/videos")] +async fn post_video(MultipartForm(form): MultipartForm) -> impl Responder { + format!( + "Uploaded file {}, with size: {}\ntemporary file ({}) was deleted\n", + form.json.name, + form.file.size, + form.file.file.path().display(), + ) +} + +#[actix_web::main] +async fn main() -> std::io::Result<()> { + env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); + + HttpServer::new(move || App::new().service(post_video).wrap(Logger::default())) + .workers(2) + .bind(("127.0.0.1", 8080))? + .run() + .await +} diff --git a/actix-multipart/src/error.rs b/actix-multipart/src/error.rs index 77b5a559f..30ef63c1a 100644 --- a/actix-multipart/src/error.rs +++ b/actix-multipart/src/error.rs @@ -11,77 +11,95 @@ use derive_more::{Display, Error, From}; #[derive(Debug, Display, From, Error)] #[non_exhaustive] pub enum MultipartError { - /// Content-Disposition header is not found or is not equal to "form-data". + /// Could not find Content-Type header. + #[display(fmt = "Could not find Content-Type header")] + ContentTypeMissing, + + /// Could not parse Content-Type header. + #[display(fmt = "Could not parse Content-Type header")] + ContentTypeParse, + + /// Parsed Content-Type did not have "multipart" top-level media type. /// - /// According to [RFC 7578 §4.2](https://datatracker.ietf.org/doc/html/rfc7578#section-4.2) a - /// Content-Disposition header must always be present and equal to "form-data". - #[display(fmt = "No Content-Disposition `form-data` header")] - NoContentDisposition, + /// Also raised when extracting a [`MultipartForm`] from a request that does not have the + /// "multipart/form-data" media type. + /// + /// [`MultipartForm`]: struct@crate::form::MultipartForm + #[display(fmt = "Parsed Content-Type did not have "multipart" top-level media type")] + ContentTypeIncompatible, - /// Content-Type header is not found - #[display(fmt = "No Content-Type header found")] - NoContentType, - - /// Can not parse Content-Type header - #[display(fmt = "Can not parse Content-Type header")] - ParseContentType, - - /// Multipart boundary is not found + /// Multipart boundary is not found. #[display(fmt = "Multipart boundary is not found")] - Boundary, + BoundaryMissing, - /// Nested multipart is not supported + /// Content-Disposition header was not found or not of disposition type "form-data" when parsing + /// a "form-data" field. + /// + /// As per [RFC 7578 §4.2], a "multipart/form-data" field's Content-Disposition header must + /// always be present and have a disposition type of "form-data". + /// + /// [RFC 7578 §4.2]: https://datatracker.ietf.org/doc/html/rfc7578#section-4.2 + #[display(fmt = "Content-Disposition header was not found when parsing a \"form-data\" field")] + ContentDispositionMissing, + + /// Content-Disposition name parameter was not found when parsing a "form-data" field. + /// + /// As per [RFC 7578 §4.2], a "multipart/form-data" field's Content-Disposition header must + /// always include a "name" parameter. + /// + /// [RFC 7578 §4.2]: https://datatracker.ietf.org/doc/html/rfc7578#section-4.2 + #[display(fmt = "Content-Disposition header was not found when parsing a \"form-data\" field")] + ContentDispositionNameMissing, + + /// Nested multipart is not supported. #[display(fmt = "Nested multipart is not supported")] Nested, - /// Multipart stream is incomplete + /// Multipart stream is incomplete. #[display(fmt = "Multipart stream is incomplete")] Incomplete, - /// Error during field parsing - #[display(fmt = "{}", _0)] + /// Field parsing failed. + #[display(fmt = "Error during field parsing")] Parse(ParseError), - /// Payload error - #[display(fmt = "{}", _0)] + /// HTTP payload error. + #[display(fmt = "Payload error")] Payload(PayloadError), - /// Not consumed - #[display(fmt = "Multipart stream is not consumed")] + /// Stream is not consumed. + #[display(fmt = "Stream is not consumed")] NotConsumed, - /// An error from a field handler in a form - #[display( - fmt = "An error occurred processing field `{}`: {}", - field_name, - source - )] + /// Form field handler raised error. + #[display(fmt = "An error occurred processing field: {name}")] Field { - field_name: String, + name: String, source: actix_web::Error, }, - /// Duplicate field - #[display(fmt = "Duplicate field found for: `{}`", _0)] + /// Duplicate field found (for structure that opted-in to denying duplicate fields). + #[display(fmt = "Duplicate field found: {_0}")] #[from(ignore)] DuplicateField(#[error(not(source))] String), - /// Missing field - #[display(fmt = "Field with name `{}` is required", _0)] + /// Required field is missing. + #[display(fmt = "Required field is missing: {_0}")] #[from(ignore)] MissingField(#[error(not(source))] String), - /// Unknown field - #[display(fmt = "Unsupported field `{}`", _0)] + /// Unknown field (for structure that opted-in to denying unknown fields). + #[display(fmt = "Unknown field: {_0}")] #[from(ignore)] - UnsupportedField(#[error(not(source))] String), + UnknownField(#[error(not(source))] String), } -/// Return `BadRequest` for `MultipartError` +/// Return `BadRequest` for `MultipartError`. impl ResponseError for MultipartError { fn status_code(&self) -> StatusCode { match &self { MultipartError::Field { source, .. } => source.as_response_error().status_code(), + MultipartError::ContentTypeIncompatible => StatusCode::UNSUPPORTED_MEDIA_TYPE, _ => StatusCode::BAD_REQUEST, } } @@ -93,7 +111,7 @@ mod tests { #[test] fn test_multipart_error() { - let resp = MultipartError::Boundary.error_response(); + let resp = MultipartError::BoundaryMissing.error_response(); assert_eq!(resp.status(), StatusCode::BAD_REQUEST); } } diff --git a/actix-multipart/src/extractor.rs b/actix-multipart/src/extractor.rs index 56ed69ae4..ab98f887e 100644 --- a/actix-multipart/src/extractor.rs +++ b/actix-multipart/src/extractor.rs @@ -10,6 +10,7 @@ use crate::server::Multipart; /// Content-type: multipart/form-data; /// /// # Examples +/// /// ``` /// use actix_web::{web, HttpResponse, Error}; /// use actix_multipart::Multipart; @@ -35,9 +36,6 @@ impl FromRequest for Multipart { #[inline] fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future { - ready(Ok(match Multipart::boundary(req.headers()) { - Ok(boundary) => Multipart::from_boundary(boundary, payload.take()), - Err(err) => Multipart::from_error(err), - })) + ready(Ok(Multipart::from_req(req, payload))) } } diff --git a/actix-multipart/src/form/bytes.rs b/actix-multipart/src/form/bytes.rs index 3c5e2eb10..c152db3d0 100644 --- a/actix-multipart/src/form/bytes.rs +++ b/actix-multipart/src/form/bytes.rs @@ -41,8 +41,9 @@ impl<'t> FieldReader<'t> for Bytes { content_type: field.content_type().map(ToOwned::to_owned), file_name: field .content_disposition() + .expect("multipart form fields should have a content-disposition header") .get_filename() - .map(str::to_owned), + .map(ToOwned::to_owned), }) }) } diff --git a/actix-multipart/src/form/json.rs b/actix-multipart/src/form/json.rs index bb4e03bf6..3504c340c 100644 --- a/actix-multipart/src/form/json.rs +++ b/actix-multipart/src/form/json.rs @@ -32,7 +32,6 @@ where fn read_field(req: &'t HttpRequest, field: Field, limits: &'t mut Limits) -> Self::Future { Box::pin(async move { let config = JsonConfig::from_req(req); - let field_name = field.name().to_owned(); if config.validate_content_type { let valid = if let Some(mime) = field.content_type() { @@ -43,17 +42,19 @@ where if !valid { return Err(MultipartError::Field { - field_name, + name: field.form_field_name, source: config.map_error(req, JsonFieldError::ContentType), }); } } + let form_field_name = field.form_field_name.clone(); + let bytes = Bytes::read_field(req, field, limits).await?; Ok(Json(serde_json::from_slice(bytes.data.as_ref()).map_err( |err| MultipartError::Field { - field_name, + name: form_field_name, source: config.map_error(req, JsonFieldError::Deserialize(err)), }, )?)) diff --git a/actix-multipart/src/form/mod.rs b/actix-multipart/src/form/mod.rs index 68cdefec5..9441d249f 100644 --- a/actix-multipart/src/form/mod.rs +++ b/actix-multipart/src/form/mod.rs @@ -80,13 +80,13 @@ where state: &'t mut State, duplicate_field: DuplicateField, ) -> Self::Future { - if state.contains_key(field.name()) { + if state.contains_key(&field.form_field_name) { match duplicate_field { DuplicateField::Ignore => return Box::pin(ready(Ok(()))), DuplicateField::Deny => { return Box::pin(ready(Err(MultipartError::DuplicateField( - field.name().to_owned(), + field.form_field_name, )))) } @@ -95,7 +95,7 @@ where } Box::pin(async move { - let field_name = field.name().to_owned(); + let field_name = field.form_field_name.clone(); let t = T::read_field(req, field, limits).await?; state.insert(field_name, Box::new(t)); Ok(()) @@ -123,10 +123,8 @@ where Box::pin(async move { // Note: Vec GroupReader always allows duplicates - let field_name = field.name().to_owned(); - let vec = state - .entry(field_name) + .entry(field.form_field_name.clone()) .or_insert_with(|| Box::>::default()) .downcast_mut::>() .unwrap(); @@ -159,13 +157,13 @@ where state: &'t mut State, duplicate_field: DuplicateField, ) -> Self::Future { - if state.contains_key(field.name()) { + if state.contains_key(&field.form_field_name) { match duplicate_field { DuplicateField::Ignore => return Box::pin(ready(Ok(()))), DuplicateField::Deny => { return Box::pin(ready(Err(MultipartError::DuplicateField( - field.name().to_owned(), + field.form_field_name, )))) } @@ -174,7 +172,7 @@ where } Box::pin(async move { - let field_name = field.name().to_owned(); + let field_name = field.form_field_name.clone(); let t = T::read_field(req, field, limits).await?; state.insert(field_name, Box::new(t)); Ok(()) @@ -281,6 +279,9 @@ impl Limits { /// [`MultipartCollect`] trait. You should use the [`macro@MultipartForm`] macro to derive this /// for your struct. /// +/// Note that this extractor rejects requests with any other Content-Type such as `multipart/mixed`, +/// `multipart/related`, or non-multipart media types. +/// /// Add a [`MultipartFormConfig`] to your app data to configure extraction. #[derive(Deref, DerefMut)] pub struct MultipartForm(pub T); @@ -294,14 +295,24 @@ impl MultipartForm { impl FromRequest for MultipartForm where - T: MultipartCollect, + T: MultipartCollect + 'static, { type Error = Error; type Future = LocalBoxFuture<'static, Result>; #[inline] fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future { - let mut payload = Multipart::new(req.headers(), payload.take()); + let mut multipart = Multipart::from_req(req, payload); + + let content_type = match multipart.content_type_or_bail() { + Ok(content_type) => content_type, + Err(err) => return Box::pin(ready(Err(err.into()))), + }; + + if content_type.subtype() != mime::FORM_DATA { + // this extractor only supports multipart/form-data + return Box::pin(ready(Err(MultipartError::ContentTypeIncompatible.into()))); + }; let config = MultipartFormConfig::from_req(req); let mut limits = Limits::new(config.total_limit, config.memory_limit); @@ -313,14 +324,20 @@ where Box::pin( async move { let mut state = State::default(); - // We need to ensure field limits are shared for all instances of this field name + + // ensure limits are shared for all fields with this name let mut field_limits = HashMap::>::new(); - while let Some(field) = payload.try_next().await? { + while let Some(field) = multipart.try_next().await? { + debug_assert!( + !field.form_field_name.is_empty(), + "multipart form fields should have names", + ); + // Retrieve the limit for this field let entry = field_limits - .entry(field.name().to_owned()) - .or_insert_with(|| T::limit(field.name())); + .entry(field.form_field_name.clone()) + .or_insert_with(|| T::limit(&field.form_field_name)); limits.field_limit_remaining.clone_from(entry); @@ -329,6 +346,7 @@ where // Update the stored limit *entry = limits.field_limit_remaining; } + let inner = T::from_state(state)?; Ok(MultipartForm(inner)) } @@ -752,6 +770,41 @@ mod tests { assert_eq!(response.status(), StatusCode::BAD_REQUEST); } + #[actix_rt::test] + async fn non_multipart_form_data() { + #[derive(MultipartForm)] + struct TestNonMultipartFormData { + #[allow(unused)] + #[multipart(limit = "30B")] + foo: Text, + } + + async fn non_multipart_form_data_route( + _form: MultipartForm, + ) -> String { + unreachable!("request is sent with multipart/mixed"); + } + + let srv = actix_test::start(|| { + App::new().route("/", web::post().to(non_multipart_form_data_route)) + }); + + let mut form = multipart::Form::default(); + form.add_text("foo", "foo"); + + // mangle content-type, keeping the boundary + let ct = form.content_type().replacen("/form-data", "/mixed", 1); + + let res = Client::default() + .post(srv.url("/")) + .content_type(ct) + .send_body(multipart::Body::from(form)) + .await + .unwrap(); + + assert_eq!(res.status(), StatusCode::UNSUPPORTED_MEDIA_TYPE); + } + #[should_panic(expected = "called `Result::unwrap()` on an `Err` value: Connect(Disconnected)")] #[actix_web::test] async fn field_try_next_panic() { diff --git a/actix-multipart/src/form/tempfile.rs b/actix-multipart/src/form/tempfile.rs index 9371a026b..f329876f2 100644 --- a/actix-multipart/src/form/tempfile.rs +++ b/actix-multipart/src/form/tempfile.rs @@ -42,38 +42,36 @@ impl<'t> FieldReader<'t> for TempFile { 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.form_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.form_field_name, TempFileError::FileIo(err)) + })?); while let Some(chunk) = field.try_next().await? { limits.try_consume_limits(chunk.len(), false)?; size += chunk.len(); file_async.write_all(chunk.as_ref()).await.map_err(|err| { - config.map_error(req, &field_name, TempFileError::FileIo(err)) + config.map_error(req, &field.form_field_name, TempFileError::FileIo(err)) })?; } - 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.form_field_name, TempFileError::FileIo(err)) + })?; Ok(TempFile { file, content_type: field.content_type().map(ToOwned::to_owned), file_name: field .content_disposition() + .expect("multipart form fields should have a content-disposition header") .get_filename() - .map(str::to_owned), + .map(ToOwned::to_owned), size, }) }) @@ -137,7 +135,7 @@ impl TempFileConfig { }; MultipartError::Field { - field_name: field_name.to_owned(), + name: field_name.to_owned(), source, } } diff --git a/actix-multipart/src/form/text.rs b/actix-multipart/src/form/text.rs index 83e211524..67a434ee6 100644 --- a/actix-multipart/src/form/text.rs +++ b/actix-multipart/src/form/text.rs @@ -36,7 +36,6 @@ where fn read_field(req: &'t HttpRequest, field: Field, limits: &'t mut Limits) -> Self::Future { Box::pin(async move { let config = TextConfig::from_req(req); - let field_name = field.name().to_owned(); if config.validate_content_type { let valid = if let Some(mime) = field.content_type() { @@ -49,22 +48,24 @@ where if !valid { return Err(MultipartError::Field { - field_name, + name: field.form_field_name, source: config.map_error(req, TextError::ContentType), }); } } + let form_field_name = field.form_field_name.clone(); + let bytes = Bytes::read_field(req, field, limits).await?; let text = str::from_utf8(&bytes.data).map_err(|err| MultipartError::Field { - field_name: field_name.clone(), + name: form_field_name.clone(), source: config.map_error(req, TextError::Utf8Error(err)), })?; Ok(Text(serde_plain::from_str(text).map_err(|err| { MultipartError::Field { - field_name, + name: form_field_name, source: config.map_error(req, TextError::Deserialize(err)), } })?)) diff --git a/actix-multipart/src/lib.rs b/actix-multipart/src/lib.rs index 51b06db38..853648beb 100644 --- a/actix-multipart/src/lib.rs +++ b/actix-multipart/src/lib.rs @@ -5,7 +5,7 @@ //! ```no_run //! use actix_web::{post, App, HttpServer, Responder}; //! -//! use actix_multipart::form::{json::Json as MPJson, tempfile::TempFile, MultipartForm}; +//! use actix_multipart::form::{json::Json as MpJson, tempfile::TempFile, MultipartForm}; //! use serde::Deserialize; //! //! #[derive(Debug, Deserialize)] @@ -17,7 +17,7 @@ //! struct UploadForm { //! #[multipart(limit = "100MB")] //! file: TempFile, -//! json: MPJson, +//! json: MpJson, //! } //! //! #[post("/videos")] @@ -36,6 +36,15 @@ //! .await //! } //! ``` +//! +//! cURL request: +//! +//! ```sh +//! curl -v --request POST \ +//! --url http://localhost:8080/videos \ +//! -F 'json={"name": "Cargo.lock"};type=application/json' \ +//! -F file=@./Cargo.lock +//! ``` #![deny(rust_2018_idioms, nonstandard_style)] #![warn(future_incompatible)] @@ -57,7 +66,4 @@ pub mod test; pub use self::{ error::MultipartError, server::{Field, Multipart}, - test::{ - create_form_data_payload_and_headers, create_form_data_payload_and_headers_with_boundary, - }, }; diff --git a/actix-multipart/src/server.rs b/actix-multipart/src/server.rs index 0256aa7bf..76eae11ff 100644 --- a/actix-multipart/src/server.rs +++ b/actix-multipart/src/server.rs @@ -10,12 +10,15 @@ use std::{ }; use actix_web::{ + dev, error::{ParseError, PayloadError}, http::header::{self, ContentDisposition, HeaderMap, HeaderName, HeaderValue}, + HttpRequest, }; use bytes::{Bytes, BytesMut}; use futures_core::stream::{LocalBoxStream, Stream}; use local_waker::LocalWaker; +use mime::Mime; use crate::error::MultipartError; @@ -23,87 +26,79 @@ const MAX_HEADERS: usize = 32; /// The server-side implementation of `multipart/form-data` requests. /// -/// This will parse the incoming stream into `MultipartItem` instances via its -/// Stream implementation. -/// `MultipartItem::Field` contains multipart field. `MultipartItem::Multipart` -/// is used for nested multipart streams. +/// This will parse the incoming stream into `MultipartItem` instances via its `Stream` +/// implementation. `MultipartItem::Field` contains multipart field. `MultipartItem::Multipart` is +/// used for nested multipart streams. pub struct Multipart { safety: Safety, - error: Option, inner: Option, -} - -enum InnerMultipartItem { - None, - Field(Rc>), -} - -#[derive(PartialEq, Debug)] -enum InnerState { - /// Stream eof - Eof, - - /// Skip data until first boundary - FirstBoundary, - - /// Reading boundary - Boundary, - - /// Reading Headers, - Headers, -} - -struct InnerMultipart { - payload: PayloadRef, - boundary: String, - state: InnerState, - item: InnerMultipartItem, + error: Option, } impl Multipart { - /// Create multipart instance for boundary. - pub fn new(headers: &HeaderMap, stream: S) -> Multipart + /// Creates multipart instance from parts. + pub fn new(headers: &HeaderMap, stream: S) -> Self where S: Stream> + 'static, { - match Self::boundary(headers) { - Ok(boundary) => Multipart::from_boundary(boundary, stream), - Err(err) => Multipart::from_error(err), + match Self::find_ct_and_boundary(headers) { + Ok((ct, boundary)) => Self::from_ct_and_boundary(ct, boundary, stream), + Err(err) => Self::from_error(err), } } - /// Extract boundary info from headers. - pub(crate) fn boundary(headers: &HeaderMap) -> Result { - headers - .get(&header::CONTENT_TYPE) - .ok_or(MultipartError::NoContentType)? - .to_str() - .ok() - .and_then(|content_type| content_type.parse::().ok()) - .ok_or(MultipartError::ParseContentType)? - .get_param(mime::BOUNDARY) - .map(|boundary| boundary.as_str().to_owned()) - .ok_or(MultipartError::Boundary) + /// Creates multipart instance from parts. + pub(crate) fn from_req(req: &HttpRequest, payload: &mut dev::Payload) -> Self { + match Self::find_ct_and_boundary(req.headers()) { + Ok((ct, boundary)) => Self::from_ct_and_boundary(ct, boundary, payload.take()), + Err(err) => Self::from_error(err), + } } - /// Create multipart instance for given boundary and stream - pub(crate) fn from_boundary(boundary: String, stream: S) -> Multipart + /// Extract Content-Type and boundary info from headers. + pub(crate) fn find_ct_and_boundary( + headers: &HeaderMap, + ) -> Result<(Mime, String), MultipartError> { + let content_type = headers + .get(&header::CONTENT_TYPE) + .ok_or(MultipartError::ContentTypeMissing)? + .to_str() + .ok() + .and_then(|content_type| content_type.parse::().ok()) + .ok_or(MultipartError::ContentTypeParse)?; + + if content_type.type_() != mime::MULTIPART { + return Err(MultipartError::ContentTypeIncompatible); + } + + let boundary = content_type + .get_param(mime::BOUNDARY) + .ok_or(MultipartError::BoundaryMissing)? + .as_str() + .to_owned(); + + Ok((content_type, boundary)) + } + + /// Constructs a new multipart reader from given Content-Type, boundary, and stream. + pub(crate) fn from_ct_and_boundary(ct: Mime, boundary: String, stream: S) -> Multipart where S: Stream> + 'static, { Multipart { - error: None, safety: Safety::new(), inner: Some(InnerMultipart { - boundary, payload: PayloadRef::new(PayloadBuffer::new(stream)), + content_type: ct, + boundary, state: InnerState::FirstBoundary, item: InnerMultipartItem::None, }), + error: None, } } - /// Create Multipart instance from MultipartError + /// Constructs a new multipart reader from given `MultipartError`. pub(crate) fn from_error(err: MultipartError) -> Multipart { Multipart { error: Some(err), @@ -111,6 +106,21 @@ impl Multipart { inner: None, } } + + /// Return requests parsed Content-Type or raise the stored error. + pub(crate) fn content_type_or_bail(&mut self) -> Result { + if let Some(err) = self.error.take() { + return Err(err); + } + + Ok(self + .inner + .as_ref() + // TODO: look into using enum instead of two options + .expect("multipart requests should have state") + .content_type + .clone()) + } } impl Stream for Multipart { @@ -141,8 +151,46 @@ impl Stream for Multipart { } } +#[derive(PartialEq, Debug)] +enum InnerState { + /// Stream EOF. + Eof, + + /// Skip data until first boundary. + FirstBoundary, + + /// Reading boundary. + Boundary, + + /// Reading Headers. + Headers, +} + +enum InnerMultipartItem { + None, + Field(Rc>), +} + +struct InnerMultipart { + /// Request's payload stream & buffer. + payload: PayloadRef, + + /// Request's Content-Type. + /// + /// Guaranteed to have "multipart" top-level media type, i.e., `multipart/*`. + content_type: Mime, + + /// Field boundary. + boundary: String, + + state: InnerState, + item: InnerMultipartItem, +} + impl InnerMultipart { - fn read_headers(payload: &mut PayloadBuffer) -> Result, MultipartError> { + fn read_field_headers( + payload: &mut PayloadBuffer, + ) -> Result, MultipartError> { match payload.read_until(b"\r\n\r\n")? { None => { if payload.eof { @@ -153,6 +201,7 @@ impl InnerMultipart { } Some(bytes) => { let mut hdrs = [httparse::EMPTY_HEADER; MAX_HEADERS]; + match httparse::parse_headers(&bytes, &mut hdrs) { Ok(httparse::Status::Complete((_, hdrs))) => { // convert headers @@ -193,7 +242,7 @@ impl InnerMultipart { || &chunk[..2] != b"--" || &chunk[2..boundary.len() + 2] != boundary.as_bytes() { - Err(MultipartError::Boundary) + Err(MultipartError::BoundaryMissing) } else if &chunk[boundary.len() + 2..] == b"\r\n" { Ok(Some(false)) } else if &chunk[boundary.len() + 2..boundary.len() + 4] == b"--" @@ -202,7 +251,7 @@ impl InnerMultipart { { Ok(Some(true)) } else { - Err(MultipartError::Boundary) + Err(MultipartError::BoundaryMissing) } } } @@ -217,7 +266,7 @@ impl InnerMultipart { match payload.readline()? { Some(chunk) => { if chunk.is_empty() { - return Err(MultipartError::Boundary); + return Err(MultipartError::BoundaryMissing); } if chunk.len() < boundary.len() { continue; @@ -282,7 +331,7 @@ impl InnerMultipart { } } - let headers = if let Some(mut payload) = self.payload.get_mut(safety) { + let field_headers = if let Some(mut payload) = self.payload.get_mut(safety) { match self.state { // read until first boundary InnerState::FirstBoundary => { @@ -317,7 +366,7 @@ impl InnerMultipart { // read field headers for next field if self.state == InnerState::Headers { - if let Some(headers) = InnerMultipart::read_headers(&mut payload)? { + if let Some(headers) = InnerMultipart::read_field_headers(&mut payload)? { self.state = InnerState::Boundary; headers } else { @@ -331,31 +380,37 @@ impl InnerMultipart { return Poll::Pending; }; - // According to RFC 7578 §4.2, a Content-Disposition header must always be present and - // set to "form-data". - - let content_disposition = headers + let field_content_disposition = field_headers .get(&header::CONTENT_DISPOSITION) .and_then(|cd| ContentDisposition::from_raw(cd).ok()) .filter(|content_disposition| { - let is_form_data = - content_disposition.disposition == header::DispositionType::FormData; - - let has_field_name = content_disposition - .parameters - .iter() - .any(|param| matches!(param, header::DispositionParam::Name(_))); - - is_form_data && has_field_name + matches!( + content_disposition.disposition, + header::DispositionType::FormData, + ) }); - let cd = if let Some(content_disposition) = content_disposition { - content_disposition + let form_field_name = if self.content_type.subtype() == mime::FORM_DATA { + // According to RFC 7578 §4.2, which relates to "multipart/form-data" requests + // specifically, fields must have a Content-Disposition header, its disposition + // type must be set as "form-data", and it must have a name parameter. + + let Some(cd) = &field_content_disposition else { + return Poll::Ready(Some(Err(MultipartError::ContentDispositionMissing))); + }; + + let Some(field_name) = cd.get_name() else { + return Poll::Ready(Some(Err(MultipartError::ContentDispositionNameMissing))); + }; + + Some(field_name.to_owned()) } else { - return Poll::Ready(Some(Err(MultipartError::NoContentDisposition))); + None }; - let ct: Option = headers + // TODO: check out other multipart/* RFCs for specific requirements + + let field_content_type: Option = field_headers .get(&header::CONTENT_TYPE) .and_then(|ct| ct.to_str().ok()) .and_then(|ct| ct.parse().ok()); @@ -363,23 +418,24 @@ impl InnerMultipart { self.state = InnerState::Boundary; // nested multipart stream is not supported - if let Some(mime) = &ct { + if let Some(mime) = &field_content_type { if mime.type_() == mime::MULTIPART { return Poll::Ready(Some(Err(MultipartError::Nested))); } } - let field = - InnerField::new_in_rc(self.payload.clone(), self.boundary.clone(), &headers)?; + let field_inner = + InnerField::new_in_rc(self.payload.clone(), self.boundary.clone(), &field_headers)?; - self.item = InnerMultipartItem::Field(Rc::clone(&field)); + self.item = InnerMultipartItem::Field(Rc::clone(&field_inner)); Poll::Ready(Some(Ok(Field::new( + field_content_type, + field_content_disposition, + form_field_name, + field_headers, safety.clone(cx), - headers, - ct, - cd, - field, + field_inner, )))) } } @@ -392,26 +448,42 @@ impl Drop for InnerMultipart { } } -/// A single field in a multipart stream +/// A single field in a multipart stream. pub struct Field { - ct: Option, - cd: ContentDisposition, + /// Field's Content-Type. + content_type: Option, + + /// Field's Content-Disposition. + content_disposition: Option, + + /// Form field name. + /// + /// A non-optional storage for form field names to avoid unwraps in `form` module. Will be an + /// empty string in non-form contexts. + /// + // INVARIANT: always non-empty when request content-type is multipart/form-data. + pub(crate) form_field_name: String, + + /// Field's header map. headers: HeaderMap, - inner: Rc>, + safety: Safety, + inner: Rc>, } impl Field { fn new( - safety: Safety, + content_type: Option, + content_disposition: Option, + form_field_name: Option, headers: HeaderMap, - ct: Option, - cd: ContentDisposition, + safety: Safety, inner: Rc>, ) -> Self { Field { - ct, - cd, + content_type, + content_disposition, + form_field_name: form_field_name.unwrap_or_default(), headers, inner, safety, @@ -428,34 +500,36 @@ impl Field { /// According to [RFC 7578](https://www.rfc-editor.org/rfc/rfc7578#section-4.4), if it is not /// present, it should default to "text/plain". Note it is the responsibility of the client to /// provide the appropriate content type, there is no attempt to validate this by the server. - pub fn content_type(&self) -> Option<&mime::Mime> { - self.ct.as_ref() + pub fn content_type(&self) -> Option<&Mime> { + self.content_type.as_ref() } - /// Returns the field's Content-Disposition. + /// Returns this field's parsed Content-Disposition header, if set. /// - /// Per [RFC 7578 §4.2]: "Each part MUST contain a Content-Disposition header field where the - /// disposition type is `form-data`. The Content-Disposition header field MUST also contain an - /// additional parameter of `name`; the value of the `name` parameter is the original field name - /// from the form." + /// # Validation /// - /// This crate validates that it exists before returning a `Field`. As such, it is safe to - /// unwrap `.content_disposition().get_name()`. The [name](Self::name) method is provided as - /// a convenience. + /// Per [RFC 7578 §4.2], the parts of a multipart/form-data payload MUST contain a + /// Content-Disposition header field where the disposition type is `form-data` and MUST also + /// contain an additional parameter of `name` with its value being the original field name from + /// the form. This requirement is enforced during extraction for multipart/form-data requests, + /// but not other kinds of multipart requests (such as multipart/related). + /// + /// As such, it is safe to `.unwrap()` calls `.content_disposition()` if you've verified. + /// + /// The [`name()`](Self::name) method is also provided as a convenience for obtaining the + /// aforementioned name parameter. /// /// [RFC 7578 §4.2]: https://datatracker.ietf.org/doc/html/rfc7578#section-4.2 - pub fn content_disposition(&self) -> &ContentDisposition { - &self.cd + pub fn content_disposition(&self) -> Option<&ContentDisposition> { + self.content_disposition.as_ref() } - /// Returns the field's name. + /// Returns the field's name, if set. /// - /// See [content_disposition](Self::content_disposition) regarding guarantees about existence of - /// the name field. - pub fn name(&self) -> &str { - self.content_disposition() - .get_name() - .expect("field name should be guaranteed to exist in multipart form-data") + /// See [`content_disposition()`](Self::content_disposition) regarding guarantees on presence of + /// the "name" field. + pub fn name(&self) -> Option<&str> { + self.content_disposition()?.get_name() } } @@ -465,6 +539,7 @@ impl Stream for Field { fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.get_mut(); let mut inner = this.inner.borrow_mut(); + if let Some(mut buffer) = inner .payload .as_ref() @@ -486,7 +561,7 @@ impl Stream for Field { impl fmt::Debug for Field { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if let Some(ct) = &self.ct { + if let Some(ct) = &self.content_type { writeln!(f, "\nField: {}", ct)?; } else { writeln!(f, "\nField:")?; @@ -570,6 +645,7 @@ impl InnerField { } /// Reads content chunk of body part with unknown length. + /// /// The `Content-Length` header for body part is not necessary. fn read_stream( payload: &mut PayloadBuffer, @@ -704,8 +780,8 @@ impl PayloadRef { } } - fn get_mut(&self, s: &Safety) -> Option> { - if s.current() { + fn get_mut(&self, safety: &Safety) -> Option> { + if safety.current() { Some(self.payload.borrow_mut()) } else { None @@ -722,10 +798,11 @@ impl Clone for PayloadRef { } /// Counter. It tracks of number of clones of payloads and give access to payload only to top most. -/// * When dropped, parent task is awakened. This is to support the case where Field is -/// dropped in a separate task than Multipart. -/// * Assumes that parent owners don't move to different tasks; only the top-most is allowed to. -/// * If dropped and is not top most owner, is_clean flag is set to false. +/// +/// - When dropped, parent task is awakened. This is to support the case where `Field` is dropped in +/// a separate task than `Multipart`. +/// - Assumes that parent owners don't move to different tasks; only the top-most is allowed to. +/// - If dropped and is not top most owner, is_clean flag is set to false. #[derive(Debug)] struct Safety { task: LocalWaker, @@ -876,6 +953,7 @@ mod tests { test::TestRequest, FromRequest, }; + use assert_matches::assert_matches; use bytes::BufMut as _; use futures_util::{future::lazy, StreamExt as _}; use tokio::sync::mpsc; @@ -888,8 +966,8 @@ mod tests { #[actix_rt::test] async fn test_boundary() { let headers = HeaderMap::new(); - match Multipart::boundary(&headers) { - Err(MultipartError::NoContentType) => {} + match Multipart::find_ct_and_boundary(&headers) { + Err(MultipartError::ContentTypeMissing) => {} _ => unreachable!("should not happen"), } @@ -899,8 +977,8 @@ mod tests { header::HeaderValue::from_static("test"), ); - match Multipart::boundary(&headers) { - Err(MultipartError::ParseContentType) => {} + match Multipart::find_ct_and_boundary(&headers) { + Err(MultipartError::ContentTypeParse) => {} _ => unreachable!("should not happen"), } @@ -909,8 +987,8 @@ mod tests { header::CONTENT_TYPE, header::HeaderValue::from_static("multipart/mixed"), ); - match Multipart::boundary(&headers) { - Err(MultipartError::Boundary) => {} + match Multipart::find_ct_and_boundary(&headers) { + Err(MultipartError::BoundaryMissing) => {} _ => unreachable!("should not happen"), } @@ -923,8 +1001,8 @@ mod tests { ); assert_eq!( - Multipart::boundary(&headers).unwrap(), - "5c02368e880e436dab70ed54e1c58209" + Multipart::find_ct_and_boundary(&headers).unwrap().1, + "5c02368e880e436dab70ed54e1c58209", ); } @@ -1059,7 +1137,7 @@ mod tests { let mut multipart = Multipart::new(&headers, payload); match multipart.next().await { Some(Ok(mut field)) => { - let cd = field.content_disposition(); + let cd = field.content_disposition().unwrap(); assert_eq!(cd.disposition, DispositionType::FormData); assert_eq!(cd.parameters[0], DispositionParam::Name("file".into())); @@ -1121,7 +1199,7 @@ mod tests { let mut multipart = Multipart::new(&headers, payload); match multipart.next().await.unwrap() { Ok(mut field) => { - let cd = field.content_disposition(); + let cd = field.content_disposition().unwrap(); assert_eq!(cd.disposition, DispositionType::FormData); assert_eq!(cd.parameters[0], DispositionParam::Name("file".into())); @@ -1245,7 +1323,7 @@ mod tests { #[actix_rt::test] async fn test_multipart_from_error() { - let err = MultipartError::NoContentType; + let err = MultipartError::ContentTypeMissing; let mut multipart = Multipart::from_error(err); assert!(multipart.next().await.unwrap().is_err()) } @@ -1254,9 +1332,8 @@ mod tests { async fn test_multipart_from_boundary() { let (_, payload) = create_stream(); let (_, headers) = create_simple_request_with_header(); - let boundary = Multipart::boundary(&headers); - assert!(boundary.is_ok()); - let _ = Multipart::from_boundary(boundary.unwrap(), payload); + let (ct, boundary) = Multipart::find_ct_and_boundary(&headers).unwrap(); + let _ = Multipart::from_ct_and_boundary(ct, boundary, payload); } #[actix_rt::test] @@ -1278,11 +1355,43 @@ mod tests { } #[actix_rt::test] - async fn no_content_disposition() { + async fn no_content_disposition_form_data() { let bytes = Bytes::from( "testasdadsad\r\n\ --abbc761f78ff4d7cb7573b5a23f96ef0\r\n\ - Content-Type: text/plain; charset=utf-8\r\nContent-Length: 4\r\n\r\n\ + Content-Type: text/plain; charset=utf-8\r\n\ + Content-Length: 4\r\n\ + \r\n\ + test\r\n\ + --abbc761f78ff4d7cb7573b5a23f96ef0\r\n", + ); + let mut headers = HeaderMap::new(); + headers.insert( + header::CONTENT_TYPE, + header::HeaderValue::from_static( + "multipart/form-data; boundary=\"abbc761f78ff4d7cb7573b5a23f96ef0\"", + ), + ); + let payload = SlowStream::new(bytes); + + let mut multipart = Multipart::new(&headers, payload); + let res = multipart.next().await.unwrap(); + assert_matches!( + res.expect_err( + "according to RFC 7578, form-data fields require a content-disposition header" + ), + MultipartError::ContentDispositionMissing + ); + } + + #[actix_rt::test] + async fn no_content_disposition_non_form_data() { + let bytes = Bytes::from( + "testasdadsad\r\n\ + --abbc761f78ff4d7cb7573b5a23f96ef0\r\n\ + Content-Type: text/plain; charset=utf-8\r\n\ + Content-Length: 4\r\n\ + \r\n\ test\r\n\ --abbc761f78ff4d7cb7573b5a23f96ef0\r\n", ); @@ -1297,20 +1406,18 @@ mod tests { let mut multipart = Multipart::new(&headers, payload); let res = multipart.next().await.unwrap(); - assert!(res.is_err()); - assert!(matches!( - res.unwrap_err(), - MultipartError::NoContentDisposition, - )); + res.unwrap(); } #[actix_rt::test] - async fn no_name_in_content_disposition() { + async fn no_name_in_form_data_content_disposition() { let bytes = Bytes::from( "testasdadsad\r\n\ --abbc761f78ff4d7cb7573b5a23f96ef0\r\n\ Content-Disposition: form-data; filename=\"fn.txt\"\r\n\ - Content-Type: text/plain; charset=utf-8\r\nContent-Length: 4\r\n\r\n\ + Content-Type: text/plain; charset=utf-8\r\n\ + Content-Length: 4\r\n\ + \r\n\ test\r\n\ --abbc761f78ff4d7cb7573b5a23f96ef0\r\n", ); @@ -1318,18 +1425,17 @@ mod tests { headers.insert( header::CONTENT_TYPE, header::HeaderValue::from_static( - "multipart/mixed; boundary=\"abbc761f78ff4d7cb7573b5a23f96ef0\"", + "multipart/form-data; boundary=\"abbc761f78ff4d7cb7573b5a23f96ef0\"", ), ); let payload = SlowStream::new(bytes); let mut multipart = Multipart::new(&headers, payload); let res = multipart.next().await.unwrap(); - assert!(res.is_err()); - assert!(matches!( - res.unwrap_err(), - MultipartError::NoContentDisposition, - )); + assert_matches!( + res.expect_err("according to RFC 7578, form-data fields require a name attribute"), + MultipartError::ContentDispositionNameMissing + ); } #[actix_rt::test] @@ -1362,7 +1468,7 @@ mod tests { let mut field = multipart.next().await.unwrap().unwrap(); let task = rt::spawn(async move { - rt::time::sleep(Duration::from_secs(1)).await; + rt::time::sleep(Duration::from_millis(500)).await; assert_eq!(field.next().await.unwrap().unwrap(), "test"); drop(field); }); diff --git a/actix-multipart/src/test.rs b/actix-multipart/src/test.rs index 77d918283..828f37957 100644 --- a/actix-multipart/src/test.rs +++ b/actix-multipart/src/test.rs @@ -1,3 +1,5 @@ +//! Multipart testing utilities. + use actix_web::http::header::{self, HeaderMap}; use bytes::{BufMut as _, Bytes, BytesMut}; use mime::Mime; diff --git a/actix-web/src/http/header/content_disposition.rs b/actix-web/src/http/header/content_disposition.rs index 9725cd19b..824bf1195 100644 --- a/actix-web/src/http/header/content_disposition.rs +++ b/actix-web/src/http/header/content_disposition.rs @@ -154,7 +154,7 @@ impl DispositionParam { #[inline] pub fn as_name(&self) -> Option<&str> { match self { - DispositionParam::Name(ref name) => Some(name.as_str()), + DispositionParam::Name(name) => Some(name.as_str()), _ => None, } } @@ -163,7 +163,7 @@ impl DispositionParam { #[inline] pub fn as_filename(&self) -> Option<&str> { match self { - DispositionParam::Filename(ref filename) => Some(filename.as_str()), + DispositionParam::Filename(filename) => Some(filename.as_str()), _ => None, } } @@ -172,7 +172,7 @@ impl DispositionParam { #[inline] pub fn as_filename_ext(&self) -> Option<&ExtendedValue> { match self { - DispositionParam::FilenameExt(ref value) => Some(value), + DispositionParam::FilenameExt(value) => Some(value), _ => None, } } From e189e4a3bf60edeff5b5259d4f60488d943eebec Mon Sep 17 00:00:00 2001 From: "Piperck(Zhinan)" Date: Mon, 1 Jul 2024 17:39:54 +0800 Subject: [PATCH 016/144] chore(awc): fix the issue where the code in the awc example cannot run (#3421) --- awc/examples/client.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/awc/examples/client.rs b/awc/examples/client.rs index 16ad330b8..41626315c 100644 --- a/awc/examples/client.rs +++ b/awc/examples/client.rs @@ -1,6 +1,8 @@ use std::error::Error as StdError; -#[tokio::main] +/// If we want to make requests to addresses starting with `https`, we need to enable the rustls feature of awc +/// `awc = { version = "3.5.0", features = ["rustls"] }` +#[actix_rt::main] async fn main() -> Result<(), Box> { env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); From 2136e07bddb511a0f86174c76def3f39c2b66cdb Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 4 Jul 2024 00:26:10 +0100 Subject: [PATCH 017/144] refactor(multipart): move Safety to module --- actix-multipart/src/lib.rs | 1 + actix-multipart/src/safety.rs | 60 +++++++++++++++++++++++++++++++++ actix-multipart/src/server.rs | 63 ++--------------------------------- 3 files changed, 63 insertions(+), 61 deletions(-) create mode 100644 actix-multipart/src/safety.rs diff --git a/actix-multipart/src/lib.rs b/actix-multipart/src/lib.rs index 853648beb..63c2e890f 100644 --- a/actix-multipart/src/lib.rs +++ b/actix-multipart/src/lib.rs @@ -60,6 +60,7 @@ extern crate self as actix_multipart; mod error; mod extractor; pub mod form; +pub(crate) mod safety; mod server; pub mod test; diff --git a/actix-multipart/src/safety.rs b/actix-multipart/src/safety.rs new file mode 100644 index 000000000..db6b3b18b --- /dev/null +++ b/actix-multipart/src/safety.rs @@ -0,0 +1,60 @@ +use std::{cell::Cell, marker::PhantomData, rc::Rc, task}; + +use local_waker::LocalWaker; + +/// Counter. It tracks of number of clones of payloads and give access to payload only to top most. +/// +/// - When dropped, parent task is awakened. This is to support the case where `Field` is dropped in +/// a separate task than `Multipart`. +/// - Assumes that parent owners don't move to different tasks; only the top-most is allowed to. +/// - If dropped and is not top most owner, is_clean flag is set to false. +#[derive(Debug)] +pub(crate) struct Safety { + task: LocalWaker, + level: usize, + payload: Rc>, + clean: Rc>, +} + +impl Safety { + pub(crate) fn new() -> Safety { + let payload = Rc::new(PhantomData); + Safety { + task: LocalWaker::new(), + level: Rc::strong_count(&payload), + clean: Rc::new(Cell::new(true)), + payload, + } + } + + pub(crate) fn current(&self) -> bool { + Rc::strong_count(&self.payload) == self.level && self.clean.get() + } + + pub(crate) fn is_clean(&self) -> bool { + self.clean.get() + } + + pub(crate) fn clone(&self, cx: &task::Context<'_>) -> Safety { + let payload = Rc::clone(&self.payload); + let s = Safety { + task: LocalWaker::new(), + level: Rc::strong_count(&payload), + clean: self.clean.clone(), + payload, + }; + s.task.register(cx.waker()); + s + } +} + +impl Drop for Safety { + fn drop(&mut self) { + if Rc::strong_count(&self.payload) != self.level { + // Multipart dropped leaving a Field + self.clean.set(false); + } + + self.task.wake(); + } +} diff --git a/actix-multipart/src/server.rs b/actix-multipart/src/server.rs index 76eae11ff..1a173f88a 100644 --- a/actix-multipart/src/server.rs +++ b/actix-multipart/src/server.rs @@ -1,9 +1,8 @@ //! Multipart response payload support. use std::{ - cell::{Cell, RefCell, RefMut}, + cell::{RefCell, RefMut}, cmp, fmt, - marker::PhantomData, pin::Pin, rc::Rc, task::{Context, Poll}, @@ -17,10 +16,9 @@ use actix_web::{ }; use bytes::{Bytes, BytesMut}; use futures_core::stream::{LocalBoxStream, Stream}; -use local_waker::LocalWaker; use mime::Mime; -use crate::error::MultipartError; +use crate::{error::MultipartError, safety::Safety}; const MAX_HEADERS: usize = 32; @@ -797,63 +795,6 @@ impl Clone for PayloadRef { } } -/// Counter. It tracks of number of clones of payloads and give access to payload only to top most. -/// -/// - When dropped, parent task is awakened. This is to support the case where `Field` is dropped in -/// a separate task than `Multipart`. -/// - Assumes that parent owners don't move to different tasks; only the top-most is allowed to. -/// - If dropped and is not top most owner, is_clean flag is set to false. -#[derive(Debug)] -struct Safety { - task: LocalWaker, - level: usize, - payload: Rc>, - clean: Rc>, -} - -impl Safety { - fn new() -> Safety { - let payload = Rc::new(PhantomData); - Safety { - task: LocalWaker::new(), - level: Rc::strong_count(&payload), - clean: Rc::new(Cell::new(true)), - payload, - } - } - - fn current(&self) -> bool { - Rc::strong_count(&self.payload) == self.level && self.clean.get() - } - - fn is_clean(&self) -> bool { - self.clean.get() - } - - fn clone(&self, cx: &Context<'_>) -> Safety { - let payload = Rc::clone(&self.payload); - let s = Safety { - task: LocalWaker::new(), - level: Rc::strong_count(&payload), - clean: self.clean.clone(), - payload, - }; - s.task.register(cx.waker()); - s - } -} - -impl Drop for Safety { - fn drop(&mut self) { - if Rc::strong_count(&self.payload) != self.level { - // Multipart dropped leaving a Field - self.clean.set(false); - } - - self.task.wake(); - } -} - /// Payload buffer. struct PayloadBuffer { eof: bool, From befb9c8196ffa124cefc533312b7361390e5d9b9 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 4 Jul 2024 00:37:25 +0100 Subject: [PATCH 018/144] refactor(multipart): move Payload* to module --- actix-multipart/Cargo.toml | 1 - actix-multipart/src/form/bytes.rs | 5 +- actix-multipart/src/form/json.rs | 3 +- actix-multipart/src/lib.rs | 1 + actix-multipart/src/payload.rs | 130 ++++++++++++++++++++++++++++++ actix-multipart/src/server.rs | 130 +++--------------------------- actix-multipart/src/test.rs | 6 +- 7 files changed, 147 insertions(+), 129 deletions(-) create mode 100644 actix-multipart/src/payload.rs diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index c5ff7dd10..e836a2c09 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -41,7 +41,6 @@ actix-multipart-derive = { version = "=0.6.1", optional = true } actix-utils = "3" actix-web = { version = "4", default-features = false } -bytes = "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"] } diff --git a/actix-multipart/src/form/bytes.rs b/actix-multipart/src/form/bytes.rs index c152db3d0..51b0cf7d9 100644 --- a/actix-multipart/src/form/bytes.rs +++ b/actix-multipart/src/form/bytes.rs @@ -1,7 +1,6 @@ //! Reads a field into memory. -use actix_web::HttpRequest; -use bytes::BytesMut; +use actix_web::{web::BytesMut, HttpRequest}; use futures_core::future::LocalBoxFuture; use futures_util::TryStreamExt as _; use mime::Mime; @@ -15,7 +14,7 @@ use crate::{ #[derive(Debug)] pub struct Bytes { /// The data. - pub data: bytes::Bytes, + pub data: actix_web::web::Bytes, /// The value of the `Content-Type` header. pub content_type: Option, diff --git a/actix-multipart/src/form/json.rs b/actix-multipart/src/form/json.rs index 3504c340c..0118a8fba 100644 --- a/actix-multipart/src/form/json.rs +++ b/actix-multipart/src/form/json.rs @@ -134,8 +134,7 @@ impl Default for JsonConfig { mod tests { use std::collections::HashMap; - use actix_web::{http::StatusCode, web, App, HttpResponse, Responder}; - use bytes::Bytes; + use actix_web::{http::StatusCode, web, web::Bytes, App, HttpResponse, Responder}; use crate::form::{ json::{Json, JsonConfig}, diff --git a/actix-multipart/src/lib.rs b/actix-multipart/src/lib.rs index 63c2e890f..d61aa139b 100644 --- a/actix-multipart/src/lib.rs +++ b/actix-multipart/src/lib.rs @@ -60,6 +60,7 @@ extern crate self as actix_multipart; mod error; mod extractor; pub mod form; +pub(crate) mod payload; pub(crate) mod safety; mod server; pub mod test; diff --git a/actix-multipart/src/payload.rs b/actix-multipart/src/payload.rs new file mode 100644 index 000000000..d27cdbe05 --- /dev/null +++ b/actix-multipart/src/payload.rs @@ -0,0 +1,130 @@ +use std::{ + cell::{RefCell, RefMut}, + pin::Pin, + rc::Rc, + task::{Context, Poll}, +}; + +use actix_web::{ + error::PayloadError, + web::{Bytes, BytesMut}, +}; +use futures_core::stream::{LocalBoxStream, Stream}; + +use crate::{error::MultipartError, safety::Safety}; + +pub(crate) struct PayloadRef { + payload: Rc>, +} + +impl PayloadRef { + pub(crate) fn new(payload: PayloadBuffer) -> PayloadRef { + PayloadRef { + payload: Rc::new(payload.into()), + } + } + + pub(crate) fn get_mut(&self, safety: &Safety) -> Option> { + if safety.current() { + Some(self.payload.borrow_mut()) + } else { + None + } + } +} + +impl Clone for PayloadRef { + fn clone(&self) -> PayloadRef { + PayloadRef { + payload: Rc::clone(&self.payload), + } + } +} + +/// Payload buffer. +pub(crate) struct PayloadBuffer { + pub(crate) eof: bool, + pub(crate) buf: BytesMut, + pub(crate) stream: LocalBoxStream<'static, Result>, +} + +impl PayloadBuffer { + /// Constructs new `PayloadBuffer` instance. + pub(crate) fn new(stream: S) -> Self + where + S: Stream> + 'static, + { + PayloadBuffer { + eof: false, + buf: BytesMut::new(), + stream: Box::pin(stream), + } + } + + pub(crate) fn poll_stream(&mut self, cx: &mut Context<'_>) -> Result<(), PayloadError> { + loop { + match Pin::new(&mut self.stream).poll_next(cx) { + Poll::Ready(Some(Ok(data))) => self.buf.extend_from_slice(&data), + Poll::Ready(Some(Err(err))) => return Err(err), + Poll::Ready(None) => { + self.eof = true; + return Ok(()); + } + Poll::Pending => return Ok(()), + } + } + } + + /// Read exact number of bytes + #[cfg(test)] + pub(crate) fn read_exact(&mut self, size: usize) -> Option { + if size <= self.buf.len() { + Some(self.buf.split_to(size).freeze()) + } else { + None + } + } + + pub(crate) fn read_max(&mut self, size: u64) -> Result, MultipartError> { + if !self.buf.is_empty() { + let size = std::cmp::min(self.buf.len() as u64, size) as usize; + Ok(Some(self.buf.split_to(size).freeze())) + } else if self.eof { + Err(MultipartError::Incomplete) + } else { + Ok(None) + } + } + + /// Read until specified ending + pub(crate) fn read_until(&mut self, line: &[u8]) -> Result, MultipartError> { + let res = memchr::memmem::find(&self.buf, line) + .map(|idx| self.buf.split_to(idx + line.len()).freeze()); + + if res.is_none() && self.eof { + Err(MultipartError::Incomplete) + } else { + Ok(res) + } + } + + /// Read bytes until new line delimiter + pub(crate) fn readline(&mut self) -> Result, MultipartError> { + self.read_until(b"\n") + } + + /// Read bytes until new line delimiter or eof + pub(crate) fn readline_or_eof(&mut self) -> Result, MultipartError> { + match self.readline() { + Err(MultipartError::Incomplete) if self.eof => Ok(Some(self.buf.split().freeze())), + line => line, + } + } + + /// Put unprocessed data back to the buffer + pub(crate) fn unprocessed(&mut self, data: Bytes) { + let buf = BytesMut::from(data.as_ref()); + let buf = std::mem::replace(&mut self.buf, buf); + self.buf.extend_from_slice(&buf); + } +} diff --git a/actix-multipart/src/server.rs b/actix-multipart/src/server.rs index 1a173f88a..bbd96621b 100644 --- a/actix-multipart/src/server.rs +++ b/actix-multipart/src/server.rs @@ -1,7 +1,7 @@ //! Multipart response payload support. use std::{ - cell::{RefCell, RefMut}, + cell::RefCell, cmp, fmt, pin::Pin, rc::Rc, @@ -12,13 +12,17 @@ use actix_web::{ dev, error::{ParseError, PayloadError}, http::header::{self, ContentDisposition, HeaderMap, HeaderName, HeaderValue}, + web::Bytes, HttpRequest, }; -use bytes::{Bytes, BytesMut}; -use futures_core::stream::{LocalBoxStream, Stream}; +use futures_core::stream::Stream; use mime::Mime; -use crate::{error::MultipartError, safety::Safety}; +use crate::{ + error::MultipartError, + payload::{PayloadBuffer, PayloadRef}, + safety::Safety, +}; const MAX_HEADERS: usize = 32; @@ -767,122 +771,6 @@ impl InnerField { } } -struct PayloadRef { - payload: Rc>, -} - -impl PayloadRef { - fn new(payload: PayloadBuffer) -> PayloadRef { - PayloadRef { - payload: Rc::new(payload.into()), - } - } - - fn get_mut(&self, safety: &Safety) -> Option> { - if safety.current() { - Some(self.payload.borrow_mut()) - } else { - None - } - } -} - -impl Clone for PayloadRef { - fn clone(&self) -> PayloadRef { - PayloadRef { - payload: Rc::clone(&self.payload), - } - } -} - -/// Payload buffer. -struct PayloadBuffer { - eof: bool, - buf: BytesMut, - stream: LocalBoxStream<'static, Result>, -} - -impl PayloadBuffer { - /// Constructs new `PayloadBuffer` instance. - fn new(stream: S) -> Self - where - S: Stream> + 'static, - { - PayloadBuffer { - eof: false, - buf: BytesMut::new(), - stream: Box::pin(stream), - } - } - - fn poll_stream(&mut self, cx: &mut Context<'_>) -> Result<(), PayloadError> { - loop { - match Pin::new(&mut self.stream).poll_next(cx) { - Poll::Ready(Some(Ok(data))) => self.buf.extend_from_slice(&data), - Poll::Ready(Some(Err(err))) => return Err(err), - Poll::Ready(None) => { - self.eof = true; - return Ok(()); - } - Poll::Pending => return Ok(()), - } - } - } - - /// Read exact number of bytes - #[cfg(test)] - fn read_exact(&mut self, size: usize) -> Option { - if size <= self.buf.len() { - Some(self.buf.split_to(size).freeze()) - } else { - None - } - } - - fn read_max(&mut self, size: u64) -> Result, MultipartError> { - if !self.buf.is_empty() { - let size = std::cmp::min(self.buf.len() as u64, size) as usize; - Ok(Some(self.buf.split_to(size).freeze())) - } else if self.eof { - Err(MultipartError::Incomplete) - } else { - Ok(None) - } - } - - /// Read until specified ending - fn read_until(&mut self, line: &[u8]) -> Result, MultipartError> { - let res = memchr::memmem::find(&self.buf, line) - .map(|idx| self.buf.split_to(idx + line.len()).freeze()); - - if res.is_none() && self.eof { - Err(MultipartError::Incomplete) - } else { - Ok(res) - } - } - - /// Read bytes until new line delimiter - fn readline(&mut self) -> Result, MultipartError> { - self.read_until(b"\n") - } - - /// Read bytes until new line delimiter or eof - fn readline_or_eof(&mut self) -> Result, MultipartError> { - match self.readline() { - Err(MultipartError::Incomplete) if self.eof => Ok(Some(self.buf.split().freeze())), - line => line, - } - } - - /// Put unprocessed data back to the buffer - fn unprocessed(&mut self, data: Bytes) { - let buf = BytesMut::from(data.as_ref()); - let buf = std::mem::replace(&mut self.buf, buf); - self.buf.extend_from_slice(&buf); - } -} - #[cfg(test)] mod tests { use std::time::Duration; @@ -892,10 +780,10 @@ mod tests { http::header::{DispositionParam, DispositionType}, rt, test::TestRequest, + web::{BufMut as _, BytesMut}, FromRequest, }; use assert_matches::assert_matches; - use bytes::BufMut as _; use futures_util::{future::lazy, StreamExt as _}; use tokio::sync::mpsc; use tokio_stream::wrappers::UnboundedReceiverStream; diff --git a/actix-multipart/src/test.rs b/actix-multipart/src/test.rs index 828f37957..956595355 100644 --- a/actix-multipart/src/test.rs +++ b/actix-multipart/src/test.rs @@ -1,7 +1,9 @@ //! Multipart testing utilities. -use actix_web::http::header::{self, HeaderMap}; -use bytes::{BufMut as _, Bytes, BytesMut}; +use actix_web::{ + http::header::{self, HeaderMap}, + web::{BufMut as _, Bytes, BytesMut}, +}; use mime::Mime; use rand::{ distributions::{Alphanumeric, DistString as _}, From 7326707599623d116bd9277e730a5a741fec1a4c Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 4 Jul 2024 00:40:25 +0100 Subject: [PATCH 019/144] refactor(multipart): move Field to module --- actix-multipart/src/field.rs | 343 ++++++++++++++++++++++++++++++++++ actix-multipart/src/lib.rs | 6 +- actix-multipart/src/server.rs | 324 +------------------------------- 3 files changed, 347 insertions(+), 326 deletions(-) create mode 100644 actix-multipart/src/field.rs diff --git a/actix-multipart/src/field.rs b/actix-multipart/src/field.rs new file mode 100644 index 000000000..86fbc8b2d --- /dev/null +++ b/actix-multipart/src/field.rs @@ -0,0 +1,343 @@ +use std::{ + cell::RefCell, + cmp, fmt, + pin::Pin, + rc::Rc, + task::{Context, Poll}, +}; + +use actix_web::{ + error::PayloadError, + http::header::{self, ContentDisposition, HeaderMap}, + web::Bytes, +}; +use futures_core::stream::Stream; +use mime::Mime; + +use crate::{ + error::MultipartError, + payload::{PayloadBuffer, PayloadRef}, + safety::Safety, +}; + +/// A single field in a multipart stream. +pub struct Field { + /// Field's Content-Type. + content_type: Option, + + /// Field's Content-Disposition. + content_disposition: Option, + + /// Form field name. + /// + /// A non-optional storage for form field names to avoid unwraps in `form` module. Will be an + /// empty string in non-form contexts. + /// + // INVARIANT: always non-empty when request content-type is multipart/form-data. + pub(crate) form_field_name: String, + + /// Field's header map. + headers: HeaderMap, + + safety: Safety, + inner: Rc>, +} + +impl Field { + pub(crate) fn new( + content_type: Option, + content_disposition: Option, + form_field_name: Option, + headers: HeaderMap, + safety: Safety, + inner: Rc>, + ) -> Self { + Field { + content_type, + content_disposition, + form_field_name: form_field_name.unwrap_or_default(), + headers, + inner, + safety, + } + } + + /// Returns a reference to the field's header map. + pub fn headers(&self) -> &HeaderMap { + &self.headers + } + + /// Returns a reference to the field's content (mime) type, if it is supplied by the client. + /// + /// According to [RFC 7578](https://www.rfc-editor.org/rfc/rfc7578#section-4.4), if it is not + /// present, it should default to "text/plain". Note it is the responsibility of the client to + /// provide the appropriate content type, there is no attempt to validate this by the server. + pub fn content_type(&self) -> Option<&Mime> { + self.content_type.as_ref() + } + + /// Returns this field's parsed Content-Disposition header, if set. + /// + /// # Validation + /// + /// Per [RFC 7578 §4.2], the parts of a multipart/form-data payload MUST contain a + /// Content-Disposition header field where the disposition type is `form-data` and MUST also + /// contain an additional parameter of `name` with its value being the original field name from + /// the form. This requirement is enforced during extraction for multipart/form-data requests, + /// but not other kinds of multipart requests (such as multipart/related). + /// + /// As such, it is safe to `.unwrap()` calls `.content_disposition()` if you've verified. + /// + /// The [`name()`](Self::name) method is also provided as a convenience for obtaining the + /// aforementioned name parameter. + /// + /// [RFC 7578 §4.2]: https://datatracker.ietf.org/doc/html/rfc7578#section-4.2 + pub fn content_disposition(&self) -> Option<&ContentDisposition> { + self.content_disposition.as_ref() + } + + /// Returns the field's name, if set. + /// + /// See [`content_disposition()`](Self::content_disposition) regarding guarantees on presence of + /// the "name" field. + pub fn name(&self) -> Option<&str> { + self.content_disposition()?.get_name() + } +} + +impl Stream for Field { + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.get_mut(); + let mut inner = this.inner.borrow_mut(); + + if let Some(mut buffer) = inner + .payload + .as_ref() + .expect("Field should not be polled after completion") + .get_mut(&this.safety) + { + // check safety and poll read payload to buffer. + buffer.poll_stream(cx)?; + } else if !this.safety.is_clean() { + // safety violation + return Poll::Ready(Some(Err(MultipartError::NotConsumed))); + } else { + return Poll::Pending; + } + + inner.poll(&this.safety) + } +} + +impl fmt::Debug for Field { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(ct) = &self.content_type { + writeln!(f, "\nField: {}", ct)?; + } else { + writeln!(f, "\nField:")?; + } + writeln!(f, " boundary: {}", self.inner.borrow().boundary)?; + writeln!(f, " headers:")?; + for (key, val) in self.headers.iter() { + writeln!(f, " {:?}: {:?}", key, val)?; + } + Ok(()) + } +} + +pub(crate) struct InnerField { + /// Payload is initialized as Some and is `take`n when the field stream finishes. + payload: Option, + boundary: String, + eof: bool, + length: Option, +} + +impl InnerField { + pub(crate) fn new_in_rc( + payload: PayloadRef, + boundary: String, + headers: &HeaderMap, + ) -> Result>, PayloadError> { + Self::new(payload, boundary, headers).map(|this| Rc::new(RefCell::new(this))) + } + + pub(crate) fn new( + payload: PayloadRef, + boundary: String, + headers: &HeaderMap, + ) -> Result { + let len = if let Some(len) = headers.get(&header::CONTENT_LENGTH) { + match len.to_str().ok().and_then(|len| len.parse::().ok()) { + Some(len) => Some(len), + None => return Err(PayloadError::Incomplete(None)), + } + } else { + None + }; + + Ok(InnerField { + boundary, + payload: Some(payload), + eof: false, + length: len, + }) + } + + /// Reads body part content chunk of the specified size. + /// + /// The body part must has `Content-Length` header with proper value. + pub(crate) fn read_len( + payload: &mut PayloadBuffer, + size: &mut u64, + ) -> Poll>> { + if *size == 0 { + Poll::Ready(None) + } else { + match payload.read_max(*size)? { + Some(mut chunk) => { + let len = cmp::min(chunk.len() as u64, *size); + *size -= len; + let ch = chunk.split_to(len as usize); + if !chunk.is_empty() { + payload.unprocessed(chunk); + } + Poll::Ready(Some(Ok(ch))) + } + None => { + if payload.eof && (*size != 0) { + Poll::Ready(Some(Err(MultipartError::Incomplete))) + } else { + Poll::Pending + } + } + } + } + } + + /// Reads content chunk of body part with unknown length. + /// + /// The `Content-Length` header for body part is not necessary. + pub(crate) fn read_stream( + payload: &mut PayloadBuffer, + boundary: &str, + ) -> Poll>> { + let mut pos = 0; + + let len = payload.buf.len(); + if len == 0 { + return if payload.eof { + Poll::Ready(Some(Err(MultipartError::Incomplete))) + } else { + Poll::Pending + }; + } + + // check boundary + if len > 4 && payload.buf[0] == b'\r' { + let b_len = if &payload.buf[..2] == b"\r\n" && &payload.buf[2..4] == b"--" { + Some(4) + } else if &payload.buf[1..3] == b"--" { + Some(3) + } else { + None + }; + + if let Some(b_len) = b_len { + let b_size = boundary.len() + b_len; + if len < b_size { + return Poll::Pending; + } else if &payload.buf[b_len..b_size] == boundary.as_bytes() { + // found boundary + return Poll::Ready(None); + } + } + } + + loop { + return if let Some(idx) = memchr::memmem::find(&payload.buf[pos..], b"\r") { + let cur = pos + idx; + + // check if we have enough data for boundary detection + if cur + 4 > len { + if cur > 0 { + Poll::Ready(Some(Ok(payload.buf.split_to(cur).freeze()))) + } else { + Poll::Pending + } + } else { + // check boundary + if (&payload.buf[cur..cur + 2] == b"\r\n" + && &payload.buf[cur + 2..cur + 4] == b"--") + || (&payload.buf[cur..=cur] == b"\r" + && &payload.buf[cur + 1..cur + 3] == b"--") + { + if cur != 0 { + // return buffer + Poll::Ready(Some(Ok(payload.buf.split_to(cur).freeze()))) + } else { + pos = cur + 1; + continue; + } + } else { + // not boundary + pos = cur + 1; + continue; + } + } + } else { + Poll::Ready(Some(Ok(payload.buf.split().freeze()))) + }; + } + } + + pub(crate) fn poll(&mut self, safety: &Safety) -> Poll>> { + if self.payload.is_none() { + return Poll::Ready(None); + } + + let result = if let Some(mut payload) = self + .payload + .as_ref() + .expect("Field should not be polled after completion") + .get_mut(safety) + { + if !self.eof { + let res = if let Some(ref mut len) = self.length { + InnerField::read_len(&mut payload, len) + } else { + InnerField::read_stream(&mut payload, &self.boundary) + }; + + match res { + Poll::Pending => return Poll::Pending, + Poll::Ready(Some(Ok(bytes))) => return Poll::Ready(Some(Ok(bytes))), + Poll::Ready(Some(Err(err))) => return Poll::Ready(Some(Err(err))), + Poll::Ready(None) => self.eof = true, + } + } + + match payload.readline() { + 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"); + } + Poll::Ready(None) + } + Err(err) => Poll::Ready(Some(Err(err))), + } + } else { + Poll::Pending + }; + + if let Poll::Ready(None) = result { + // drop payload buffer and make future un-poll-able + let _ = self.payload.take(); + } + + result + } +} diff --git a/actix-multipart/src/lib.rs b/actix-multipart/src/lib.rs index d61aa139b..fefef3ffe 100644 --- a/actix-multipart/src/lib.rs +++ b/actix-multipart/src/lib.rs @@ -59,13 +59,11 @@ extern crate self as actix_multipart; mod error; mod extractor; +pub(crate) mod field; pub mod form; pub(crate) mod payload; pub(crate) mod safety; mod server; pub mod test; -pub use self::{ - error::MultipartError, - server::{Field, Multipart}, -}; +pub use self::{error::MultipartError, field::Field, server::Multipart}; diff --git a/actix-multipart/src/server.rs b/actix-multipart/src/server.rs index bbd96621b..67232a82b 100644 --- a/actix-multipart/src/server.rs +++ b/actix-multipart/src/server.rs @@ -2,7 +2,6 @@ use std::{ cell::RefCell, - cmp, fmt, pin::Pin, rc::Rc, task::{Context, Poll}, @@ -20,8 +19,10 @@ use mime::Mime; use crate::{ error::MultipartError, + field::InnerField, payload::{PayloadBuffer, PayloadRef}, safety::Safety, + Field, }; const MAX_HEADERS: usize = 32; @@ -450,327 +451,6 @@ impl Drop for InnerMultipart { } } -/// A single field in a multipart stream. -pub struct Field { - /// Field's Content-Type. - content_type: Option, - - /// Field's Content-Disposition. - content_disposition: Option, - - /// Form field name. - /// - /// A non-optional storage for form field names to avoid unwraps in `form` module. Will be an - /// empty string in non-form contexts. - /// - // INVARIANT: always non-empty when request content-type is multipart/form-data. - pub(crate) form_field_name: String, - - /// Field's header map. - headers: HeaderMap, - - safety: Safety, - inner: Rc>, -} - -impl Field { - fn new( - content_type: Option, - content_disposition: Option, - form_field_name: Option, - headers: HeaderMap, - safety: Safety, - inner: Rc>, - ) -> Self { - Field { - content_type, - content_disposition, - form_field_name: form_field_name.unwrap_or_default(), - headers, - inner, - safety, - } - } - - /// Returns a reference to the field's header map. - pub fn headers(&self) -> &HeaderMap { - &self.headers - } - - /// Returns a reference to the field's content (mime) type, if it is supplied by the client. - /// - /// According to [RFC 7578](https://www.rfc-editor.org/rfc/rfc7578#section-4.4), if it is not - /// present, it should default to "text/plain". Note it is the responsibility of the client to - /// provide the appropriate content type, there is no attempt to validate this by the server. - pub fn content_type(&self) -> Option<&Mime> { - self.content_type.as_ref() - } - - /// Returns this field's parsed Content-Disposition header, if set. - /// - /// # Validation - /// - /// Per [RFC 7578 §4.2], the parts of a multipart/form-data payload MUST contain a - /// Content-Disposition header field where the disposition type is `form-data` and MUST also - /// contain an additional parameter of `name` with its value being the original field name from - /// the form. This requirement is enforced during extraction for multipart/form-data requests, - /// but not other kinds of multipart requests (such as multipart/related). - /// - /// As such, it is safe to `.unwrap()` calls `.content_disposition()` if you've verified. - /// - /// The [`name()`](Self::name) method is also provided as a convenience for obtaining the - /// aforementioned name parameter. - /// - /// [RFC 7578 §4.2]: https://datatracker.ietf.org/doc/html/rfc7578#section-4.2 - pub fn content_disposition(&self) -> Option<&ContentDisposition> { - self.content_disposition.as_ref() - } - - /// Returns the field's name, if set. - /// - /// See [`content_disposition()`](Self::content_disposition) regarding guarantees on presence of - /// the "name" field. - pub fn name(&self) -> Option<&str> { - self.content_disposition()?.get_name() - } -} - -impl Stream for Field { - type Item = Result; - - fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - let this = self.get_mut(); - let mut inner = this.inner.borrow_mut(); - - if let Some(mut buffer) = inner - .payload - .as_ref() - .expect("Field should not be polled after completion") - .get_mut(&this.safety) - { - // check safety and poll read payload to buffer. - buffer.poll_stream(cx)?; - } else if !this.safety.is_clean() { - // safety violation - return Poll::Ready(Some(Err(MultipartError::NotConsumed))); - } else { - return Poll::Pending; - } - - inner.poll(&this.safety) - } -} - -impl fmt::Debug for Field { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if let Some(ct) = &self.content_type { - writeln!(f, "\nField: {}", ct)?; - } else { - writeln!(f, "\nField:")?; - } - writeln!(f, " boundary: {}", self.inner.borrow().boundary)?; - writeln!(f, " headers:")?; - for (key, val) in self.headers.iter() { - writeln!(f, " {:?}: {:?}", key, val)?; - } - Ok(()) - } -} - -struct InnerField { - /// Payload is initialized as Some and is `take`n when the field stream finishes. - payload: Option, - boundary: String, - eof: bool, - length: Option, -} - -impl InnerField { - fn new_in_rc( - payload: PayloadRef, - boundary: String, - headers: &HeaderMap, - ) -> Result>, PayloadError> { - Self::new(payload, boundary, headers).map(|this| Rc::new(RefCell::new(this))) - } - - fn new( - payload: PayloadRef, - boundary: String, - headers: &HeaderMap, - ) -> Result { - let len = if let Some(len) = headers.get(&header::CONTENT_LENGTH) { - match len.to_str().ok().and_then(|len| len.parse::().ok()) { - Some(len) => Some(len), - None => return Err(PayloadError::Incomplete(None)), - } - } else { - None - }; - - Ok(InnerField { - boundary, - payload: Some(payload), - eof: false, - length: len, - }) - } - - /// Reads body part content chunk of the specified size. - /// The body part must has `Content-Length` header with proper value. - fn read_len( - payload: &mut PayloadBuffer, - size: &mut u64, - ) -> Poll>> { - if *size == 0 { - Poll::Ready(None) - } else { - match payload.read_max(*size)? { - Some(mut chunk) => { - let len = cmp::min(chunk.len() as u64, *size); - *size -= len; - let ch = chunk.split_to(len as usize); - if !chunk.is_empty() { - payload.unprocessed(chunk); - } - Poll::Ready(Some(Ok(ch))) - } - None => { - if payload.eof && (*size != 0) { - Poll::Ready(Some(Err(MultipartError::Incomplete))) - } else { - Poll::Pending - } - } - } - } - } - - /// Reads content chunk of body part with unknown length. - /// - /// The `Content-Length` header for body part is not necessary. - fn read_stream( - payload: &mut PayloadBuffer, - boundary: &str, - ) -> Poll>> { - let mut pos = 0; - - let len = payload.buf.len(); - if len == 0 { - return if payload.eof { - Poll::Ready(Some(Err(MultipartError::Incomplete))) - } else { - Poll::Pending - }; - } - - // check boundary - if len > 4 && payload.buf[0] == b'\r' { - let b_len = if &payload.buf[..2] == b"\r\n" && &payload.buf[2..4] == b"--" { - Some(4) - } else if &payload.buf[1..3] == b"--" { - Some(3) - } else { - None - }; - - if let Some(b_len) = b_len { - let b_size = boundary.len() + b_len; - if len < b_size { - return Poll::Pending; - } else if &payload.buf[b_len..b_size] == boundary.as_bytes() { - // found boundary - return Poll::Ready(None); - } - } - } - - loop { - return if let Some(idx) = memchr::memmem::find(&payload.buf[pos..], b"\r") { - let cur = pos + idx; - - // check if we have enough data for boundary detection - if cur + 4 > len { - if cur > 0 { - Poll::Ready(Some(Ok(payload.buf.split_to(cur).freeze()))) - } else { - Poll::Pending - } - } else { - // check boundary - if (&payload.buf[cur..cur + 2] == b"\r\n" - && &payload.buf[cur + 2..cur + 4] == b"--") - || (&payload.buf[cur..=cur] == b"\r" - && &payload.buf[cur + 1..cur + 3] == b"--") - { - if cur != 0 { - // return buffer - Poll::Ready(Some(Ok(payload.buf.split_to(cur).freeze()))) - } else { - pos = cur + 1; - continue; - } - } else { - // not boundary - pos = cur + 1; - continue; - } - } - } else { - Poll::Ready(Some(Ok(payload.buf.split().freeze()))) - }; - } - } - - fn poll(&mut self, s: &Safety) -> Poll>> { - if self.payload.is_none() { - return Poll::Ready(None); - } - - let result = if let Some(mut payload) = self - .payload - .as_ref() - .expect("Field should not be polled after completion") - .get_mut(s) - { - if !self.eof { - let res = if let Some(ref mut len) = self.length { - InnerField::read_len(&mut payload, len) - } else { - InnerField::read_stream(&mut payload, &self.boundary) - }; - - match res { - Poll::Pending => return Poll::Pending, - Poll::Ready(Some(Ok(bytes))) => return Poll::Ready(Some(Ok(bytes))), - Poll::Ready(Some(Err(err))) => return Poll::Ready(Some(Err(err))), - Poll::Ready(None) => self.eof = true, - } - } - - match payload.readline() { - 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"); - } - Poll::Ready(None) - } - Err(err) => Poll::Ready(Some(Err(err))), - } - } else { - Poll::Pending - }; - - if let Poll::Ready(None) = result { - // drop payload buffer and make future un-poll-able - let _ = self.payload.take(); - } - - result - } -} - #[cfg(test)] mod tests { use std::time::Duration; From 00c185f617ea08070117942e23b230b28ace561b Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 4 Jul 2024 01:12:17 +0100 Subject: [PATCH 020/144] refactor(multipart): move lints to manifest --- actix-multipart/Cargo.toml | 5 ++ actix-multipart/src/lib.rs | 3 -- actix-multipart/src/payload.rs | 13 ++--- actix-multipart/src/server.rs | 99 +++++++++++++++++----------------- 4 files changed, 61 insertions(+), 59 deletions(-) diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index e836a2c09..e5d1b5b1d 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -69,3 +69,8 @@ futures-util = { version = "0.3.17", default-features = false, features = ["allo multer = "3" tokio = { version = "1.24.2", features = ["sync"] } tokio-stream = "0.1" + +[lints.rust] +future_incompatible = { level = "deny" } +rust_2018_idioms = { level = "deny" } +nonstandard_style = { level = "deny" } diff --git a/actix-multipart/src/lib.rs b/actix-multipart/src/lib.rs index fefef3ffe..d33f17097 100644 --- a/actix-multipart/src/lib.rs +++ b/actix-multipart/src/lib.rs @@ -46,9 +46,6 @@ //! -F file=@./Cargo.lock //! ``` -#![deny(rust_2018_idioms, nonstandard_style)] -#![warn(future_incompatible)] -#![allow(clippy::borrow_interior_mutable_const)] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] diff --git a/actix-multipart/src/payload.rs b/actix-multipart/src/payload.rs index d27cdbe05..a798f2c1a 100644 --- a/actix-multipart/src/payload.rs +++ b/actix-multipart/src/payload.rs @@ -1,5 +1,6 @@ use std::{ cell::{RefCell, RefMut}, + cmp, pin::Pin, rc::Rc, task::{Context, Poll}, @@ -75,7 +76,7 @@ impl PayloadBuffer { } } - /// Read exact number of bytes + /// Read exact number of bytes. #[cfg(test)] pub(crate) fn read_exact(&mut self, size: usize) -> Option { if size <= self.buf.len() { @@ -87,7 +88,7 @@ impl PayloadBuffer { pub(crate) fn read_max(&mut self, size: u64) -> Result, MultipartError> { if !self.buf.is_empty() { - let size = std::cmp::min(self.buf.len() as u64, size) as usize; + let size = cmp::min(self.buf.len() as u64, size) as usize; Ok(Some(self.buf.split_to(size).freeze())) } else if self.eof { Err(MultipartError::Incomplete) @@ -96,7 +97,7 @@ impl PayloadBuffer { } } - /// Read until specified ending + /// Read until specified ending. pub(crate) fn read_until(&mut self, line: &[u8]) -> Result, MultipartError> { let res = memchr::memmem::find(&self.buf, line) .map(|idx| self.buf.split_to(idx + line.len()).freeze()); @@ -108,12 +109,12 @@ impl PayloadBuffer { } } - /// Read bytes until new line delimiter + /// Read bytes until new line delimiter. pub(crate) fn readline(&mut self) -> Result, MultipartError> { self.read_until(b"\n") } - /// Read bytes until new line delimiter or eof + /// Read bytes until new line delimiter or EOF. pub(crate) fn readline_or_eof(&mut self) -> Result, MultipartError> { match self.readline() { Err(MultipartError::Incomplete) if self.eof => Ok(Some(self.buf.split().freeze())), @@ -121,7 +122,7 @@ impl PayloadBuffer { } } - /// Put unprocessed data back to the buffer + /// Put unprocessed data back to the buffer. pub(crate) fn unprocessed(&mut self, data: Bytes) { let buf = BytesMut::from(data.as_ref()); let buf = std::mem::replace(&mut self.buf, buf); diff --git a/actix-multipart/src/server.rs b/actix-multipart/src/server.rs index 67232a82b..d0ed5be59 100644 --- a/actix-multipart/src/server.rs +++ b/actix-multipart/src/server.rs @@ -34,7 +34,7 @@ const MAX_HEADERS: usize = 32; /// used for nested multipart streams. pub struct Multipart { safety: Safety, - inner: Option, + inner: Option, error: Option, } @@ -90,12 +90,12 @@ impl Multipart { { Multipart { safety: Safety::new(), - inner: Some(InnerMultipart { + inner: Some(Inner { payload: PayloadRef::new(PayloadBuffer::new(stream)), content_type: ct, boundary, - state: InnerState::FirstBoundary, - item: InnerMultipartItem::None, + state: State::FirstBoundary, + item: Item::None, }), error: None, } @@ -155,10 +155,7 @@ impl Stream for Multipart { } #[derive(PartialEq, Debug)] -enum InnerState { - /// Stream EOF. - Eof, - +enum State { /// Skip data until first boundary. FirstBoundary, @@ -167,14 +164,17 @@ enum InnerState { /// Reading Headers. Headers, + + /// Stream EOF. + Eof, } -enum InnerMultipartItem { +enum Item { None, Field(Rc>), } -struct InnerMultipart { +struct Inner { /// Request's payload stream & buffer. payload: PayloadRef, @@ -186,11 +186,11 @@ struct InnerMultipart { /// Field boundary. boundary: String, - state: InnerState, - item: InnerMultipartItem, + state: State, + item: Item, } -impl InnerMultipart { +impl Inner { fn read_field_headers( payload: &mut PayloadBuffer, ) -> Result, MultipartError> { @@ -265,6 +265,7 @@ impl InnerMultipart { boundary: &str, ) -> Result, MultipartError> { let mut eof = false; + loop { match payload.readline()? { Some(chunk) => { @@ -306,7 +307,7 @@ impl InnerMultipart { safety: &Safety, cx: &Context<'_>, ) -> Poll>> { - if self.state == InnerState::Eof { + if self.state == State::Eof { Poll::Ready(None) } else { // release field @@ -315,20 +316,18 @@ impl InnerMultipart { // before switching to next if safety.current() { let stop = match self.item { - InnerMultipartItem::Field(ref mut field) => { - 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(None) => true, - } - } - InnerMultipartItem::None => false, + Item::Field(ref mut field) => 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(None) => true, + }, + Item::None => false, }; if stop { - self.item = InnerMultipartItem::None; + self.item = Item::None; } - if let InnerMultipartItem::None = self.item { + if let Item::None = self.item { break; } } @@ -337,40 +336,40 @@ impl InnerMultipart { let field_headers = if let Some(mut payload) = self.payload.get_mut(safety) { match self.state { // read until first boundary - InnerState::FirstBoundary => { - match InnerMultipart::skip_until_boundary(&mut payload, &self.boundary)? { + State::FirstBoundary => { + match Inner::skip_until_boundary(&mut payload, &self.boundary)? { Some(eof) => { if eof { - self.state = InnerState::Eof; + self.state = State::Eof; return Poll::Ready(None); } else { - self.state = InnerState::Headers; + self.state = State::Headers; } } None => return Poll::Pending, } } + // read boundary - InnerState::Boundary => { - match InnerMultipart::read_boundary(&mut payload, &self.boundary)? { - None => return Poll::Pending, - Some(eof) => { - if eof { - self.state = InnerState::Eof; - return Poll::Ready(None); - } else { - self.state = InnerState::Headers; - } + State::Boundary => match Inner::read_boundary(&mut payload, &self.boundary)? { + None => return Poll::Pending, + Some(eof) => { + if eof { + self.state = State::Eof; + return Poll::Ready(None); + } else { + self.state = State::Headers; } } - } + }, + _ => {} } // read field headers for next field - if self.state == InnerState::Headers { - if let Some(headers) = InnerMultipart::read_field_headers(&mut payload)? { - self.state = InnerState::Boundary; + if self.state == State::Headers { + if let Some(headers) = Inner::read_field_headers(&mut payload)? { + self.state = State::Boundary; headers } else { return Poll::Pending; @@ -418,7 +417,7 @@ impl InnerMultipart { .and_then(|ct| ct.to_str().ok()) .and_then(|ct| ct.parse().ok()); - self.state = InnerState::Boundary; + self.state = State::Boundary; // nested multipart stream is not supported if let Some(mime) = &field_content_type { @@ -430,7 +429,7 @@ impl InnerMultipart { let field_inner = InnerField::new_in_rc(self.payload.clone(), self.boundary.clone(), &field_headers)?; - self.item = InnerMultipartItem::Field(Rc::clone(&field_inner)); + self.item = Item::Field(Rc::clone(&field_inner)); Poll::Ready(Some(Ok(Field::new( field_content_type, @@ -444,10 +443,10 @@ impl InnerMultipart { } } -impl Drop for InnerMultipart { +impl Drop for Inner { fn drop(&mut self) { // InnerMultipartItem::Field has to be dropped first because of Safety. - self.item = InnerMultipartItem::None; + self.item = Item::None; } } @@ -772,7 +771,7 @@ mod tests { } #[actix_rt::test] - async fn test_readmax() { + async fn read_max() { let (mut sender, payload) = h1::Payload::create(false); let mut payload = PayloadBuffer::new(payload); @@ -789,7 +788,7 @@ mod tests { } #[actix_rt::test] - async fn test_readexactly() { + async fn read_exactly() { let (mut sender, payload) = h1::Payload::create(false); let mut payload = PayloadBuffer::new(payload); @@ -807,7 +806,7 @@ mod tests { } #[actix_rt::test] - async fn test_readuntil() { + async fn read_until() { let (mut sender, payload) = h1::Payload::create(false); let mut payload = PayloadBuffer::new(payload); From 210c9a5eb3be0995e9df097a1079e43f87909168 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 4 Jul 2024 04:53:10 +0100 Subject: [PATCH 021/144] refactor: multipart tweaks --- actix-multipart/src/error.rs | 10 +- actix-multipart/src/extractor.rs | 6 +- actix-multipart/src/field.rs | 16 +-- actix-multipart/src/lib.rs | 2 +- actix-multipart/src/payload.rs | 72 +++++++----- actix-multipart/src/server.rs | 195 +++++++++++++++++-------------- actix-multipart/src/test.rs | 3 +- 7 files changed, 169 insertions(+), 135 deletions(-) diff --git a/actix-multipart/src/error.rs b/actix-multipart/src/error.rs index 30ef63c1a..cdb608738 100644 --- a/actix-multipart/src/error.rs +++ b/actix-multipart/src/error.rs @@ -10,7 +10,7 @@ use derive_more::{Display, Error, From}; /// A set of errors that can occur during parsing multipart streams. #[derive(Debug, Display, From, Error)] #[non_exhaustive] -pub enum MultipartError { +pub enum Error { /// Could not find Content-Type header. #[display(fmt = "Could not find Content-Type header")] ContentTypeMissing, @@ -95,11 +95,11 @@ pub enum MultipartError { } /// Return `BadRequest` for `MultipartError`. -impl ResponseError for MultipartError { +impl ResponseError for Error { fn status_code(&self) -> StatusCode { match &self { - MultipartError::Field { source, .. } => source.as_response_error().status_code(), - MultipartError::ContentTypeIncompatible => StatusCode::UNSUPPORTED_MEDIA_TYPE, + Error::Field { source, .. } => source.as_response_error().status_code(), + Error::ContentTypeIncompatible => StatusCode::UNSUPPORTED_MEDIA_TYPE, _ => StatusCode::BAD_REQUEST, } } @@ -111,7 +111,7 @@ mod tests { #[test] fn test_multipart_error() { - let resp = MultipartError::BoundaryMissing.error_response(); + let resp = Error::BoundaryMissing.error_response(); assert_eq!(resp.status(), StatusCode::BAD_REQUEST); } } diff --git a/actix-multipart/src/extractor.rs b/actix-multipart/src/extractor.rs index ab98f887e..f7777100e 100644 --- a/actix-multipart/src/extractor.rs +++ b/actix-multipart/src/extractor.rs @@ -12,11 +12,11 @@ use crate::server::Multipart; /// # Examples /// /// ``` -/// use actix_web::{web, HttpResponse, Error}; +/// use actix_web::{web, HttpResponse}; /// use actix_multipart::Multipart; /// use futures_util::StreamExt as _; /// -/// async fn index(mut payload: Multipart) -> Result { +/// async fn index(mut payload: Multipart) -> actix_web::Result { /// // iterate over multipart stream /// while let Some(item) = payload.next().await { /// let mut field = item?; @@ -27,7 +27,7 @@ use crate::server::Multipart; /// } /// } /// -/// Ok(HttpResponse::Ok().into()) +/// Ok(HttpResponse::Ok().finish()) /// } /// ``` impl FromRequest for Multipart { diff --git a/actix-multipart/src/field.rs b/actix-multipart/src/field.rs index 86fbc8b2d..50660b5d3 100644 --- a/actix-multipart/src/field.rs +++ b/actix-multipart/src/field.rs @@ -15,7 +15,7 @@ use futures_core::stream::Stream; use mime::Mime; use crate::{ - error::MultipartError, + error::Error, payload::{PayloadBuffer, PayloadRef}, safety::Safety, }; @@ -106,7 +106,7 @@ impl Field { } impl Stream for Field { - type Item = Result; + type Item = Result; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.get_mut(); @@ -122,7 +122,7 @@ impl Stream for Field { buffer.poll_stream(cx)?; } else if !this.safety.is_clean() { // safety violation - return Poll::Ready(Some(Err(MultipartError::NotConsumed))); + return Poll::Ready(Some(Err(Error::NotConsumed))); } else { return Poll::Pending; } @@ -192,7 +192,7 @@ impl InnerField { pub(crate) fn read_len( payload: &mut PayloadBuffer, size: &mut u64, - ) -> Poll>> { + ) -> Poll>> { if *size == 0 { Poll::Ready(None) } else { @@ -208,7 +208,7 @@ impl InnerField { } None => { if payload.eof && (*size != 0) { - Poll::Ready(Some(Err(MultipartError::Incomplete))) + Poll::Ready(Some(Err(Error::Incomplete))) } else { Poll::Pending } @@ -223,13 +223,13 @@ impl InnerField { pub(crate) fn read_stream( payload: &mut PayloadBuffer, boundary: &str, - ) -> Poll>> { + ) -> Poll>> { let mut pos = 0; let len = payload.buf.len(); if len == 0 { return if payload.eof { - Poll::Ready(Some(Err(MultipartError::Incomplete))) + Poll::Ready(Some(Err(Error::Incomplete))) } else { Poll::Pending }; @@ -293,7 +293,7 @@ impl InnerField { } } - pub(crate) fn poll(&mut self, safety: &Safety) -> Poll>> { + pub(crate) fn poll(&mut self, safety: &Safety) -> Poll>> { if self.payload.is_none() { return Poll::Ready(None); } diff --git a/actix-multipart/src/lib.rs b/actix-multipart/src/lib.rs index d33f17097..744c27088 100644 --- a/actix-multipart/src/lib.rs +++ b/actix-multipart/src/lib.rs @@ -63,4 +63,4 @@ pub(crate) mod safety; mod server; pub mod test; -pub use self::{error::MultipartError, field::Field, server::Multipart}; +pub use self::{error::Error as MultipartError, field::Field, server::Multipart}; diff --git a/actix-multipart/src/payload.rs b/actix-multipart/src/payload.rs index a798f2c1a..ed5477997 100644 --- a/actix-multipart/src/payload.rs +++ b/actix-multipart/src/payload.rs @@ -1,6 +1,6 @@ use std::{ cell::{RefCell, RefMut}, - cmp, + cmp, mem, pin::Pin, rc::Rc, task::{Context, Poll}, @@ -12,7 +12,7 @@ use actix_web::{ }; use futures_core::stream::{LocalBoxStream, Stream}; -use crate::{error::MultipartError, safety::Safety}; +use crate::{error::Error, safety::Safety}; pub(crate) struct PayloadRef { payload: Rc>, @@ -21,7 +21,7 @@ pub(crate) struct PayloadRef { impl PayloadRef { pub(crate) fn new(payload: PayloadBuffer) -> PayloadRef { PayloadRef { - payload: Rc::new(payload.into()), + payload: Rc::new(RefCell::new(payload)), } } @@ -44,28 +44,33 @@ impl Clone for PayloadRef { /// Payload buffer. pub(crate) struct PayloadBuffer { - pub(crate) eof: bool, - pub(crate) buf: BytesMut, pub(crate) stream: LocalBoxStream<'static, Result>, + pub(crate) buf: BytesMut, + /// EOF flag. If true, no more payload reads will be attempted. + pub(crate) eof: bool, } impl PayloadBuffer { - /// Constructs new `PayloadBuffer` instance. + /// Constructs new payload buffer. pub(crate) fn new(stream: S) -> Self where S: Stream> + 'static, { PayloadBuffer { - eof: false, - buf: BytesMut::new(), stream: Box::pin(stream), + buf: BytesMut::with_capacity(1_024), // pre-allocate 1KiB + eof: false, } } pub(crate) fn poll_stream(&mut self, cx: &mut Context<'_>) -> Result<(), PayloadError> { loop { match Pin::new(&mut self.stream).poll_next(cx) { - Poll::Ready(Some(Ok(data))) => self.buf.extend_from_slice(&data), + Poll::Ready(Some(Ok(data))) => { + self.buf.extend_from_slice(&data); + // try to read more data + continue; + } Poll::Ready(Some(Err(err))) => return Err(err), Poll::Ready(None) => { self.eof = true; @@ -76,7 +81,7 @@ impl PayloadBuffer { } } - /// Read exact number of bytes. + /// Reads exact number of bytes. #[cfg(test)] pub(crate) fn read_exact(&mut self, size: usize) -> Option { if size <= self.buf.len() { @@ -86,46 +91,57 @@ impl PayloadBuffer { } } - pub(crate) fn read_max(&mut self, size: u64) -> Result, MultipartError> { + pub(crate) fn read_max(&mut self, size: u64) -> Result, Error> { if !self.buf.is_empty() { let size = cmp::min(self.buf.len() as u64, size) as usize; Ok(Some(self.buf.split_to(size).freeze())) } else if self.eof { - Err(MultipartError::Incomplete) + Err(Error::Incomplete) } else { Ok(None) } } - /// Read until specified ending. - pub(crate) fn read_until(&mut self, line: &[u8]) -> Result, MultipartError> { - let res = memchr::memmem::find(&self.buf, line) - .map(|idx| self.buf.split_to(idx + line.len()).freeze()); + /// Reads until specified ending. + /// + /// Returns: + /// + /// - `Ok(Some(chunk))` - `needle` is found, with chunk ending after needle + /// - `Err(Incomplete)` - `needle` is not found and we're at EOF + /// - `Ok(None)` - `needle` is not found otherwise + pub(crate) fn read_until(&mut self, needle: &[u8]) -> Result, Error> { + match memchr::memmem::find(&self.buf, needle) { + // buffer exhausted and EOF without finding needle + None if self.eof => Err(Error::Incomplete), - if res.is_none() && self.eof { - Err(MultipartError::Incomplete) - } else { - Ok(res) + // needle not yet found + None => Ok(None), + + // needle found, split chunk out of buf + Some(idx) => Ok(Some(self.buf.split_to(idx + needle.len()).freeze())), } } - /// Read bytes until new line delimiter. - pub(crate) fn readline(&mut self) -> Result, MultipartError> { + /// Reads bytes until new line delimiter. + #[inline] + pub(crate) fn readline(&mut self) -> Result, Error> { self.read_until(b"\n") } - /// Read bytes until new line delimiter or EOF. - pub(crate) fn readline_or_eof(&mut self) -> Result, MultipartError> { + /// Reads bytes until new line delimiter or until EOF. + #[inline] + pub(crate) fn readline_or_eof(&mut self) -> Result, Error> { match self.readline() { - Err(MultipartError::Incomplete) if self.eof => Ok(Some(self.buf.split().freeze())), + Err(Error::Incomplete) if self.eof => Ok(Some(self.buf.split().freeze())), line => line, } } - /// Put unprocessed data back to the buffer. + /// Puts unprocessed data back to the buffer. pub(crate) fn unprocessed(&mut self, data: Bytes) { - let buf = BytesMut::from(data.as_ref()); - let buf = std::mem::replace(&mut self.buf, buf); + // TODO: use BytesMut::from when it's released, see https://github.com/tokio-rs/bytes/pull/710 + let buf = BytesMut::from(&data[..]); + let buf = mem::replace(&mut self.buf, buf); self.buf.extend_from_slice(&buf); } } diff --git a/actix-multipart/src/server.rs b/actix-multipart/src/server.rs index d0ed5be59..dc6a9ecb7 100644 --- a/actix-multipart/src/server.rs +++ b/actix-multipart/src/server.rs @@ -18,7 +18,7 @@ use futures_core::stream::Stream; use mime::Mime; use crate::{ - error::MultipartError, + error::Error, field::InnerField, payload::{PayloadBuffer, PayloadRef}, safety::Safety, @@ -33,9 +33,15 @@ const MAX_HEADERS: usize = 32; /// implementation. `MultipartItem::Field` contains multipart field. `MultipartItem::Multipart` is /// used for nested multipart streams. pub struct Multipart { + flow: Flow, safety: Safety, - inner: Option, - error: Option, +} + +enum Flow { + InFlight(Inner), + + /// Error container is Some until an error is returned out of the flow. + Error(Option), } impl Multipart { @@ -59,24 +65,22 @@ impl Multipart { } /// Extract Content-Type and boundary info from headers. - pub(crate) fn find_ct_and_boundary( - headers: &HeaderMap, - ) -> Result<(Mime, String), MultipartError> { + pub(crate) fn find_ct_and_boundary(headers: &HeaderMap) -> Result<(Mime, String), Error> { let content_type = headers .get(&header::CONTENT_TYPE) - .ok_or(MultipartError::ContentTypeMissing)? + .ok_or(Error::ContentTypeMissing)? .to_str() .ok() .and_then(|content_type| content_type.parse::().ok()) - .ok_or(MultipartError::ContentTypeParse)?; + .ok_or(Error::ContentTypeParse)?; if content_type.type_() != mime::MULTIPART { - return Err(MultipartError::ContentTypeIncompatible); + return Err(Error::ContentTypeIncompatible); } let boundary = content_type .get_param(mime::BOUNDARY) - .ok_or(MultipartError::BoundaryMissing)? + .ok_or(Error::BoundaryMissing)? .as_str() .to_owned(); @@ -90,64 +94,57 @@ impl Multipart { { Multipart { safety: Safety::new(), - inner: Some(Inner { + flow: Flow::InFlight(Inner { payload: PayloadRef::new(PayloadBuffer::new(stream)), content_type: ct, boundary, state: State::FirstBoundary, item: Item::None, }), - error: None, } } /// Constructs a new multipart reader from given `MultipartError`. - pub(crate) fn from_error(err: MultipartError) -> Multipart { + pub(crate) fn from_error(err: Error) -> Multipart { Multipart { - error: Some(err), + flow: Flow::Error(Some(err)), safety: Safety::new(), - inner: None, } } /// Return requests parsed Content-Type or raise the stored error. - pub(crate) fn content_type_or_bail(&mut self) -> Result { - if let Some(err) = self.error.take() { - return Err(err); + pub(crate) fn content_type_or_bail(&mut self) -> Result { + match self.flow { + Flow::InFlight(ref inner) => Ok(inner.content_type.clone()), + Flow::Error(ref mut err) => Err(err + .take() + .expect("error should not be taken after it was returned")), } - - Ok(self - .inner - .as_ref() - // TODO: look into using enum instead of two options - .expect("multipart requests should have state") - .content_type - .clone()) } } impl Stream for Multipart { - type Item = Result; + type Item = Result; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.get_mut(); - match this.inner.as_mut() { - Some(inner) => { + match this.flow { + Flow::InFlight(ref mut inner) => { if let Some(mut buffer) = inner.payload.get_mut(&this.safety) { // check safety and poll read payload to buffer. buffer.poll_stream(cx)?; } else if !this.safety.is_clean() { // safety violation - return Poll::Ready(Some(Err(MultipartError::NotConsumed))); + return Poll::Ready(Some(Err(Error::NotConsumed))); } else { return Poll::Pending; } inner.poll(&this.safety, cx) } - None => Poll::Ready(Some(Err(this - .error + + Flow::Error(ref mut err) => Poll::Ready(Some(Err(err .take() .expect("Multipart polled after finish")))), } @@ -191,22 +188,21 @@ struct Inner { } impl Inner { - fn read_field_headers( - payload: &mut PayloadBuffer, - ) -> Result, MultipartError> { + fn read_field_headers(payload: &mut PayloadBuffer) -> Result, Error> { match payload.read_until(b"\r\n\r\n")? { None => { if payload.eof { - Err(MultipartError::Incomplete) + Err(Error::Incomplete) } else { Ok(None) } } + Some(bytes) => { let mut hdrs = [httparse::EMPTY_HEADER; MAX_HEADERS]; - match httparse::parse_headers(&bytes, &mut hdrs) { - Ok(httparse::Status::Complete((_, hdrs))) => { + match httparse::parse_headers(&bytes, &mut hdrs).map_err(ParseError::from)? { + httparse::Status::Complete((_, hdrs)) => { // convert headers let mut headers = HeaderMap::with_capacity(hdrs.len()); @@ -220,57 +216,84 @@ impl Inner { Ok(Some(headers)) } - Ok(httparse::Status::Partial) => Err(ParseError::Header.into()), - Err(err) => Err(ParseError::from(err).into()), + + httparse::Status::Partial => Err(ParseError::Header.into()), } } } } - fn read_boundary( - payload: &mut PayloadBuffer, - boundary: &str, - ) -> Result, MultipartError> { + /// Reads a field boundary from the payload buffer (and discards it). + /// + /// Reads "in-between" and "final" boundaries. E.g. for boundary = "foo": + /// + /// ```plain + /// --foo <-- in-between fields + /// --foo-- <-- end of request body, should be followed by EOF + /// ``` + /// + /// Returns: + /// + /// - `Ok(Some(true))` - final field boundary read (EOF) + /// - `Ok(Some(false))` - field boundary read + /// - `Ok(None)` - boundary not found, more data needs reading + /// - `Err(BoundaryMissing)` - multipart boundary is missing + fn read_boundary(payload: &mut PayloadBuffer, boundary: &str) -> Result, Error> { // TODO: need to read epilogue - match payload.readline_or_eof()? { - None => { - if payload.eof { - Ok(Some(true)) - } else { - Ok(None) - } - } - Some(chunk) => { - if chunk.len() < boundary.len() + 4 - || &chunk[..2] != b"--" - || &chunk[2..boundary.len() + 2] != boundary.as_bytes() - { - Err(MultipartError::BoundaryMissing) - } else if &chunk[boundary.len() + 2..] == b"\r\n" { - Ok(Some(false)) - } else if &chunk[boundary.len() + 2..boundary.len() + 4] == b"--" - && (chunk.len() == boundary.len() + 4 - || &chunk[boundary.len() + 4..] == b"\r\n") - { - Ok(Some(true)) - } else { - Err(MultipartError::BoundaryMissing) - } - } + let chunk = match payload.readline_or_eof()? { + // TODO: this might be okay as a let Some() else return Ok(None) + None => return Ok(payload.eof.then_some(true)), + Some(chunk) => chunk, + }; + + const BOUNDARY_MARKER: &[u8] = b"--"; + const LINE_BREAK: &[u8] = b"\r\n"; + + let boundary_len = boundary.len(); + + if chunk.len() < boundary_len + 2 + 2 + || !chunk.starts_with(BOUNDARY_MARKER) + || &chunk[2..boundary_len + 2] != boundary.as_bytes() + { + return Err(Error::BoundaryMissing); } + + // chunk facts: + // - long enough to contain boundary + 2 markers or 1 marker and line-break + // - starts with boundary marker + // - chunk contains correct boundary + + if &chunk[boundary_len + 2..] == LINE_BREAK { + // boundary is followed by line-break, indicating more fields to come + return Ok(Some(false)); + } + + // boundary is followed by marker + if &chunk[boundary_len + 2..boundary_len + 4] == BOUNDARY_MARKER + && ( + // chunk is exactly boundary len + 2 markers + chunk.len() == boundary_len + 2 + 2 + // final boundary is allowed to end with a line-break + || &chunk[boundary_len + 4..] == LINE_BREAK + ) + { + return Ok(Some(true)); + } + + Err(Error::BoundaryMissing) } fn skip_until_boundary( payload: &mut PayloadBuffer, boundary: &str, - ) -> Result, MultipartError> { + ) -> Result, Error> { let mut eof = false; loop { match payload.readline()? { Some(chunk) => { if chunk.is_empty() { - return Err(MultipartError::BoundaryMissing); + return Err(Error::BoundaryMissing); } if chunk.len() < boundary.len() { continue; @@ -292,7 +315,7 @@ impl Inner { } None => { return if payload.eof { - Err(MultipartError::Incomplete) + Err(Error::Incomplete) } else { Ok(None) }; @@ -302,11 +325,7 @@ impl Inner { Ok(Some(eof)) } - fn poll( - &mut self, - safety: &Safety, - cx: &Context<'_>, - ) -> Poll>> { + fn poll(&mut self, safety: &Safety, cx: &Context<'_>) -> Poll>> { if self.state == State::Eof { Poll::Ready(None) } else { @@ -338,6 +357,7 @@ impl Inner { // read until first boundary State::FirstBoundary => { match Inner::skip_until_boundary(&mut payload, &self.boundary)? { + None => return Poll::Pending, Some(eof) => { if eof { self.state = State::Eof; @@ -346,7 +366,6 @@ impl Inner { self.state = State::Headers; } } - None => return Poll::Pending, } } @@ -398,11 +417,11 @@ impl Inner { // type must be set as "form-data", and it must have a name parameter. let Some(cd) = &field_content_disposition else { - return Poll::Ready(Some(Err(MultipartError::ContentDispositionMissing))); + return Poll::Ready(Some(Err(Error::ContentDispositionMissing))); }; let Some(field_name) = cd.get_name() else { - return Poll::Ready(Some(Err(MultipartError::ContentDispositionNameMissing))); + return Poll::Ready(Some(Err(Error::ContentDispositionNameMissing))); }; Some(field_name.to_owned()) @@ -422,7 +441,7 @@ impl Inner { // nested multipart stream is not supported if let Some(mime) = &field_content_type { if mime.type_() == mime::MULTIPART { - return Poll::Ready(Some(Err(MultipartError::Nested))); + return Poll::Ready(Some(Err(Error::Nested))); } } @@ -475,7 +494,7 @@ mod tests { async fn test_boundary() { let headers = HeaderMap::new(); match Multipart::find_ct_and_boundary(&headers) { - Err(MultipartError::ContentTypeMissing) => {} + Err(Error::ContentTypeMissing) => {} _ => unreachable!("should not happen"), } @@ -486,7 +505,7 @@ mod tests { ); match Multipart::find_ct_and_boundary(&headers) { - Err(MultipartError::ContentTypeParse) => {} + Err(Error::ContentTypeParse) => {} _ => unreachable!("should not happen"), } @@ -496,7 +515,7 @@ mod tests { header::HeaderValue::from_static("multipart/mixed"), ); match Multipart::find_ct_and_boundary(&headers) { - Err(MultipartError::BoundaryMissing) => {} + Err(Error::BoundaryMissing) => {} _ => unreachable!("should not happen"), } @@ -831,7 +850,7 @@ mod tests { #[actix_rt::test] async fn test_multipart_from_error() { - let err = MultipartError::ContentTypeMissing; + let err = Error::ContentTypeMissing; let mut multipart = Multipart::from_error(err); assert!(multipart.next().await.unwrap().is_err()) } @@ -888,7 +907,7 @@ mod tests { res.expect_err( "according to RFC 7578, form-data fields require a content-disposition header" ), - MultipartError::ContentDispositionMissing + Error::ContentDispositionMissing ); } @@ -942,7 +961,7 @@ mod tests { let res = multipart.next().await.unwrap(); assert_matches!( res.expect_err("according to RFC 7578, form-data fields require a name attribute"), - MultipartError::ContentDispositionNameMissing + Error::ContentDispositionNameMissing ); } @@ -960,7 +979,7 @@ mod tests { // should fail immediately match field.next().await { - Some(Err(MultipartError::NotConsumed)) => {} + Some(Err(Error::NotConsumed)) => {} _ => panic!(), }; } diff --git a/actix-multipart/src/test.rs b/actix-multipart/src/test.rs index 956595355..7dec85f8e 100644 --- a/actix-multipart/src/test.rs +++ b/actix-multipart/src/test.rs @@ -25,8 +25,7 @@ const BOUNDARY_PREFIX: &str = "------------------------"; /// /// ``` /// use actix_multipart::test::create_form_data_payload_and_headers; -/// use actix_web::test::TestRequest; -/// use bytes::Bytes; +/// use actix_web::{test::TestRequest, web::Bytes}; /// use memchr::memmem::find; /// /// let (body, headers) = create_form_data_payload_and_headers( From 611154beb29cc54698ba8ec390f4bab661eca0a6 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 4 Jul 2024 05:03:42 +0100 Subject: [PATCH 022/144] refactor: rename multipart module --- actix-multipart/src/extractor.rs | 8 +++----- actix-multipart/src/lib.rs | 4 ++-- actix-multipart/src/{server.rs => multipart.rs} | 0 3 files changed, 5 insertions(+), 7 deletions(-) rename actix-multipart/src/{server.rs => multipart.rs} (100%) diff --git a/actix-multipart/src/extractor.rs b/actix-multipart/src/extractor.rs index f7777100e..31999228e 100644 --- a/actix-multipart/src/extractor.rs +++ b/actix-multipart/src/extractor.rs @@ -1,13 +1,11 @@ -//! Multipart payload support - use actix_utils::future::{ready, Ready}; use actix_web::{dev::Payload, Error, FromRequest, HttpRequest}; -use crate::server::Multipart; +use crate::multipart::Multipart; -/// Get request's payload as multipart stream. +/// Extract request's payload as multipart stream. /// -/// Content-type: multipart/form-data; +/// Content-type: multipart/*; /// /// # Examples /// diff --git a/actix-multipart/src/lib.rs b/actix-multipart/src/lib.rs index 744c27088..ac07a172a 100644 --- a/actix-multipart/src/lib.rs +++ b/actix-multipart/src/lib.rs @@ -58,9 +58,9 @@ mod error; mod extractor; pub(crate) mod field; pub mod form; +mod multipart; pub(crate) mod payload; pub(crate) mod safety; -mod server; pub mod test; -pub use self::{error::Error as MultipartError, field::Field, server::Multipart}; +pub use self::{error::Error as MultipartError, field::Field, multipart::Multipart}; diff --git a/actix-multipart/src/server.rs b/actix-multipart/src/multipart.rs similarity index 100% rename from actix-multipart/src/server.rs rename to actix-multipart/src/multipart.rs From 5c9e6e7c1d43d29c5b51638e198ae238ef5c51f7 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 6 Jul 2024 22:58:54 +0100 Subject: [PATCH 023/144] feat(multipart): add field bytes method --- actix-multipart/CHANGES.md | 1 + actix-multipart/src/field.rs | 155 ++++++++++++++++++++++++++++++++++- 2 files changed, 152 insertions(+), 4 deletions(-) diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index dea24ab9d..86cd26060 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -4,6 +4,7 @@ - Add `MultipartError::ContentTypeIncompatible` variant. - Add `MultipartError::ContentDispositionNameMissing` variant. +- Add `Field::bytes()` method. - Rename `MultipartError::{NoContentDisposition => ContentDispositionMissing}` variant. - Rename `MultipartError::{NoContentType => ContentTypeMissing}` variant. - Rename `MultipartError::{ParseContentType => ContentTypeParse}` variant. diff --git a/actix-multipart/src/field.rs b/actix-multipart/src/field.rs index 50660b5d3..6bb1e5265 100644 --- a/actix-multipart/src/field.rs +++ b/actix-multipart/src/field.rs @@ -1,17 +1,19 @@ use std::{ cell::RefCell, - cmp, fmt, + cmp, fmt, mem, pin::Pin, rc::Rc, - task::{Context, Poll}, + task::{ready, Context, Poll}, }; +use actix_utils::future::poll_fn; use actix_web::{ error::PayloadError, http::header::{self, ContentDisposition, HeaderMap}, - web::Bytes, + web::{Bytes, BytesMut}, }; -use futures_core::stream::Stream; +use derive_more::{Display, Error}; +use futures_core::Stream; use mime::Mime; use crate::{ @@ -20,6 +22,10 @@ use crate::{ safety::Safety, }; +#[derive(Debug, Display, Error)] +#[display(fmt = "limit exceeded")] +pub struct LimitExceeded; + /// A single field in a multipart stream. pub struct Field { /// Field's Content-Type. @@ -103,6 +109,56 @@ impl Field { pub fn name(&self) -> Option<&str> { self.content_disposition()?.get_name() } + + /// Collects the raw field data, up to `limit` bytes. + /// + /// # Errors + /// + /// Any errors produced by the data stream are returned as `Ok(Err(Error))` immediately. + /// + /// If the buffered data size would exceed `limit`, an `Err(LimitExceeded)` is returned. Note + /// that, in this case, the full data stream is exhausted before returning the error so that + /// subsequent fields can still be read. To better defend against malicious/infinite requests, + /// it is advisable to also put a timeout on this call. + pub async fn bytes(&mut self, limit: usize) -> Result, LimitExceeded> { + /// Sensible default (2kB) for initial, bounded allocation when collecting body bytes. + const INITIAL_ALLOC_BYTES: usize = 2 * 1024; + + let mut exceeded_limit = false; + let mut buf = BytesMut::with_capacity(INITIAL_ALLOC_BYTES); + + let mut field = Pin::new(self); + + match poll_fn(|cx| loop { + match ready!(field.as_mut().poll_next(cx)) { + // if already over limit, discard chunk to advance multipart request + Some(Ok(_chunk)) if exceeded_limit => {} + + // if limit is exceeded set flag to true and continue + Some(Ok(chunk)) if buf.len() + chunk.len() > limit => { + exceeded_limit = true; + // eagerly de-allocate field data buffer + let _ = mem::take(&mut buf); + } + + Some(Ok(chunk)) => buf.extend_from_slice(&chunk), + + None => return Poll::Ready(Ok(())), + Some(Err(err)) => return Poll::Ready(Err(err)), + } + }) + .await + { + // propagate error returned from body poll + Err(err) => Ok(Err(err)), + + // limit was exceeded while reading body + Ok(()) if exceeded_limit => Err(LimitExceeded), + + // otherwise return body buffer + Ok(()) => Ok(Ok(buf.freeze())), + } + } } impl Stream for Field { @@ -341,3 +397,94 @@ impl InnerField { result } } + +#[cfg(test)] +mod tests { + use futures_util::{stream, StreamExt as _}; + + use super::*; + use crate::Multipart; + + // TODO: use test utility when multi-file support is introduced + fn create_double_request_with_header() -> (Bytes, HeaderMap) { + let bytes = Bytes::from( + "testasdadsad\r\n\ + --abbc761f78ff4d7cb7573b5a23f96ef0\r\n\ + Content-Disposition: form-data; name=\"file\"; filename=\"fn.txt\"\r\n\ + Content-Type: text/plain; charset=utf-8\r\n\ + \r\n\ + one+one+one\r\n\ + --abbc761f78ff4d7cb7573b5a23f96ef0\r\n\ + Content-Disposition: form-data; name=\"file\"; filename=\"fn.txt\"\r\n\ + Content-Type: text/plain; charset=utf-8\r\n\ + \r\n\ + two+two+two\r\n\ + --abbc761f78ff4d7cb7573b5a23f96ef0--\r\n", + ); + let mut headers = HeaderMap::new(); + headers.insert( + header::CONTENT_TYPE, + header::HeaderValue::from_static( + "multipart/mixed; boundary=\"abbc761f78ff4d7cb7573b5a23f96ef0\"", + ), + ); + (bytes, headers) + } + + #[actix_rt::test] + async fn bytes_unlimited() { + let (body, headers) = create_double_request_with_header(); + + let mut multipart = Multipart::new(&headers, stream::iter([Ok(body)])); + + let field = multipart + .next() + .await + .expect("multipart should have two fields") + .expect("multipart body should be well formatted") + .bytes(usize::MAX) + .await + .expect("field data should not be size limited") + .expect("reading field data should not error"); + assert_eq!(field, "one+one+one"); + + let field = multipart + .next() + .await + .expect("multipart should have two fields") + .expect("multipart body should be well formatted") + .bytes(usize::MAX) + .await + .expect("field data should not be size limited") + .expect("reading field data should not error"); + assert_eq!(field, "two+two+two"); + } + + #[actix_rt::test] + async fn bytes_limited() { + let (body, headers) = create_double_request_with_header(); + + let mut multipart = Multipart::new(&headers, stream::iter([Ok(body)])); + + multipart + .next() + .await + .expect("multipart should have two fields") + .expect("multipart body should be well formatted") + .bytes(8) // smaller than data size + .await + .expect_err("field data should be size limited"); + + // next field still readable + let field = multipart + .next() + .await + .expect("multipart should have two fields") + .expect("multipart body should be well formatted") + .bytes(usize::MAX) + .await + .expect("field data should not be size limited") + .expect("reading field data should not error"); + assert_eq!(field, "two+two+two"); + } +} From 6ae131ce298330c7388b426ec06e7a5969023b75 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 6 Jul 2024 23:38:37 +0100 Subject: [PATCH 024/144] test(multipart): replace SlowStream helper --- actix-multipart/Cargo.toml | 1 + actix-multipart/src/multipart.rs | 58 ++++++++------------------------ 2 files changed, 15 insertions(+), 44 deletions(-) diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index e5d1b5b1d..19761bb2e 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -66,6 +66,7 @@ assert_matches = "1" awc = "3" env_logger = "0.11" futures-util = { version = "0.3.17", default-features = false, features = ["alloc"] } +futures-test = "0.3" multer = "3" tokio = { version = "1.24.2", features = ["sync"] } tokio-stream = "0.1" diff --git a/actix-multipart/src/multipart.rs b/actix-multipart/src/multipart.rs index dc6a9ecb7..e511cb6df 100644 --- a/actix-multipart/src/multipart.rs +++ b/actix-multipart/src/multipart.rs @@ -482,7 +482,8 @@ mod tests { FromRequest, }; use assert_matches::assert_matches; - use futures_util::{future::lazy, StreamExt as _}; + use futures_test::stream::StreamTestExt as _; + use futures_util::{future::lazy, stream, StreamExt as _}; use tokio::sync::mpsc; use tokio_stream::wrappers::UnboundedReceiverStream; @@ -545,45 +546,6 @@ mod tests { ) } - // Stream that returns from a Bytes, one char at a time and Pending every other poll() - struct SlowStream { - bytes: Bytes, - pos: usize, - ready: bool, - } - - impl SlowStream { - fn new(bytes: Bytes) -> SlowStream { - SlowStream { - bytes, - pos: 0, - ready: false, - } - } - } - - impl Stream for SlowStream { - type Item = Result; - - fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - let this = self.get_mut(); - if !this.ready { - this.ready = true; - cx.waker().wake_by_ref(); - return Poll::Pending; - } - - if this.pos == this.bytes.len() { - return Poll::Ready(None); - } - - let res = Poll::Ready(Some(Ok(this.bytes.slice(this.pos..(this.pos + 1))))); - this.pos += 1; - this.ready = false; - res - } - } - fn create_simple_request_with_header() -> (Bytes, HeaderMap) { let (body, headers) = crate::test::create_form_data_payload_and_headers_with_boundary( BOUNDARY, @@ -721,7 +683,9 @@ mod tests { #[actix_rt::test] async fn test_stream() { let (bytes, headers) = create_double_request_with_header(); - let payload = SlowStream::new(bytes); + let payload = stream::iter(bytes) + .map(|byte| Ok(Bytes::copy_from_slice(&[byte]))) + .interleave_pending(); let mut multipart = Multipart::new(&headers, payload); match multipart.next().await.unwrap() { @@ -899,7 +863,9 @@ mod tests { "multipart/form-data; boundary=\"abbc761f78ff4d7cb7573b5a23f96ef0\"", ), ); - let payload = SlowStream::new(bytes); + let payload = stream::iter(bytes) + .map(|byte| Ok(Bytes::copy_from_slice(&[byte]))) + .interleave_pending(); let mut multipart = Multipart::new(&headers, payload); let res = multipart.next().await.unwrap(); @@ -929,7 +895,9 @@ mod tests { "multipart/mixed; boundary=\"abbc761f78ff4d7cb7573b5a23f96ef0\"", ), ); - let payload = SlowStream::new(bytes); + let payload = stream::iter(bytes) + .map(|byte| Ok(Bytes::copy_from_slice(&[byte]))) + .interleave_pending(); let mut multipart = Multipart::new(&headers, payload); let res = multipart.next().await.unwrap(); @@ -955,7 +923,9 @@ mod tests { "multipart/form-data; boundary=\"abbc761f78ff4d7cb7573b5a23f96ef0\"", ), ); - let payload = SlowStream::new(bytes); + let payload = stream::iter(bytes) + .map(|byte| Ok(Bytes::copy_from_slice(&[byte]))) + .interleave_pending(); let mut multipart = Multipart::new(&headers, payload); let res = multipart.next().await.unwrap(); From 01d60f331586d036a0ccee516abc7b6208f2ecbd Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 7 Jul 2024 00:05:53 +0100 Subject: [PATCH 025/144] chore(actix-multipart): prepare release 0.7.0 --- actix-multipart-derive/Cargo.toml | 2 +- actix-multipart/CHANGES.md | 2 ++ actix-multipart/Cargo.toml | 2 +- actix-multipart/README.md | 4 ++-- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/actix-multipart-derive/Cargo.toml b/actix-multipart-derive/Cargo.toml index e978864a3..35cbcc130 100644 --- a/actix-multipart-derive/Cargo.toml +++ b/actix-multipart-derive/Cargo.toml @@ -25,7 +25,7 @@ quote = "1" syn = "2" [dev-dependencies] -actix-multipart = "0.6" +actix-multipart = "0.7" actix-web = "4" rustversion = "1" trybuild = "1" diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index 86cd26060..e9d1314e5 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.7.0 + - Add `MultipartError::ContentTypeIncompatible` variant. - Add `MultipartError::ContentDispositionNameMissing` variant. - Add `Field::bytes()` method. diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index 19761bb2e..61a9b5089 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-multipart" -version = "0.6.2" +version = "0.7.0" authors = [ "Nikolay Kim ", "Jacob Halsey ", diff --git a/actix-multipart/README.md b/actix-multipart/README.md index 917dceece..0356976b2 100644 --- a/actix-multipart/README.md +++ b/actix-multipart/README.md @@ -3,11 +3,11 @@ [![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.2)](https://docs.rs/actix-multipart/0.6.2) +[![Documentation](https://docs.rs/actix-multipart/badge.svg?version=0.7.0)](https://docs.rs/actix-multipart/0.7.0) ![Version](https://img.shields.io/badge/rustc-1.72+-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.2/status.svg)](https://deps.rs/crate/actix-multipart/0.6.2) +[![dependency status](https://deps.rs/crate/actix-multipart/0.7.0/status.svg)](https://deps.rs/crate/actix-multipart/0.7.0) [![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) From ffee672909db5db809d09f6b67ff52352505107b Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 7 Jul 2024 00:19:22 +0100 Subject: [PATCH 026/144] chore(actix-multipart): prepare release 0.7.1 --- actix-multipart/CHANGES.md | 4 ++++ actix-multipart/Cargo.toml | 2 +- actix-multipart/README.md | 4 ++-- actix-multipart/src/field.rs | 4 +++- actix-multipart/src/lib.rs | 6 +++++- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index e9d1314e5..adc568253 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.7.1 + +- Expose `LimitExceeded` error type. + ## 0.7.0 - Add `MultipartError::ContentTypeIncompatible` variant. diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index 61a9b5089..f567d2d7c 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-multipart" -version = "0.7.0" +version = "0.7.1" authors = [ "Nikolay Kim ", "Jacob Halsey ", diff --git a/actix-multipart/README.md b/actix-multipart/README.md index 0356976b2..20673d524 100644 --- a/actix-multipart/README.md +++ b/actix-multipart/README.md @@ -3,11 +3,11 @@ [![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.7.0)](https://docs.rs/actix-multipart/0.7.0) +[![Documentation](https://docs.rs/actix-multipart/badge.svg?version=0.7.1)](https://docs.rs/actix-multipart/0.7.1) ![Version](https://img.shields.io/badge/rustc-1.72+-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.7.0/status.svg)](https://deps.rs/crate/actix-multipart/0.7.0) +[![dependency status](https://deps.rs/crate/actix-multipart/0.7.1/status.svg)](https://deps.rs/crate/actix-multipart/0.7.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/actix-multipart/src/field.rs b/actix-multipart/src/field.rs index 6bb1e5265..0e4167c8e 100644 --- a/actix-multipart/src/field.rs +++ b/actix-multipart/src/field.rs @@ -22,8 +22,10 @@ use crate::{ safety::Safety, }; +/// Error type returned from [`Field::bytes()`] when field data is larger than limit. #[derive(Debug, Display, Error)] -#[display(fmt = "limit exceeded")] +#[display(fmt = "size limit exceeded while collecting field data")] +#[non_exhaustive] pub struct LimitExceeded; /// A single field in a multipart stream. diff --git a/actix-multipart/src/lib.rs b/actix-multipart/src/lib.rs index ac07a172a..a56b9846b 100644 --- a/actix-multipart/src/lib.rs +++ b/actix-multipart/src/lib.rs @@ -63,4 +63,8 @@ pub(crate) mod payload; pub(crate) mod safety; pub mod test; -pub use self::{error::Error as MultipartError, field::Field, multipart::Multipart}; +pub use self::{ + error::Error as MultipartError, + field::{Field, LimitExceeded}, + multipart::Multipart, +}; From 215a294584fc2d209aef974a2e3b0759c1488c08 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 7 Jul 2024 00:30:27 +0100 Subject: [PATCH 027/144] chore(actix-multipart-derive): prepare release 0.7.0 --- actix-multipart-derive/CHANGES.md | 2 ++ actix-multipart-derive/Cargo.toml | 2 +- actix-multipart-derive/README.md | 4 ++-- actix-multipart/CHANGES.md | 2 ++ actix-multipart/Cargo.toml | 2 +- actix-multipart/src/field.rs | 5 +++-- 6 files changed, 11 insertions(+), 6 deletions(-) diff --git a/actix-multipart-derive/CHANGES.md b/actix-multipart-derive/CHANGES.md index 1b44ba4b7..d0c759297 100644 --- a/actix-multipart-derive/CHANGES.md +++ b/actix-multipart-derive/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.7.0 + - Minimum supported Rust version (MSRV) is now 1.72. ## 0.6.1 diff --git a/actix-multipart-derive/Cargo.toml b/actix-multipart-derive/Cargo.toml index 35cbcc130..33eacd460 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.1" +version = "0.7.0" authors = ["Jacob Halsey "] description = "Multipart form derive macro for Actix Web" keywords = ["http", "web", "framework", "async", "futures"] diff --git a/actix-multipart-derive/README.md b/actix-multipart-derive/README.md index ec0afffdd..bf75613ed 100644 --- a/actix-multipart-derive/README.md +++ b/actix-multipart-derive/README.md @@ -5,11 +5,11 @@ [![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.6.1)](https://docs.rs/actix-multipart-derive/0.6.1) +[![Documentation](https://docs.rs/actix-multipart-derive/badge.svg?version=0.7.0)](https://docs.rs/actix-multipart-derive/0.7.0) ![Version](https://img.shields.io/badge/rustc-1.72+-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.6.1/status.svg)](https://deps.rs/crate/actix-multipart-derive/0.6.1) +[![dependency status](https://deps.rs/crate/actix-multipart-derive/0.7.0/status.svg)](https://deps.rs/crate/actix-multipart-derive/0.7.0) [![Download](https://img.shields.io/crates/d/actix-multipart-derive.svg)](https://crates.io/crates/actix-multipart-derive) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index adc568253..201502691 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +- Fix re-exported version of `actix-multipart-derive`. + ## 0.7.1 - Expose `LimitExceeded` error type. diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index f567d2d7c..5d81f6973 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -37,7 +37,7 @@ derive = ["actix-multipart-derive"] tempfile = ["dep:tempfile", "tokio/fs"] [dependencies] -actix-multipart-derive = { version = "=0.6.1", optional = true } +actix-multipart-derive = { version = "=0.7.0", optional = true } actix-utils = "3" actix-web = { version = "4", default-features = false } diff --git a/actix-multipart/src/field.rs b/actix-multipart/src/field.rs index 0e4167c8e..652b3e8b7 100644 --- a/actix-multipart/src/field.rs +++ b/actix-multipart/src/field.rs @@ -1,12 +1,13 @@ use std::{ cell::RefCell, - cmp, fmt, mem, + cmp, fmt, + future::poll_fn, + mem, pin::Pin, rc::Rc, task::{ready, Context, Poll}, }; -use actix_utils::future::poll_fn; use actix_web::{ error::PayloadError, http::header::{self, ContentDisposition, HeaderMap}, From b01fbddba484a52309d3fd50dafd862e29684453 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 7 Jul 2024 00:34:18 +0100 Subject: [PATCH 028/144] chore(actix-multipart): prepare release 0.7.2 --- actix-multipart/CHANGES.md | 2 ++ actix-multipart/Cargo.toml | 2 +- actix-multipart/README.md | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index 201502691..c3f3b6e39 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.7.2 + - Fix re-exported version of `actix-multipart-derive`. ## 0.7.1 diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index 5d81f6973..e1172e8cf 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-multipart" -version = "0.7.1" +version = "0.7.2" authors = [ "Nikolay Kim ", "Jacob Halsey ", diff --git a/actix-multipart/README.md b/actix-multipart/README.md index 20673d524..52df77d13 100644 --- a/actix-multipart/README.md +++ b/actix-multipart/README.md @@ -3,11 +3,11 @@ [![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.7.1)](https://docs.rs/actix-multipart/0.7.1) +[![Documentation](https://docs.rs/actix-multipart/badge.svg?version=0.7.2)](https://docs.rs/actix-multipart/0.7.2) ![Version](https://img.shields.io/badge/rustc-1.72+-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.7.1/status.svg)](https://deps.rs/crate/actix-multipart/0.7.1) +[![dependency status](https://deps.rs/crate/actix-multipart/0.7.2/status.svg)](https://deps.rs/crate/actix-multipart/0.7.2) [![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) From e0e4d1e66124a8dfcc2259dc6c74f86159fbffb3 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 7 Jul 2024 03:54:00 +0100 Subject: [PATCH 029/144] chore: move deny lints to manifests --- Cargo.toml | 8 ++++++++ actix-files/Cargo.toml | 3 +++ actix-files/src/lib.rs | 3 +-- actix-http-test/Cargo.toml | 3 +++ actix-http-test/src/lib.rs | 2 -- actix-http/Cargo.toml | 3 +++ actix-http/src/h1/service.rs | 2 +- actix-http/src/h2/service.rs | 2 +- actix-http/src/lib.rs | 2 -- actix-http/src/message.rs | 2 +- actix-http/src/service.rs | 4 ++-- actix-http/src/test.rs | 4 ++-- actix-multipart-derive/Cargo.toml | 3 +++ actix-multipart-derive/src/lib.rs | 2 -- actix-multipart/Cargo.toml | 6 ++---- actix-router/Cargo.toml | 3 +++ actix-router/src/lib.rs | 2 -- actix-test/Cargo.toml | 3 +++ actix-test/src/lib.rs | 2 -- actix-web-actors/Cargo.toml | 3 +++ actix-web-actors/src/lib.rs | 2 -- actix-web-codegen/Cargo.toml | 3 +++ actix-web-codegen/src/lib.rs | 2 -- actix-web-codegen/tests/routes.rs | 2 +- actix-web-codegen/tests/scopes.rs | 2 +- actix-web/Cargo.toml | 3 +++ actix-web/src/app.rs | 2 +- actix-web/src/app_service.rs | 2 +- actix-web/src/config.rs | 4 ++-- actix-web/src/data.rs | 2 +- actix-web/src/lib.rs | 2 -- actix-web/src/middleware/default_headers.rs | 2 +- actix-web/src/middleware/err_handlers.rs | 16 ++++++++++------ actix-web/src/middleware/logger.rs | 2 +- actix-web/src/resource.rs | 6 +++--- actix-web/src/route.rs | 2 +- actix-web/src/server.rs | 18 +++++++++--------- awc/Cargo.toml | 3 +++ awc/src/client/pool.rs | 15 +++++++++------ awc/src/frozen.rs | 10 +++++----- awc/src/lib.rs | 2 -- awc/src/middleware/redirect.rs | 2 +- 42 files changed, 95 insertions(+), 71 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 19d5dd116..51f998314 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,3 +51,11 @@ awc = { path = "awc" } # actix-utils = { path = "../actix-net/actix-utils" } # actix-tls = { path = "../actix-net/actix-tls" } # actix-server = { path = "../actix-net/actix-server" } + +[workspace.lints.rust] +rust_2018_idioms = { level = "deny" } +future_incompatible = { level = "deny" } +nonstandard_style = { level = "deny" } + +[workspace.lints.clippy] +# clone_on_ref_ptr = { level = "deny" } diff --git a/actix-files/Cargo.toml b/actix-files/Cargo.toml index 57cd4e913..0c02359c4 100644 --- a/actix-files/Cargo.toml +++ b/actix-files/Cargo.toml @@ -54,3 +54,6 @@ actix-test = "0.1" actix-web = "4" env_logger = "0.11" tempfile = "3.2" + +[lints] +workspace = true diff --git a/actix-files/src/lib.rs b/actix-files/src/lib.rs index 0178c13de..551a14fa4 100644 --- a/actix-files/src/lib.rs +++ b/actix-files/src/lib.rs @@ -11,8 +11,7 @@ //! .service(Files::new("/static", ".").prefer_utf8(true)); //! ``` -#![deny(rust_2018_idioms, nonstandard_style)] -#![warn(future_incompatible, missing_docs, missing_debug_implementations)] +#![warn(missing_docs, missing_debug_implementations)] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] diff --git a/actix-http-test/Cargo.toml b/actix-http-test/Cargo.toml index 0947579a5..7ccb70a45 100644 --- a/actix-http-test/Cargo.toml +++ b/actix-http-test/Cargo.toml @@ -59,3 +59,6 @@ tokio = { version = "1.24.2", features = ["sync"] } [dev-dependencies] actix-http = "3" + +[lints] +workspace = true diff --git a/actix-http-test/src/lib.rs b/actix-http-test/src/lib.rs index 554af9102..d83b0b3ea 100644 --- a/actix-http-test/src/lib.rs +++ b/actix-http-test/src/lib.rs @@ -1,7 +1,5 @@ //! Various helpers for Actix applications to use during testing. -#![deny(rust_2018_idioms, nonstandard_style)] -#![warn(future_incompatible)] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 0a0252e9a..8fb31da4f 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -167,6 +167,9 @@ tls-openssl = { package = "openssl", version = "0.10.55" } tls-rustls_023 = { package = "rustls", version = "0.23" } tokio = { version = "1.24.2", features = ["net", "rt", "macros"] } +[lints] +workspace = true + [[example]] name = "ws" required-features = ["ws", "rustls-0_23"] diff --git a/actix-http/src/h1/service.rs b/actix-http/src/h1/service.rs index f2f8a0e48..4fbccf844 100644 --- a/actix-http/src/h1/service.rs +++ b/actix-http/src/h1/service.rs @@ -541,6 +541,6 @@ where fn call(&self, (io, addr): (T, Option)) -> Self::Future { let conn_data = OnConnectData::from_io(&io, self.on_connect_ext.as_deref()); - Dispatcher::new(io, self.flow.clone(), self.cfg.clone(), addr, conn_data) + Dispatcher::new(io, Rc::clone(&self.flow), self.cfg.clone(), addr, conn_data) } } diff --git a/actix-http/src/h2/service.rs b/actix-http/src/h2/service.rs index 636ac3161..debc73e59 100644 --- a/actix-http/src/h2/service.rs +++ b/actix-http/src/h2/service.rs @@ -434,7 +434,7 @@ where H2ServiceHandlerResponse { state: State::Handshake( - Some(self.flow.clone()), + Some(Rc::clone(&self.flow)), Some(self.cfg.clone()), addr, on_connect_data, diff --git a/actix-http/src/lib.rs b/actix-http/src/lib.rs index ac79433c6..734e6e1e1 100644 --- a/actix-http/src/lib.rs +++ b/actix-http/src/lib.rs @@ -20,8 +20,6 @@ //! [rustls]: https://crates.io/crates/rustls //! [trust-dns]: https://crates.io/crates/trust-dns -#![deny(rust_2018_idioms, nonstandard_style)] -#![warn(future_incompatible)] #![allow( clippy::type_complexity, clippy::too_many_arguments, diff --git a/actix-http/src/message.rs b/actix-http/src/message.rs index 47b128fd0..d2241b229 100644 --- a/actix-http/src/message.rs +++ b/actix-http/src/message.rs @@ -66,7 +66,7 @@ impl ops::DerefMut for Message { impl Drop for Message { fn drop(&mut self) { - T::with_pool(|p| p.release(self.head.clone())) + T::with_pool(|p| p.release(Rc::clone(&self.head))) } } diff --git a/actix-http/src/service.rs b/actix-http/src/service.rs index 37cee960f..3ea88274a 100644 --- a/actix-http/src/service.rs +++ b/actix-http/src/service.rs @@ -910,7 +910,7 @@ where handshake: Some(( crate::h2::handshake_with_timeout(io, &self.cfg), self.cfg.clone(), - self.flow.clone(), + Rc::clone(&self.flow), conn_data, peer_addr, )), @@ -926,7 +926,7 @@ where state: State::H1 { dispatcher: h1::Dispatcher::new( io, - self.flow.clone(), + Rc::clone(&self.flow), self.cfg.clone(), peer_addr, conn_data, diff --git a/actix-http/src/test.rs b/actix-http/src/test.rs index 3815e64c6..dfa9a86c9 100644 --- a/actix-http/src/test.rs +++ b/actix-http/src/test.rs @@ -159,8 +159,8 @@ impl TestBuffer { #[allow(dead_code)] pub(crate) fn clone(&self) -> Self { Self { - read_buf: self.read_buf.clone(), - write_buf: self.write_buf.clone(), + read_buf: Rc::clone(&self.read_buf), + write_buf: Rc::clone(&self.write_buf), err: self.err.clone(), } } diff --git a/actix-multipart-derive/Cargo.toml b/actix-multipart-derive/Cargo.toml index 33eacd460..964ef2b74 100644 --- a/actix-multipart-derive/Cargo.toml +++ b/actix-multipart-derive/Cargo.toml @@ -29,3 +29,6 @@ actix-multipart = "0.7" actix-web = "4" rustversion = "1" trybuild = "1" + +[lints] +workspace = true diff --git a/actix-multipart-derive/src/lib.rs b/actix-multipart-derive/src/lib.rs index 44db1fa0e..6818d477c 100644 --- a/actix-multipart-derive/src/lib.rs +++ b/actix-multipart-derive/src/lib.rs @@ -2,8 +2,6 @@ //! //! See [`macro@MultipartForm`] for usage examples. -#![deny(rust_2018_idioms, nonstandard_style)] -#![warn(future_incompatible)] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index e1172e8cf..a5b0e3a2c 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -71,7 +71,5 @@ multer = "3" tokio = { version = "1.24.2", features = ["sync"] } tokio-stream = "0.1" -[lints.rust] -future_incompatible = { level = "deny" } -rust_2018_idioms = { level = "deny" } -nonstandard_style = { level = "deny" } +[lints] +workspace = true diff --git a/actix-router/Cargo.toml b/actix-router/Cargo.toml index 7e7e3beb8..7def1bdb4 100644 --- a/actix-router/Cargo.toml +++ b/actix-router/Cargo.toml @@ -38,6 +38,9 @@ http = "0.2.7" serde = { version = "1", features = ["derive"] } percent-encoding = "2.1" +[lints] +workspace = true + [[bench]] name = "router" harness = false diff --git a/actix-router/src/lib.rs b/actix-router/src/lib.rs index c4d0d2c87..3f5e969e7 100644 --- a/actix-router/src/lib.rs +++ b/actix-router/src/lib.rs @@ -1,7 +1,5 @@ //! Resource path matching and router. -#![deny(rust_2018_idioms, nonstandard_style)] -#![warn(future_incompatible)] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] diff --git a/actix-test/Cargo.toml b/actix-test/Cargo.toml index e810ae80b..34fdf2c82 100644 --- a/actix-test/Cargo.toml +++ b/actix-test/Cargo.toml @@ -73,3 +73,6 @@ tls-rustls-0_21 = { package = "rustls", version = "0.21", optional = true } tls-rustls-0_22 = { package = "rustls", version = "0.22", optional = true } tls-rustls-0_23 = { package = "rustls", version = "0.23", default-features = false, optional = true } tokio = { version = "1.24.2", features = ["sync"] } + +[lints] +workspace = true diff --git a/actix-test/src/lib.rs b/actix-test/src/lib.rs index 9be99978d..f0da2c20d 100644 --- a/actix-test/src/lib.rs +++ b/actix-test/src/lib.rs @@ -27,8 +27,6 @@ //! } //! ``` -#![deny(rust_2018_idioms, nonstandard_style)] -#![warn(future_incompatible)] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] diff --git a/actix-web-actors/Cargo.toml b/actix-web-actors/Cargo.toml index 3c74a4f47..f753b7f7f 100644 --- a/actix-web-actors/Cargo.toml +++ b/actix-web-actors/Cargo.toml @@ -41,3 +41,6 @@ actix-web = { version = "4", features = ["macros"] } env_logger = "0.11" futures-util = { version = "0.3.17", default-features = false, features = ["std"] } mime = "0.3" + +[lints] +workspace = true diff --git a/actix-web-actors/src/lib.rs b/actix-web-actors/src/lib.rs index d89b0ee35..0198c830f 100644 --- a/actix-web-actors/src/lib.rs +++ b/actix-web-actors/src/lib.rs @@ -55,8 +55,6 @@ //! * [`HttpContext`]: This struct provides actor support for streaming HTTP responses. //! -#![deny(rust_2018_idioms, nonstandard_style)] -#![warn(future_incompatible)] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] diff --git a/actix-web-codegen/Cargo.toml b/actix-web-codegen/Cargo.toml index 7500807d2..d3938da8e 100644 --- a/actix-web-codegen/Cargo.toml +++ b/actix-web-codegen/Cargo.toml @@ -35,3 +35,6 @@ actix-web = "4" futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] } trybuild = "1" rustversion = "1" + +[lints] +workspace = true diff --git a/actix-web-codegen/src/lib.rs b/actix-web-codegen/src/lib.rs index c518007a0..e22bff8cd 100644 --- a/actix-web-codegen/src/lib.rs +++ b/actix-web-codegen/src/lib.rs @@ -73,8 +73,6 @@ //! [DELETE]: macro@delete #![recursion_limit = "512"] -#![deny(rust_2018_idioms, nonstandard_style)] -#![warn(future_incompatible)] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] diff --git a/actix-web-codegen/tests/routes.rs b/actix-web-codegen/tests/routes.rs index fb50d4ae0..a6e606871 100644 --- a/actix-web-codegen/tests/routes.rs +++ b/actix-web-codegen/tests/routes.rs @@ -145,7 +145,7 @@ async fn custom_resource_name_test<'a>(req: HttpRequest) -> impl Responder { mod guard_module { use actix_web::{guard::GuardContext, http::header}; - pub fn guard(ctx: &GuardContext) -> bool { + pub fn guard(ctx: &GuardContext<'_>) -> bool { ctx.header::() .map(|h| h.preference() == "image/*") .unwrap_or(false) diff --git a/actix-web-codegen/tests/scopes.rs b/actix-web-codegen/tests/scopes.rs index 4ee6db16f..b8c832682 100644 --- a/actix-web-codegen/tests/scopes.rs +++ b/actix-web-codegen/tests/scopes.rs @@ -1,7 +1,7 @@ use actix_web::{guard::GuardContext, http, http::header, web, App, HttpResponse, Responder}; use actix_web_codegen::{delete, get, post, route, routes, scope}; -pub fn image_guard(ctx: &GuardContext) -> bool { +pub fn image_guard(ctx: &GuardContext<'_>) -> bool { ctx.header::() .map(|h| h.preference() == "image/*") .unwrap_or(false) diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index 125cfe20f..543f44400 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -188,6 +188,9 @@ tls-rustls = { package = "rustls", version = "0.23" } tokio = { version = "1.24.2", features = ["rt-multi-thread", "macros"] } zstd = "0.13" +[lints] +workspace = true + [[test]] name = "test_server" required-features = ["compress-brotli", "compress-gzip", "compress-zstd", "cookies"] diff --git a/actix-web/src/app.rs b/actix-web/src/app.rs index 21a4443cf..240e5b982 100644 --- a/actix-web/src/app.rs +++ b/actix-web/src/app.rs @@ -39,7 +39,7 @@ impl App { let factory_ref = Rc::new(RefCell::new(None)); App { - endpoint: AppEntry::new(factory_ref.clone()), + endpoint: AppEntry::new(Rc::clone(&factory_ref)), data_factories: Vec::new(), services: Vec::new(), default: None, diff --git a/actix-web/src/app_service.rs b/actix-web/src/app_service.rs index 65a6ed87b..7aa16b790 100644 --- a/actix-web/src/app_service.rs +++ b/actix-web/src/app_service.rs @@ -71,7 +71,7 @@ where }); // create App config to pass to child services - let mut config = AppService::new(config, default.clone()); + let mut config = AppService::new(config, Rc::clone(&default)); // register services mem::take(&mut *self.services.borrow_mut()) diff --git a/actix-web/src/config.rs b/actix-web/src/config.rs index 5e8b056f1..0e856f574 100644 --- a/actix-web/src/config.rs +++ b/actix-web/src/config.rs @@ -68,7 +68,7 @@ impl AppService { pub(crate) fn clone_config(&self) -> Self { AppService { config: self.config.clone(), - default: self.default.clone(), + default: Rc::clone(&self.default), services: Vec::new(), root: false, } @@ -81,7 +81,7 @@ impl AppService { /// Returns default handler factory. pub fn default_service(&self) -> Rc { - self.default.clone() + Rc::clone(&self.default) } /// Register HTTP service. diff --git a/actix-web/src/data.rs b/actix-web/src/data.rs index acbb8e23a..088df55d2 100644 --- a/actix-web/src/data.rs +++ b/actix-web/src/data.rs @@ -184,7 +184,7 @@ impl FromRequest for Data { impl DataFactory for Data { fn create(&self, extensions: &mut Extensions) -> bool { - extensions.insert(Data(self.0.clone())); + extensions.insert(Data(Arc::clone(&self.0))); true } } diff --git a/actix-web/src/lib.rs b/actix-web/src/lib.rs index 205391388..752852525 100644 --- a/actix-web/src/lib.rs +++ b/actix-web/src/lib.rs @@ -70,8 +70,6 @@ //! - `rustls-0_23` - HTTPS support via `rustls` 0.23 crate, supports `HTTP/2` //! - `secure-cookies` - secure cookies support -#![deny(rust_2018_idioms, nonstandard_style)] -#![warn(future_incompatible)] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] diff --git a/actix-web/src/middleware/default_headers.rs b/actix-web/src/middleware/default_headers.rs index f21afe6eb..2669a047e 100644 --- a/actix-web/src/middleware/default_headers.rs +++ b/actix-web/src/middleware/default_headers.rs @@ -141,7 +141,7 @@ where actix_service::forward_ready!(service); fn call(&self, req: ServiceRequest) -> Self::Future { - let inner = self.inner.clone(); + let inner = Rc::clone(&self.inner); let fut = self.service.call(req); DefaultHeaderFuture { diff --git a/actix-web/src/middleware/err_handlers.rs b/actix-web/src/middleware/err_handlers.rs index aa6d1c8a4..3c50d5c8f 100644 --- a/actix-web/src/middleware/err_handlers.rs +++ b/actix-web/src/middleware/err_handlers.rs @@ -220,16 +220,20 @@ impl ErrorHandlers { /// [`.handler()`][ErrorHandlers::handler]) will fall back on this. /// /// Note that this will overwrite any default handlers previously set by calling - /// [`.default_handler_client()`][ErrorHandlers::default_handler_client] or - /// [`.default_handler_server()`][ErrorHandlers::default_handler_server], but not any set by - /// calling [`.handler()`][ErrorHandlers::handler]. + /// [`default_handler_client()`] or [`.default_handler_server()`], but not any set by calling + /// [`.handler()`]. + /// + /// [`default_handler_client()`]: ErrorHandlers::default_handler_client + /// [`.default_handler_server()`]: ErrorHandlers::default_handler_server + /// [`.handler()`]: ErrorHandlers::handler pub fn default_handler(self, handler: F) -> Self where F: Fn(ServiceResponse) -> Result> + 'static, { let handler = Rc::new(handler); + let handler2 = Rc::clone(&handler); Self { - default_server: Some(handler.clone()), + default_server: Some(handler2), default_client: Some(handler), ..self } @@ -288,7 +292,7 @@ where type Future = LocalBoxFuture<'static, Result>; fn new_transform(&self, service: S) -> Self::Future { - let handlers = self.handlers.clone(); + let handlers = Rc::clone(&self.handlers); let default_client = self.default_client.clone(); let default_server = self.default_server.clone(); Box::pin(async move { @@ -323,7 +327,7 @@ where actix_service::forward_ready!(service); fn call(&self, req: ServiceRequest) -> Self::Future { - let handlers = self.handlers.clone(); + let handlers = Rc::clone(&self.handlers); let default_client = self.default_client.clone(); let default_server = self.default_server.clone(); let fut = self.service.call(req); diff --git a/actix-web/src/middleware/logger.rs b/actix-web/src/middleware/logger.rs index dc1b02399..e9ac24d50 100644 --- a/actix-web/src/middleware/logger.rs +++ b/actix-web/src/middleware/logger.rs @@ -276,7 +276,7 @@ where ready(Ok(LoggerMiddleware { service, - inner: self.0.clone(), + inner: Rc::clone(&self.0), })) } } diff --git a/actix-web/src/resource.rs b/actix-web/src/resource.rs index 00555b7b2..d89438edb 100644 --- a/actix-web/src/resource.rs +++ b/actix-web/src/resource.rs @@ -62,14 +62,14 @@ pub struct Resource { impl Resource { /// Constructs new resource that matches a `path` pattern. pub fn new(path: T) -> Resource { - let fref = Rc::new(RefCell::new(None)); + let factory_ref = Rc::new(RefCell::new(None)); Resource { routes: Vec::new(), rdef: path.patterns(), name: None, - endpoint: ResourceEndpoint::new(fref.clone()), - factory_ref: fref, + endpoint: ResourceEndpoint::new(Rc::clone(&factory_ref)), + factory_ref, guards: Vec::new(), app_data: None, default: boxed::factory(fn_service(|req: ServiceRequest| async { diff --git a/actix-web/src/route.rs b/actix-web/src/route.rs index 261e6b9ae..e05e6be52 100644 --- a/actix-web/src/route.rs +++ b/actix-web/src/route.rs @@ -77,7 +77,7 @@ impl ServiceFactory for Route { fn new_service(&self, _: ()) -> Self::Future { let fut = self.service.new_service(()); - let guards = self.guards.clone(); + let guards = Rc::clone(&self.guards); Box::pin(async move { let service = fut.await?; diff --git a/actix-web/src/server.rs b/actix-web/src/server.rs index 95e15581f..d8519fb9e 100644 --- a/actix-web/src/server.rs +++ b/actix-web/src/server.rs @@ -510,7 +510,7 @@ where /// No changes are made to `lst`'s configuration. Ensure it is configured properly before /// passing ownership to `listen()`. pub fn listen(mut self, lst: net::TcpListener) -> io::Result { - let cfg = self.config.clone(); + let cfg = Arc::clone(&self.config); let factory = self.factory.clone(); let addr = lst.local_addr().unwrap(); @@ -554,7 +554,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 cfg = Arc::clone(&self.config); let factory = self.factory.clone(); let addr = lst.local_addr().unwrap(); @@ -632,7 +632,7 @@ where config: actix_tls::accept::rustls_0_20::reexports::ServerConfig, ) -> io::Result { let factory = self.factory.clone(); - let cfg = self.config.clone(); + let cfg = Arc::clone(&self.config); let addr = lst.local_addr().unwrap(); self.sockets.push(Socket { addr, @@ -683,7 +683,7 @@ where config: actix_tls::accept::rustls_0_21::reexports::ServerConfig, ) -> io::Result { let factory = self.factory.clone(); - let cfg = self.config.clone(); + let cfg = Arc::clone(&self.config); let addr = lst.local_addr().unwrap(); self.sockets.push(Socket { addr, @@ -749,7 +749,7 @@ where config: actix_tls::accept::rustls_0_22::reexports::ServerConfig, ) -> io::Result { let factory = self.factory.clone(); - let cfg = self.config.clone(); + let cfg = Arc::clone(&self.config); let addr = lst.local_addr().unwrap(); self.sockets.push(Socket { addr, @@ -815,7 +815,7 @@ where config: actix_tls::accept::rustls_0_23::reexports::ServerConfig, ) -> io::Result { let factory = self.factory.clone(); - let cfg = self.config.clone(); + let cfg = Arc::clone(&self.config); let addr = lst.local_addr().unwrap(); self.sockets.push(Socket { addr, @@ -880,7 +880,7 @@ where acceptor: SslAcceptor, ) -> io::Result { let factory = self.factory.clone(); - let cfg = self.config.clone(); + let cfg = Arc::clone(&self.config); let addr = lst.local_addr().unwrap(); self.sockets.push(Socket { addr, @@ -937,7 +937,7 @@ where use actix_rt::net::UnixStream; use actix_service::{fn_service, ServiceFactoryExt as _}; - let cfg = self.config.clone(); + let cfg = Arc::clone(&self.config); let factory = self.factory.clone(); let socket_addr = net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080); @@ -982,7 +982,7 @@ where use actix_rt::net::UnixStream; use actix_service::{fn_service, ServiceFactoryExt as _}; - let cfg = self.config.clone(); + let cfg = Arc::clone(&self.config); let factory = self.factory.clone(); let socket_addr = net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080); diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 4fc2057f6..353ca0d54 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -153,6 +153,9 @@ tokio = { version = "1.24.2", features = ["rt-multi-thread", "macros"] } zstd = "0.13" tls-rustls-0_23 = { package = "rustls", version = "0.23" } # add rustls 0.23 with default features to make aws_lc_rs work in tests +[lints] +workspace = true + [[example]] name = "client" required-features = ["rustls-0_23-webpki-roots"] diff --git a/awc/src/client/pool.rs b/awc/src/client/pool.rs index 2938353fd..4c439e4eb 100644 --- a/awc/src/client/pool.rs +++ b/awc/src/client/pool.rs @@ -173,12 +173,15 @@ where }; // acquire an owned permit and carry it with connection - let permit = inner.permits.clone().acquire_owned().await.map_err(|_| { - ConnectError::Io(io::Error::new( - io::ErrorKind::Other, - "failed to acquire semaphore on client connection pool", - )) - })?; + let permit = Arc::clone(&inner.permits) + .acquire_owned() + .await + .map_err(|_| { + ConnectError::Io(io::Error::new( + io::ErrorKind::Other, + "failed to acquire semaphore on client connection pool", + )) + })?; let conn = { let mut conn = None; diff --git a/awc/src/frozen.rs b/awc/src/frozen.rs index 8f3244997..90b2c6efd 100644 --- a/awc/src/frozen.rs +++ b/awc/src/frozen.rs @@ -49,7 +49,7 @@ impl FrozenClientRequest { where B: MessageBody + 'static, { - RequestSender::Rc(self.head.clone(), None).send_body( + RequestSender::Rc(Rc::clone(&self.head), None).send_body( self.addr, self.response_decompress, self.timeout, @@ -60,7 +60,7 @@ impl FrozenClientRequest { /// Send a json body. pub fn send_json(&self, value: &T) -> SendClientRequest { - RequestSender::Rc(self.head.clone(), None).send_json( + RequestSender::Rc(Rc::clone(&self.head), None).send_json( self.addr, self.response_decompress, self.timeout, @@ -71,7 +71,7 @@ impl FrozenClientRequest { /// Send an urlencoded body. pub fn send_form(&self, value: &T) -> SendClientRequest { - RequestSender::Rc(self.head.clone(), None).send_form( + RequestSender::Rc(Rc::clone(&self.head), None).send_form( self.addr, self.response_decompress, self.timeout, @@ -86,7 +86,7 @@ impl FrozenClientRequest { S: Stream> + 'static, E: Into + 'static, { - RequestSender::Rc(self.head.clone(), None).send_stream( + RequestSender::Rc(Rc::clone(&self.head), None).send_stream( self.addr, self.response_decompress, self.timeout, @@ -97,7 +97,7 @@ impl FrozenClientRequest { /// Send an empty body. pub fn send(&self) -> SendClientRequest { - RequestSender::Rc(self.head.clone(), None).send( + RequestSender::Rc(Rc::clone(&self.head), None).send( self.addr, self.response_decompress, self.timeout, diff --git a/awc/src/lib.rs b/awc/src/lib.rs index 460480994..b582d51e4 100644 --- a/awc/src/lib.rs +++ b/awc/src/lib.rs @@ -100,8 +100,6 @@ //! # } //! ``` -#![deny(rust_2018_idioms, nonstandard_style)] -#![warn(future_incompatible)] #![allow(unknown_lints)] // temp: #[allow(non_local_definitions)] #![allow( clippy::type_complexity, diff --git a/awc/src/middleware/redirect.rs b/awc/src/middleware/redirect.rs index 0ea5f174e..b2cf9c45b 100644 --- a/awc/src/middleware/redirect.rs +++ b/awc/src/middleware/redirect.rs @@ -78,7 +78,7 @@ where RedirectServiceFuture::Tunnel { fut } } ConnectRequest::Client(head, body, addr) => { - let connector = self.connector.clone(); + let connector = Rc::clone(&self.connector); let max_redirect_times = self.max_redirect_times; // backup the uri and method for reuse schema and authority. From e9ccfbc866d53dcbad82c9816ac25c32d409f587 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 7 Jul 2024 20:19:35 +0100 Subject: [PATCH 030/144] refactor(multipart): clean up InnerField::poll --- actix-multipart/src/field.rs | 68 ++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/actix-multipart/src/field.rs b/actix-multipart/src/field.rs index 652b3e8b7..f4eb601fb 100644 --- a/actix-multipart/src/field.rs +++ b/actix-multipart/src/field.rs @@ -209,8 +209,14 @@ impl fmt::Debug for Field { pub(crate) struct InnerField { /// Payload is initialized as Some and is `take`n when the field stream finishes. payload: Option, + + /// Field boundary (without "--" prefix). boundary: String, + + /// True if request payload has been exhausted. eof: bool, + + /// Field data's stated size according to it's Content-Length header. length: Option, } @@ -286,6 +292,7 @@ impl InnerField { let mut pos = 0; let len = payload.buf.len(); + if len == 0 { return if payload.eof { Poll::Ready(Some(Err(Error::Incomplete))) @@ -296,7 +303,7 @@ impl InnerField { // check boundary if len > 4 && payload.buf[0] == b'\r' { - let b_len = if &payload.buf[..2] == b"\r\n" && &payload.buf[2..4] == b"--" { + let b_len = if payload.buf.starts_with(b"\r\n") && &payload.buf[2..4] == b"--" { Some(4) } else if &payload.buf[1..3] == b"--" { Some(3) @@ -357,41 +364,42 @@ impl InnerField { return Poll::Ready(None); } - let result = if let Some(mut payload) = self + let Some(mut payload) = self .payload .as_ref() .expect("Field should not be polled after completion") .get_mut(safety) - { - if !self.eof { - let res = if let Some(ref mut len) = self.length { - InnerField::read_len(&mut payload, len) - } else { - InnerField::read_stream(&mut payload, &self.boundary) - }; - - match res { - Poll::Pending => return Poll::Pending, - Poll::Ready(Some(Ok(bytes))) => return Poll::Ready(Some(Ok(bytes))), - Poll::Ready(Some(Err(err))) => return Poll::Ready(Some(Err(err))), - Poll::Ready(None) => self.eof = true, - } - } - - match payload.readline() { - 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"); - } - Poll::Ready(None) - } - Err(err) => Poll::Ready(Some(Err(err))), - } - } else { - Poll::Pending + else { + return Poll::Pending; }; + if !self.eof { + let res = if let Some(ref mut len) = self.length { + Self::read_len(&mut payload, len) + } else { + Self::read_stream(&mut payload, &self.boundary) + }; + + match ready!(res) { + Some(Ok(bytes)) => return Poll::Ready(Some(Ok(bytes))), + Some(Err(err)) => return Poll::Ready(Some(Err(err))), + None => self.eof = true, + } + } + + let result = match payload.readline() { + 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"); + } + Poll::Ready(None) + } + Err(err) => Poll::Ready(Some(Err(err))), + }; + + drop(payload); + if let Poll::Ready(None) = result { // drop payload buffer and make future un-poll-able let _ = self.payload.take(); From 16125bd3be26ea458eb58c079d8c96c71df47cc0 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 7 Jul 2024 20:19:56 +0100 Subject: [PATCH 031/144] docs(multipart): doc PayloadBuffer::readline --- actix-multipart/src/payload.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/actix-multipart/src/payload.rs b/actix-multipart/src/payload.rs index ed5477997..fae4ba032 100644 --- a/actix-multipart/src/payload.rs +++ b/actix-multipart/src/payload.rs @@ -122,7 +122,13 @@ impl PayloadBuffer { } } - /// Reads bytes until new line delimiter. + /// Reads bytes until new line delimiter (`\n`, `0x0A`). + /// + /// Returns: + /// + /// - `Ok(Some(chunk))` - `needle` is found, with chunk ending after needle + /// - `Err(Incomplete)` - `needle` is not found and we're at EOF + /// - `Ok(None)` - `needle` is not found otherwise #[inline] pub(crate) fn readline(&mut self) -> Result, Error> { self.read_until(b"\n") From e97e28db4f939e1a0db7fb0ff8128e7a2fc4678f Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 7 Jul 2024 20:32:56 +0100 Subject: [PATCH 032/144] docs(multipart): improve crate root docs --- actix-multipart/Cargo.toml | 13 ++-- actix-multipart/README.md | 12 +++- actix-multipart/src/form/mod.rs | 2 +- actix-multipart/src/lib.rs | 12 +++- actix-multipart/src/multipart.rs | 96 +---------------------------- actix-multipart/src/payload.rs | 102 +++++++++++++++++++++++++++++++ 6 files changed, 131 insertions(+), 106 deletions(-) diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index a5b0e3a2c..7a80b265f 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -4,13 +4,14 @@ version = "0.7.2" authors = [ "Nikolay Kim ", "Jacob Halsey ", + "Rob Ede ", ] -description = "Multipart form support for Actix Web" -keywords = ["http", "web", "framework", "async", "futures"] -homepage = "https://actix.rs" -repository = "https://github.com/actix/actix-web" -license = "MIT OR Apache-2.0" -edition = "2021" +description = "Multipart request & form support for Actix Web" +keywords = ["http", "actix", "web", "multipart", "form"] +homepage.workspace = true +repository.workspace = true +license.workspace = true +edition.workspace = true [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] diff --git a/actix-multipart/README.md b/actix-multipart/README.md index 52df77d13..ec2e94bd8 100644 --- a/actix-multipart/README.md +++ b/actix-multipart/README.md @@ -15,14 +15,18 @@ -Multipart form support for Actix Web. +Multipart request & form support for Actix Web. + +The [`Multipart`] extractor aims to support all kinds of `multipart/*` requests, including `multipart/form-data`, `multipart/related` and `multipart/mixed`. This is a lower-level extractor which supports reading [multipart fields](Field), in the order they are sent by the client. + +Due to additional requirements for `multipart/form-data` requests, the higher level [`MultipartForm`] extractor and derive macro only supports this media type. ## Examples ```rust use actix_web::{post, App, HttpServer, Responder}; -use actix_multipart::form::{json::Json as MPJson, tempfile::TempFile, MultipartForm}; +use actix_multipart::form::{json::Json as MpJson, tempfile::TempFile, MultipartForm}; use serde::Deserialize; #[derive(Debug, Deserialize)] @@ -34,7 +38,7 @@ struct Metadata { struct UploadForm { #[multipart(limit = "100MB")] file: TempFile, - json: MPJson, + json: MpJson, } #[post("/videos")] @@ -63,6 +67,8 @@ curl -v --request POST \ -F file=@./Cargo.lock ``` +[`MultipartForm`]: struct@form::MultipartForm + [More available in the examples repo →](https://github.com/actix/examples/tree/master/forms/multipart) diff --git a/actix-multipart/src/form/mod.rs b/actix-multipart/src/form/mod.rs index 9441d249f..693a45e8e 100644 --- a/actix-multipart/src/form/mod.rs +++ b/actix-multipart/src/form/mod.rs @@ -1,4 +1,4 @@ -//! Process and extract typed data from a multipart stream. +//! Extract and process typed data from fields of a `multipart/form-data` request. use std::{ any::Any, diff --git a/actix-multipart/src/lib.rs b/actix-multipart/src/lib.rs index a56b9846b..8eea35f2e 100644 --- a/actix-multipart/src/lib.rs +++ b/actix-multipart/src/lib.rs @@ -1,4 +1,12 @@ -//! Multipart form support for Actix Web. +//! Multipart request & form support for Actix Web. +//! +//! The [`Multipart`] extractor aims to support all kinds of `multipart/*` requests, including +//! `multipart/form-data`, `multipart/related` and `multipart/mixed`. This is a lower-level +//! extractor which supports reading [multipart fields](Field), in the order they are sent by the +//! client. +//! +//! Due to additional requirements for `multipart/form-data` requests, the higher level +//! [`MultipartForm`] extractor and derive macro only supports this media type. //! //! # Examples //! @@ -45,6 +53,8 @@ //! -F 'json={"name": "Cargo.lock"};type=application/json' \ //! -F file=@./Cargo.lock //! ``` +//! +//! [`MultipartForm`]: struct@form::MultipartForm #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] diff --git a/actix-multipart/src/multipart.rs b/actix-multipart/src/multipart.rs index e511cb6df..e38fbde9e 100644 --- a/actix-multipart/src/multipart.rs +++ b/actix-multipart/src/multipart.rs @@ -483,7 +483,7 @@ mod tests { }; use assert_matches::assert_matches; use futures_test::stream::StreamTestExt as _; - use futures_util::{future::lazy, stream, StreamExt as _}; + use futures_util::{stream, StreamExt as _}; use tokio::sync::mpsc; use tokio_stream::wrappers::UnboundedReceiverStream; @@ -718,100 +718,6 @@ mod tests { } } - #[actix_rt::test] - async fn test_basic() { - let (_, payload) = h1::Payload::create(false); - let mut payload = PayloadBuffer::new(payload); - - assert_eq!(payload.buf.len(), 0); - lazy(|cx| payload.poll_stream(cx)).await.unwrap(); - assert_eq!(None, payload.read_max(1).unwrap()); - } - - #[actix_rt::test] - async fn test_eof() { - let (mut sender, payload) = h1::Payload::create(false); - let mut payload = PayloadBuffer::new(payload); - - assert_eq!(None, payload.read_max(4).unwrap()); - sender.feed_data(Bytes::from("data")); - sender.feed_eof(); - lazy(|cx| payload.poll_stream(cx)).await.unwrap(); - - assert_eq!(Some(Bytes::from("data")), payload.read_max(4).unwrap()); - assert_eq!(payload.buf.len(), 0); - assert!(payload.read_max(1).is_err()); - assert!(payload.eof); - } - - #[actix_rt::test] - async fn test_err() { - let (mut sender, payload) = h1::Payload::create(false); - let mut payload = PayloadBuffer::new(payload); - assert_eq!(None, payload.read_max(1).unwrap()); - sender.set_error(PayloadError::Incomplete(None)); - lazy(|cx| payload.poll_stream(cx)).await.err().unwrap(); - } - - #[actix_rt::test] - async fn read_max() { - let (mut sender, payload) = h1::Payload::create(false); - let mut payload = PayloadBuffer::new(payload); - - sender.feed_data(Bytes::from("line1")); - sender.feed_data(Bytes::from("line2")); - lazy(|cx| payload.poll_stream(cx)).await.unwrap(); - assert_eq!(payload.buf.len(), 10); - - assert_eq!(Some(Bytes::from("line1")), payload.read_max(5).unwrap()); - assert_eq!(payload.buf.len(), 5); - - assert_eq!(Some(Bytes::from("line2")), payload.read_max(5).unwrap()); - assert_eq!(payload.buf.len(), 0); - } - - #[actix_rt::test] - async fn read_exactly() { - let (mut sender, payload) = h1::Payload::create(false); - let mut payload = PayloadBuffer::new(payload); - - assert_eq!(None, payload.read_exact(2)); - - sender.feed_data(Bytes::from("line1")); - sender.feed_data(Bytes::from("line2")); - lazy(|cx| payload.poll_stream(cx)).await.unwrap(); - - assert_eq!(Some(Bytes::from_static(b"li")), payload.read_exact(2)); - assert_eq!(payload.buf.len(), 8); - - assert_eq!(Some(Bytes::from_static(b"ne1l")), payload.read_exact(4)); - assert_eq!(payload.buf.len(), 4); - } - - #[actix_rt::test] - async fn read_until() { - let (mut sender, payload) = h1::Payload::create(false); - let mut payload = PayloadBuffer::new(payload); - - assert_eq!(None, payload.read_until(b"ne").unwrap()); - - sender.feed_data(Bytes::from("line1")); - sender.feed_data(Bytes::from("line2")); - lazy(|cx| payload.poll_stream(cx)).await.unwrap(); - - assert_eq!( - Some(Bytes::from("line")), - payload.read_until(b"ne").unwrap() - ); - assert_eq!(payload.buf.len(), 6); - - assert_eq!( - Some(Bytes::from("1line2")), - payload.read_until(b"2").unwrap() - ); - assert_eq!(payload.buf.len(), 0); - } - #[actix_rt::test] async fn test_multipart_from_error() { let err = Error::ContentTypeMissing; diff --git a/actix-multipart/src/payload.rs b/actix-multipart/src/payload.rs index fae4ba032..858634bc0 100644 --- a/actix-multipart/src/payload.rs +++ b/actix-multipart/src/payload.rs @@ -151,3 +151,105 @@ impl PayloadBuffer { self.buf.extend_from_slice(&buf); } } + +#[cfg(test)] +mod tests { + use actix_http::h1; + use futures_util::future::lazy; + + use super::*; + + #[actix_rt::test] + async fn basic() { + let (_, payload) = h1::Payload::create(false); + let mut payload = PayloadBuffer::new(payload); + + assert_eq!(payload.buf.len(), 0); + lazy(|cx| payload.poll_stream(cx)).await.unwrap(); + assert_eq!(None, payload.read_max(1).unwrap()); + } + + #[actix_rt::test] + async fn eof() { + let (mut sender, payload) = h1::Payload::create(false); + let mut payload = PayloadBuffer::new(payload); + + assert_eq!(None, payload.read_max(4).unwrap()); + sender.feed_data(Bytes::from("data")); + sender.feed_eof(); + lazy(|cx| payload.poll_stream(cx)).await.unwrap(); + + assert_eq!(Some(Bytes::from("data")), payload.read_max(4).unwrap()); + assert_eq!(payload.buf.len(), 0); + assert!(payload.read_max(1).is_err()); + assert!(payload.eof); + } + + #[actix_rt::test] + async fn err() { + let (mut sender, payload) = h1::Payload::create(false); + let mut payload = PayloadBuffer::new(payload); + assert_eq!(None, payload.read_max(1).unwrap()); + sender.set_error(PayloadError::Incomplete(None)); + lazy(|cx| payload.poll_stream(cx)).await.err().unwrap(); + } + + #[actix_rt::test] + async fn read_max() { + let (mut sender, payload) = h1::Payload::create(false); + let mut payload = PayloadBuffer::new(payload); + + sender.feed_data(Bytes::from("line1")); + sender.feed_data(Bytes::from("line2")); + lazy(|cx| payload.poll_stream(cx)).await.unwrap(); + assert_eq!(payload.buf.len(), 10); + + assert_eq!(Some(Bytes::from("line1")), payload.read_max(5).unwrap()); + assert_eq!(payload.buf.len(), 5); + + assert_eq!(Some(Bytes::from("line2")), payload.read_max(5).unwrap()); + assert_eq!(payload.buf.len(), 0); + } + + #[actix_rt::test] + async fn read_exactly() { + let (mut sender, payload) = h1::Payload::create(false); + let mut payload = PayloadBuffer::new(payload); + + assert_eq!(None, payload.read_exact(2)); + + sender.feed_data(Bytes::from("line1")); + sender.feed_data(Bytes::from("line2")); + lazy(|cx| payload.poll_stream(cx)).await.unwrap(); + + assert_eq!(Some(Bytes::from_static(b"li")), payload.read_exact(2)); + assert_eq!(payload.buf.len(), 8); + + assert_eq!(Some(Bytes::from_static(b"ne1l")), payload.read_exact(4)); + assert_eq!(payload.buf.len(), 4); + } + + #[actix_rt::test] + async fn read_until() { + let (mut sender, payload) = h1::Payload::create(false); + let mut payload = PayloadBuffer::new(payload); + + assert_eq!(None, payload.read_until(b"ne").unwrap()); + + sender.feed_data(Bytes::from("line1")); + sender.feed_data(Bytes::from("line2")); + lazy(|cx| payload.poll_stream(cx)).await.unwrap(); + + assert_eq!( + Some(Bytes::from("line")), + payload.read_until(b"ne").unwrap() + ); + assert_eq!(payload.buf.len(), 6); + + assert_eq!( + Some(Bytes::from("1line2")), + payload.read_until(b"2").unwrap() + ); + assert_eq!(payload.buf.len(), 0); + } +} From 5c6e0e17d34ac58fcb3fcc8d16fa712f47d10e97 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 7 Jul 2024 21:16:25 +0100 Subject: [PATCH 033/144] feat(http): impl FromIter for HeaderMap --- actix-http/CHANGES.md | 4 ++++ actix-http/src/header/map.rs | 32 +++++++++++++++++++++++++++++--- awc/src/any_body.rs | 1 + 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 48c730bb2..b2e5af79f 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -2,6 +2,10 @@ ## Unreleased +### Added + +- Implement `FromIterator<(HeaderName, HeaderValue)>` for `HeaderMap`. + ## 3.8.0 ### Added diff --git a/actix-http/src/header/map.rs b/actix-http/src/header/map.rs index b86798a4c..6da01d2c0 100644 --- a/actix-http/src/header/map.rs +++ b/actix-http/src/header/map.rs @@ -13,8 +13,9 @@ use super::AsHeaderName; /// `HeaderMap` is a "multi-map" of [`HeaderName`] to one or more [`HeaderValue`]s. /// /// # Examples +/// /// ``` -/// use actix_http::header::{self, HeaderMap, HeaderValue}; +/// # use actix_http::header::{self, HeaderMap, HeaderValue}; /// /// let mut map = HeaderMap::new(); /// @@ -29,6 +30,21 @@ use super::AsHeaderName; /// /// assert!(!map.contains_key(header::ORIGIN)); /// ``` +/// +/// Construct a header map using the [`FromIterator`] implementation. Note that it uses the append +/// strategy, so duplicate header names are preserved. +/// +/// ``` +/// use actix_http::header::{self, HeaderMap, HeaderValue}; +/// +/// let headers = HeaderMap::from_iter([ +/// (header::CONTENT_TYPE, HeaderValue::from_static("text/plain")), +/// (header::COOKIE, HeaderValue::from_static("foo=1")), +/// (header::COOKIE, HeaderValue::from_static("bar=1")), +/// ]); +/// +/// assert_eq!(headers.len(), 3); +/// ``` #[derive(Debug, Clone, Default)] pub struct HeaderMap { pub(crate) inner: AHashMap, @@ -368,8 +384,8 @@ impl HeaderMap { /// let removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/html")); /// assert!(!removed.is_empty()); /// ``` - pub fn insert(&mut self, key: HeaderName, val: HeaderValue) -> Removed { - let value = self.inner.insert(key, Value::one(val)); + pub fn insert(&mut self, name: HeaderName, val: HeaderValue) -> Removed { + let value = self.inner.insert(name, Value::one(val)); Removed::new(value) } @@ -636,6 +652,16 @@ impl<'a> IntoIterator for &'a HeaderMap { } } +impl FromIterator<(HeaderName, HeaderValue)> for HeaderMap { + fn from_iter>(iter: T) -> Self { + iter.into_iter() + .fold(Self::new(), |mut map, (name, value)| { + map.append(name, value); + map + }) + } +} + /// Convert a `http::HeaderMap` to our `HeaderMap`. impl From for HeaderMap { fn from(mut map: http::HeaderMap) -> Self { diff --git a/awc/src/any_body.rs b/awc/src/any_body.rs index 08f5cc25e..ef0edfb9e 100644 --- a/awc/src/any_body.rs +++ b/awc/src/any_body.rs @@ -163,6 +163,7 @@ mod tests { use super::*; + #[allow(dead_code)] struct PinType(PhantomPinned); impl MessageBody for PinType { From b6bee346f7c42b083b4e3cb44f4ff8d38ef8f0fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 10:31:50 +0100 Subject: [PATCH 034/144] build(deps): bump taiki-e/install-action from 2.41.7 to 2.41.10 (#3423) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.41.7 to 2.41.10. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.41.7...v2.41.10) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 444f1b174..dcf6ae4aa 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.41.7 + uses: taiki-e/install-action@v2.41.10 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.41.7 + uses: taiki-e/install-action@v2.41.10 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index caee78896..178294355 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.41.7 + uses: taiki-e/install-action@v2.41.10 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.41.7 + uses: taiki-e/install-action@v2.41.10 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 260d65e27..6dc99ebd8 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.41.7 + uses: taiki-e/install-action@v2.41.10 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1fd20f221..f2f7473c5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -76,7 +76,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.41.7 + uses: taiki-e/install-action@v2.41.10 with: tool: just @@ -105,7 +105,7 @@ jobs: toolchain: nightly-2024-06-07 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.41.7 + uses: taiki-e/install-action@v2.41.10 with: tool: cargo-public-api From f71f9ca66b28bc33b263f0e4c86f4d112c1afec1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 20 Jul 2024 01:13:57 +0100 Subject: [PATCH 035/144] build(deps): bump taiki-e/install-action from 2.41.10 to 2.41.17 (#3431) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.41.10 to 2.41.17. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.41.10...v2.41.17) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index dcf6ae4aa..516edc574 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.41.10 + uses: taiki-e/install-action@v2.41.17 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.41.10 + uses: taiki-e/install-action@v2.41.17 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 178294355..32ae0a73d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.41.10 + uses: taiki-e/install-action@v2.41.17 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.41.10 + uses: taiki-e/install-action@v2.41.17 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 6dc99ebd8..56fa4e5a8 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.41.10 + uses: taiki-e/install-action@v2.41.17 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f2f7473c5..cdb94f1da 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -76,7 +76,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.41.10 + uses: taiki-e/install-action@v2.41.17 with: tool: just @@ -105,7 +105,7 @@ jobs: toolchain: nightly-2024-06-07 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.41.10 + uses: taiki-e/install-action@v2.41.17 with: tool: cargo-public-api From 07f720f716ee6df9b1e8804ee3146d1db390669c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?On=C3=A8?= <43485962+c-git@users.noreply.github.com> Date: Sun, 21 Jul 2024 13:34:42 -0400 Subject: [PATCH 036/144] docs: fix typo (#3439) --- actix-web/src/middleware/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-web/src/middleware/mod.rs b/actix-web/src/middleware/mod.rs index 1c27b1110..79c94658b 100644 --- a/actix-web/src/middleware/mod.rs +++ b/actix-web/src/middleware/mod.rs @@ -67,7 +67,7 @@ //! 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 +//! the request (possibly 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, From 270a6a3b7074264dca3438b0ab05bc6a6fb68f02 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 01:49:25 +0100 Subject: [PATCH 037/144] build(deps): bump taiki-e/install-action from 2.41.17 to 2.42.4 (#3440) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.41.17 to 2.42.4. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.41.17...v2.42.4) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 516edc574..25583acc3 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.41.17 + uses: taiki-e/install-action@v2.42.4 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.41.17 + uses: taiki-e/install-action@v2.42.4 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 32ae0a73d..2b91d0f7b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.41.17 + uses: taiki-e/install-action@v2.42.4 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.41.17 + uses: taiki-e/install-action@v2.42.4 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 56fa4e5a8..969ce7404 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.41.17 + uses: taiki-e/install-action@v2.42.4 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index cdb94f1da..1db7411a5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -76,7 +76,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.41.17 + uses: taiki-e/install-action@v2.42.4 with: tool: just @@ -105,7 +105,7 @@ jobs: toolchain: nightly-2024-06-07 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.41.17 + uses: taiki-e/install-action@v2.42.4 with: tool: cargo-public-api From 9aa62112aab8249b7cc90180d5102221ebac3d42 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 00:25:30 +0000 Subject: [PATCH 038/144] build(deps): bump taiki-e/install-action from 2.42.4 to 2.42.9 (#3441) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.42.4 to 2.42.9. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.42.4...v2.42.9) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 25583acc3..4fa650431 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.42.4 + uses: taiki-e/install-action@v2.42.9 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.42.4 + uses: taiki-e/install-action@v2.42.9 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2b91d0f7b..73f90535c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.42.4 + uses: taiki-e/install-action@v2.42.9 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.42.4 + uses: taiki-e/install-action@v2.42.9 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 969ce7404..45391e18d 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.42.4 + uses: taiki-e/install-action@v2.42.9 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1db7411a5..4487d5fc7 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -76,7 +76,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.42.4 + uses: taiki-e/install-action@v2.42.9 with: tool: just @@ -105,7 +105,7 @@ jobs: toolchain: nightly-2024-06-07 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.42.4 + uses: taiki-e/install-action@v2.42.9 with: tool: cargo-public-api From 323d1fa64fb5e92c8bc4ee897b239fe58c28d6bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 02:05:32 +0100 Subject: [PATCH 039/144] build(deps): bump taiki-e/install-action from 2.42.9 to 2.42.17 (#3442) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.42.9 to 2.42.17. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.42.9...v2.42.17) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 4fa650431..c1afdb1cc 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.42.9 + uses: taiki-e/install-action@v2.42.17 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.42.9 + uses: taiki-e/install-action@v2.42.17 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 73f90535c..f98e17a87 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.42.9 + uses: taiki-e/install-action@v2.42.17 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.42.9 + uses: taiki-e/install-action@v2.42.17 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 45391e18d..f30c8ff42 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.42.9 + uses: taiki-e/install-action@v2.42.17 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4487d5fc7..f3bdb3515 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -76,7 +76,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.42.9 + uses: taiki-e/install-action@v2.42.17 with: tool: just @@ -105,7 +105,7 @@ jobs: toolchain: nightly-2024-06-07 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.42.9 + uses: taiki-e/install-action@v2.42.17 with: tool: cargo-public-api From e4e4bb799ca0387712d67c416aee3959be6a0b40 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Wed, 7 Aug 2024 04:01:20 +0100 Subject: [PATCH 040/144] chore(actix-web-actors): prepare release 4.3.1 --- actix-web-actors/CHANGES.md | 5 ++++- actix-web-actors/Cargo.toml | 11 ++++++----- actix-web-actors/README.md | 6 ++++-- actix-web-actors/src/lib.rs | 2 ++ 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/actix-web-actors/CHANGES.md b/actix-web-actors/CHANGES.md index 3e854c0b8..da39a349b 100644 --- a/actix-web-actors/CHANGES.md +++ b/actix-web-actors/CHANGES.md @@ -2,7 +2,10 @@ ## Unreleased -- Take the encoded buffer when yielding bytes in the response stream rather than splitting the buffer, reducing memory use +## 4.3.1 + +- Reduce memory usage by `take`-ing (rather than `split`-ing) the encoded buffer when yielding bytes in the response stream. +- Mark crate as deprecated. - Minimum supported Rust version (MSRV) is now 1.72. ## 4.3.0 diff --git a/actix-web-actors/Cargo.toml b/actix-web-actors/Cargo.toml index f753b7f7f..e7034ab84 100644 --- a/actix-web-actors/Cargo.toml +++ b/actix-web-actors/Cargo.toml @@ -1,13 +1,14 @@ [package] name = "actix-web-actors" -version = "4.3.0" +version = "4.3.1+deprecated" authors = ["Nikolay Kim "] description = "Actix actors support for Actix Web" keywords = ["actix", "http", "web", "framework", "async"] -homepage = "https://actix.rs" -repository = "https://github.com/actix/actix-web" -license = "MIT OR Apache-2.0" -edition = "2021" +homepage.workspace = true +repository.workspace = true +license.workspace = true +edition.workspace = true +rust-version.workspace = true [package.metadata.cargo_check_external_types] allowed_external_types = [ diff --git a/actix-web-actors/README.md b/actix-web-actors/README.md index feb3d1b33..ea5db55a6 100644 --- a/actix-web-actors/README.md +++ b/actix-web-actors/README.md @@ -1,15 +1,17 @@ # `actix-web-actors` > Actix actors support for Actix Web. +> +> This crate is deprecated. Migrate to [`actix-ws`](https://crates.io/crates/actix-ws). [![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.3.0)](https://docs.rs/actix-web-actors/4.3.0) +[![Documentation](https://docs.rs/actix-web-actors/badge.svg?version=4.3.1)](https://docs.rs/actix-web-actors/4.3.1) ![Version](https://img.shields.io/badge/rustc-1.72+-ab6000.svg) ![License](https://img.shields.io/crates/l/actix-web-actors.svg)
-[![dependency status](https://deps.rs/crate/actix-web-actors/4.3.0/status.svg)](https://deps.rs/crate/actix-web-actors/4.3.0) +[![dependency status](https://deps.rs/crate/actix-web-actors/4.3.1/status.svg)](https://deps.rs/crate/actix-web-actors/4.3.1) [![Download](https://img.shields.io/crates/d/actix-web-actors.svg)](https://crates.io/crates/actix-web-actors) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) diff --git a/actix-web-actors/src/lib.rs b/actix-web-actors/src/lib.rs index 0198c830f..4831d2637 100644 --- a/actix-web-actors/src/lib.rs +++ b/actix-web-actors/src/lib.rs @@ -1,5 +1,7 @@ //! Actix actors support for Actix Web. //! +//! This crate is deprecated. Migrate to [`actix-ws`](https://crates.io/crates/actix-ws). +//! //! # Examples //! //! ```no_run From d7d9000b19e5e6fb96c0c37c3417ce6fc91fd9cc Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Wed, 7 Aug 2024 04:06:18 +0100 Subject: [PATCH 041/144] chore: address clippy warnings --- actix-router/src/de.rs | 5 --- actix-web/benches/responder.rs | 36 ++----------------- actix-web/src/handler.rs | 2 +- .../src/http/header/content_disposition.rs | 2 +- actix-web/src/http/header/range.rs | 14 ++++---- actix-web/src/middleware/logger.rs | 12 ++----- actix-web/src/response/builder.rs | 2 +- 7 files changed, 14 insertions(+), 59 deletions(-) diff --git a/actix-router/src/de.rs b/actix-router/src/de.rs index ce2dcf8f3..2f50619f8 100644 --- a/actix-router/src/de.rs +++ b/actix-router/src/de.rs @@ -511,11 +511,6 @@ mod tests { value: String, } - #[derive(Deserialize)] - struct Id { - _id: String, - } - #[derive(Debug, Deserialize)] struct Test1(String, u32); diff --git a/actix-web/benches/responder.rs b/actix-web/benches/responder.rs index c675eadff..489515e40 100644 --- a/actix-web/benches/responder.rs +++ b/actix-web/benches/responder.rs @@ -2,11 +2,9 @@ use std::{future::Future, time::Instant}; use actix_http::body::BoxBody; use actix_utils::future::{ready, Ready}; -use actix_web::{ - error, http::StatusCode, test::TestRequest, Error, HttpRequest, HttpResponse, Responder, -}; +use actix_web::{http::StatusCode, test::TestRequest, Error, HttpRequest, HttpResponse, Responder}; use criterion::{criterion_group, criterion_main, Criterion}; -use futures_util::future::{join_all, Either}; +use futures_util::future::join_all; // responder simulate the old responder trait. trait FutureResponder { @@ -16,9 +14,6 @@ trait FutureResponder { fn future_respond_to(self, req: &HttpRequest) -> Self::Future; } -// a simple option responder type. -struct OptionResponder(Option); - // a simple wrapper type around string struct StringResponder(String); @@ -34,22 +29,6 @@ impl FutureResponder for StringResponder { } } -impl FutureResponder for OptionResponder -where - T: FutureResponder, - T::Future: Future>, -{ - type Error = Error; - type Future = Either>>; - - fn future_respond_to(self, req: &HttpRequest) -> Self::Future { - match self.0 { - Some(t) => Either::Left(t.future_respond_to(req)), - None => Either::Right(ready(Err(error::ErrorInternalServerError("err")))), - } - } -} - impl Responder for StringResponder { type Body = BoxBody; @@ -60,17 +39,6 @@ impl Responder for StringResponder { } } -impl Responder for OptionResponder { - type Body = BoxBody; - - fn respond_to(self, req: &HttpRequest) -> HttpResponse { - match self.0 { - Some(t) => t.respond_to(req).map_into_boxed_body(), - None => HttpResponse::from_error(error::ErrorInternalServerError("err")), - } - } -} - fn future_responder(c: &mut Criterion) { let rt = actix_rt::System::new(); let req = TestRequest::default().to_http_request(); diff --git a/actix-web/src/handler.rs b/actix-web/src/handler.rs index 6e4e2250a..10015cb69 100644 --- a/actix-web/src/handler.rs +++ b/actix-web/src/handler.rs @@ -19,7 +19,7 @@ use crate::{ /// 1. It is an async function (or a function/closure that returns an appropriate future); /// 1. The function parameters (up to 12) implement [`FromRequest`]; /// 1. The async function (or future) resolves to a type that can be converted into an -/// [`HttpResponse`] (i.e., it implements the [`Responder`] trait). +/// [`HttpResponse`] (i.e., it implements the [`Responder`] trait). /// /// /// # Compiler Errors diff --git a/actix-web/src/http/header/content_disposition.rs b/actix-web/src/http/header/content_disposition.rs index 824bf1195..592fc9f6a 100644 --- a/actix-web/src/http/header/content_disposition.rs +++ b/actix-web/src/http/header/content_disposition.rs @@ -493,7 +493,7 @@ impl Header for ContentDisposition { } fn parse(msg: &T) -> Result { - if let Some(h) = msg.headers().get(&Self::name()) { + if let Some(h) = msg.headers().get(Self::name()) { Self::from_raw(h) } else { Err(crate::error::ParseError::Header) diff --git a/actix-web/src/http/header/range.rs b/actix-web/src/http/header/range.rs index 2326bb19c..4a5d95d93 100644 --- a/actix-web/src/http/header/range.rs +++ b/actix-web/src/http/header/range.rs @@ -107,16 +107,16 @@ impl ByteRangeSpec { /// satisfiable if they meet the following conditions: /// /// > If a valid byte-range-set includes at least one byte-range-spec with a first-byte-pos that - /// is less than the current length of the representation, or at least one - /// suffix-byte-range-spec with a non-zero suffix-length, then the byte-range-set - /// is satisfiable. Otherwise, the byte-range-set is unsatisfiable. + /// > is less than the current length of the representation, or at least one + /// > suffix-byte-range-spec with a non-zero suffix-length, then the byte-range-set is + /// > satisfiable. Otherwise, the byte-range-set is unsatisfiable. /// /// The function also computes remainder ranges based on the RFC: /// /// > If the last-byte-pos value is absent, or if the value is greater than or equal to the - /// current length of the representation data, the byte range is interpreted as the remainder - /// of the representation (i.e., the server replaces the value of last-byte-pos with a value - /// that is one less than the current length of the selected representation). + /// > current length of the representation data, the byte range is interpreted as the remainder + /// > of the representation (i.e., the server replaces the value of last-byte-pos with a value + /// > that is one less than the current length of the selected representation). /// /// [RFC 7233 §2.1]: https://datatracker.ietf.org/doc/html/rfc7233 pub fn to_satisfiable_range(&self, full_length: u64) -> Option<(u64, u64)> { @@ -270,7 +270,7 @@ impl Header for Range { #[inline] fn parse(msg: &T) -> Result { - header::from_one_raw_str(msg.headers().get(&Self::name())) + header::from_one_raw_str(msg.headers().get(Self::name())) } } diff --git a/actix-web/src/middleware/logger.rs b/actix-web/src/middleware/logger.rs index e9ac24d50..21986baae 100644 --- a/actix-web/src/middleware/logger.rs +++ b/actix-web/src/middleware/logger.rs @@ -622,11 +622,7 @@ impl FormatText { FormatText::ResponseHeader(ref name) => { let s = if let Some(val) = res.headers().get(name) { - if let Ok(s) = val.to_str() { - s - } else { - "-" - } + val.to_str().unwrap_or("-") } else { "-" }; @@ -670,11 +666,7 @@ impl FormatText { FormatText::RequestTime => *self = FormatText::Str(now.format(&Rfc3339).unwrap()), FormatText::RequestHeader(ref name) => { let s = if let Some(val) = req.headers().get(name) { - if let Ok(s) = val.to_str() { - s - } else { - "-" - } + val.to_str().unwrap_or("-") } else { "-" }; diff --git a/actix-web/src/response/builder.rs b/actix-web/src/response/builder.rs index 023842ee5..c23de8e36 100644 --- a/actix-web/src/response/builder.rs +++ b/actix-web/src/response/builder.rs @@ -463,7 +463,7 @@ mod tests { // content type override let res = HttpResponse::Ok() .insert_header((CONTENT_TYPE, "text/json")) - .json(&vec!["v1", "v2", "v3"]); + .json(["v1", "v2", "v3"]); let ct = res.headers().get(CONTENT_TYPE).unwrap(); assert_eq!(ct, HeaderValue::from_static("text/json")); assert_body_eq!(res, br#"["v1","v2","v3"]"#); From 5be53820f0718260f6f3573d2edff49f09653206 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Wed, 7 Aug 2024 04:32:16 +0100 Subject: [PATCH 042/144] docs(actors): add maintenance badge --- actix-web-actors/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-web-actors/README.md b/actix-web-actors/README.md index ea5db55a6..0ec91a224 100644 --- a/actix-web-actors/README.md +++ b/actix-web-actors/README.md @@ -11,7 +11,7 @@ ![Version](https://img.shields.io/badge/rustc-1.72+-ab6000.svg) ![License](https://img.shields.io/crates/l/actix-web-actors.svg)
-[![dependency status](https://deps.rs/crate/actix-web-actors/4.3.1/status.svg)](https://deps.rs/crate/actix-web-actors/4.3.1) +![maintenance-status](https://img.shields.io/badge/maintenance-deprecated-red.svg) [![Download](https://img.shields.io/crates/d/actix-web-actors.svg)](https://crates.io/crates/actix-web-actors) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) From a431b7356c1f987ceffc482be7cbdf43fe4132a5 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 10 Aug 2024 00:42:34 +0100 Subject: [PATCH 043/144] feat: add ThinData wrapper (#3446) --- actix-web/CHANGES.md | 4 ++ actix-web/Cargo.toml | 1 + actix-web/src/lib.rs | 1 + actix-web/src/thin_data.rs | 121 +++++++++++++++++++++++++++++++++++++ actix-web/src/web.rs | 4 +- 5 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 actix-web/src/thin_data.rs diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 90c7b7e2a..10a0e8038 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -2,6 +2,10 @@ ## Unreleased +### Added + +- Add `web::ThinData` extractor. + ## 4.8.0 ### Added diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index 543f44400..f27a5a5b6 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -151,6 +151,7 @@ encoding_rs = "0.8" futures-core = { version = "0.3.17", default-features = false } futures-util = { version = "0.3.17", default-features = false } itoa = "1" +impl-more = "0.1.4" language-tags = "0.3" log = "0.4" mime = "0.3" diff --git a/actix-web/src/lib.rs b/actix-web/src/lib.rs index 752852525..e2a8e2275 100644 --- a/actix-web/src/lib.rs +++ b/actix-web/src/lib.rs @@ -104,6 +104,7 @@ mod scope; mod server; mod service; pub mod test; +mod thin_data; pub(crate) mod types; pub mod web; diff --git a/actix-web/src/thin_data.rs b/actix-web/src/thin_data.rs new file mode 100644 index 000000000..a9cd4e3a4 --- /dev/null +++ b/actix-web/src/thin_data.rs @@ -0,0 +1,121 @@ +use std::any::type_name; + +use actix_utils::future::{ready, Ready}; + +use crate::{dev::Payload, error, FromRequest, HttpRequest}; + +/// Application data wrapper and extractor for cheaply-cloned types. +/// +/// Similar to the [`Data`] wrapper but for `Clone`/`Copy` types that are already an `Arc` internally, +/// share state using some other means when cloned, or is otherwise static data that is very cheap +/// to clone. +/// +/// Unlike `Data`, this wrapper clones `T` during extraction. Therefore, it is the user's +/// responsibility to ensure that clones of `T` do actually share the same state, otherwise state +/// may be unexpectedly different across multiple requests. +/// +/// Note that if your type is literally an `Arc` then it's recommended to use the +/// [`Data::from(arc)`][data_from_arc] conversion instead. +/// +/// # Examples +/// +/// ``` +/// use actix_web::{ +/// web::{self, ThinData}, +/// App, HttpResponse, Responder, +/// }; +/// +/// // Use the `ThinData` extractor to access a database connection pool. +/// async fn index(ThinData(db_pool): ThinData) -> impl Responder { +/// // database action ... +/// +/// HttpResponse::Ok() +/// } +/// +/// # type DbPool = (); +/// let db_pool = DbPool::default(); +/// +/// App::new() +/// .app_data(ThinData(db_pool.clone())) +/// .service(web::resource("/").get(index)) +/// # ; +/// ``` +/// +/// [`Data`]: crate::web::Data +/// [data_from_arc]: crate::web::Data#impl-From>-for-Data +#[derive(Debug, Clone)] +pub struct ThinData(pub T); + +impl_more::impl_as_ref!(ThinData => T); +impl_more::impl_as_mut!(ThinData => T); +impl_more::impl_deref_and_mut!( in ThinData => T); + +impl FromRequest for ThinData { + type Error = crate::Error; + type Future = Ready>; + + #[inline] + fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future { + ready(req.app_data::().cloned().ok_or_else(|| { + log::debug!( + "Failed to extract `ThinData<{}>` for `{}` handler. For the ThinData extractor to work \ + correctly, wrap the data with `ThinData()` and pass it to `App::app_data()`. \ + Ensure that types align in both the set and retrieve calls.", + type_name::(), + req.match_name().unwrap_or(req.path()) + ); + + error::ErrorInternalServerError( + "Requested application data is not configured correctly. \ + View/enable debug logs for more details.", + ) + })) + } +} + +#[cfg(test)] +mod tests { + use std::sync::{Arc, Mutex}; + + use super::*; + use crate::{ + http::StatusCode, + test::{call_service, init_service, TestRequest}, + web, App, HttpResponse, + }; + + type TestT = Arc>; + + #[actix_rt::test] + async fn thin_data() { + let test_data = TestT::default(); + + let app = init_service(App::new().app_data(ThinData(test_data.clone())).service( + web::resource("/").to(|td: ThinData| { + *td.lock().unwrap() += 1; + HttpResponse::Ok() + }), + )) + .await; + + for _ in 0..3 { + let req = TestRequest::default().to_request(); + let resp = call_service(&app, req).await; + assert_eq!(resp.status(), StatusCode::OK); + } + + assert_eq!(*test_data.lock().unwrap(), 3); + } + + #[actix_rt::test] + async fn thin_data_missing() { + let app = init_service( + App::new().service(web::resource("/").to(|_: ThinData| HttpResponse::Ok())), + ) + .await; + + let req = TestRequest::default().to_request(); + let resp = call_service(&app, req).await; + assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR); + } +} diff --git a/actix-web/src/web.rs b/actix-web/src/web.rs index 204313752..3a4c46730 100644 --- a/actix-web/src/web.rs +++ b/actix-web/src/web.rs @@ -2,6 +2,7 @@ //! //! # Request Extractors //! - [`Data`]: Application data item +//! - [`ThinData`]: Cheap-to-clone application data item //! - [`ReqData`]: Request-local data item //! - [`Path`]: URL path parameters / dynamic segments //! - [`Query`]: URL query parameters @@ -22,7 +23,8 @@ use actix_router::IntoPatterns; pub use bytes::{Buf, BufMut, Bytes, BytesMut}; pub use crate::{ - config::ServiceConfig, data::Data, redirect::Redirect, request_data::ReqData, types::*, + config::ServiceConfig, data::Data, redirect::Redirect, request_data::ReqData, + thin_data::ThinData, types::*, }; use crate::{ error::BlockingError, http::Method, service::WebService, FromRequest, Handler, Resource, From be28a0bd6d404e883e6bef6111a7d9606bab39d6 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 10 Aug 2024 01:41:27 +0100 Subject: [PATCH 044/144] feat: add from_fn middleware (#3447) --- actix-web/CHANGES.md | 1 + actix-web/examples/middleware_from_fn.rs | 127 +++++++++ actix-web/src/middleware/from_fn.rs | 349 +++++++++++++++++++++++ actix-web/src/middleware/mod.rs | 61 ++-- 4 files changed, 521 insertions(+), 17 deletions(-) create mode 100644 actix-web/examples/middleware_from_fn.rs create mode 100644 actix-web/src/middleware/from_fn.rs diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 10a0e8038..d26859a36 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -4,6 +4,7 @@ ### Added +- Add `middleware::from_fn()` helper. - Add `web::ThinData` extractor. ## 4.8.0 diff --git a/actix-web/examples/middleware_from_fn.rs b/actix-web/examples/middleware_from_fn.rs new file mode 100644 index 000000000..da92ef05b --- /dev/null +++ b/actix-web/examples/middleware_from_fn.rs @@ -0,0 +1,127 @@ +//! Shows a couple of ways to use the `from_fn` middleware. + +use std::{collections::HashMap, io, rc::Rc, time::Duration}; + +use actix_web::{ + body::MessageBody, + dev::{Service, ServiceRequest, ServiceResponse, Transform}, + http::header::{self, HeaderValue, Range}, + middleware::{from_fn, Logger, Next}, + web::{self, Header, Query}, + App, Error, HttpResponse, HttpServer, +}; + +async fn noop(req: ServiceRequest, next: Next) -> Result, Error> { + next.call(req).await +} + +async fn print_range_header( + range_header: Option>, + req: ServiceRequest, + next: Next, +) -> Result, Error> { + if let Some(Header(range)) = range_header { + println!("Range: {range}"); + } else { + println!("No Range header"); + } + + next.call(req).await +} + +async fn mutate_body_type( + req: ServiceRequest, + next: Next, +) -> Result, Error> { + let res = next.call(req).await?; + Ok(res.map_into_left_body::<()>()) +} + +async fn mutate_body_type_with_extractors( + string_body: String, + query: Query>, + req: ServiceRequest, + next: Next, +) -> Result, Error> { + println!("body is: {string_body}"); + println!("query string: {query:?}"); + + let res = next.call(req).await?; + + Ok(res.map_body(move |_, _| string_body)) +} + +async fn timeout_10secs( + req: ServiceRequest, + next: Next, +) -> Result, Error> { + match tokio::time::timeout(Duration::from_secs(10), next.call(req)).await { + Ok(res) => res, + Err(_err) => Err(actix_web::error::ErrorRequestTimeout("")), + } +} + +struct MyMw(bool); + +impl MyMw { + async fn mw_cb( + &self, + req: ServiceRequest, + next: Next, + ) -> Result, Error> { + let mut res = match self.0 { + true => req.into_response("short-circuited").map_into_right_body(), + false => next.call(req).await?.map_into_left_body(), + }; + + res.headers_mut() + .insert(header::WARNING, HeaderValue::from_static("42")); + + Ok(res) + } + + pub fn into_middleware( + self, + ) -> impl Transform< + S, + ServiceRequest, + Response = ServiceResponse, + Error = Error, + InitError = (), + > + where + S: Service, Error = Error> + 'static, + B: MessageBody + 'static, + { + let this = Rc::new(self); + from_fn(move |req, next| { + let this = Rc::clone(&this); + async move { Self::mw_cb(&this, req, next).await } + }) + } +} + +#[actix_web::main] +async fn main() -> io::Result<()> { + env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); + + let bind = ("127.0.0.1", 8080); + log::info!("staring server at http://{}:{}", &bind.0, &bind.1); + + HttpServer::new(|| { + App::new() + .wrap(from_fn(noop)) + .wrap(from_fn(print_range_header)) + .wrap(from_fn(mutate_body_type)) + .wrap(from_fn(mutate_body_type_with_extractors)) + .wrap(from_fn(timeout_10secs)) + // switch bool to true to observe early response + .wrap(MyMw(false).into_middleware()) + .wrap(Logger::default()) + .default_service(web::to(HttpResponse::Ok)) + }) + .workers(1) + .bind(bind)? + .run() + .await +} diff --git a/actix-web/src/middleware/from_fn.rs b/actix-web/src/middleware/from_fn.rs new file mode 100644 index 000000000..608833319 --- /dev/null +++ b/actix-web/src/middleware/from_fn.rs @@ -0,0 +1,349 @@ +use std::{future::Future, marker::PhantomData, rc::Rc}; + +use actix_service::boxed::{self, BoxFuture, RcService}; +use actix_utils::future::{ready, Ready}; +use futures_core::future::LocalBoxFuture; + +use crate::{ + body::MessageBody, + dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform}, + Error, FromRequest, +}; + +/// Wraps an async function to be used as a middleware. +/// +/// # Examples +/// +/// The wrapped function should have the following form: +/// +/// ``` +/// # use actix_web::{ +/// # App, Error, +/// # body::MessageBody, +/// # dev::{ServiceRequest, ServiceResponse, Service as _}, +/// # }; +/// use actix_web::middleware::{self, Next}; +/// +/// async fn my_mw( +/// req: ServiceRequest, +/// next: Next, +/// ) -> Result, Error> { +/// // pre-processing +/// next.call(req).await +/// // post-processing +/// } +/// # App::new().wrap(middleware::from_fn(my_mw)); +/// ``` +/// +/// Then use in an app builder like this: +/// +/// ``` +/// use actix_web::{ +/// App, Error, +/// dev::{ServiceRequest, ServiceResponse, Service as _}, +/// }; +/// use actix_web::middleware::from_fn; +/// # use actix_web::middleware::Next; +/// # async fn my_mw(req: ServiceRequest, next: Next) -> Result, Error> { +/// # next.call(req).await +/// # } +/// +/// App::new() +/// .wrap(from_fn(my_mw)) +/// # ; +/// ``` +/// +/// It is also possible to write a middleware that automatically uses extractors, similar to request +/// handlers, by declaring them as the first parameters. As usual, **take care with extractors that +/// consume the body stream**, since handlers will no longer be able to read it again without +/// putting the body "back" into the request object within your middleware. +/// +/// ``` +/// # use std::collections::HashMap; +/// # use actix_web::{ +/// # App, Error, +/// # body::MessageBody, +/// # dev::{ServiceRequest, ServiceResponse}, +/// # http::header::{Accept, Date}, +/// # web::{Header, Query}, +/// # }; +/// use actix_web::middleware::Next; +/// +/// async fn my_extracting_mw( +/// accept: Header, +/// query: Query>, +/// req: ServiceRequest, +/// next: Next, +/// ) -> Result, Error> { +/// // pre-processing +/// next.call(req).await +/// // post-processing +/// } +/// # App::new().wrap(actix_web::middleware::from_fn(my_extracting_mw)); +pub fn from_fn(mw_fn: F) -> MiddlewareFn { + MiddlewareFn { + mw_fn: Rc::new(mw_fn), + _phantom: PhantomData, + } +} + +/// Middleware transform for [`from_fn`]. +#[allow(missing_debug_implementations)] +pub struct MiddlewareFn { + mw_fn: Rc, + _phantom: PhantomData, +} + +impl Transform for MiddlewareFn +where + S: Service, Error = Error> + 'static, + F: Fn(ServiceRequest, Next) -> Fut + 'static, + Fut: Future, Error>>, + B2: MessageBody, +{ + type Response = ServiceResponse; + type Error = Error; + type Transform = MiddlewareFnService; + type InitError = (); + type Future = Ready>; + + fn new_transform(&self, service: S) -> Self::Future { + ready(Ok(MiddlewareFnService { + service: boxed::rc_service(service), + mw_fn: Rc::clone(&self.mw_fn), + _phantom: PhantomData, + })) + } +} + +/// Middleware service for [`from_fn`]. +#[allow(missing_debug_implementations)] +pub struct MiddlewareFnService { + service: RcService, Error>, + mw_fn: Rc, + _phantom: PhantomData<(B, Es)>, +} + +impl Service for MiddlewareFnService +where + F: Fn(ServiceRequest, Next) -> Fut, + Fut: Future, Error>>, + B2: MessageBody, +{ + type Response = ServiceResponse; + type Error = Error; + type Future = Fut; + + forward_ready!(service); + + fn call(&self, req: ServiceRequest) -> Self::Future { + (self.mw_fn)( + req, + Next:: { + service: Rc::clone(&self.service), + }, + ) + } +} + +macro_rules! impl_middleware_fn_service { + ($($ext_type:ident),*) => { + impl Transform for MiddlewareFn + where + S: Service, Error = Error> + 'static, + F: Fn($($ext_type),*, ServiceRequest, Next) -> Fut + 'static, + $($ext_type: FromRequest + 'static,)* + Fut: Future, Error>> + 'static, + B: MessageBody + 'static, + B2: MessageBody + 'static, + { + type Response = ServiceResponse; + type Error = Error; + type Transform = MiddlewareFnService; + type InitError = (); + type Future = Ready>; + + fn new_transform(&self, service: S) -> Self::Future { + ready(Ok(MiddlewareFnService { + service: boxed::rc_service(service), + mw_fn: Rc::clone(&self.mw_fn), + _phantom: PhantomData, + })) + } + } + + impl Service + for MiddlewareFnService + where + F: Fn( + $($ext_type),*, + ServiceRequest, + Next + ) -> Fut + 'static, + $($ext_type: FromRequest + 'static,)* + Fut: Future, Error>> + 'static, + B2: MessageBody + 'static, + { + type Response = ServiceResponse; + type Error = Error; + type Future = LocalBoxFuture<'static, Result>; + + forward_ready!(service); + + #[allow(nonstandard_style)] + fn call(&self, mut req: ServiceRequest) -> Self::Future { + let mw_fn = Rc::clone(&self.mw_fn); + let service = Rc::clone(&self.service); + + Box::pin(async move { + let ($($ext_type,)*) = req.extract::<($($ext_type,)*)>().await?; + + (mw_fn)($($ext_type),*, req, Next:: { service }).await + }) + } + } + }; +} + +impl_middleware_fn_service!(E1); +impl_middleware_fn_service!(E1, E2); +impl_middleware_fn_service!(E1, E2, E3); +impl_middleware_fn_service!(E1, E2, E3, E4); +impl_middleware_fn_service!(E1, E2, E3, E4, E5); +impl_middleware_fn_service!(E1, E2, E3, E4, E5, E6); +impl_middleware_fn_service!(E1, E2, E3, E4, E5, E6, E7); +impl_middleware_fn_service!(E1, E2, E3, E4, E5, E6, E7, E8); +impl_middleware_fn_service!(E1, E2, E3, E4, E5, E6, E7, E8, E9); + +/// Wraps the "next" service in the middleware chain. +#[allow(missing_debug_implementations)] +pub struct Next { + service: RcService, Error>, +} + +impl Next { + /// Equivalent to `Service::call(self, req)`. + pub fn call(&self, req: ServiceRequest) -> >::Future { + Service::call(self, req) + } +} + +impl Service for Next { + type Response = ServiceResponse; + type Error = Error; + type Future = BoxFuture>; + + forward_ready!(service); + + fn call(&self, req: ServiceRequest) -> Self::Future { + self.service.call(req) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + http::header::{self, HeaderValue}, + middleware::{Compat, Logger}, + test, web, App, HttpResponse, + }; + + async fn noop(req: ServiceRequest, next: Next) -> Result, Error> { + next.call(req).await + } + + async fn add_res_header( + req: ServiceRequest, + next: Next, + ) -> Result, Error> { + let mut res = next.call(req).await?; + res.headers_mut() + .insert(header::WARNING, HeaderValue::from_static("42")); + Ok(res) + } + + async fn mutate_body_type( + req: ServiceRequest, + next: Next, + ) -> Result, Error> { + let res = next.call(req).await?; + Ok(res.map_into_left_body::<()>()) + } + + struct MyMw(bool); + + impl MyMw { + async fn mw_cb( + &self, + req: ServiceRequest, + next: Next, + ) -> Result, Error> { + let mut res = match self.0 { + true => req.into_response("short-circuited").map_into_right_body(), + false => next.call(req).await?.map_into_left_body(), + }; + res.headers_mut() + .insert(header::WARNING, HeaderValue::from_static("42")); + Ok(res) + } + + pub fn into_middleware( + self, + ) -> impl Transform< + S, + ServiceRequest, + Response = ServiceResponse, + Error = Error, + InitError = (), + > + where + S: Service, Error = Error> + 'static, + B: MessageBody + 'static, + { + let this = Rc::new(self); + from_fn(move |req, next| { + let this = Rc::clone(&this); + async move { Self::mw_cb(&this, req, next).await } + }) + } + } + + #[actix_rt::test] + async fn compat_compat() { + let _ = App::new().wrap(Compat::new(from_fn(noop))); + let _ = App::new().wrap(Compat::new(from_fn(mutate_body_type))); + } + + #[actix_rt::test] + async fn permits_different_in_and_out_body_types() { + let app = test::init_service( + App::new() + .wrap(from_fn(mutate_body_type)) + .wrap(from_fn(add_res_header)) + .wrap(Logger::default()) + .wrap(from_fn(noop)) + .default_service(web::to(HttpResponse::NotFound)), + ) + .await; + + let req = test::TestRequest::default().to_request(); + let res = test::call_service(&app, req).await; + assert!(res.headers().contains_key(header::WARNING)); + } + + #[actix_rt::test] + async fn closure_capture_and_return_from_fn() { + let app = test::init_service( + App::new() + .wrap(Logger::default()) + .wrap(MyMw(true).into_middleware()) + .wrap(Logger::default()), + ) + .await; + + let req = test::TestRequest::default().to_request(); + let res = test::call_service(&app, req).await; + assert!(res.headers().contains_key(header::WARNING)); + } +} diff --git a/actix-web/src/middleware/mod.rs b/actix-web/src/middleware/mod.rs index 79c94658b..4b5b3e896 100644 --- a/actix-web/src/middleware/mod.rs +++ b/actix-web/src/middleware/mod.rs @@ -15,10 +15,47 @@ //! - 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). +//! [`Resource`](crate::Resource) and executed in opposite order as registration. +//! +//! # Simple Middleware +//! +//! In many cases, you can model your middleware as an async function via the [`from_fn()`] helper +//! that provides a natural interface for implementing your desired behaviors. +//! +//! ``` +//! # use actix_web::{ +//! # App, Error, +//! # body::MessageBody, +//! # dev::{ServiceRequest, ServiceResponse, Service as _}, +//! # }; +//! use actix_web::middleware::{self, Next}; +//! +//! async fn my_mw( +//! req: ServiceRequest, +//! next: Next, +//! ) -> Result, Error> { +//! // pre-processing +//! +//! // invoke the wrapped middleware or service +//! let res = next.call(req).await?; +//! +//! // post-processing +//! +//! Ok(res) +//! } +//! +//! App::new() +//! .wrap(middleware::from_fn(my_mw)); +//! ``` +//! +//! ## Complex Middleware +//! +//! In the more general ase, 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). +//! +//! All the built-in middleware use this pattern with pairs of builder (`Transform`) + +//! implementation (`Service`) types. //! //! # Ordering //! @@ -196,18 +233,6 @@ //! # } //! ``` //! -//! # 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 @@ -215,7 +240,7 @@ //! [`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 +//! [`from_fn`]: crate mod compat; #[cfg(feature = "__compress")] @@ -223,6 +248,7 @@ mod compress; mod condition; mod default_headers; mod err_handlers; +mod from_fn; mod identity; mod logger; mod normalize; @@ -234,6 +260,7 @@ pub use self::{ condition::Condition, default_headers::DefaultHeaders, err_handlers::{ErrorHandlerResponse, ErrorHandlers}, + from_fn::{from_fn, Next}, identity::Identity, logger::Logger, normalize::{NormalizePath, TrailingSlash}, From 882fb3d25b323994dc5caa471ae05d127cd3dc34 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 10 Aug 2024 03:08:18 +0100 Subject: [PATCH 045/144] chore(actors): add version marker in changelog --- actix-web-actors/CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-web-actors/CHANGES.md b/actix-web-actors/CHANGES.md index da39a349b..3f214274d 100644 --- a/actix-web-actors/CHANGES.md +++ b/actix-web-actors/CHANGES.md @@ -2,7 +2,7 @@ ## Unreleased -## 4.3.1 +## 4.3.1 - Reduce memory usage by `take`-ing (rather than `split`-ing) the encoded buffer when yielding bytes in the response stream. - Mark crate as deprecated. From 9ba326aed0dfe1a992c43a07fcb74958e4cfb3c6 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 10 Aug 2024 03:09:09 +0100 Subject: [PATCH 046/144] chore(actix-http): prepare release 3.9.0 --- actix-http/CHANGES.md | 2 ++ actix-http/Cargo.toml | 2 +- actix-http/README.md | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index b2e5af79f..15b211c1a 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.9.0 + ### Added - Implement `FromIterator<(HeaderName, HeaderValue)>` for `HeaderMap`. diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 8fb31da4f..e8dea0bd0 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-http" -version = "3.8.0" +version = "3.9.0" authors = [ "Nikolay Kim ", "Rob Ede ", diff --git a/actix-http/README.md b/actix-http/README.md index 7d56f2517..f78ea86f5 100644 --- a/actix-http/README.md +++ b/actix-http/README.md @@ -5,11 +5,11 @@ [![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.8.0)](https://docs.rs/actix-http/3.8.0) +[![Documentation](https://docs.rs/actix-http/badge.svg?version=3.9.0)](https://docs.rs/actix-http/3.9.0) ![Version](https://img.shields.io/badge/rustc-1.72+-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.8.0/status.svg)](https://deps.rs/crate/actix-http/3.8.0) +[![dependency status](https://deps.rs/crate/actix-http/3.9.0/status.svg)](https://deps.rs/crate/actix-http/3.9.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) From e0918fb1795c899ac38fb903694ca1aa3b58d46d Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 10 Aug 2024 03:21:55 +0100 Subject: [PATCH 047/144] chore(actix-web): prepare release 4.9.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 d26859a36..588320f4d 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +## 4.9.0 + ### Added - Add `middleware::from_fn()` helper. diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index f27a5a5b6..1e69973d0 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-web" -version = "4.8.0" +version = "4.9.0" description = "Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust" authors = [ "Nikolay Kim ", diff --git a/actix-web/README.md b/actix-web/README.md index d30d945a4..e5e412c85 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.8.0)](https://docs.rs/actix-web/4.8.0) +[![Documentation](https://docs.rs/actix-web/badge.svg?version=4.9.0)](https://docs.rs/actix-web/4.9.0) ![MSRV](https://img.shields.io/badge/rustc-1.72+-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.8.0/status.svg)](https://deps.rs/crate/actix-web/4.8.0) +[![Dependency Status](https://deps.rs/crate/actix-web/4.9.0/status.svg)](https://deps.rs/crate/actix-web/4.9.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 5ad92c0062c3ee972005b9c2b0bbb0c2d5d59fbb Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 10 Aug 2024 03:58:45 +0100 Subject: [PATCH 048/144] fix(awc): ws host req header includes port --- awc/CHANGES.md | 4 +++- awc/src/ws.rs | 27 +++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/awc/CHANGES.md b/awc/CHANGES.md index 54c5e9869..9a344ceb0 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -2,11 +2,13 @@ ## Unreleased +- Fix WebSocket `Host` request header value when using a non-default port. + ## 3.5.0 - Add `rustls-0_23`, `rustls-0_23-webpki-roots`, and `rustls-0_23-native-roots` crate features. - Add `awc::Connector::rustls_0_23()` constructor. -- Fix `rustls-0_22-native-roots` root store lookup +- Fix `rustls-0_22-native-roots` root store lookup. - Update `brotli` dependency to `6`. - Minimum supported Rust version (MSRV) is now 1.72. diff --git a/awc/src/ws.rs b/awc/src/ws.rs index c3340206d..794dccbfe 100644 --- a/awc/src/ws.rs +++ b/awc/src/ws.rs @@ -257,8 +257,9 @@ impl WebsocketsRequest { return Err(e.into()); } - // validate uri + // validate URI let uri = &self.head.uri; + if uri.host().is_none() { return Err(InvalidUrl::MissingHost.into()); } else if uri.scheme().is_none() { @@ -273,9 +274,12 @@ impl WebsocketsRequest { } if !self.head.headers.contains_key(header::HOST) { + let hostname = uri.host().unwrap(); + let port = uri.port(); + self.head.headers.insert( header::HOST, - HeaderValue::from_str(uri.host().unwrap()).unwrap(), + HeaderValue::from_str(&Host { hostname, port }.to_string()).unwrap(), ); } @@ -434,6 +438,25 @@ impl fmt::Debug for WebsocketsRequest { } } +/// Formatter for host (hostname+port) header values. +struct Host<'a> { + hostname: &'a str, + port: Option>, +} + +impl<'a> fmt::Display for Host<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.hostname)?; + + if let Some(port) = &self.port { + f.write_str(":")?; + f.write_str(port.as_str())?; + } + + Ok(()) + } +} + #[cfg(test)] mod tests { use super::*; From 70e3758ecc9bde13ef12a6f96576524c36050277 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 10 Aug 2024 04:08:38 +0100 Subject: [PATCH 049/144] chore(awc): prepare release 3.5.1 --- 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 9a344ceb0..9c0f3b607 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.5.1 + - Fix WebSocket `Host` request header value when using a non-default port. ## 3.5.0 diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 353ca0d54..26b483bfa 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "awc" -version = "3.5.0" +version = "3.5.1" 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 8e7b42812..28d28ed89 100644 --- a/awc/README.md +++ b/awc/README.md @@ -5,9 +5,9 @@ [![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.5.0)](https://docs.rs/awc/3.5.0) +[![Documentation](https://docs.rs/awc/badge.svg?version=3.5.1)](https://docs.rs/awc/3.5.1) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/awc) -[![Dependency Status](https://deps.rs/crate/awc/3.5.0/status.svg)](https://deps.rs/crate/awc/3.5.0) +[![Dependency Status](https://deps.rs/crate/awc/3.5.1/status.svg)](https://deps.rs/crate/awc/3.5.1) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) From 538c1bea34911f50be12679b19f81e5d180ff922 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 10 Aug 2024 05:15:49 +0100 Subject: [PATCH 050/144] chore: disallow e bindings --- .clippy.toml | 7 +++++++ actix-files/src/service.rs | 2 +- actix-http-test/src/lib.rs | 2 +- actix-http/src/h1/encoder.rs | 4 ++-- actix-http/src/h1/service.rs | 14 +++++++------- actix-http/src/service.rs | 18 +++++++++--------- actix-http/src/ws/dispatcher.rs | 18 +++++++++--------- actix-multipart-derive/src/lib.rs | 2 ++ actix-router/src/path.rs | 16 +++++++++------- actix-web-actors/src/ws.rs | 7 ++----- actix-web/src/app.rs | 6 +++--- actix-web/src/resource.rs | 7 +++---- actix-web/src/scope.rs | 4 +++- actix-web/src/types/json.rs | 4 ++-- actix-web/src/types/path.rs | 4 ++-- actix-web/src/types/query.rs | 14 +++++++------- awc/src/client/error.rs | 4 ++-- awc/src/client/pool.rs | 10 +++++----- awc/src/frozen.rs | 16 ++++++++-------- awc/src/request.rs | 4 ++-- awc/src/sender.rs | 16 ++++++++-------- awc/src/ws.rs | 4 ++-- 22 files changed, 96 insertions(+), 87 deletions(-) create mode 100644 .clippy.toml diff --git a/.clippy.toml b/.clippy.toml new file mode 100644 index 000000000..8c0cbc8bf --- /dev/null +++ b/.clippy.toml @@ -0,0 +1,7 @@ +disallowed-names = [ + "e", # no single letter error bindings +] +disallowed-methods = [ + "std::cell::RefCell::default()", + "std::rc::Rc::default()", +] diff --git a/actix-files/src/service.rs b/actix-files/src/service.rs index 3d3b36c40..393ad9244 100644 --- a/actix-files/src/service.rs +++ b/actix-files/src/service.rs @@ -79,7 +79,7 @@ impl FilesService { let (req, _) = req.into_parts(); - (self.renderer)(&dir, &req).unwrap_or_else(|e| ServiceResponse::from_err(e, req)) + (self.renderer)(&dir, &req).unwrap_or_else(|err| ServiceResponse::from_err(err, req)) } } diff --git a/actix-http-test/src/lib.rs b/actix-http-test/src/lib.rs index d83b0b3ea..a359cec09 100644 --- a/actix-http-test/src/lib.rs +++ b/actix-http-test/src/lib.rs @@ -106,7 +106,7 @@ pub async fn test_server_with_addr>( 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)) diff --git a/actix-http/src/h1/encoder.rs b/actix-http/src/h1/encoder.rs index abe396ce2..77e34bcdc 100644 --- a/actix-http/src/h1/encoder.rs +++ b/actix-http/src/h1/encoder.rs @@ -313,7 +313,7 @@ impl MessageType for RequestHeadType { _ => return Err(io::Error::new(io::ErrorKind::Other, "unsupported version")), } ) - .map_err(|e| io::Error::new(io::ErrorKind::Other, e)) + .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) } } @@ -433,7 +433,7 @@ impl TransferEncoding { buf.extend_from_slice(b"0\r\n\r\n"); } else { writeln!(helpers::MutWriter(buf), "{:X}\r", msg.len()) - .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; + .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; buf.reserve(msg.len() + 2); buf.extend_from_slice(msg); diff --git a/actix-http/src/h1/service.rs b/actix-http/src/h1/service.rs index 4fbccf844..2cf76edb2 100644 --- a/actix-http/src/h1/service.rs +++ b/actix-http/src/h1/service.rs @@ -480,15 +480,15 @@ where let cfg = self.cfg.clone(); Box::pin(async move { - let expect = expect - .await - .map_err(|e| error!("Init http expect service error: {:?}", e))?; + let expect = expect.await.map_err(|err| { + tracing::error!("Initialization of HTTP expect service error: {err:?}"); + })?; let upgrade = match upgrade { Some(upgrade) => { - let upgrade = upgrade - .await - .map_err(|e| error!("Init http upgrade service error: {:?}", e))?; + let upgrade = upgrade.await.map_err(|err| { + tracing::error!("Initialization of HTTP upgrade service error: {err:?}"); + })?; Some(upgrade) } None => None, @@ -496,7 +496,7 @@ where let service = service .await - .map_err(|e| error!("Init http service error: {:?}", e))?; + .map_err(|err| error!("Initialization of HTTP service error: {err:?}"))?; Ok(H1ServiceHandler::new( cfg, diff --git a/actix-http/src/service.rs b/actix-http/src/service.rs index 3ea88274a..3be099d9f 100644 --- a/actix-http/src/service.rs +++ b/actix-http/src/service.rs @@ -775,23 +775,23 @@ where let cfg = self.cfg.clone(); Box::pin(async move { - let expect = expect - .await - .map_err(|e| error!("Init http expect service error: {:?}", e))?; + let expect = expect.await.map_err(|err| { + tracing::error!("Initialization of HTTP expect service error: {err:?}"); + })?; let upgrade = match upgrade { Some(upgrade) => { - let upgrade = upgrade - .await - .map_err(|e| error!("Init http upgrade service error: {:?}", e))?; + let upgrade = upgrade.await.map_err(|err| { + tracing::error!("Initialization of HTTP upgrade service error: {err:?}"); + })?; Some(upgrade) } None => None, }; - let service = service - .await - .map_err(|e| error!("Init http service error: {:?}", e))?; + let service = service.await.map_err(|err| { + tracing::error!("Initialization of HTTP service error: {err:?}"); + })?; Ok(HttpServiceHandler::new( cfg, diff --git a/actix-http/src/ws/dispatcher.rs b/actix-http/src/ws/dispatcher.rs index 1354d5ae1..7d0a300b7 100644 --- a/actix-http/src/ws/dispatcher.rs +++ b/actix-http/src/ws/dispatcher.rs @@ -114,14 +114,14 @@ mod inner { { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - DispatcherError::Service(ref e) => { - write!(fmt, "DispatcherError::Service({:?})", e) + DispatcherError::Service(ref err) => { + write!(fmt, "DispatcherError::Service({err:?})") } - DispatcherError::Encoder(ref e) => { - write!(fmt, "DispatcherError::Encoder({:?})", e) + DispatcherError::Encoder(ref err) => { + write!(fmt, "DispatcherError::Encoder({err:?})") } - DispatcherError::Decoder(ref e) => { - write!(fmt, "DispatcherError::Decoder({:?})", e) + DispatcherError::Decoder(ref err) => { + write!(fmt, "DispatcherError::Decoder({err:?})") } } } @@ -136,9 +136,9 @@ mod inner { { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - DispatcherError::Service(ref e) => write!(fmt, "{}", e), - DispatcherError::Encoder(ref e) => write!(fmt, "{:?}", e), - DispatcherError::Decoder(ref e) => write!(fmt, "{:?}", e), + DispatcherError::Service(ref err) => write!(fmt, "{err}"), + DispatcherError::Encoder(ref err) => write!(fmt, "{err:?}"), + DispatcherError::Decoder(ref err) => write!(fmt, "{err:?}"), } } } diff --git a/actix-multipart-derive/src/lib.rs b/actix-multipart-derive/src/lib.rs index 6818d477c..57d2fa875 100644 --- a/actix-multipart-derive/src/lib.rs +++ b/actix-multipart-derive/src/lib.rs @@ -5,6 +5,7 @@ #![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_favicon_url = "https://actix.rs/favicon.ico")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![allow(clippy::disallowed_names)] // false positives in some macro expansions use std::collections::HashSet; @@ -35,6 +36,7 @@ struct MultipartFormAttrs { duplicate_field: DuplicateField, } +#[allow(clippy::disallowed_names)] // false positive in macro expansion #[derive(FromField, Default)] #[darling(attributes(multipart), default)] struct FieldAttrs { diff --git a/actix-router/src/path.rs b/actix-router/src/path.rs index 9031ab763..ab4a943fe 100644 --- a/actix-router/src/path.rs +++ b/actix-router/src/path.rs @@ -143,9 +143,9 @@ impl Path { for (seg_name, val) in self.segments.iter() { if name == seg_name { return match val { - PathItem::Static(ref s) => Some(s), - PathItem::Segment(s, e) => { - Some(&self.path.path()[(*s as usize)..(*e as usize)]) + PathItem::Static(ref seg) => Some(seg), + PathItem::Segment(start, end) => { + Some(&self.path.path()[(*start as usize)..(*end as usize)]) } }; } @@ -193,8 +193,10 @@ impl<'a, T: ResourcePath> Iterator for PathIter<'a, T> { if self.idx < self.params.segment_count() { let idx = self.idx; let res = match self.params.segments[idx].1 { - PathItem::Static(ref s) => s, - PathItem::Segment(s, e) => &self.params.path.path()[(s as usize)..(e as usize)], + PathItem::Static(ref seg) => seg, + PathItem::Segment(start, end) => { + &self.params.path.path()[(start as usize)..(end as usize)] + } }; self.idx += 1; return Some((&self.params.segments[idx].0, res)); @@ -217,8 +219,8 @@ impl Index for Path { fn index(&self, idx: usize) -> &str { match self.segments[idx].1 { - PathItem::Static(ref s) => s, - PathItem::Segment(s, e) => &self.path.path()[(s as usize)..(e as usize)], + PathItem::Static(ref seg) => seg, + PathItem::Segment(start, end) => &self.path.path()[(start as usize)..(end as usize)], } } } diff --git a/actix-web-actors/src/ws.rs b/actix-web-actors/src/ws.rs index 7f7607fa9..0002f87e2 100644 --- a/actix-web-actors/src/ws.rs +++ b/actix-web-actors/src/ws.rs @@ -796,11 +796,8 @@ where Some(frm) => { let msg = match frm { Frame::Text(data) => { - Message::Text(ByteString::try_from(data).map_err(|e| { - ProtocolError::Io(io::Error::new( - io::ErrorKind::Other, - format!("{}", e), - )) + Message::Text(ByteString::try_from(data).map_err(|err| { + ProtocolError::Io(io::Error::new(io::ErrorKind::Other, err)) })?) } Frame::Binary(data) => Message::Binary(data), diff --git a/actix-web/src/app.rs b/actix-web/src/app.rs index 240e5b982..f12d39979 100644 --- a/actix-web/src/app.rs +++ b/actix-web/src/app.rs @@ -269,9 +269,9 @@ where + 'static, U::InitError: fmt::Debug, { - let svc = svc - .into_factory() - .map_init_err(|e| log::error!("Can not construct default service: {:?}", e)); + let svc = svc.into_factory().map_init_err(|err| { + log::error!("Can not construct default service: {err:?}"); + }); self.default = Some(Rc::new(boxed::factory(svc))); diff --git a/actix-web/src/resource.rs b/actix-web/src/resource.rs index d89438edb..6486fb39d 100644 --- a/actix-web/src/resource.rs +++ b/actix-web/src/resource.rs @@ -358,10 +358,9 @@ where U::InitError: fmt::Debug, { // create and configure default resource - self.default = boxed::factory( - f.into_factory() - .map_init_err(|e| log::error!("Can not construct default service: {:?}", e)), - ); + self.default = boxed::factory(f.into_factory().map_init_err(|err| { + log::error!("Can not construct default service: {err:?}"); + })); self } diff --git a/actix-web/src/scope.rs b/actix-web/src/scope.rs index 81f3615b0..e317349da 100644 --- a/actix-web/src/scope.rs +++ b/actix-web/src/scope.rs @@ -278,7 +278,9 @@ where { // create and configure default resource self.default = Some(Rc::new(boxed::factory(f.into_factory().map_init_err( - |e| log::error!("Can not construct default service: {:?}", e), + |err| { + log::error!("Can not construct default service: {err:?}"); + }, )))); self diff --git a/actix-web/src/types/json.rs b/actix-web/src/types/json.rs index 6b75c0cfe..51a322e43 100644 --- a/actix-web/src/types/json.rs +++ b/actix-web/src/types/json.rs @@ -398,7 +398,7 @@ impl JsonBody { _res: PhantomData, } } - JsonBody::Error(e) => JsonBody::Error(e), + JsonBody::Error(err) => JsonBody::Error(err), } } } @@ -434,7 +434,7 @@ impl Future for JsonBody { } } }, - JsonBody::Error(e) => Poll::Ready(Err(e.take().unwrap())), + JsonBody::Error(err) => Poll::Ready(Err(err.take().unwrap())), } } } diff --git a/actix-web/src/types/path.rs b/actix-web/src/types/path.rs index cc87bb80f..d6cf186f6 100644 --- a/actix-web/src/types/path.rs +++ b/actix-web/src/types/path.rs @@ -89,8 +89,8 @@ where ); if let Some(error_handler) = error_handler { - let e = PathError::Deserialize(err); - (error_handler)(e, req) + let err = PathError::Deserialize(err); + (error_handler)(err, req) } else { ErrorNotFound(err) } diff --git a/actix-web/src/types/query.rs b/actix-web/src/types/query.rs index e71b886f2..e5505131e 100644 --- a/actix-web/src/types/query.rs +++ b/actix-web/src/types/query.rs @@ -2,7 +2,7 @@ use std::{fmt, ops, sync::Arc}; -use actix_utils::future::{err, ok, Ready}; +use actix_utils::future::{ok, ready, Ready}; use serde::de::DeserializeOwned; use crate::{dev::Payload, error::QueryPayloadError, Error, FromRequest, HttpRequest}; @@ -118,8 +118,8 @@ impl FromRequest for Query { serde_urlencoded::from_str::(req.query_string()) .map(|val| ok(Query(val))) - .unwrap_or_else(move |e| { - let e = QueryPayloadError::Deserialize(e); + .unwrap_or_else(move |err| { + let err = QueryPayloadError::Deserialize(err); log::debug!( "Failed during Query extractor deserialization. \ @@ -127,13 +127,13 @@ impl FromRequest for Query { req.path() ); - let e = if let Some(error_handler) = error_handler { - (error_handler)(e, req) + let err = if let Some(error_handler) = error_handler { + (error_handler)(err, req) } else { - e.into() + err.into() }; - err(e) + ready(Err(err)) }) } } diff --git a/awc/src/client/error.rs b/awc/src/client/error.rs index d351e1067..22cf2c200 100644 --- a/awc/src/client/error.rs +++ b/awc/src/client/error.rs @@ -54,11 +54,11 @@ impl std::error::Error for ConnectError {} impl From for ConnectError { fn from(err: actix_tls::connect::ConnectError) -> ConnectError { match err { - actix_tls::connect::ConnectError::Resolver(e) => ConnectError::Resolver(e), + actix_tls::connect::ConnectError::Resolver(err) => ConnectError::Resolver(err), actix_tls::connect::ConnectError::NoRecords => ConnectError::NoRecords, actix_tls::connect::ConnectError::InvalidInput => panic!(), actix_tls::connect::ConnectError::Unresolved => ConnectError::Unresolved, - actix_tls::connect::ConnectError::Io(e) => ConnectError::Io(e), + actix_tls::connect::ConnectError::Io(err) => ConnectError::Io(err), } } } diff --git a/awc/src/client/pool.rs b/awc/src/client/pool.rs index 4c439e4eb..1736f2b02 100644 --- a/awc/src/client/pool.rs +++ b/awc/src/client/pool.rs @@ -31,7 +31,7 @@ use super::{ Connect, }; -#[derive(Hash, Eq, PartialEq, Clone, Debug)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Key { authority: Authority, } @@ -42,8 +42,8 @@ impl From for Key { } } +/// Connections pool to reuse I/O per [`Authority`]. #[doc(hidden)] -/// Connections pool for reuse Io type for certain [`http::uri::Authority`] as key. pub struct ConnectionPool where Io: AsyncWrite + Unpin + 'static, @@ -52,7 +52,7 @@ where inner: ConnectionPoolInner, } -/// wrapper type for check the ref count of Rc. +/// Wrapper type for check the ref count of Rc. pub struct ConnectionPoolInner(Rc>) where Io: AsyncWrite + Unpin + 'static; @@ -63,7 +63,7 @@ where { fn new(config: ConnectorConfig) -> Self { let permits = Arc::new(Semaphore::new(config.limit)); - let available = RefCell::new(HashMap::default()); + let available = RefCell::new(HashMap::new()); Self(Rc::new(ConnectionPoolInnerPriv { config, @@ -72,7 +72,7 @@ where })) } - /// spawn a async for graceful shutdown h1 Io type with a timeout. + /// Spawns a graceful shutdown task for the underlying I/O with a timeout. fn close(&self, conn: ConnectionInnerType) { if let Some(timeout) = self.config.disconnect_timeout { if let ConnectionInnerType::H1(io) = conn { diff --git a/awc/src/frozen.rs b/awc/src/frozen.rs index 90b2c6efd..862405234 100644 --- a/awc/src/frozen.rs +++ b/awc/src/frozen.rs @@ -147,8 +147,8 @@ impl FrozenSendBuilder { /// Complete request construction and send a body. pub fn send_body(self, body: impl MessageBody + 'static) -> SendClientRequest { - if let Some(e) = self.err { - return e.into(); + if let Some(err) = self.err { + return err.into(); } RequestSender::Rc(self.req.head, Some(self.extra_headers)).send_body( @@ -177,8 +177,8 @@ impl FrozenSendBuilder { /// Complete request construction and send an urlencoded body. pub fn send_form(self, value: impl Serialize) -> SendClientRequest { - if let Some(e) = self.err { - return e.into(); + if let Some(err) = self.err { + return err.into(); } RequestSender::Rc(self.req.head, Some(self.extra_headers)).send_form( @@ -196,8 +196,8 @@ impl FrozenSendBuilder { S: Stream> + 'static, E: Into + 'static, { - if let Some(e) = self.err { - return e.into(); + if let Some(err) = self.err { + return err.into(); } RequestSender::Rc(self.req.head, Some(self.extra_headers)).send_stream( @@ -211,8 +211,8 @@ impl FrozenSendBuilder { /// Complete request construction and send an empty body. pub fn send(self) -> SendClientRequest { - if let Some(e) = self.err { - return e.into(); + if let Some(err) = self.err { + return err.into(); } RequestSender::Rc(self.req.head, Some(self.extra_headers)).send( diff --git a/awc/src/request.rs b/awc/src/request.rs index 28ed8b5f5..5f42f67ec 100644 --- a/awc/src/request.rs +++ b/awc/src/request.rs @@ -415,8 +415,8 @@ impl ClientRequest { // allow unused mut when cookies feature is disabled fn prep_for_sending(#[allow(unused_mut)] mut self) -> Result { - if let Some(e) = self.err { - return Err(e.into()); + if let Some(err) = self.err { + return Err(err.into()); } // validate uri diff --git a/awc/src/sender.rs b/awc/src/sender.rs index 8de1033a3..0015743bd 100644 --- a/awc/src/sender.rs +++ b/awc/src/sender.rs @@ -54,8 +54,8 @@ impl From for FreezeRequestError { impl From for SendRequestError { fn from(err: PrepForSendingError) -> SendRequestError { match err { - PrepForSendingError::Url(e) => SendRequestError::Url(e), - PrepForSendingError::Http(e) => SendRequestError::Http(e), + PrepForSendingError::Url(err) => SendRequestError::Url(err), + PrepForSendingError::Http(err) => SendRequestError::Http(err), PrepForSendingError::Json(err) => { SendRequestError::Custom(Box::new(err), Box::new("json serialization error")) } @@ -156,20 +156,20 @@ impl Future for SendClientRequest { } impl From for SendClientRequest { - fn from(e: SendRequestError) -> Self { - SendClientRequest::Err(Some(e)) + fn from(err: SendRequestError) -> Self { + SendClientRequest::Err(Some(err)) } } impl From for SendClientRequest { - fn from(e: HttpError) -> Self { - SendClientRequest::Err(Some(e.into())) + fn from(err: HttpError) -> Self { + SendClientRequest::Err(Some(err.into())) } } impl From for SendClientRequest { - fn from(e: PrepForSendingError) -> Self { - SendClientRequest::Err(Some(e.into())) + fn from(err: PrepForSendingError) -> Self { + SendClientRequest::Err(Some(err.into())) } } diff --git a/awc/src/ws.rs b/awc/src/ws.rs index 794dccbfe..760331e9d 100644 --- a/awc/src/ws.rs +++ b/awc/src/ws.rs @@ -253,8 +253,8 @@ impl WebsocketsRequest { pub async fn connect( mut self, ) -> Result<(ClientResponse, Framed), WsClientError> { - if let Some(e) = self.err.take() { - return Err(e.into()); + if let Some(err) = self.err.take() { + return Err(err.into()); } // validate URI From f61fcbe8407019ad6ec958ab78ef2401f2ccd68f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 13:12:48 +0100 Subject: [PATCH 051/144] build(deps): bump taiki-e/install-action from 2.42.17 to 2.42.22 (#3451) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.42.17 to 2.42.22. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.42.17...v2.42.22) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index c1afdb1cc..f94f0b20b 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.42.17 + uses: taiki-e/install-action@v2.42.22 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.42.17 + uses: taiki-e/install-action@v2.42.22 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f98e17a87..f4a526e38 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.42.17 + uses: taiki-e/install-action@v2.42.22 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.42.17 + uses: taiki-e/install-action@v2.42.22 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index f30c8ff42..8282ac18e 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.42.17 + uses: taiki-e/install-action@v2.42.22 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f3bdb3515..d105b67d5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -76,7 +76,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.42.17 + uses: taiki-e/install-action@v2.42.22 with: tool: just @@ -105,7 +105,7 @@ jobs: toolchain: nightly-2024-06-07 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.42.17 + uses: taiki-e/install-action@v2.42.22 with: tool: cargo-public-api From 4303dd8c37f1e320a861e79ca27637633e2e6eb8 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 18 Aug 2024 14:10:33 +0100 Subject: [PATCH 052/144] docs(web): mention try_init_service --- actix-web/src/test/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/actix-web/src/test/mod.rs b/actix-web/src/test/mod.rs index 5e647956b..701771588 100644 --- a/actix-web/src/test/mod.rs +++ b/actix-web/src/test/mod.rs @@ -1,7 +1,8 @@ //! Various helpers for Actix applications to use during testing. //! -//! # Creating A Test Service +//! # Initializing A Test Service //! - [`init_service`] +//! - [`try_init_service`] //! //! # Off-The-Shelf Test Services //! - [`ok_service`] @@ -49,6 +50,7 @@ pub use self::{ /// Must be used inside an async test. Works for both `ServiceRequest` and `HttpRequest`. /// /// # Examples +/// /// ``` /// use actix_web::{http::StatusCode, HttpResponse}; /// From 78ac5cf4829dd923b88c52145f509ec74b34a41a Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 18 Aug 2024 14:33:28 +0100 Subject: [PATCH 053/144] docs(web): unmention try_init_service --- actix-http/examples/actix-web.rs | 4 ++-- actix-http/examples/echo.rs | 5 ++--- actix-http/examples/hello-world.rs | 2 +- actix-http/examples/streaming-error.rs | 6 +++--- actix-http/examples/ws.rs | 7 +++---- actix-web/src/test/mod.rs | 1 - 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/actix-http/examples/actix-web.rs b/actix-http/examples/actix-web.rs index 449e5899b..e07abfd97 100644 --- a/actix-http/examples/actix-web.rs +++ b/actix-http/examples/actix-web.rs @@ -1,10 +1,10 @@ use actix_http::HttpService; use actix_server::Server; use actix_service::map_config; -use actix_web::{dev::AppConfig, get, App}; +use actix_web::{dev::AppConfig, get, App, Responder}; #[get("/")] -async fn index() -> &'static str { +async fn index() -> impl Responder { "Hello, world. From Actix Web!" } diff --git a/actix-http/examples/echo.rs b/actix-http/examples/echo.rs index ae6f00cce..11fd2750e 100644 --- a/actix-http/examples/echo.rs +++ b/actix-http/examples/echo.rs @@ -23,7 +23,7 @@ async fn main() -> io::Result<()> { body.extend_from_slice(&item?); } - info!("request body: {:?}", body); + info!("request body: {body:?}"); let res = Response::build(StatusCode::OK) .insert_header(("x-head", HeaderValue::from_static("dummy value!"))) @@ -31,8 +31,7 @@ async fn main() -> io::Result<()> { Ok::<_, Error>(res) }) - // No TLS - .tcp() + .tcp() // No TLS })? .run() .await diff --git a/actix-http/examples/hello-world.rs b/actix-http/examples/hello-world.rs index cf10beddf..afa3883a4 100644 --- a/actix-http/examples/hello-world.rs +++ b/actix-http/examples/hello-world.rs @@ -17,7 +17,7 @@ async fn main() -> io::Result<()> { ext.insert(42u32); }) .finish(|req: Request| async move { - info!("{:?}", req); + info!("{req:?}"); let mut res = Response::build(StatusCode::OK); res.insert_header(("x-head", HeaderValue::from_static("dummy value!"))); diff --git a/actix-http/examples/streaming-error.rs b/actix-http/examples/streaming-error.rs index 8c8a249cb..39f214fa1 100644 --- a/actix-http/examples/streaming-error.rs +++ b/actix-http/examples/streaming-error.rs @@ -22,16 +22,16 @@ async fn main() -> io::Result<()> { .bind("streaming-error", ("127.0.0.1", 8080), || { HttpService::build() .finish(|req| async move { - info!("{:?}", req); + info!("{req:?}"); let res = Response::ok(); Ok::<_, Infallible>(res.set_body(BodyStream::new(stream! { yield Ok(Bytes::from("123")); yield Ok(Bytes::from("456")); - actix_rt::time::sleep(Duration::from_millis(1000)).await; + actix_rt::time::sleep(Duration::from_secs(1)).await; - yield Err(io::Error::new(io::ErrorKind::Other, "")); + yield Err(io::Error::new(io::ErrorKind::Other, "abc")); }))) }) .tcp() diff --git a/actix-http/examples/ws.rs b/actix-http/examples/ws.rs index fb86bc5ea..af83e4c3d 100644 --- a/actix-http/examples/ws.rs +++ b/actix-http/examples/ws.rs @@ -17,7 +17,6 @@ use bytes::{Bytes, BytesMut}; use bytestring::ByteString; use futures_core::{ready, Stream}; use tokio_util::codec::Encoder; -use tracing::{info, trace}; #[actix_rt::main] async fn main() -> io::Result<()> { @@ -37,12 +36,12 @@ async fn main() -> io::Result<()> { } async fn handler(req: Request) -> Result>, Error> { - info!("handshaking"); + tracing::info!("handshaking"); let mut res = ws::handshake(req.head())?; // handshake will always fail under HTTP/2 - info!("responding"); + tracing::info!("responding"); res.message_body(BodyStream::new(Heartbeat::new(ws::Codec::new()))) } @@ -64,7 +63,7 @@ impl Stream for Heartbeat { type Item = Result; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - trace!("poll"); + tracing::trace!("poll"); ready!(self.as_mut().interval.poll_tick(cx)); diff --git a/actix-web/src/test/mod.rs b/actix-web/src/test/mod.rs index 701771588..86cb60956 100644 --- a/actix-web/src/test/mod.rs +++ b/actix-web/src/test/mod.rs @@ -2,7 +2,6 @@ //! //! # Initializing A Test Service //! - [`init_service`] -//! - [`try_init_service`] //! //! # Off-The-Shelf Test Services //! - [`ok_service`] From d6bdfac1b9d3ec7bba50c37600346f9a8dcf8ecb Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Sun, 18 Aug 2024 22:17:03 +0800 Subject: [PATCH 054/144] build(deps): update derive_more to v1.0 (#3453) * build(deps): update derive_more to v1.0 * refactor: use from derive module --------- Co-authored-by: Rob Ede --- Cargo.toml | 2 +- actix-files/CHANGES.md | 2 + actix-files/Cargo.toml | 2 +- actix-files/src/error.rs | 14 ++-- actix-files/src/named.rs | 2 +- actix-files/src/range.rs | 2 +- actix-http/CHANGES.md | 2 + actix-http/Cargo.toml | 4 +- actix-http/src/body/body_stream.rs | 4 +- actix-http/src/body/utils.rs | 4 +- actix-http/src/encoding/encoder.rs | 6 +- actix-http/src/error.rs | 74 +++++++++---------- .../src/header/shared/content_encoding.rs | 4 +- actix-http/src/header/shared/quality.rs | 4 +- actix-http/src/ws/mod.rs | 34 ++++----- actix-http/tests/test_client.rs | 4 +- actix-http/tests/test_openssl.rs | 4 +- actix-http/tests/test_rustls.rs | 4 +- actix-http/tests/test_server.rs | 6 +- actix-http/tests/test_ws.rs | 10 +-- actix-multipart/CHANGES.md | 2 + actix-multipart/Cargo.toml | 2 +- actix-multipart/src/error.rs | 32 ++++---- actix-multipart/src/field.rs | 4 +- actix-multipart/src/form/json.rs | 6 +- actix-multipart/src/form/mod.rs | 2 +- actix-multipart/src/form/tempfile.rs | 4 +- actix-multipart/src/form/text.rs | 8 +- actix-web/CHANGES.md | 2 + actix-web/Cargo.toml | 4 +- actix-web/src/error/mod.rs | 50 ++++++------- actix-web/src/http/header/content_length.rs | 2 +- actix-web/src/info.rs | 6 +- actix-web/src/types/path.rs | 6 +- actix-web/src/types/query.rs | 2 +- awc/CHANGES.md | 2 + awc/Cargo.toml | 2 +- awc/src/client/error.rs | 48 ++++++------ awc/src/error.rs | 24 +++--- awc/src/sender.rs | 2 +- 40 files changed, 204 insertions(+), 194 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 51f998314..d5601f8f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ homepage = "https://actix.rs" repository = "https://github.com/actix/actix-web" license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.72" +rust-version = "1.75" [profile.dev] # Disabling debug info speeds up builds a bunch and we don't rely on it for debugging that much. diff --git a/actix-files/CHANGES.md b/actix-files/CHANGES.md index e94f43907..afb2d5d20 100644 --- a/actix-files/CHANGES.md +++ b/actix-files/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +- Minimum supported Rust version (MSRV) is now 1.75. + ## 0.6.6 - Update `tokio-uring` dependency to `0.4`. diff --git a/actix-files/Cargo.toml b/actix-files/Cargo.toml index 0c02359c4..48d38874f 100644 --- a/actix-files/Cargo.toml +++ b/actix-files/Cargo.toml @@ -33,7 +33,7 @@ actix-web = { version = "4", default-features = false } bitflags = "2" bytes = "1" -derive_more = "0.99.5" +derive_more = { version = "1", features = ["display", "error", "from"] } futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] } http-range = "0.1.4" log = "0.4" diff --git a/actix-files/src/error.rs b/actix-files/src/error.rs index d614651fc..1d4818887 100644 --- a/actix-files/src/error.rs +++ b/actix-files/src/error.rs @@ -1,16 +1,16 @@ use actix_web::{http::StatusCode, ResponseError}; -use derive_more::Display; +use derive_more::derive::Display; /// Errors which can occur when serving static files. #[derive(Debug, PartialEq, Eq, Display)] pub enum FilesError { /// Path is not a directory. #[allow(dead_code)] - #[display(fmt = "path is not a directory. Unable to serve static files")] + #[display("path is not a directory. Unable to serve static files")] IsNotDirectory, /// Cannot render directory. - #[display(fmt = "unable to render directory without index file")] + #[display("unable to render directory without index file")] IsDirectory, } @@ -25,19 +25,19 @@ impl ResponseError for FilesError { #[non_exhaustive] pub enum UriSegmentError { /// Segment started with the wrapped invalid character. - #[display(fmt = "segment started with invalid character: ('{_0}')")] + #[display("segment started with invalid character: ('{_0}')")] BadStart(char), /// Segment contained the wrapped invalid character. - #[display(fmt = "segment contained invalid character ('{_0}')")] + #[display("segment contained invalid character ('{_0}')")] BadChar(char), /// Segment ended with the wrapped invalid character. - #[display(fmt = "segment ended with invalid character: ('{_0}')")] + #[display("segment ended with invalid character: ('{_0}')")] BadEnd(char), /// Path is not a valid UTF-8 string after percent-decoding. - #[display(fmt = "path is not a valid UTF-8 string after percent-decoding")] + #[display("path is not a valid UTF-8 string after percent-decoding")] NotValidUtf8, } diff --git a/actix-files/src/named.rs b/actix-files/src/named.rs index 9e4a37737..7f839890e 100644 --- a/actix-files/src/named.rs +++ b/actix-files/src/named.rs @@ -21,7 +21,7 @@ use actix_web::{ Error, HttpMessage, HttpRequest, HttpResponse, Responder, }; use bitflags::bitflags; -use derive_more::{Deref, DerefMut}; +use derive_more::derive::{Deref, DerefMut}; use futures_core::future::LocalBoxFuture; use mime::Mime; diff --git a/actix-files/src/range.rs b/actix-files/src/range.rs index 528911ae0..c6e346329 100644 --- a/actix-files/src/range.rs +++ b/actix-files/src/range.rs @@ -1,6 +1,6 @@ use std::fmt; -use derive_more::Error; +use derive_more::derive::Error; /// Copy of `http_range::HttpRangeParseError`. #[derive(Debug, Clone)] diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 15b211c1a..95b51254b 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +- Minimum supported Rust version (MSRV) is now 1.75. + ## 3.9.0 ### Added diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index e8dea0bd0..f910276f1 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -110,7 +110,7 @@ ahash = "0.8" bitflags = "2" bytes = "1" bytestring = "1" -derive_more = "0.99.5" +derive_more = { version = "1", features = ["as_ref", "deref", "deref_mut", "display", "error", "from"] } encoding_rs = "0.8" futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] } http = "0.2.7" @@ -160,7 +160,7 @@ rcgen = "0.13" regex = "1.3" rustversion = "1" rustls-pemfile = "2" -serde = { version = "1.0", features = ["derive"] } +serde = { version = "1", features = ["derive"] } serde_json = "1.0" static_assertions = "1" tls-openssl = { package = "openssl", version = "0.10.55" } diff --git a/actix-http/src/body/body_stream.rs b/actix-http/src/body/body_stream.rs index 4574b2519..2ae12c279 100644 --- a/actix-http/src/body/body_stream.rs +++ b/actix-http/src/body/body_stream.rs @@ -75,7 +75,7 @@ mod tests { time::{sleep, Sleep}, }; use actix_utils::future::poll_fn; - use derive_more::{Display, Error}; + use derive_more::derive::{Display, Error}; use futures_core::ready; use futures_util::{stream, FutureExt as _}; use pin_project_lite::pin_project; @@ -131,7 +131,7 @@ mod tests { assert_eq!(to_bytes(body).await.ok(), Some(Bytes::from("12"))); } #[derive(Debug, Display, Error)] - #[display(fmt = "stream error")] + #[display("stream error")] struct StreamErr; #[actix_rt::test] diff --git a/actix-http/src/body/utils.rs b/actix-http/src/body/utils.rs index d1449179f..1fdb3ff5a 100644 --- a/actix-http/src/body/utils.rs +++ b/actix-http/src/body/utils.rs @@ -3,7 +3,7 @@ use std::task::Poll; use actix_rt::pin; use actix_utils::future::poll_fn; use bytes::{Bytes, BytesMut}; -use derive_more::{Display, Error}; +use derive_more::derive::{Display, Error}; use futures_core::ready; use super::{BodySize, MessageBody}; @@ -38,7 +38,7 @@ pub async fn to_bytes(body: B) -> Result { /// Error type returned from [`to_bytes_limited`] when body produced exceeds limit. #[derive(Debug, Display, Error)] -#[display(fmt = "limit exceeded while collecting body bytes")] +#[display("limit exceeded while collecting body bytes")] #[non_exhaustive] pub struct BodyLimitExceeded; diff --git a/actix-http/src/encoding/encoder.rs b/actix-http/src/encoding/encoder.rs index 180927ac6..3c9eec811 100644 --- a/actix-http/src/encoding/encoder.rs +++ b/actix-http/src/encoding/encoder.rs @@ -10,7 +10,7 @@ use std::{ use actix_rt::task::{spawn_blocking, JoinHandle}; use bytes::Bytes; -use derive_more::Display; +use derive_more::derive::Display; #[cfg(feature = "compress-gzip")] use flate2::write::{GzEncoder, ZlibEncoder}; use futures_core::ready; @@ -415,11 +415,11 @@ fn new_brotli_compressor() -> Box> { #[non_exhaustive] pub enum EncoderError { /// Wrapped body stream error. - #[display(fmt = "body")] + #[display("body")] Body(Box), /// Generic I/O error. - #[display(fmt = "io")] + #[display("io")] Io(io::Error), } diff --git a/actix-http/src/error.rs b/actix-http/src/error.rs index 6f332118e..92126f797 100644 --- a/actix-http/src/error.rs +++ b/actix-http/src/error.rs @@ -2,7 +2,7 @@ use std::{error::Error as StdError, fmt, io, str::Utf8Error, string::FromUtf8Error}; -use derive_more::{Display, Error, From}; +use derive_more::derive::{Display, Error, From}; pub use http::{status::InvalidStatusCode, Error as HttpError}; use http::{uri::InvalidUri, StatusCode}; @@ -80,28 +80,28 @@ impl From for Response { #[derive(Debug, Clone, Copy, PartialEq, Eq, Display)] pub(crate) enum Kind { - #[display(fmt = "error processing HTTP")] + #[display("error processing HTTP")] Http, - #[display(fmt = "error parsing HTTP message")] + #[display("error parsing HTTP message")] Parse, - #[display(fmt = "request payload read error")] + #[display("request payload read error")] Payload, - #[display(fmt = "response body write error")] + #[display("response body write error")] Body, - #[display(fmt = "send response error")] + #[display("send response error")] SendResponse, - #[display(fmt = "error in WebSocket process")] + #[display("error in WebSocket process")] Ws, - #[display(fmt = "connection error")] + #[display("connection error")] Io, - #[display(fmt = "encoder error")] + #[display("encoder error")] Encoder, } @@ -160,44 +160,44 @@ impl From for Error { #[non_exhaustive] pub enum ParseError { /// An invalid `Method`, such as `GE.T`. - #[display(fmt = "invalid method specified")] + #[display("invalid method specified")] Method, /// An invalid `Uri`, such as `exam ple.domain`. - #[display(fmt = "URI error: {}", _0)] + #[display("URI error: {}", _0)] Uri(InvalidUri), /// An invalid `HttpVersion`, such as `HTP/1.1` - #[display(fmt = "invalid HTTP version specified")] + #[display("invalid HTTP version specified")] Version, /// An invalid `Header`. - #[display(fmt = "invalid Header provided")] + #[display("invalid Header provided")] Header, /// A message head is too large to be reasonable. - #[display(fmt = "message head is too large")] + #[display("message head is too large")] TooLarge, /// A message reached EOF, but is not complete. - #[display(fmt = "message is incomplete")] + #[display("message is incomplete")] Incomplete, /// An invalid `Status`, such as `1337 ELITE`. - #[display(fmt = "invalid status provided")] + #[display("invalid status provided")] Status, /// A timeout occurred waiting for an IO event. #[allow(dead_code)] - #[display(fmt = "timeout")] + #[display("timeout")] Timeout, /// An I/O error that occurred while trying to read or write to a network stream. - #[display(fmt = "I/O error: {}", _0)] + #[display("I/O error: {}", _0)] Io(io::Error), /// Parsing a field as string failed. - #[display(fmt = "UTF-8 error: {}", _0)] + #[display("UTF-8 error: {}", _0)] Utf8(Utf8Error), } @@ -256,28 +256,28 @@ impl From for Response { #[non_exhaustive] pub enum PayloadError { /// A payload reached EOF, but is not complete. - #[display(fmt = "payload reached EOF before completing: {:?}", _0)] + #[display("payload reached EOF before completing: {:?}", _0)] Incomplete(Option), /// Content encoding stream corruption. - #[display(fmt = "can not decode content-encoding")] + #[display("can not decode content-encoding")] EncodingCorrupted, /// Payload reached size limit. - #[display(fmt = "payload reached size limit")] + #[display("payload reached size limit")] Overflow, /// Payload length is unknown. - #[display(fmt = "payload length is unknown")] + #[display("payload length is unknown")] UnknownLength, /// HTTP/2 payload error. #[cfg(feature = "http2")] - #[display(fmt = "{}", _0)] + #[display("{}", _0)] Http2Payload(::h2::Error), /// Generic I/O error. - #[display(fmt = "{}", _0)] + #[display("{}", _0)] Io(io::Error), } @@ -326,44 +326,44 @@ impl From for Error { #[non_exhaustive] pub enum DispatchError { /// Service error. - #[display(fmt = "service error")] + #[display("service error")] Service(Response), /// Body streaming error. - #[display(fmt = "body error: {}", _0)] + #[display("body error: {}", _0)] Body(Box), /// Upgrade service error. - #[display(fmt = "upgrade error")] + #[display("upgrade error")] Upgrade, /// An `io::Error` that occurred while trying to read or write to a network stream. - #[display(fmt = "I/O error: {}", _0)] + #[display("I/O error: {}", _0)] Io(io::Error), /// Request parse error. - #[display(fmt = "request parse error: {}", _0)] + #[display("request parse error: {}", _0)] Parse(ParseError), /// HTTP/2 error. - #[display(fmt = "{}", _0)] + #[display("{}", _0)] #[cfg(feature = "http2")] H2(h2::Error), /// The first request did not complete within the specified timeout. - #[display(fmt = "request did not complete within the specified timeout")] + #[display("request did not complete within the specified timeout")] SlowRequestTimeout, /// Disconnect timeout. Makes sense for TLS streams. - #[display(fmt = "connection shutdown timeout")] + #[display("connection shutdown timeout")] DisconnectTimeout, /// Handler dropped payload before reading EOF. - #[display(fmt = "handler dropped payload before reading EOF")] + #[display("handler dropped payload before reading EOF")] HandlerDroppedPayload, /// Internal error. - #[display(fmt = "internal error")] + #[display("internal error")] InternalError, } @@ -389,11 +389,11 @@ impl StdError for DispatchError { #[non_exhaustive] pub enum ContentTypeError { /// Can not parse content type. - #[display(fmt = "could not parse content type")] + #[display("could not parse content type")] ParseError, /// Unknown content encoding. - #[display(fmt = "unknown content encoding")] + #[display("unknown content encoding")] UnknownEncoding, } diff --git a/actix-http/src/header/shared/content_encoding.rs b/actix-http/src/header/shared/content_encoding.rs index c3b4bc4c2..0b83659d0 100644 --- a/actix-http/src/header/shared/content_encoding.rs +++ b/actix-http/src/header/shared/content_encoding.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use derive_more::{Display, Error}; +use derive_more::derive::{Display, Error}; use http::header::InvalidHeaderValue; use crate::{ @@ -11,7 +11,7 @@ use crate::{ /// Error returned when a content encoding is unknown. #[derive(Debug, Display, Error)] -#[display(fmt = "unsupported content encoding")] +#[display("unsupported content encoding")] pub struct ContentEncodingParseError; /// Represents a supported content encoding. diff --git a/actix-http/src/header/shared/quality.rs b/actix-http/src/header/shared/quality.rs index c2276cf1b..2a76bc8ca 100644 --- a/actix-http/src/header/shared/quality.rs +++ b/actix-http/src/header/shared/quality.rs @@ -1,6 +1,6 @@ use std::fmt; -use derive_more::{Display, Error}; +use derive_more::derive::{Display, Error}; const MAX_QUALITY_INT: u16 = 1000; const MAX_QUALITY_FLOAT: f32 = 1.0; @@ -125,7 +125,7 @@ pub fn itoa_fmt(mut wr: W, value: V) -> fmt::Re } #[derive(Debug, Clone, Display, Error)] -#[display(fmt = "quality out of bounds")] +#[display("quality out of bounds")] #[non_exhaustive] pub struct QualityOutOfBounds; diff --git a/actix-http/src/ws/mod.rs b/actix-http/src/ws/mod.rs index 3ed53b70a..88053b254 100644 --- a/actix-http/src/ws/mod.rs +++ b/actix-http/src/ws/mod.rs @@ -5,7 +5,7 @@ use std::io; -use derive_more::{Display, Error, From}; +use derive_more::derive::{Display, Error, From}; use http::{header, Method, StatusCode}; use crate::{body::BoxBody, header::HeaderValue, RequestHead, Response, ResponseBuilder}; @@ -27,43 +27,43 @@ pub use self::{ #[derive(Debug, Display, Error, From)] pub enum ProtocolError { /// Received an unmasked frame from client. - #[display(fmt = "received an unmasked frame from client")] + #[display("received an unmasked frame from client")] UnmaskedFrame, /// Received a masked frame from server. - #[display(fmt = "received a masked frame from server")] + #[display("received a masked frame from server")] MaskedFrame, /// Encountered invalid opcode. - #[display(fmt = "invalid opcode ({})", _0)] + #[display("invalid opcode ({})", _0)] InvalidOpcode(#[error(not(source))] u8), /// Invalid control frame length - #[display(fmt = "invalid control frame length ({})", _0)] + #[display("invalid control frame length ({})", _0)] InvalidLength(#[error(not(source))] usize), /// Bad opcode. - #[display(fmt = "bad opcode")] + #[display("bad opcode")] BadOpCode, /// A payload reached size limit. - #[display(fmt = "payload reached size limit")] + #[display("payload reached size limit")] Overflow, /// Continuation has not started. - #[display(fmt = "continuation has not started")] + #[display("continuation has not started")] ContinuationNotStarted, /// Received new continuation but it is already started. - #[display(fmt = "received new continuation but it has already started")] + #[display("received new continuation but it has already started")] ContinuationStarted, /// Unknown continuation fragment. - #[display(fmt = "unknown continuation fragment: {}", _0)] + #[display("unknown continuation fragment: {}", _0)] ContinuationFragment(#[error(not(source))] OpCode), /// I/O error. - #[display(fmt = "I/O error: {}", _0)] + #[display("I/O error: {}", _0)] Io(io::Error), } @@ -71,27 +71,27 @@ pub enum ProtocolError { #[derive(Debug, Clone, Copy, PartialEq, Eq, Display, Error)] pub enum HandshakeError { /// Only get method is allowed. - #[display(fmt = "method not allowed")] + #[display("method not allowed")] GetMethodRequired, /// Upgrade header if not set to WebSocket. - #[display(fmt = "WebSocket upgrade is expected")] + #[display("WebSocket upgrade is expected")] NoWebsocketUpgrade, /// Connection header is not set to upgrade. - #[display(fmt = "connection upgrade is expected")] + #[display("connection upgrade is expected")] NoConnectionUpgrade, /// WebSocket version header is not set. - #[display(fmt = "WebSocket version header is required")] + #[display("WebSocket version header is required")] NoVersionHeader, /// Unsupported WebSocket version. - #[display(fmt = "unsupported WebSocket version")] + #[display("unsupported WebSocket version")] UnsupportedVersion, /// WebSocket key is not set or wrong. - #[display(fmt = "unknown WebSocket key")] + #[display("unknown WebSocket key")] BadWebsocketKey, } diff --git a/actix-http/tests/test_client.rs b/actix-http/tests/test_client.rs index 5888527f1..c0019d06b 100644 --- a/actix-http/tests/test_client.rs +++ b/actix-http/tests/test_client.rs @@ -5,7 +5,7 @@ use actix_http_test::test_server; use actix_service::ServiceFactoryExt; use actix_utils::future; use bytes::Bytes; -use derive_more::{Display, Error}; +use derive_more::derive::{Display, Error}; use futures_util::StreamExt as _; const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ @@ -94,7 +94,7 @@ async fn with_query_parameter() { } #[derive(Debug, Display, Error)] -#[display(fmt = "expect failed")] +#[display("expect failed")] struct ExpectFailed; impl From for Response { diff --git a/actix-http/tests/test_openssl.rs b/actix-http/tests/test_openssl.rs index 4dd22b585..77a66f32f 100644 --- a/actix-http/tests/test_openssl.rs +++ b/actix-http/tests/test_openssl.rs @@ -14,7 +14,7 @@ use actix_http_test::test_server; use actix_service::{fn_service, ServiceFactoryExt}; use actix_utils::future::{err, ok, ready}; use bytes::{Bytes, BytesMut}; -use derive_more::{Display, Error}; +use derive_more::derive::{Display, Error}; use futures_core::Stream; use futures_util::{stream::once, StreamExt as _}; use openssl::{ @@ -398,7 +398,7 @@ async fn h2_response_http_error_handling() { } #[derive(Debug, Display, Error)] -#[display(fmt = "error")] +#[display("error")] struct BadRequest; impl From for Response { diff --git a/actix-http/tests/test_rustls.rs b/actix-http/tests/test_rustls.rs index 3ca0d94c2..5b02637dc 100644 --- a/actix-http/tests/test_rustls.rs +++ b/actix-http/tests/test_rustls.rs @@ -23,7 +23,7 @@ use actix_service::{fn_factory_with_config, fn_service}; use actix_tls::connect::rustls_0_23::webpki_roots_cert_store; use actix_utils::future::{err, ok, poll_fn}; use bytes::{Bytes, BytesMut}; -use derive_more::{Display, Error}; +use derive_more::derive::{Display, Error}; use futures_core::{ready, Stream}; use futures_util::stream::once; use rustls::{pki_types::ServerName, ServerConfig as RustlsServerConfig}; @@ -480,7 +480,7 @@ async fn h2_response_http_error_handling() { } #[derive(Debug, Display, Error)] -#[display(fmt = "error")] +#[display("error")] struct BadRequest; impl From for Response { diff --git a/actix-http/tests/test_server.rs b/actix-http/tests/test_server.rs index 4ba64a53c..e93d35598 100644 --- a/actix-http/tests/test_server.rs +++ b/actix-http/tests/test_server.rs @@ -14,7 +14,7 @@ use actix_rt::{net::TcpStream, time::sleep}; use actix_service::fn_service; use actix_utils::future::{err, ok, ready}; use bytes::Bytes; -use derive_more::{Display, Error}; +use derive_more::derive::{Display, Error}; use futures_util::{stream::once, FutureExt as _, StreamExt as _}; use regex::Regex; @@ -62,7 +62,7 @@ async fn h1_2() { } #[derive(Debug, Display, Error)] -#[display(fmt = "expect failed")] +#[display("expect failed")] struct ExpectFailed; impl From for Response { @@ -723,7 +723,7 @@ async fn h1_response_http_error_handling() { } #[derive(Debug, Display, Error)] -#[display(fmt = "error")] +#[display("error")] struct BadRequest; impl From for Response { diff --git a/actix-http/tests/test_ws.rs b/actix-http/tests/test_ws.rs index 9a78074c4..e9c4a01af 100644 --- a/actix-http/tests/test_ws.rs +++ b/actix-http/tests/test_ws.rs @@ -14,7 +14,7 @@ use actix_http::{ use actix_http_test::test_server; use actix_service::{fn_factory, Service}; use bytes::Bytes; -use derive_more::{Display, Error, From}; +use derive_more::derive::{Display, Error, From}; use futures_core::future::LocalBoxFuture; use futures_util::{SinkExt as _, StreamExt as _}; @@ -37,16 +37,16 @@ impl WsService { #[derive(Debug, Display, Error, From)] enum WsServiceError { - #[display(fmt = "HTTP error")] + #[display("HTTP error")] Http(actix_http::Error), - #[display(fmt = "WS handshake error")] + #[display("WS handshake error")] Ws(actix_http::ws::HandshakeError), - #[display(fmt = "I/O error")] + #[display("I/O error")] Io(std::io::Error), - #[display(fmt = "dispatcher error")] + #[display("dispatcher error")] Dispatcher, } diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index c3f3b6e39..a030fac44 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +- Minimum supported Rust version (MSRV) is now 1.75. + ## 0.7.2 - Fix re-exported version of `actix-multipart-derive`. diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index 7a80b265f..aa33bfc93 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -42,7 +42,7 @@ actix-multipart-derive = { version = "=0.7.0", optional = true } actix-utils = "3" actix-web = { version = "4", default-features = false } -derive_more = "0.99.5" +derive_more = { version = "1", features = ["display", "error", "from"] } futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] } futures-util = { version = "0.3.17", default-features = false, features = ["alloc"] } httparse = "1.3" diff --git a/actix-multipart/src/error.rs b/actix-multipart/src/error.rs index cdb608738..8fff5c593 100644 --- a/actix-multipart/src/error.rs +++ b/actix-multipart/src/error.rs @@ -5,18 +5,18 @@ use actix_web::{ http::StatusCode, ResponseError, }; -use derive_more::{Display, Error, From}; +use derive_more::derive::{Display, Error, From}; /// A set of errors that can occur during parsing multipart streams. #[derive(Debug, Display, From, Error)] #[non_exhaustive] pub enum Error { /// Could not find Content-Type header. - #[display(fmt = "Could not find Content-Type header")] + #[display("Could not find Content-Type header")] ContentTypeMissing, /// Could not parse Content-Type header. - #[display(fmt = "Could not parse Content-Type header")] + #[display("Could not parse Content-Type header")] ContentTypeParse, /// Parsed Content-Type did not have "multipart" top-level media type. @@ -25,11 +25,11 @@ pub enum Error { /// "multipart/form-data" media type. /// /// [`MultipartForm`]: struct@crate::form::MultipartForm - #[display(fmt = "Parsed Content-Type did not have "multipart" top-level media type")] + #[display("Parsed Content-Type did not have 'multipart' top-level media type")] ContentTypeIncompatible, /// Multipart boundary is not found. - #[display(fmt = "Multipart boundary is not found")] + #[display("Multipart boundary is not found")] BoundaryMissing, /// Content-Disposition header was not found or not of disposition type "form-data" when parsing @@ -39,7 +39,7 @@ pub enum Error { /// always be present and have a disposition type of "form-data". /// /// [RFC 7578 §4.2]: https://datatracker.ietf.org/doc/html/rfc7578#section-4.2 - #[display(fmt = "Content-Disposition header was not found when parsing a \"form-data\" field")] + #[display("Content-Disposition header was not found when parsing a \"form-data\" field")] ContentDispositionMissing, /// Content-Disposition name parameter was not found when parsing a "form-data" field. @@ -48,48 +48,48 @@ pub enum Error { /// always include a "name" parameter. /// /// [RFC 7578 §4.2]: https://datatracker.ietf.org/doc/html/rfc7578#section-4.2 - #[display(fmt = "Content-Disposition header was not found when parsing a \"form-data\" field")] + #[display("Content-Disposition header was not found when parsing a \"form-data\" field")] ContentDispositionNameMissing, /// Nested multipart is not supported. - #[display(fmt = "Nested multipart is not supported")] + #[display("Nested multipart is not supported")] Nested, /// Multipart stream is incomplete. - #[display(fmt = "Multipart stream is incomplete")] + #[display("Multipart stream is incomplete")] Incomplete, /// Field parsing failed. - #[display(fmt = "Error during field parsing")] + #[display("Error during field parsing")] Parse(ParseError), /// HTTP payload error. - #[display(fmt = "Payload error")] + #[display("Payload error")] Payload(PayloadError), /// Stream is not consumed. - #[display(fmt = "Stream is not consumed")] + #[display("Stream is not consumed")] NotConsumed, /// Form field handler raised error. - #[display(fmt = "An error occurred processing field: {name}")] + #[display("An error occurred processing field: {name}")] Field { name: String, source: actix_web::Error, }, /// Duplicate field found (for structure that opted-in to denying duplicate fields). - #[display(fmt = "Duplicate field found: {_0}")] + #[display("Duplicate field found: {_0}")] #[from(ignore)] DuplicateField(#[error(not(source))] String), /// Required field is missing. - #[display(fmt = "Required field is missing: {_0}")] + #[display("Required field is missing: {_0}")] #[from(ignore)] MissingField(#[error(not(source))] String), /// Unknown field (for structure that opted-in to denying unknown fields). - #[display(fmt = "Unknown field: {_0}")] + #[display("Unknown field: {_0}")] #[from(ignore)] UnknownField(#[error(not(source))] String), } diff --git a/actix-multipart/src/field.rs b/actix-multipart/src/field.rs index f4eb601fb..b42d8ae1b 100644 --- a/actix-multipart/src/field.rs +++ b/actix-multipart/src/field.rs @@ -13,7 +13,7 @@ use actix_web::{ http::header::{self, ContentDisposition, HeaderMap}, web::{Bytes, BytesMut}, }; -use derive_more::{Display, Error}; +use derive_more::derive::{Display, Error}; use futures_core::Stream; use mime::Mime; @@ -25,7 +25,7 @@ use crate::{ /// Error type returned from [`Field::bytes()`] when field data is larger than limit. #[derive(Debug, Display, Error)] -#[display(fmt = "size limit exceeded while collecting field data")] +#[display("size limit exceeded while collecting field data")] #[non_exhaustive] pub struct LimitExceeded; diff --git a/actix-multipart/src/form/json.rs b/actix-multipart/src/form/json.rs index 0118a8fba..8fb1f5ca7 100644 --- a/actix-multipart/src/form/json.rs +++ b/actix-multipart/src/form/json.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use actix_web::{http::StatusCode, web, Error, HttpRequest, ResponseError}; -use derive_more::{Deref, DerefMut, Display, Error}; +use derive_more::derive::{Deref, DerefMut, Display, Error}; use futures_core::future::LocalBoxFuture; use serde::de::DeserializeOwned; @@ -66,11 +66,11 @@ where #[non_exhaustive] pub enum JsonFieldError { /// Deserialize error. - #[display(fmt = "Json deserialize error: {}", _0)] + #[display("Json deserialize error: {}", _0)] Deserialize(serde_json::Error), /// Content type error. - #[display(fmt = "Content type error")] + #[display("Content type error")] ContentType, } diff --git a/actix-multipart/src/form/mod.rs b/actix-multipart/src/form/mod.rs index 693a45e8e..a9a1ad569 100644 --- a/actix-multipart/src/form/mod.rs +++ b/actix-multipart/src/form/mod.rs @@ -8,7 +8,7 @@ use std::{ }; use actix_web::{dev, error::PayloadError, web, Error, FromRequest, HttpRequest}; -use derive_more::{Deref, DerefMut}; +use derive_more::derive::{Deref, DerefMut}; use futures_core::future::LocalBoxFuture; use futures_util::{TryFutureExt as _, TryStreamExt as _}; diff --git a/actix-multipart/src/form/tempfile.rs b/actix-multipart/src/form/tempfile.rs index f329876f2..df7a2368a 100644 --- a/actix-multipart/src/form/tempfile.rs +++ b/actix-multipart/src/form/tempfile.rs @@ -7,7 +7,7 @@ use std::{ }; use actix_web::{http::StatusCode, web, Error, HttpRequest, ResponseError}; -use derive_more::{Display, Error}; +use derive_more::derive::{Display, Error}; use futures_core::future::LocalBoxFuture; use futures_util::TryStreamExt as _; use mime::Mime; @@ -82,7 +82,7 @@ impl<'t> FieldReader<'t> for TempFile { #[non_exhaustive] pub enum TempFileError { /// File I/O Error - #[display(fmt = "File I/O error: {}", _0)] + #[display("File I/O error: {}", _0)] FileIo(std::io::Error), } diff --git a/actix-multipart/src/form/text.rs b/actix-multipart/src/form/text.rs index 67a434ee6..c4b307f83 100644 --- a/actix-multipart/src/form/text.rs +++ b/actix-multipart/src/form/text.rs @@ -3,7 +3,7 @@ use std::{str, sync::Arc}; use actix_web::{http::StatusCode, web, Error, HttpRequest, ResponseError}; -use derive_more::{Deref, DerefMut, Display, Error}; +use derive_more::derive::{Deref, DerefMut, Display, Error}; use futures_core::future::LocalBoxFuture; use serde::de::DeserializeOwned; @@ -77,15 +77,15 @@ where #[non_exhaustive] pub enum TextError { /// UTF-8 decoding error. - #[display(fmt = "UTF-8 decoding error: {}", _0)] + #[display("UTF-8 decoding error: {}", _0)] Utf8Error(str::Utf8Error), /// Deserialize error. - #[display(fmt = "Plain text deserialize error: {}", _0)] + #[display("Plain text deserialize error: {}", _0)] Deserialize(serde_plain::Error), /// Content type error. - #[display(fmt = "Content type error")] + #[display("Content type error")] ContentType, } diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 588320f4d..36e8b62dd 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +- Minimum supported Rust version (MSRV) is now 1.75. + ## 4.9.0 ### Added diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index 1e69973d0..f97eab7c9 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -146,7 +146,7 @@ bytes = "1" bytestring = "1" cfg-if = "1" cookie = { version = "0.16", features = ["percent-encode"], optional = true } -derive_more = "0.99.8" +derive_more = { version = "1", features = ["display", "error", "from"] } encoding_rs = "0.8" futures-core = { version = "0.3.17", default-features = false } futures-util = { version = "0.3.17", default-features = false } @@ -182,7 +182,7 @@ futures-util = { version = "0.3.17", default-features = false, features = ["std" rand = "0.8" rcgen = "0.13" rustls-pemfile = "2" -serde = { version = "1.0", features = ["derive"] } +serde = { version = "1", features = ["derive"] } static_assertions = "1" tls-openssl = { package = "openssl", version = "0.10.55" } tls-rustls = { package = "rustls", version = "0.23" } diff --git a/actix-web/src/error/mod.rs b/actix-web/src/error/mod.rs index 25535332c..fce7ca399 100644 --- a/actix-web/src/error/mod.rs +++ b/actix-web/src/error/mod.rs @@ -6,7 +6,7 @@ // // See pub use actix_http::error::{ContentTypeError, DispatchError, HttpError, ParseError, PayloadError}; -use derive_more::{Display, Error, From}; +use derive_more::derive::{Display, Error, From}; use serde_json::error::Error as JsonError; use serde_urlencoded::{de::Error as FormDeError, ser::Error as FormError}; use url::ParseError as UrlParseError; @@ -29,7 +29,7 @@ pub type Result = std::result::Result; /// An error representing a problem running a blocking task on a thread pool. #[derive(Debug, Display, Error)] -#[display(fmt = "Blocking thread pool is shut down unexpectedly")] +#[display("Blocking thread pool is shut down unexpectedly")] #[non_exhaustive] pub struct BlockingError; @@ -40,15 +40,15 @@ impl ResponseError for crate::error::BlockingError {} #[non_exhaustive] pub enum UrlGenerationError { /// Resource not found. - #[display(fmt = "Resource not found")] + #[display("Resource not found")] ResourceNotFound, /// Not all URL parameters covered. - #[display(fmt = "Not all URL parameters covered")] + #[display("Not all URL parameters covered")] NotEnoughElements, /// URL parse error. - #[display(fmt = "{}", _0)] + #[display("{}", _0)] ParseError(UrlParseError), } @@ -59,39 +59,39 @@ impl ResponseError for UrlGenerationError {} #[non_exhaustive] pub enum UrlencodedError { /// Can not decode chunked transfer encoding. - #[display(fmt = "Can not decode chunked transfer encoding.")] + #[display("Can not decode chunked transfer encoding.")] Chunked, /// Payload size is larger than allowed. (default limit: 256kB). #[display( - fmt = "URL encoded payload is larger ({} bytes) than allowed (limit: {} bytes).", + "URL encoded payload is larger ({} bytes) than allowed (limit: {} bytes).", size, limit )] Overflow { size: usize, limit: usize }, /// Payload size is now known. - #[display(fmt = "Payload size is now known.")] + #[display("Payload size is now known.")] UnknownLength, /// Content type error. - #[display(fmt = "Content type error.")] + #[display("Content type error.")] ContentType, /// Parse error. - #[display(fmt = "Parse error: {}.", _0)] + #[display("Parse error: {}.", _0)] Parse(FormDeError), /// Encoding error. - #[display(fmt = "Encoding error.")] + #[display("Encoding error.")] Encoding, /// Serialize error. - #[display(fmt = "Serialize error: {}.", _0)] + #[display("Serialize error: {}.", _0)] Serialize(FormError), /// Payload error. - #[display(fmt = "Error that occur during reading payload: {}.", _0)] + #[display("Error that occur during reading payload: {}.", _0)] Payload(PayloadError), } @@ -113,30 +113,30 @@ impl ResponseError for UrlencodedError { pub enum JsonPayloadError { /// Payload size is bigger than allowed & content length header set. (default: 2MB) #[display( - fmt = "JSON payload ({} bytes) is larger than allowed (limit: {} bytes).", + "JSON payload ({} bytes) is larger than allowed (limit: {} bytes).", length, limit )] OverflowKnownLength { length: usize, limit: usize }, /// Payload size is bigger than allowed but no content length header set. (default: 2MB) - #[display(fmt = "JSON payload has exceeded limit ({} bytes).", limit)] + #[display("JSON payload has exceeded limit ({} bytes).", limit)] Overflow { limit: usize }, /// Content type error - #[display(fmt = "Content type error")] + #[display("Content type error")] ContentType, /// Deserialize error - #[display(fmt = "Json deserialize error: {}", _0)] + #[display("Json deserialize error: {}", _0)] Deserialize(JsonError), /// Serialize error - #[display(fmt = "Json serialize error: {}", _0)] + #[display("Json serialize error: {}", _0)] Serialize(JsonError), /// Payload error - #[display(fmt = "Error that occur during reading payload: {}", _0)] + #[display("Error that occur during reading payload: {}", _0)] Payload(PayloadError), } @@ -166,7 +166,7 @@ impl ResponseError for JsonPayloadError { #[non_exhaustive] pub enum PathError { /// Deserialize error - #[display(fmt = "Path deserialize error: {}", _0)] + #[display("Path deserialize error: {}", _0)] Deserialize(serde::de::value::Error), } @@ -182,7 +182,7 @@ impl ResponseError for PathError { #[non_exhaustive] pub enum QueryPayloadError { /// Query deserialize error. - #[display(fmt = "Query deserialize error: {}", _0)] + #[display("Query deserialize error: {}", _0)] Deserialize(serde::de::value::Error), } @@ -196,20 +196,20 @@ impl ResponseError for QueryPayloadError { #[derive(Debug, Display, Error, From)] #[non_exhaustive] pub enum ReadlinesError { - #[display(fmt = "Encoding error")] + #[display("Encoding error")] /// Payload size is bigger than allowed. (default: 256kB) EncodingError, /// Payload error. - #[display(fmt = "Error that occur during reading payload: {}", _0)] + #[display("Error that occur during reading payload: {}", _0)] Payload(PayloadError), /// Line limit exceeded. - #[display(fmt = "Line limit exceeded")] + #[display("Line limit exceeded")] LimitOverflow, /// ContentType error. - #[display(fmt = "Content-type error")] + #[display("Content-type error")] ContentTypeError(ContentTypeError), } diff --git a/actix-web/src/http/header/content_length.rs b/actix-web/src/http/header/content_length.rs index 557c7c9f5..734f4ef38 100644 --- a/actix-web/src/http/header/content_length.rs +++ b/actix-web/src/http/header/content_length.rs @@ -1,6 +1,6 @@ use std::{convert::Infallible, str}; -use derive_more::{Deref, DerefMut}; +use derive_more::derive::{Deref, DerefMut}; use crate::{ error::ParseError, diff --git a/actix-web/src/info.rs b/actix-web/src/info.rs index 1b2e554f9..0655a3df2 100644 --- a/actix-web/src/info.rs +++ b/actix-web/src/info.rs @@ -1,7 +1,7 @@ use std::{convert::Infallible, net::SocketAddr}; use actix_utils::future::{err, ok, Ready}; -use derive_more::{Display, Error}; +use derive_more::derive::{Display, Error}; use crate::{ dev::{AppConfig, Payload, RequestHead}, @@ -235,7 +235,7 @@ impl FromRequest for ConnectionInfo { /// # let _svc = actix_web::web::to(handler); /// ``` #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Display)] -#[display(fmt = "{}", _0)] +#[display("{}", _0)] pub struct PeerAddr(pub SocketAddr); impl PeerAddr { @@ -247,7 +247,7 @@ impl PeerAddr { #[derive(Debug, Display, Error)] #[non_exhaustive] -#[display(fmt = "Missing peer address")] +#[display("Missing peer address")] pub struct MissingPeerAddr; impl ResponseError for MissingPeerAddr {} diff --git a/actix-web/src/types/path.rs b/actix-web/src/types/path.rs index d6cf186f6..ada72a72e 100644 --- a/actix-web/src/types/path.rs +++ b/actix-web/src/types/path.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use actix_router::PathDeserializer; use actix_utils::future::{ready, Ready}; -use derive_more::{AsRef, Deref, DerefMut, Display, From}; +use derive_more::derive::{AsRef, Deref, DerefMut, Display, From}; use serde::de; use crate::{ @@ -152,14 +152,14 @@ impl PathConfig { #[cfg(test)] mod tests { use actix_router::ResourceDef; - use derive_more::Display; + use derive_more::derive::Display; use serde::Deserialize; use super::*; use crate::{error, http, test::TestRequest, HttpResponse}; #[derive(Deserialize, Debug, Display)] - #[display(fmt = "MyStruct({}, {})", key, value)] + #[display("MyStruct({}, {})", key, value)] struct MyStruct { key: String, value: String, diff --git a/actix-web/src/types/query.rs b/actix-web/src/types/query.rs index e5505131e..a8e23f78c 100644 --- a/actix-web/src/types/query.rs +++ b/actix-web/src/types/query.rs @@ -187,7 +187,7 @@ impl QueryConfig { #[cfg(test)] mod tests { use actix_http::StatusCode; - use derive_more::Display; + use derive_more::derive::Display; use serde::Deserialize; use super::*; diff --git a/awc/CHANGES.md b/awc/CHANGES.md index 9c0f3b607..a2e51c8d2 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +- Minimum supported Rust version (MSRV) is now 1.75. + ## 3.5.1 - Fix WebSocket `Host` request header value when using a non-default port. diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 26b483bfa..849ca571f 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -106,7 +106,7 @@ actix-utils = "3" base64 = "0.22" bytes = "1" cfg-if = "1" -derive_more = "0.99.5" +derive_more = { version = "1", features = ["display", "error", "from"] } 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.26" diff --git a/awc/src/client/error.rs b/awc/src/client/error.rs index 22cf2c200..81543fb7d 100644 --- a/awc/src/client/error.rs +++ b/awc/src/client/error.rs @@ -3,7 +3,7 @@ use std::{fmt, io}; use actix_http::error::{HttpError, ParseError}; #[cfg(feature = "openssl")] use actix_tls::accept::openssl::reexports::Error as OpensslError; -use derive_more::{Display, From}; +use derive_more::derive::{Display, From}; use crate::BoxError; @@ -12,40 +12,40 @@ use crate::BoxError; #[non_exhaustive] pub enum ConnectError { /// SSL feature is not enabled - #[display(fmt = "SSL is not supported")] + #[display("SSL is not supported")] SslIsNotSupported, /// SSL error #[cfg(feature = "openssl")] - #[display(fmt = "{}", _0)] + #[display("{}", _0)] SslError(OpensslError), /// Failed to resolve the hostname - #[display(fmt = "Failed resolving hostname: {}", _0)] + #[display("Failed resolving hostname: {}", _0)] Resolver(Box), /// No dns records - #[display(fmt = "No DNS records found for the input")] + #[display("No DNS records found for the input")] NoRecords, /// Http2 error - #[display(fmt = "{}", _0)] + #[display("{}", _0)] H2(h2::Error), /// Connecting took too long - #[display(fmt = "Timeout while establishing connection")] + #[display("Timeout while establishing connection")] Timeout, /// Connector has been disconnected - #[display(fmt = "Internal error: connector has been disconnected")] + #[display("Internal error: connector has been disconnected")] Disconnected, /// Unresolved host name - #[display(fmt = "Connector received `Connect` method with unresolved host")] + #[display("Connector received `Connect` method with unresolved host")] Unresolved, /// Connection io error - #[display(fmt = "{}", _0)] + #[display("{}", _0)] Io(io::Error), } @@ -66,16 +66,16 @@ impl From for ConnectError { #[derive(Debug, Display, From)] #[non_exhaustive] pub enum InvalidUrl { - #[display(fmt = "Missing URL scheme")] + #[display("Missing URL scheme")] MissingScheme, - #[display(fmt = "Unknown URL scheme")] + #[display("Unknown URL scheme")] UnknownScheme, - #[display(fmt = "Missing host name")] + #[display("Missing host name")] MissingHost, - #[display(fmt = "URL parse error: {}", _0)] + #[display("URL parse error: {}", _0)] HttpError(http::Error), } @@ -86,11 +86,11 @@ impl std::error::Error for InvalidUrl {} #[non_exhaustive] pub enum SendRequestError { /// Invalid URL - #[display(fmt = "Invalid URL: {}", _0)] + #[display("Invalid URL: {}", _0)] Url(InvalidUrl), /// Failed to connect to host - #[display(fmt = "Failed to connect to host: {}", _0)] + #[display("Failed to connect to host: {}", _0)] Connect(ConnectError), /// Error sending request @@ -100,26 +100,26 @@ pub enum SendRequestError { Response(ParseError), /// Http error - #[display(fmt = "{}", _0)] + #[display("{}", _0)] Http(HttpError), /// Http2 error - #[display(fmt = "{}", _0)] + #[display("{}", _0)] H2(h2::Error), /// Response took too long - #[display(fmt = "Timeout while waiting for response")] + #[display("Timeout while waiting for response")] Timeout, /// Tunnels are not supported for HTTP/2 connection - #[display(fmt = "Tunnels are not supported for http2 connection")] + #[display("Tunnels are not supported for http2 connection")] TunnelNotSupported, /// Error sending request body Body(BoxError), /// Other errors that can occur after submitting a request. - #[display(fmt = "{:?}: {}", _1, _0)] + #[display("{:?}: {}", _1, _0)] Custom(BoxError, Box), } @@ -130,15 +130,15 @@ impl std::error::Error for SendRequestError {} #[non_exhaustive] pub enum FreezeRequestError { /// Invalid URL - #[display(fmt = "Invalid URL: {}", _0)] + #[display("Invalid URL: {}", _0)] Url(InvalidUrl), /// HTTP error - #[display(fmt = "{}", _0)] + #[display("{}", _0)] Http(HttpError), /// Other errors that can occur after submitting a request. - #[display(fmt = "{:?}: {}", _1, _0)] + #[display("{:?}: {}", _1, _0)] Custom(BoxError, Box), } diff --git a/awc/src/error.rs b/awc/src/error.rs index 0104e5fe8..59dbc8b67 100644 --- a/awc/src/error.rs +++ b/awc/src/error.rs @@ -7,7 +7,7 @@ pub use actix_http::{ ws::{HandshakeError as WsHandshakeError, ProtocolError as WsProtocolError}, StatusCode, }; -use derive_more::{Display, From}; +use derive_more::derive::{Display, From}; use serde_json::error::Error as JsonError; pub use crate::client::{ConnectError, FreezeRequestError, InvalidUrl, SendRequestError}; @@ -18,35 +18,35 @@ pub use crate::client::{ConnectError, FreezeRequestError, InvalidUrl, SendReques #[derive(Debug, Display, From)] pub enum WsClientError { /// Invalid response status - #[display(fmt = "Invalid response status")] + #[display("Invalid response status")] InvalidResponseStatus(StatusCode), /// Invalid upgrade header - #[display(fmt = "Invalid upgrade header")] + #[display("Invalid upgrade header")] InvalidUpgradeHeader, /// Invalid connection header - #[display(fmt = "Invalid connection header")] + #[display("Invalid connection header")] InvalidConnectionHeader(HeaderValue), /// Missing Connection header - #[display(fmt = "Missing Connection header")] + #[display("Missing Connection header")] MissingConnectionHeader, /// Missing Sec-Websocket-Accept header - #[display(fmt = "Missing Sec-Websocket-Accept header")] + #[display("Missing Sec-Websocket-Accept header")] MissingWebSocketAcceptHeader, /// Invalid challenge response - #[display(fmt = "Invalid challenge response")] + #[display("Invalid challenge response")] InvalidChallengeResponse([u8; 28], HeaderValue), /// Protocol error - #[display(fmt = "{}", _0)] + #[display("{}", _0)] Protocol(WsProtocolError), /// Send request error - #[display(fmt = "{}", _0)] + #[display("{}", _0)] SendRequest(SendRequestError), } @@ -68,13 +68,13 @@ impl From for WsClientError { #[derive(Debug, Display, From)] pub enum JsonPayloadError { /// Content type error - #[display(fmt = "Content type error")] + #[display("Content type error")] ContentType, /// Deserialize error - #[display(fmt = "Json deserialize error: {}", _0)] + #[display("Json deserialize error: {}", _0)] Deserialize(JsonError), /// Payload error - #[display(fmt = "Error that occur during reading payload: {}", _0)] + #[display("Error that occur during reading payload: {}", _0)] Payload(PayloadError), } diff --git a/awc/src/sender.rs b/awc/src/sender.rs index 0015743bd..b676ebf28 100644 --- a/awc/src/sender.rs +++ b/awc/src/sender.rs @@ -17,7 +17,7 @@ use actix_http::{ use actix_http::{encoding::Decoder, header::ContentEncoding, Payload}; use actix_rt::time::{sleep, Sleep}; use bytes::Bytes; -use derive_more::From; +use derive_more::derive::From; use futures_core::Stream; use serde::Serialize; From c05572399799e8c2d961209a03026eb291166c42 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 18 Aug 2024 15:54:36 +0100 Subject: [PATCH 055/144] fix(awc): prevent panics in pool drop for h1 connections (#3448) --- awc/CHANGES.md | 1 + awc/src/client/pool.rs | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/awc/CHANGES.md b/awc/CHANGES.md index a2e51c8d2..11cb150ab 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -2,6 +2,7 @@ ## Unreleased +- Prevent panics on connection pool drop when Tokio runtime is shutdown early. - Minimum supported Rust version (MSRV) is now 1.75. ## 3.5.1 diff --git a/awc/src/client/pool.rs b/awc/src/client/pool.rs index 1736f2b02..5d764f729 100644 --- a/awc/src/client/pool.rs +++ b/awc/src/client/pool.rs @@ -76,7 +76,9 @@ where fn close(&self, conn: ConnectionInnerType) { if let Some(timeout) = self.config.disconnect_timeout { if let ConnectionInnerType::H1(io) = conn { - actix_rt::spawn(CloseConnection::new(io, timeout)); + if tokio::runtime::Handle::try_current().is_ok() { + actix_rt::spawn(CloseConnection::new(io, timeout)); + } } } } From b4f8bda0329a96009521999eb23ac9f874880504 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 02:24:23 +0100 Subject: [PATCH 056/144] build(deps): bump taiki-e/install-action from 2.42.22 to 2.42.26 (#3456) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.42.22 to 2.42.26. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.42.22...v2.42.26) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index f94f0b20b..69e14ebb3 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.42.22 + uses: taiki-e/install-action@v2.42.26 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.42.22 + uses: taiki-e/install-action@v2.42.26 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f4a526e38..317577a56 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.42.22 + uses: taiki-e/install-action@v2.42.26 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.42.22 + uses: taiki-e/install-action@v2.42.26 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 8282ac18e..b6fa35559 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.42.22 + uses: taiki-e/install-action@v2.42.26 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index d105b67d5..418432a16 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -76,7 +76,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.42.22 + uses: taiki-e/install-action@v2.42.26 with: tool: just @@ -105,7 +105,7 @@ jobs: toolchain: nightly-2024-06-07 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.42.22 + uses: taiki-e/install-action@v2.42.26 with: tool: cargo-public-api From b52e77beb4e44db9438f037c498e2a6123e84739 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 02:00:33 +0100 Subject: [PATCH 057/144] build(deps): bump taiki-e/install-action from 2.42.26 to 2.42.33 (#3459) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.42.26 to 2.42.33. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.42.26...v2.42.33) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 69e14ebb3..b2be7d342 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.42.26 + uses: taiki-e/install-action@v2.42.33 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.42.26 + uses: taiki-e/install-action@v2.42.33 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 317577a56..434612877 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.42.26 + uses: taiki-e/install-action@v2.42.33 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.42.26 + uses: taiki-e/install-action@v2.42.33 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b6fa35559..4d412670b 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.42.26 + uses: taiki-e/install-action@v2.42.33 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 418432a16..2448d9a41 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -76,7 +76,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.42.26 + uses: taiki-e/install-action@v2.42.33 with: tool: just @@ -105,7 +105,7 @@ jobs: toolchain: nightly-2024-06-07 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.42.26 + uses: taiki-e/install-action@v2.42.33 with: tool: cargo-public-api From bb13f541800f8892edbfd34ad2e0cbafb05bf8d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 02:13:30 +0100 Subject: [PATCH 058/144] build(deps): bump taiki-e/install-action from 2.42.33 to 2.42.37 (#3464) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.42.33 to 2.42.37. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.42.33...v2.42.37) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index b2be7d342..a976e6a30 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.42.33 + uses: taiki-e/install-action@v2.42.37 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.42.33 + uses: taiki-e/install-action@v2.42.37 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 434612877..7b05e4ce4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.42.33 + uses: taiki-e/install-action@v2.42.37 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.42.33 + uses: taiki-e/install-action@v2.42.37 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 4d412670b..4d7fe348b 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.42.33 + uses: taiki-e/install-action@v2.42.37 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 2448d9a41..1c668477a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -76,7 +76,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.42.33 + uses: taiki-e/install-action@v2.42.37 with: tool: just @@ -105,7 +105,7 @@ jobs: toolchain: nightly-2024-06-07 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.42.33 + uses: taiki-e/install-action@v2.42.37 with: tool: cargo-public-api From 48aaf41638e86ef932a4003c8153d714f30d47bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 20:15:07 +0100 Subject: [PATCH 059/144] build(deps): bump taiki-e/install-action from 2.42.37 to 2.43.1 (#3465) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.42.37 to 2.43.1. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.42.37...v2.43.1) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index a976e6a30..7473fb96b 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.42.37 + uses: taiki-e/install-action@v2.43.1 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.42.37 + uses: taiki-e/install-action@v2.43.1 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7b05e4ce4..f3582606b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.42.37 + uses: taiki-e/install-action@v2.43.1 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.42.37 + uses: taiki-e/install-action@v2.43.1 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 4d7fe348b..876769a96 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.42.37 + uses: taiki-e/install-action@v2.43.1 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1c668477a..82f3858d1 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -76,7 +76,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.42.37 + uses: taiki-e/install-action@v2.43.1 with: tool: just @@ -105,7 +105,7 @@ jobs: toolchain: nightly-2024-06-07 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.42.37 + uses: taiki-e/install-action@v2.43.1 with: tool: cargo-public-api From 7360c732b3089fd4fcf51658b0411c9ca55fbc4e Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 1 Oct 2024 04:50:09 +0100 Subject: [PATCH 060/144] ci: downgrade parse-size for msrv --- justfile | 1 + 1 file changed, 1 insertion(+) diff --git a/justfile b/justfile index 5cd56b12e..2de247a6a 100644 --- a/justfile +++ b/justfile @@ -10,6 +10,7 @@ fmt: # Downgrade dev-dependencies necessary to run MSRV checks/tests. [private] downgrade-for-msrv: + cargo update -p=parse-size --precise=1.0.0 cargo update -p=clap --precise=4.4.18 msrv := ``` From d148e84aba0da0a0d10afb0ea818ec5782fff3ea Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 1 Oct 2024 05:01:32 +0100 Subject: [PATCH 061/144] ci: fix nightly toolchain requirements --- .github/workflows/lint.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 82f3858d1..87e32d7e8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -70,10 +70,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Install Rust (nightly-2024-05-01) + - name: Install Rust (nightly-2024-09-30) uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 with: - toolchain: nightly-2024-05-01 + toolchain: nightly-2024-09-30 - name: Install just uses: taiki-e/install-action@v2.43.1 @@ -86,7 +86,7 @@ jobs: tool: cargo-check-external-types - name: check external types - run: just check-external-types-all +nightly-2024-05-01 + run: just check-external-types-all +nightly-2024-09-30 public-api-diff: runs-on: ubuntu-latest @@ -99,10 +99,10 @@ jobs: - name: Checkout PR branch uses: actions/checkout@v4 - - name: Install Rust (nightly-2024-06-07) + - name: Install Rust (nightly-2024-09-30) uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 with: - toolchain: nightly-2024-06-07 + toolchain: nightly-2024-09-30 - name: Install cargo-public-api uses: taiki-e/install-action@v2.43.1 From 93edef8fee0cdcd7e1599d5bd116d65f56548c7b Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 1 Oct 2024 05:13:20 +0100 Subject: [PATCH 062/144] ci: disable check-external-types job --- .github/workflows/lint.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 87e32d7e8..68e8b7c77 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -66,14 +66,15 @@ jobs: run: cargo +nightly doc --no-deps --workspace --all-features check-external-types: + if: false # disable until https://github.com/awslabs/cargo-check-external-types/pull/177 is marged runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Install Rust (nightly-2024-09-30) + - name: Install Rust (nightly-2024-05-01) uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 with: - toolchain: nightly-2024-09-30 + toolchain: nightly-2024-05-01 - name: Install just uses: taiki-e/install-action@v2.43.1 @@ -86,7 +87,7 @@ jobs: tool: cargo-check-external-types - name: check external types - run: just check-external-types-all +nightly-2024-09-30 + run: just check-external-types-all +nightly-2024-05-01 public-api-diff: runs-on: ubuntu-latest From 9a685cabad9785ff8cd8baf3379e4bb9fa7b3ac0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 04:31:19 +0000 Subject: [PATCH 063/144] build(deps): bump taiki-e/install-action from 2.43.1 to 2.44.15 (#3476) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.43.1 to 2.44.15. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.43.1...v2.44.15) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 7473fb96b..f56e9b0c0 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.43.1 + uses: taiki-e/install-action@v2.44.15 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.43.1 + uses: taiki-e/install-action@v2.44.15 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3582606b..e2735cde4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.43.1 + uses: taiki-e/install-action@v2.44.15 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.43.1 + uses: taiki-e/install-action@v2.44.15 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 876769a96..1a4bef793 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.43.1 + uses: taiki-e/install-action@v2.44.15 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 68e8b7c77..738a405b5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.43.1 + uses: taiki-e/install-action@v2.44.15 with: tool: just @@ -106,7 +106,7 @@ jobs: toolchain: nightly-2024-09-30 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.43.1 + uses: taiki-e/install-action@v2.44.15 with: tool: cargo-public-api From d9d22825d44576512863a4abe8933fc67129ea83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 04:32:19 +0000 Subject: [PATCH 064/144] build(deps): bump actions-rust-lang/setup-rust-toolchain from 1.9.0 to 1.10.0 (#3471) build(deps): bump actions-rust-lang/setup-rust-toolchain Bumps [actions-rust-lang/setup-rust-toolchain](https://github.com/actions-rust-lang/setup-rust-toolchain) from 1.9.0 to 1.10.0. - [Release notes](https://github.com/actions-rust-lang/setup-rust-toolchain/releases) - [Changelog](https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions-rust-lang/setup-rust-toolchain/compare/v1.9.0...v1.10.0) --- updated-dependencies: - dependency-name: actions-rust-lang/setup-rust-toolchain dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 6 +++--- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 10 +++++----- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index f56e9b0c0..c0a2676a4 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -44,7 +44,7 @@ jobs: echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV - name: Install Rust (${{ matrix.version.name }}) - uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 with: toolchain: ${{ matrix.version.version }} @@ -80,7 +80,7 @@ jobs: uses: rui314/setup-mold@v1 - name: Install Rust - uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 - name: Install just, cargo-hack uses: taiki-e/install-action@v2.44.15 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e2735cde4..b3164b57b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,7 @@ jobs: uses: rui314/setup-mold@v1 - name: Install Rust (${{ matrix.version.name }}) - uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 with: toolchain: ${{ matrix.version.version }} @@ -92,7 +92,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust - uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 with: toolchain: nightly @@ -108,7 +108,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust (nightly) - uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 with: toolchain: nightly diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 1a4bef793..63797507c 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust (nightly) - uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 with: toolchain: nightly components: llvm-tools diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 738a405b5..7325e87fc 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust (nightly) - uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 with: toolchain: nightly components: rustfmt @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust - uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 with: components: clippy @@ -55,7 +55,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust (nightly) - uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 with: toolchain: nightly components: rust-docs @@ -72,7 +72,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust (nightly-2024-05-01) - uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 with: toolchain: nightly-2024-05-01 @@ -101,7 +101,7 @@ jobs: uses: actions/checkout@v4 - name: Install Rust (nightly-2024-09-30) - uses: actions-rust-lang/setup-rust-toolchain@v1.9.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 with: toolchain: nightly-2024-09-30 From 1c4e265a708b7ed600d96c8e03f3ac0e5b801502 Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" <2125584+bjones1@users.noreply.github.com> Date: Tue, 1 Oct 2024 02:08:34 -0500 Subject: [PATCH 065/144] Set `SO_REUSEADDR` only non-Windows platforms (#3473) * Fix: Per discussion in #2958, set `SO_REUSEADDR` only non-Windows platforms. Add: Tests confirming that only a single webserver instance may bind to a given address. * Clean: Lint. * Clean: another guess at making the formatter happy. * Clean: More cargo fmt fun. (Running cargo fmt locally doesn't help.) --------- Co-authored-by: Bryan A. Jones Co-authored-by: Rob Ede --- actix-web/CHANGES.md | 1 + actix-web/src/server.rs | 5 ++++- actix-web/tests/test_httpserver.rs | 30 ++++++++++++++++++++++++------ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 36e8b62dd..aca4ccfae 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -3,6 +3,7 @@ ## Unreleased - Minimum supported Rust version (MSRV) is now 1.75. +- On Windows platforms, produce an error when invoking `HttpServer::bind` on a socket that's already in use. See [issue 2958](https://github.com/actix/actix-web/issues/2958). ## 4.9.0 diff --git a/actix-web/src/server.rs b/actix-web/src/server.rs index d8519fb9e..4fbeb0186 100644 --- a/actix-web/src/server.rs +++ b/actix-web/src/server.rs @@ -1085,7 +1085,10 @@ fn create_tcp_listener(addr: net::SocketAddr, backlog: u32) -> io::Result Date: Mon, 7 Oct 2024 00:44:11 +0000 Subject: [PATCH 066/144] build(deps): bump taiki-e/install-action from 2.44.15 to 2.44.24 (#3480) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.44.15 to 2.44.24. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.44.15...v2.44.24) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index c0a2676a4..6ef1e89dd 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.44.15 + uses: taiki-e/install-action@v2.44.24 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.44.15 + uses: taiki-e/install-action@v2.44.24 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b3164b57b..63c628b88 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.44.15 + uses: taiki-e/install-action@v2.44.24 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.44.15 + uses: taiki-e/install-action@v2.44.24 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 63797507c..f48fbe5de 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.44.15 + uses: taiki-e/install-action@v2.44.24 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 7325e87fc..13d0fff0c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.44.15 + uses: taiki-e/install-action@v2.44.24 with: tool: just @@ -106,7 +106,7 @@ jobs: toolchain: nightly-2024-09-30 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.44.15 + uses: taiki-e/install-action@v2.44.24 with: tool: cargo-public-api From a0a6761bfe1c9f6b59e21082f69d05c81f905495 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 00:44:29 +0000 Subject: [PATCH 067/144] build(deps): bump actions-rust-lang/setup-rust-toolchain from 1.10.0 to 1.10.1 (#3479) build(deps): bump actions-rust-lang/setup-rust-toolchain Bumps [actions-rust-lang/setup-rust-toolchain](https://github.com/actions-rust-lang/setup-rust-toolchain) from 1.10.0 to 1.10.1. - [Release notes](https://github.com/actions-rust-lang/setup-rust-toolchain/releases) - [Changelog](https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions-rust-lang/setup-rust-toolchain/compare/v1.10.0...v1.10.1) --- updated-dependencies: - dependency-name: actions-rust-lang/setup-rust-toolchain dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 6 +++--- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 10 +++++----- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 6ef1e89dd..76cad6c17 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -44,7 +44,7 @@ jobs: echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV - name: Install Rust (${{ matrix.version.name }}) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 with: toolchain: ${{ matrix.version.version }} @@ -80,7 +80,7 @@ jobs: uses: rui314/setup-mold@v1 - name: Install Rust - uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack uses: taiki-e/install-action@v2.44.24 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 63c628b88..f30590708 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,7 @@ jobs: uses: rui314/setup-mold@v1 - name: Install Rust (${{ matrix.version.name }}) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 with: toolchain: ${{ matrix.version.version }} @@ -92,7 +92,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust - uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 with: toolchain: nightly @@ -108,7 +108,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust (nightly) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 with: toolchain: nightly diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index f48fbe5de..c64f104e7 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust (nightly) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 with: toolchain: nightly components: llvm-tools diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 13d0fff0c..ab9e3a8e4 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust (nightly) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 with: toolchain: nightly components: rustfmt @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust - uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 with: components: clippy @@ -55,7 +55,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust (nightly) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 with: toolchain: nightly components: rust-docs @@ -72,7 +72,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust (nightly-2024-05-01) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 with: toolchain: nightly-2024-05-01 @@ -101,7 +101,7 @@ jobs: uses: actions/checkout@v4 - name: Install Rust (nightly-2024-09-30) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.0 + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 with: toolchain: nightly-2024-09-30 From b7a0ff0a3a35741093a71381ac887246341bcbe1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 00:45:37 +0000 Subject: [PATCH 068/144] build(deps): bump codecov/codecov-action from 4.5.0 to 4.6.0 (#3481) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.5.0 to 4.6.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4.5.0...v4.6.0) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index c64f104e7..cb713608c 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -32,7 +32,7 @@ jobs: run: just test-coverage-codecov - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4.5.0 + uses: codecov/codecov-action@v4.6.0 with: files: codecov.json fail_ci_if_error: true From 049b49290d87859f1e6ac57374aa69387589ab90 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 7 Oct 2024 21:23:17 +0100 Subject: [PATCH 069/144] docs: fix long paragraph warning --- actix-web/src/http/header/content_disposition.rs | 15 ++++++++++----- justfile | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/actix-web/src/http/header/content_disposition.rs b/actix-web/src/http/header/content_disposition.rs index 592fc9f6a..ff3bb6761 100644 --- a/actix-web/src/http/header/content_disposition.rs +++ b/actix-web/src/http/header/content_disposition.rs @@ -206,11 +206,11 @@ impl DispositionParam { } } -/// A *Content-Disposition* header. It is compatible to be used either as -/// [a response header for the main body](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#as_a_response_header_for_the_main_body) -/// as (re)defined in [RFC 6266](https://datatracker.ietf.org/doc/html/rfc6266), or as -/// [a header for a multipart body](https://mdn.io/Content-Disposition#As_a_header_for_a_multipart_body) -/// as (re)defined in [RFC 7587](https://datatracker.ietf.org/doc/html/rfc7578). +/// `Content-Disposition` header. +/// +/// It is compatible to be used either as [a response header for the main body][use_main_body] +/// as (re)defined in [RFC 6266], or as [a header for a multipart body][use_multipart] as +/// (re)defined in [RFC 7587]. /// /// In a regular HTTP response, the *Content-Disposition* response header is a header indicating if /// the content is expected to be displayed *inline* in the browser, that is, as a Web page or as @@ -305,6 +305,11 @@ impl DispositionParam { /// change to match local file system conventions if applicable, and do not use directory path /// information that may be present. /// See [RFC 2183 §2.3](https://datatracker.ietf.org/doc/html/rfc2183#section-2.3). +/// +/// [use_main_body]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#as_a_response_header_for_the_main_body +/// [RFC 6266]: https://datatracker.ietf.org/doc/html/rfc6266 +/// [use_multipart]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#as_a_header_for_a_multipart_body +/// [RFC 7587]: https://datatracker.ietf.org/doc/html/rfc7578 #[derive(Debug, Clone, PartialEq, Eq)] pub struct ContentDisposition { /// The disposition type diff --git a/justfile b/justfile index 2de247a6a..4ab2796c0 100644 --- a/justfile +++ b/justfile @@ -73,6 +73,7 @@ test-coverage-lcov toolchain="": (test-coverage toolchain) # Document crates in workspace. doc *args: && doc-set-workspace-crates + rm -f "$(cargo metadata --format-version=1 | jq -r '.target_directory')/doc/crates.js" RUSTDOCFLAGS="--cfg=docsrs -Dwarnings" cargo +nightly doc --workspace {{ all_crate_features }} {{ args }} [private] From a5c2d0531b30bc6f80beba13dc2916b50e9787ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 20:40:14 +0000 Subject: [PATCH 070/144] build(deps): update brotli requirement from 6 to 7 (#3482) * build(deps): update brotli requirement from 6 to 7 Updates the requirements on [brotli](https://github.com/dropbox/rust-brotli) to permit the latest version. - [Release notes](https://github.com/dropbox/rust-brotli/releases) - [Commits](https://github.com/dropbox/rust-brotli/commits) --- updated-dependencies: - dependency-name: brotli dependency-type: direct:production ... Signed-off-by: dependabot[bot] * docs: update changelogs --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Rob Ede --- actix-http/CHANGES.md | 1 + actix-http/Cargo.toml | 2 +- actix-web/CHANGES.md | 3 ++- actix-web/Cargo.toml | 2 +- awc/CHANGES.md | 1 + awc/Cargo.toml | 2 +- 6 files changed, 7 insertions(+), 4 deletions(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 95b51254b..2bbcebc07 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -2,6 +2,7 @@ ## Unreleased +- Update `brotli` dependency to `7`. - Minimum supported Rust version (MSRV) is now 1.75. ## 3.9.0 diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index f910276f1..3f81ea9f0 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -139,7 +139,7 @@ sha1 = { version = "0.10", optional = true } actix-tls = { version = "3.4", default-features = false, optional = true } # compress-* -brotli = { version = "6", optional = true } +brotli = { version = "7", optional = true } flate2 = { version = "1.0.13", optional = true } zstd = { version = "0.13", optional = true } diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index aca4ccfae..cee14dc4b 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -2,8 +2,9 @@ ## Unreleased +- On Windows, an error is now returned from `HttpServer::bind()` (or TLS variants) when binding to a socket that's already in use. +- Update `brotli` dependency to `7`. - Minimum supported Rust version (MSRV) is now 1.75. -- On Windows platforms, produce an error when invoking `HttpServer::bind` on a socket that's already in use. See [issue 2958](https://github.com/actix/actix-web/issues/2958). ## 4.9.0 diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index f97eab7c9..ab70bf07c 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -172,7 +172,7 @@ actix-files = "0.6" actix-test = { version = "0.1", features = ["openssl", "rustls-0_23"] } awc = { version = "3", features = ["openssl"] } -brotli = "6" +brotli = "7" const-str = "0.5" core_affinity = "0.8" criterion = { version = "0.5", features = ["html_reports"] } diff --git a/awc/CHANGES.md b/awc/CHANGES.md index 11cb150ab..8a2a1ec43 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -2,6 +2,7 @@ ## Unreleased +- Update `brotli` dependency to `7`. - Prevent panics on connection pool drop when Tokio runtime is shutdown early. - Minimum supported Rust version (MSRV) is now 1.75. diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 849ca571f..c09f32ac8 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -141,7 +141,7 @@ actix-tls = { version = "3.4", features = ["openssl", "rustls-0_23"] } actix-utils = "3" actix-web = { version = "4", features = ["openssl"] } -brotli = "6" +brotli = "7" const-str = "0.5" env_logger = "0.11" flate2 = "1.0.13" From 3849cdaa6c525501bf5666a34b429f46dbb9529d Mon Sep 17 00:00:00 2001 From: Luca Iachini <77624486+luca-iachini@users.noreply.github.com> Date: Mon, 7 Oct 2024 23:16:10 +0200 Subject: [PATCH 071/144] Improve worker_max_blocking_threads documentation (#3477) * improve worker_max_blocking_threads doc * docs: tweak doc --------- Co-authored-by: Rob Ede --- actix-web/src/server.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-web/src/server.rs b/actix-web/src/server.rs index 4fbeb0186..1ea4de4ca 100644 --- a/actix-web/src/server.rs +++ b/actix-web/src/server.rs @@ -193,7 +193,7 @@ where /// /// One thread pool is set up **per worker**; not shared across workers. /// - /// By default set to 512 divided by the number of workers. + /// By default, set to 512 divided by [available parallelism](std::thread::available_parallelism()). pub fn worker_max_blocking_threads(mut self, num: usize) -> Self { self.builder = self.builder.worker_max_blocking_threads(num); self From 27c07f122bafcd26a9ef688f0689340f8718294c Mon Sep 17 00:00:00 2001 From: Durairaj Subramaniam Date: Mon, 7 Oct 2024 23:03:38 +0100 Subject: [PATCH 072/144] fix: service macro comments (#3474) * fix: service macro comments #3472 * test: service macro comments #3472 * fix: add case for empty tuple seperately * doc: add case for empty tuple seperately * test: move test_services into lib --------- Co-authored-by: Rob Ede --- actix-web/src/service.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/actix-web/src/service.rs b/actix-web/src/service.rs index a1672eba2..6c7f6f5c8 100644 --- a/actix-web/src/service.rs +++ b/actix-web/src/service.rs @@ -662,6 +662,7 @@ where /// ``` #[macro_export] macro_rules! services { + () => {()}; ($($x:expr),+ $(,)?) => { ($($x,)+) } @@ -870,4 +871,40 @@ mod tests { let req = test::TestRequest::default().to_request(); let _res = test::call_service(&app, req).await; } + + #[test] + fn define_services_macro_with_multiple_arguments() { + let result = services!(1, 2, 3); + assert_eq!(result, (1, 2, 3)); + } + + #[test] + fn define_services_macro_with_single_argument() { + let result = services!(1); + assert_eq!(result, (1,)); + } + + #[test] + fn define_services_macro_with_no_arguments() { + let result = services!(); + let () = result; + } + + #[test] + fn define_services_macro_with_trailing_comma() { + let result = services!(1, 2, 3,); + assert_eq!(result, (1, 2, 3)); + } + + #[test] + fn define_services_macro_with_comments_in_arguments() { + let result = services!( + 1, // First comment + 2, // Second comment + 3 // Third comment + ); + + // Assert that comments are ignored and it correctly returns a tuple. + assert_eq!(result, (1, 2, 3)); + } } From 4c05c87b11a9a4264d668f78e0c086bfb396a313 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 20:07:05 +0200 Subject: [PATCH 073/144] build(deps): bump taiki-e/install-action from 2.44.24 to 2.44.34 (#3485) --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 76cad6c17..3b3bbee95 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.44.24 + uses: taiki-e/install-action@v2.44.34 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.44.24 + uses: taiki-e/install-action@v2.44.34 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f30590708..c17afd635 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.44.24 + uses: taiki-e/install-action@v2.44.34 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.44.24 + uses: taiki-e/install-action@v2.44.34 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index cb713608c..85aee1c4f 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.44.24 + uses: taiki-e/install-action@v2.44.34 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ab9e3a8e4..a889da2bb 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.44.24 + uses: taiki-e/install-action@v2.44.34 with: tool: just @@ -106,7 +106,7 @@ jobs: toolchain: nightly-2024-09-30 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.44.24 + uses: taiki-e/install-action@v2.44.34 with: tool: cargo-public-api From ec05381f6f8644ff97880b000b592b58e5a23c2e Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 15 Oct 2024 07:00:04 +0100 Subject: [PATCH 074/144] feat: add CLEAR_SITE_DATA header --- actix-http/CHANGES.md | 6 ++++++ actix-http/src/header/common.rs | 8 ++++++++ actix-http/src/header/mod.rs | 6 +++--- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 2bbcebc07..982add26a 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -2,6 +2,12 @@ ## Unreleased +### Added + +- Add `header::CLEAR_SITE_DATA` constant. + +### Changed + - Update `brotli` dependency to `7`. - Minimum supported Rust version (MSRV) is now 1.75. diff --git a/actix-http/src/header/common.rs b/actix-http/src/header/common.rs index 6942dc26a..ebdd6708f 100644 --- a/actix-http/src/header/common.rs +++ b/actix-http/src/header/common.rs @@ -18,6 +18,14 @@ pub const CACHE_STATUS: HeaderName = HeaderName::from_static("cache-status"); // TODO(breaking): replace with http's version pub const CDN_CACHE_CONTROL: HeaderName = HeaderName::from_static("cdn-cache-control"); +/// Response header field that sends a signal to the user agent that it ought to remove all data of +/// a certain set of types. +/// +/// See the [W3C Clear-Site-Data spec] for full semantics. +/// +/// [W3C Clear-Site-Data spec]: https://www.w3.org/TR/clear-site-data/#header +pub const CLEAR_SITE_DATA: HeaderName = HeaderName::from_static("clear-site-data"); + /// Response header that prevents a document from loading any cross-origin resources that don't /// explicitly grant the document permission (using [CORP] or [CORS]). /// diff --git a/actix-http/src/header/mod.rs b/actix-http/src/header/mod.rs index 79f91afef..b22c43f76 100644 --- a/actix-http/src/header/mod.rs +++ b/actix-http/src/header/mod.rs @@ -42,9 +42,9 @@ 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, + CACHE_STATUS, CDN_CACHE_CONTROL, CLEAR_SITE_DATA, 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, From 03c65d93e54ee9cf473bcd7112b98ae584dbe41f Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 15 Oct 2024 08:35:39 +0100 Subject: [PATCH 075/144] docs: add from_fn examples --- actix-web/Cargo.toml | 1 + actix-web/examples/from_fn.rs | 128 ++++++++++++++++++++++++++++++++++ justfile | 3 + 3 files changed, 132 insertions(+) create mode 100644 actix-web/examples/from_fn.rs diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index ab70bf07c..9b10f14b1 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -163,6 +163,7 @@ serde = "1.0" serde_json = "1.0" serde_urlencoded = "0.7" smallvec = "1.6.1" +tracing = "0.1.30" socket2 = "0.5" time = { version = "0.3", default-features = false, features = ["formatting"] } url = "2.1" diff --git a/actix-web/examples/from_fn.rs b/actix-web/examples/from_fn.rs new file mode 100644 index 000000000..a6006d23c --- /dev/null +++ b/actix-web/examples/from_fn.rs @@ -0,0 +1,128 @@ +//! Shows a few of ways to use the `from_fn` middleware. + +use std::{collections::HashMap, io, rc::Rc, time::Duration}; + +use actix_web::{ + body::MessageBody, + dev::{Service, ServiceRequest, ServiceResponse, Transform}, + http::header::{self, HeaderValue, Range}, + middleware::{from_fn, Logger, Next}, + web::{self, Header, Query}, + App, Error, HttpResponse, HttpServer, +}; +use tracing::info; + +async fn noop(req: ServiceRequest, next: Next) -> Result, Error> { + next.call(req).await +} + +async fn print_range_header( + range_header: Option>, + req: ServiceRequest, + next: Next, +) -> Result, Error> { + if let Some(Header(range)) = range_header { + println!("Range: {range}"); + } else { + println!("No Range header"); + } + + next.call(req).await +} + +async fn mutate_body_type( + req: ServiceRequest, + next: Next, +) -> Result, Error> { + let res = next.call(req).await?; + Ok(res.map_into_left_body::<()>()) +} + +async fn mutate_body_type_with_extractors( + string_body: String, + query: Query>, + req: ServiceRequest, + next: Next, +) -> Result, Error> { + println!("body is: {string_body}"); + println!("query string: {query:?}"); + + let res = next.call(req).await?; + + Ok(res.map_body(move |_, _| string_body)) +} + +async fn timeout_10secs( + req: ServiceRequest, + next: Next, +) -> Result, Error> { + match tokio::time::timeout(Duration::from_secs(10), next.call(req)).await { + Ok(res) => res, + Err(_err) => Err(actix_web::error::ErrorRequestTimeout("")), + } +} + +struct MyMw(bool); + +impl MyMw { + async fn mw_cb( + &self, + req: ServiceRequest, + next: Next, + ) -> Result, Error> { + let mut res = match self.0 { + true => req.into_response("short-circuited").map_into_right_body(), + false => next.call(req).await?.map_into_left_body(), + }; + + res.headers_mut() + .insert(header::WARNING, HeaderValue::from_static("42")); + + Ok(res) + } + + pub fn into_middleware( + self, + ) -> impl Transform< + S, + ServiceRequest, + Response = ServiceResponse, + Error = Error, + InitError = (), + > + where + S: Service, Error = Error> + 'static, + B: MessageBody + 'static, + { + let this = Rc::new(self); + from_fn(move |req, next| { + let this = Rc::clone(&this); + async move { Self::mw_cb(&this, req, next).await } + }) + } +} + +#[actix_web::main] +async fn main() -> io::Result<()> { + env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); + + let bind = ("127.0.0.1", 8080); + info!("staring server at http://{}:{}", &bind.0, &bind.1); + + HttpServer::new(|| { + App::new() + .wrap(from_fn(noop)) + .wrap(from_fn(print_range_header)) + .wrap(from_fn(mutate_body_type)) + .wrap(from_fn(mutate_body_type_with_extractors)) + .wrap(from_fn(timeout_10secs)) + // switch bool to true to observe early response + .wrap(MyMw(false).into_middleware()) + .wrap(Logger::default()) + .default_service(web::to(HttpResponse::Ok)) + }) + .workers(1) + .bind(bind)? + .run() + .await +} diff --git a/justfile b/justfile index 4ab2796c0..a970b62e7 100644 --- a/justfile +++ b/justfile @@ -36,6 +36,9 @@ check-min: check-default: cargo hack --workspace check +# Run Clippy over workspace. +check toolchain="": && (clippy toolchain) + # Run Clippy over workspace. clippy toolchain="": cargo {{ toolchain }} clippy --workspace --all-targets {{ all_crate_features }} From 568bffeb58db083d63d887bd0f1cceaa0464d1c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 13:19:31 +0100 Subject: [PATCH 076/144] build(deps): bump taiki-e/install-action from 2.44.34 to 2.44.43 (#3488) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.44.34 to 2.44.43. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.44.34...v2.44.43) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 3b3bbee95..e8c260921 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.44.34 + uses: taiki-e/install-action@v2.44.43 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.44.34 + uses: taiki-e/install-action@v2.44.43 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c17afd635..522d20014 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.44.34 + uses: taiki-e/install-action@v2.44.43 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.44.34 + uses: taiki-e/install-action@v2.44.43 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 85aee1c4f..5615ecefe 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.44.34 + uses: taiki-e/install-action@v2.44.43 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a889da2bb..1b2c5a24d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.44.34 + uses: taiki-e/install-action@v2.44.43 with: tool: just @@ -106,7 +106,7 @@ jobs: toolchain: nightly-2024-09-30 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.44.34 + uses: taiki-e/install-action@v2.44.43 with: tool: cargo-public-api From ef977055fcba8aa6b9fa42686764c87c2d701caf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 21:48:34 +0000 Subject: [PATCH 077/144] build(deps): bump taiki-e/install-action from 2.44.43 to 2.44.60 (#3494) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index e8c260921..f0ed2173b 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.44.43 + uses: taiki-e/install-action@v2.44.60 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.44.43 + uses: taiki-e/install-action@v2.44.60 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 522d20014..b04213dc3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.44.43 + uses: taiki-e/install-action@v2.44.60 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.44.43 + uses: taiki-e/install-action@v2.44.60 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 5615ecefe..1d4e580c9 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.44.43 + uses: taiki-e/install-action@v2.44.60 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1b2c5a24d..94380aee5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: nightly-2024-05-01 - name: Install just - uses: taiki-e/install-action@v2.44.43 + uses: taiki-e/install-action@v2.44.60 with: tool: just @@ -106,7 +106,7 @@ jobs: toolchain: nightly-2024-09-30 - name: Install cargo-public-api - uses: taiki-e/install-action@v2.44.43 + uses: taiki-e/install-action@v2.44.60 with: tool: cargo-public-api From 6771be20b39a14be3d55fdb08f16a67521a644cc Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 14 Nov 2024 09:29:00 +0100 Subject: [PATCH 078/144] ci: nightly rust versions in variables (#3501) --- .github/workflows/lint.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 94380aee5..825bee1c9 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -66,15 +66,15 @@ jobs: run: cargo +nightly doc --no-deps --workspace --all-features check-external-types: - if: false # disable until https://github.com/awslabs/cargo-check-external-types/pull/177 is marged + if: false # rustdoc mismatch currently runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Install Rust (nightly-2024-05-01) + - name: Install Rust (${{ vars.RUST_VERSION_EXTERNAL_TYPES }}) uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 with: - toolchain: nightly-2024-05-01 + toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just uses: taiki-e/install-action@v2.44.60 @@ -87,7 +87,7 @@ jobs: tool: cargo-check-external-types - name: check external types - run: just check-external-types-all +nightly-2024-05-01 + run: just check-external-types-all +${{ vars.RUST_VERSION_EXTERNAL_TYPES }} public-api-diff: runs-on: ubuntu-latest @@ -100,10 +100,10 @@ jobs: - name: Checkout PR branch uses: actions/checkout@v4 - - name: Install Rust (nightly-2024-09-30) + - name: Install Rust (${{ vars.RUST_VERSION_API_DIFF }}) uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 with: - toolchain: nightly-2024-09-30 + toolchain: ${{ vars.RUST_VERSION_API_DIFF }} - name: Install cargo-public-api uses: taiki-e/install-action@v2.44.60 From 9d849c19a59e339def1d5d81fe62ab5a0cd7f147 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 08:55:07 +0000 Subject: [PATCH 079/144] build(deps): bump taiki-e/install-action from 2.44.60 to 2.44.69 (#3502) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.44.60 to 2.44.69. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.44.60...v2.44.69) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index f0ed2173b..1e1ab4610 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.44.60 + uses: taiki-e/install-action@v2.44.69 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.44.60 + uses: taiki-e/install-action@v2.44.69 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b04213dc3..6bfa276c4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.44.60 + uses: taiki-e/install-action@v2.44.69 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.44.60 + uses: taiki-e/install-action@v2.44.69 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 1d4e580c9..1dc126c59 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.44.60 + uses: taiki-e/install-action@v2.44.69 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 825bee1c9..2059aefe8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.44.60 + uses: taiki-e/install-action@v2.44.69 with: tool: just @@ -106,7 +106,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_API_DIFF }} - name: Install cargo-public-api - uses: taiki-e/install-action@v2.44.60 + uses: taiki-e/install-action@v2.44.69 with: tool: cargo-public-api From eff2a20c9046e7e44ac037a281b32753901db02b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 11:26:12 +0000 Subject: [PATCH 080/144] build(deps): bump taiki-e/install-action from 2.44.69 to 2.44.71 (#3505) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.44.69 to 2.44.71. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.44.69...v2.44.71) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 1e1ab4610..fe1aa73dc 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.44.69 + uses: taiki-e/install-action@v2.44.71 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.44.69 + uses: taiki-e/install-action@v2.44.71 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6bfa276c4..c4e90769c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.44.69 + uses: taiki-e/install-action@v2.44.71 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.44.69 + uses: taiki-e/install-action@v2.44.71 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 1dc126c59..da1f0a470 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.44.69 + uses: taiki-e/install-action@v2.44.71 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 2059aefe8..5ba3ae8d3 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.44.69 + uses: taiki-e/install-action@v2.44.71 with: tool: just @@ -106,7 +106,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_API_DIFF }} - name: Install cargo-public-api - uses: taiki-e/install-action@v2.44.69 + uses: taiki-e/install-action@v2.44.71 with: tool: cargo-public-api From 2132c95b01c903208ace4388836dfe6489bd58cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 11:26:30 +0000 Subject: [PATCH 081/144] build(deps): bump codecov/codecov-action from 4.6.0 to 5.0.2 (#3504) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.6.0 to 5.0.2. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4.6.0...v5.0.2) --- updated-dependencies: - dependency-name: codecov/codecov-action 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/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index da1f0a470..a11fb0b20 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -32,7 +32,7 @@ jobs: run: just test-coverage-codecov - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4.6.0 + uses: codecov/codecov-action@v5.0.2 with: files: codecov.json fail_ci_if_error: true From 836c75064b1f5e91e8ecd9cba8df879d5d24dff8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 00:42:41 +0000 Subject: [PATCH 082/144] build(deps): bump codecov/codecov-action from 5.0.2 to 5.0.7 (#3508) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.0.2 to 5.0.7. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v5.0.2...v5.0.7) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index a11fb0b20..80eabac4b 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -32,7 +32,7 @@ jobs: run: just test-coverage-codecov - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.0.2 + uses: codecov/codecov-action@v5.0.7 with: files: codecov.json fail_ci_if_error: true From 002c1b5a196ba38ccf59a2d76927d8f4d8a05263 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 00:43:45 +0000 Subject: [PATCH 083/144] build(deps): bump taiki-e/install-action from 2.44.71 to 2.45.6 (#3509) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.44.71 to 2.45.6. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.44.71...v2.45.6) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index fe1aa73dc..059c22824 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.44.71 + uses: taiki-e/install-action@v2.45.6 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.44.71 + uses: taiki-e/install-action@v2.45.6 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c4e90769c..8ee35f636 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.44.71 + uses: taiki-e/install-action@v2.45.6 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.44.71 + uses: taiki-e/install-action@v2.45.6 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 80eabac4b..97437cc8e 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.44.71 + uses: taiki-e/install-action@v2.45.6 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5ba3ae8d3..ef3f30b1c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.44.71 + uses: taiki-e/install-action@v2.45.6 with: tool: just @@ -106,7 +106,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_API_DIFF }} - name: Install cargo-public-api - uses: taiki-e/install-action@v2.44.71 + uses: taiki-e/install-action@v2.45.6 with: tool: cargo-public-api From 8115c818c15792a6edab01f939f049b6c0e38792 Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Tue, 10 Dec 2024 17:11:12 +0100 Subject: [PATCH 084/144] Fix continuous integration (#3526) fix(ci): downgrade divan to 0.1.15 on msrv --- justfile | 1 + 1 file changed, 1 insertion(+) diff --git a/justfile b/justfile index a970b62e7..0a69a1e89 100644 --- a/justfile +++ b/justfile @@ -12,6 +12,7 @@ fmt: downgrade-for-msrv: cargo update -p=parse-size --precise=1.0.0 cargo update -p=clap --precise=4.4.18 + cargo update -p=divan --precise=0.1.15 msrv := ``` cargo metadata --format-version=1 \ From a908afa56b2e38f0684ee1233daf62e4c8d78c2f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Dec 2024 09:22:53 +0000 Subject: [PATCH 085/144] build(deps): bump taiki-e/install-action from 2.45.6 to 2.46.20 (#3537) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.45.6 to 2.46.20. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.45.6...v2.46.20) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 059c22824..32a126ae7 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.45.6 + uses: taiki-e/install-action@v2.46.20 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.45.6 + uses: taiki-e/install-action@v2.46.20 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8ee35f636..89cc9bb73 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.45.6 + uses: taiki-e/install-action@v2.46.20 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.45.6 + uses: taiki-e/install-action@v2.46.20 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 97437cc8e..bf32781e2 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.45.6 + uses: taiki-e/install-action@v2.46.20 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ef3f30b1c..1281ff107 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.45.6 + uses: taiki-e/install-action@v2.46.20 with: tool: just @@ -106,7 +106,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_API_DIFF }} - name: Install cargo-public-api - uses: taiki-e/install-action@v2.45.6 + uses: taiki-e/install-action@v2.46.20 with: tool: cargo-public-api From d8566da66f25ece1c176ad9dc52002c0451a1176 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Dec 2024 22:54:53 +0000 Subject: [PATCH 086/144] build(deps): bump codecov/codecov-action from 5.0.7 to 5.1.2 (#3536) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.0.7 to 5.1.2. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v5.0.7...v5.1.2) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index bf32781e2..b8efdb938 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -32,7 +32,7 @@ jobs: run: just test-coverage-codecov - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.0.7 + uses: codecov/codecov-action@v5.1.2 with: files: codecov.json fail_ci_if_error: true From 472dbca64e00432a136a60b3e7949ec615e3120e Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 29 Dec 2024 14:29:29 +0000 Subject: [PATCH 087/144] ci: remove public-api-diff job --- .github/workflows/lint.yml | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1281ff107..e77723d58 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -88,30 +88,3 @@ jobs: - name: check external types run: just check-external-types-all +${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - - public-api-diff: - runs-on: ubuntu-latest - steps: - - name: Checkout main branch - uses: actions/checkout@v4 - with: - ref: ${{ github.base_ref }} - - - name: Checkout PR branch - uses: actions/checkout@v4 - - - name: Install Rust (${{ vars.RUST_VERSION_API_DIFF }}) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - with: - toolchain: ${{ vars.RUST_VERSION_API_DIFF }} - - - name: Install cargo-public-api - uses: taiki-e/install-action@v2.46.20 - with: - tool: cargo-public-api - - - name: Generate API diff - run: | - for f in $(find -mindepth 2 -maxdepth 2 -name Cargo.toml); do - cargo public-api --manifest-path "$f" --simplified diff ${{ github.event.pull_request.base.sha }}..${{ github.sha }} - done From 34327bd2217bdccdff030198e9d5aa0d6e3a8e82 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 29 Dec 2024 15:03:43 +0000 Subject: [PATCH 088/144] chore: address clippy warnings --- actix-http/src/header/map.rs | 2 +- actix-http/src/helpers.rs | 2 +- actix-http/src/http_message.rs | 2 +- actix-router/src/resource_path.rs | 2 +- actix-web-codegen/tests/routes.rs | 2 +- actix-web/src/helpers.rs | 2 +- actix-web/src/middleware/logger.rs | 2 +- actix-web/src/types/json.rs | 2 +- awc/src/client/connector.rs | 15 ++++++++++----- awc/src/ws.rs | 2 +- 10 files changed, 19 insertions(+), 14 deletions(-) diff --git a/actix-http/src/header/map.rs b/actix-http/src/header/map.rs index 6da01d2c0..7be282b11 100644 --- a/actix-http/src/header/map.rs +++ b/actix-http/src/header/map.rs @@ -830,7 +830,7 @@ impl<'a> Drain<'a> { } } -impl<'a> Iterator for Drain<'a> { +impl Iterator for Drain<'_> { type Item = (Option, HeaderValue); fn next(&mut self) -> Option { diff --git a/actix-http/src/helpers.rs b/actix-http/src/helpers.rs index 7f28018e7..61175bdc9 100644 --- a/actix-http/src/helpers.rs +++ b/actix-http/src/helpers.rs @@ -61,7 +61,7 @@ pub fn write_content_length(n: u64, buf: &mut B, camel_case: bool) { /// perform a remaining length check before writing. pub(crate) struct MutWriter<'a, B>(pub(crate) &'a mut B); -impl<'a, B> io::Write for MutWriter<'a, B> +impl io::Write for MutWriter<'_, B> where B: BufMut, { diff --git a/actix-http/src/http_message.rs b/actix-http/src/http_message.rs index 3ba9ef752..2800f40ba 100644 --- a/actix-http/src/http_message.rs +++ b/actix-http/src/http_message.rs @@ -103,7 +103,7 @@ pub trait HttpMessage: Sized { } } -impl<'a, T> HttpMessage for &'a mut T +impl HttpMessage for &mut T where T: HttpMessage, { diff --git a/actix-router/src/resource_path.rs b/actix-router/src/resource_path.rs index 45948aa2a..610dc344d 100644 --- a/actix-router/src/resource_path.rs +++ b/actix-router/src/resource_path.rs @@ -19,7 +19,7 @@ impl ResourcePath for String { } } -impl<'a> ResourcePath for &'a str { +impl ResourcePath for &str { fn path(&self) -> &str { self } diff --git a/actix-web-codegen/tests/routes.rs b/actix-web-codegen/tests/routes.rs index a6e606871..1443f9a75 100644 --- a/actix-web-codegen/tests/routes.rs +++ b/actix-web-codegen/tests/routes.rs @@ -136,7 +136,7 @@ async fn routes_overlapping_inaccessible_test(req: HttpRequest) -> impl Responde } #[get("/custom_resource_name", name = "custom")] -async fn custom_resource_name_test<'a>(req: HttpRequest) -> impl Responder { +async fn custom_resource_name_test(req: HttpRequest) -> impl Responder { assert!(req.url_for_static("custom").is_ok()); assert!(req.url_for_static("custom_resource_name_test").is_err()); HttpResponse::Ok() diff --git a/actix-web/src/helpers.rs b/actix-web/src/helpers.rs index 1d2679fce..c7b33a083 100644 --- a/actix-web/src/helpers.rs +++ b/actix-web/src/helpers.rs @@ -10,7 +10,7 @@ use bytes::BufMut; /// perform a remaining length check before writing. pub(crate) struct MutWriter<'a, B>(pub(crate) &'a mut B); -impl<'a, B> io::Write for MutWriter<'a, B> +impl io::Write for MutWriter<'_, B> where B: BufMut, { diff --git a/actix-web/src/middleware/logger.rs b/actix-web/src/middleware/logger.rs index 21986baae..125925603 100644 --- a/actix-web/src/middleware/logger.rs +++ b/actix-web/src/middleware/logger.rs @@ -704,7 +704,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>); -impl<'a> fmt::Display for FormatDisplay<'a> { +impl fmt::Display for FormatDisplay<'_> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { (self.0)(fmt) } diff --git a/actix-web/src/types/json.rs b/actix-web/src/types/json.rs index 51a322e43..22ed624c3 100644 --- a/actix-web/src/types/json.rs +++ b/actix-web/src/types/json.rs @@ -332,7 +332,7 @@ impl JsonBody { (true, Ok(Some(mime))) => { mime.subtype() == mime::JSON || mime.suffix() == Some(mime::JSON) - || ctype_fn.map_or(false, |predicate| predicate(mime)) + || ctype_fn.is_some_and(|predicate| predicate(mime)) } // if content-type is expected but not parsable as mime type, bail diff --git a/awc/src/client/connector.rs b/awc/src/client/connector.rs index f3d443070..15dc34557 100644 --- a/awc/src/client/connector.rs +++ b/awc/src/client/connector.rs @@ -511,7 +511,8 @@ where let h2 = sock .ssl() .selected_alpn_protocol() - .map_or(false, |protos| protos.windows(2).any(|w| w == H2)); + .is_some_and(|protos| protos.windows(2).any(|w| w == H2)); + if h2 { (Box::new(sock), Protocol::Http2) } else { @@ -550,7 +551,8 @@ where .get_ref() .1 .alpn_protocol() - .map_or(false, |protos| protos.windows(2).any(|w| w == H2)); + .is_some_and(|protos| protos.windows(2).any(|w| w == H2)); + if h2 { (Box::new(sock), Protocol::Http2) } else { @@ -584,7 +586,8 @@ where .get_ref() .1 .alpn_protocol() - .map_or(false, |protos| protos.windows(2).any(|w| w == H2)); + .is_some_and(|protos| protos.windows(2).any(|w| w == H2)); + if h2 { (Box::new(sock), Protocol::Http2) } else { @@ -621,7 +624,8 @@ where .get_ref() .1 .alpn_protocol() - .map_or(false, |protos| protos.windows(2).any(|w| w == H2)); + .is_some_and(|protos| protos.windows(2).any(|w| w == H2)); + if h2 { (Box::new(sock), Protocol::Http2) } else { @@ -655,7 +659,8 @@ where .get_ref() .1 .alpn_protocol() - .map_or(false, |protos| protos.windows(2).any(|w| w == H2)); + .is_some_and(|protos| protos.windows(2).any(|w| w == H2)); + if h2 { (Box::new(sock), Protocol::Http2) } else { diff --git a/awc/src/ws.rs b/awc/src/ws.rs index 760331e9d..b05063d22 100644 --- a/awc/src/ws.rs +++ b/awc/src/ws.rs @@ -444,7 +444,7 @@ struct Host<'a> { port: Option>, } -impl<'a> fmt::Display for Host<'a> { +impl fmt::Display for Host<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.hostname)?; From ee6a6ec03e80041783d64cbd00b486fb36272f79 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 29 Dec 2024 15:17:18 +0000 Subject: [PATCH 089/144] docs: add tls to awc example --- awc/Cargo.toml | 6 +++--- awc/examples/client.rs | 30 ++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/awc/Cargo.toml b/awc/Cargo.toml index c09f32ac8..d6626f906 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -153,9 +153,9 @@ tokio = { version = "1.24.2", features = ["rt-multi-thread", "macros"] } zstd = "0.13" tls-rustls-0_23 = { package = "rustls", version = "0.23" } # add rustls 0.23 with default features to make aws_lc_rs work in tests -[lints] -workspace = true - [[example]] name = "client" required-features = ["rustls-0_23-webpki-roots"] + +[lints] +workspace = true diff --git a/awc/examples/client.rs b/awc/examples/client.rs index 41626315c..b6eb919c7 100644 --- a/awc/examples/client.rs +++ b/awc/examples/client.rs @@ -1,25 +1,39 @@ -use std::error::Error as StdError; +//! Demonstrates construction and usage of a TLS-capable HTTP client. + +extern crate tls_rustls_0_23 as rustls; + +use std::{error::Error as StdError, sync::Arc}; + +use actix_tls::connect::rustls_0_23::webpki_roots_cert_store; +use rustls::ClientConfig; -/// If we want to make requests to addresses starting with `https`, we need to enable the rustls feature of awc -/// `awc = { version = "3.5.0", features = ["rustls"] }` #[actix_rt::main] async fn main() -> Result<(), Box> { env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); - // construct request builder - let client = awc::Client::new(); + let mut config = ClientConfig::builder() + .with_root_certificates(webpki_roots_cert_store()) + .with_no_client_auth(); + + let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; + config.alpn_protocols = protos; + + // construct request builder with TLS support + let client = awc::Client::builder() + .connector(awc::Connector::new().rustls_0_23(Arc::new(config))) + .finish(); // configure request let request = client .get("https://www.rust-lang.org/") - .append_header(("User-Agent", "Actix-web")); + .append_header(("User-Agent", "awc/3.0")); - println!("Request: {:?}", request); + println!("Request: {request:?}"); let mut response = request.send().await?; // server response head - println!("Response: {:?}", response); + println!("Response: {response:?}"); // read response body let body = response.body().await?; From 5b60d81f57aaede263f2029c2790d596e3668795 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 29 Dec 2024 15:18:40 +0000 Subject: [PATCH 090/144] docs: fix changelog --- actix-web/README.md | 2 +- justfile | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/actix-web/README.md b/actix-web/README.md index e5e412c85..70f167dfd 100644 --- a/actix-web/README.md +++ b/actix-web/README.md @@ -14,7 +14,7 @@ [![Dependency Status](https://deps.rs/crate/actix-web/4.9.0/status.svg)](https://deps.rs/crate/actix-web/4.9.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) +[![codecov](https://codecov.io/gh/actix/actix-web/graph/badge.svg?token=dSwOnp9QCv)](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) diff --git a/justfile b/justfile index 0a69a1e89..3a5e417fd 100644 --- a/justfile +++ b/justfile @@ -51,8 +51,8 @@ test-msrv: downgrade-for-msrv (test msrv_rustup) test toolchain="": cargo {{ toolchain }} test --lib --tests -p=actix-web-codegen --all-features cargo {{ toolchain }} test --lib --tests -p=actix-multipart-derive --all-features - cargo {{ toolchain }} nextest run -p=actix-router --no-default-features - cargo {{ toolchain }} nextest run --workspace --exclude=actix-web-codegen --exclude=actix-multipart-derive {{ all_crate_features }} --filter-expr="not test(test_reading_deflate_encoding_large_random_rustls)" + cargo {{ toolchain }} nextest run --no-tests=warn -p=actix-router --no-default-features + cargo {{ toolchain }} nextest run --no-tests=warn --workspace --exclude=actix-web-codegen --exclude=actix-multipart-derive {{ all_crate_features }} --filter-expr="not test(test_reading_deflate_encoding_large_random_rustls)" # Test workspace docs. test-docs toolchain="": && doc @@ -64,7 +64,7 @@ test-all toolchain="": (test toolchain) (test-docs toolchain) # Test workspace and collect coverage info. [private] test-coverage toolchain="": - cargo {{ toolchain }} llvm-cov nextest --no-report {{ all_crate_features }} + cargo {{ toolchain }} llvm-cov nextest --no-tests=warn --no-report {{ all_crate_features }} cargo {{ toolchain }} llvm-cov --doc --no-report {{ all_crate_features }} # Test workspace and generate Codecov report. From 8200e4ee82ad07dbeccbb96ba70ae173a4222927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?On=C3=A8?= <43485962+c-git@users.noreply.github.com> Date: Sun, 29 Dec 2024 09:52:29 -0500 Subject: [PATCH 091/144] docs: reword sentence (#3530) * docs: reword sentence The sentence was a bit hard to follow. I think it seems more natural now. * docs: fix whitespace --------- Co-authored-by: Rob Ede --- actix-web/src/resource.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/actix-web/src/resource.rs b/actix-web/src/resource.rs index 6486fb39d..aee0dff93 100644 --- a/actix-web/src/resource.rs +++ b/actix-web/src/resource.rs @@ -28,9 +28,9 @@ use crate::{ /// /// Resource in turn has at least one route. Route consists of an handlers objects and list of /// guards (objects that implement `Guard` trait). Resources and routes uses builder-like pattern -/// for configuration. During request handling, resource object iterate through all routes and check -/// guards for specific route, if request matches all guards, route considered matched and route -/// handler get called. +/// for configuration. During request handling, the resource object iterates through all routes +/// and checks guards for the specific route, if the request matches all the guards, then the route +/// is considered matched and the route handler gets called. /// /// # Examples /// ``` From ac2a3bb124dfa9e10bc282dfd8192bc8c4158cf1 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 29 Dec 2024 16:20:00 +0000 Subject: [PATCH 092/144] refactor: replace ahash with foldhash (#3483) --- actix-http/Cargo.toml | 2 +- actix-http/src/extensions.rs | 2 +- actix-http/src/header/map.rs | 6 +++--- actix-web/Cargo.toml | 2 +- actix-web/src/middleware/err_handlers.rs | 4 ++-- actix-web/src/rmap.rs | 8 ++++---- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 3f81ea9f0..f164d8538 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -106,12 +106,12 @@ actix-codec = "0.5" actix-utils = "3" actix-rt = { version = "2.2", default-features = false } -ahash = "0.8" bitflags = "2" bytes = "1" bytestring = "1" derive_more = { version = "1", features = ["as_ref", "deref", "deref_mut", "display", "error", "from"] } encoding_rs = "0.8" +foldhash = "0.1" futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] } http = "0.2.7" httparse = "1.5.1" diff --git a/actix-http/src/extensions.rs b/actix-http/src/extensions.rs index f2047a9ce..2ed3973bf 100644 --- a/actix-http/src/extensions.rs +++ b/actix-http/src/extensions.rs @@ -31,7 +31,7 @@ impl Hasher for NoOpHasher { /// All entries into this map must be owned types (or static references). #[derive(Default)] pub struct Extensions { - /// Use AHasher with a std HashMap with for faster lookups on the small `TypeId` keys. + // use no-op hasher with a std HashMap with for faster lookups on the small `TypeId` keys map: HashMap, BuildHasherDefault>, } diff --git a/actix-http/src/header/map.rs b/actix-http/src/header/map.rs index 7be282b11..a9a201e1a 100644 --- a/actix-http/src/header/map.rs +++ b/actix-http/src/header/map.rs @@ -2,7 +2,7 @@ use std::{borrow::Cow, collections::hash_map, iter, ops}; -use ahash::AHashMap; +use foldhash::{HashMap as FoldHashMap, HashMapExt as _}; use http::header::{HeaderName, HeaderValue}; use smallvec::{smallvec, SmallVec}; @@ -47,7 +47,7 @@ use super::AsHeaderName; /// ``` #[derive(Debug, Clone, Default)] pub struct HeaderMap { - pub(crate) inner: AHashMap, + pub(crate) inner: FoldHashMap, } /// A bespoke non-empty list for HeaderMap values. @@ -116,7 +116,7 @@ impl HeaderMap { /// ``` pub fn with_capacity(capacity: usize) -> Self { HeaderMap { - inner: AHashMap::with_capacity(capacity), + inner: FoldHashMap::with_capacity(capacity), } } diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index 9b10f14b1..f4159cf27 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -141,13 +141,13 @@ actix-http = { version = "3.7", features = ["ws"] } actix-router = { version = "0.5.3", default-features = false, features = ["http"] } actix-web-codegen = { version = "4.3", optional = true, default-features = false } -ahash = "0.8" bytes = "1" bytestring = "1" cfg-if = "1" cookie = { version = "0.16", features = ["percent-encode"], optional = true } derive_more = { version = "1", features = ["display", "error", "from"] } encoding_rs = "0.8" +foldhash = "0.1" futures-core = { version = "0.3.17", default-features = false } futures-util = { version = "0.3.17", default-features = false } itoa = "1" diff --git a/actix-web/src/middleware/err_handlers.rs b/actix-web/src/middleware/err_handlers.rs index 3c50d5c8f..649c1a97a 100644 --- a/actix-web/src/middleware/err_handlers.rs +++ b/actix-web/src/middleware/err_handlers.rs @@ -8,7 +8,7 @@ use std::{ }; use actix_service::{Service, Transform}; -use ahash::AHashMap; +use foldhash::HashMap as FoldHashMap; use futures_core::{future::LocalBoxFuture, ready}; use pin_project_lite::pin_project; @@ -185,7 +185,7 @@ pub struct ErrorHandlers { handlers: Handlers, } -type Handlers = Rc>>>; +type Handlers = Rc>>>; impl Default for ErrorHandlers { fn default() -> Self { diff --git a/actix-web/src/rmap.rs b/actix-web/src/rmap.rs index 462f3b313..b445687ac 100644 --- a/actix-web/src/rmap.rs +++ b/actix-web/src/rmap.rs @@ -6,7 +6,7 @@ use std::{ }; use actix_router::ResourceDef; -use ahash::AHashMap; +use foldhash::HashMap as FoldHashMap; use url::Url; use crate::{error::UrlGenerationError, request::HttpRequest}; @@ -19,7 +19,7 @@ pub struct ResourceMap { /// Named resources within the tree or, for external resources, it points to isolated nodes /// outside the tree. - named: AHashMap>, + named: FoldHashMap>, parent: RefCell>, @@ -32,7 +32,7 @@ impl ResourceMap { pub fn new(root: ResourceDef) -> Self { ResourceMap { pattern: root, - named: AHashMap::default(), + named: FoldHashMap::default(), parent: RefCell::new(Weak::new()), nodes: Some(Vec::new()), } @@ -86,7 +86,7 @@ impl ResourceMap { } else { let new_node = Rc::new(ResourceMap { pattern: pattern.clone(), - named: AHashMap::default(), + named: FoldHashMap::default(), parent: RefCell::new(Weak::new()), nodes: None, }); From bb1442e20b9cc79e2c196da170453ee400f61c44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 29 Dec 2024 16:50:44 +0000 Subject: [PATCH 093/144] build(deps): update actix-multipart-rfc7578 requirement from 0.10 to 0.11 (#3517) build(deps): update actix-multipart-rfc7578 requirement --- updated-dependencies: - dependency-name: actix-multipart-rfc7578 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- actix-multipart/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index aa33bfc93..62b53eb79 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -59,7 +59,7 @@ tokio = { version = "1.24.2", features = ["sync", "io-util"] } [dev-dependencies] actix-http = "3" -actix-multipart-rfc7578 = "0.10" +actix-multipart-rfc7578 = "0.11" actix-rt = "2.2" actix-test = "0.1" actix-web = "4" From 856480cd902923049cca066509d44486c6a391db Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Sun, 29 Dec 2024 17:55:32 +0100 Subject: [PATCH 094/144] fix(http2): remove host header when using http2 (#3516) Co-authored-by: Rob Ede --- awc/CHANGES.md | 1 + awc/src/client/h2proto.rs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/awc/CHANGES.md b/awc/CHANGES.md index 8a2a1ec43..df3003981 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -5,6 +5,7 @@ - Update `brotli` dependency to `7`. - Prevent panics on connection pool drop when Tokio runtime is shutdown early. - Minimum supported Rust version (MSRV) is now 1.75. +- Do not send `Host` header on HTTP/2 requests, as it is not required, and some web servers may reject it. ## 3.5.1 diff --git a/awc/src/client/h2proto.rs b/awc/src/client/h2proto.rs index c3f801f20..f12ac3b43 100644 --- a/awc/src/client/h2proto.rs +++ b/awc/src/client/h2proto.rs @@ -12,7 +12,7 @@ use h2::{ SendStream, }; use http::{ - header::{HeaderValue, CONNECTION, CONTENT_LENGTH, TRANSFER_ENCODING}, + header::{HeaderValue, CONNECTION, CONTENT_LENGTH, HOST, TRANSFER_ENCODING}, request::Request, Method, Version, }; @@ -97,7 +97,7 @@ where // TODO: consider skipping other headers according to: // https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.2 // omit HTTP/1.x only headers - CONNECTION | TRANSFER_ENCODING => continue, + CONNECTION | TRANSFER_ENCODING | HOST => continue, CONTENT_LENGTH if skip_len => continue, // DATE => has_date = true, _ => {} From 5aeb0dd950214d1cf0f4ac2045b8a8116d89678b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 01:24:31 +0000 Subject: [PATCH 095/144] build(deps): bump taiki-e/install-action from 2.46.20 to 2.47.0 (#3540) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.46.20 to 2.47.0. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.46.20...v2.47.0) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 32a126ae7..7645ca5ec 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.46.20 + uses: taiki-e/install-action@v2.47.0 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.46.20 + uses: taiki-e/install-action@v2.47.0 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 89cc9bb73..419c630a9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.46.20 + uses: taiki-e/install-action@v2.47.0 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.46.20 + uses: taiki-e/install-action@v2.47.0 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b8efdb938..b9150b0c6 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.46.20 + uses: taiki-e/install-action@v2.47.0 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e77723d58..8973840c7 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.46.20 + uses: taiki-e/install-action@v2.47.0 with: tool: just From 0fafb486d4877df3d505ea6533765af499d99a5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:08:33 +0000 Subject: [PATCH 096/144] build(deps): bump taiki-e/install-action from 2.47.0 to 2.47.7 (#3544) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.47.0 to 2.47.7. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.47.0...v2.47.7) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 7645ca5ec..94ef82bb8 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.47.0 + uses: taiki-e/install-action@v2.47.7 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.47.0 + uses: taiki-e/install-action@v2.47.7 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 419c630a9..82e18d81f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.47.0 + uses: taiki-e/install-action@v2.47.7 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.47.0 + uses: taiki-e/install-action@v2.47.7 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b9150b0c6..860e399f8 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.47.0 + uses: taiki-e/install-action@v2.47.7 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 8973840c7..9855134b8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.47.0 + uses: taiki-e/install-action@v2.47.7 with: tool: just From b0fe67978485b43ea11ff817dc5afaac4a12559f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 01:47:23 +0000 Subject: [PATCH 097/144] build(deps): bump taiki-e/install-action from 2.47.7 to 2.47.11 (#3550) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 94ef82bb8..d455d8316 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.47.7 + uses: taiki-e/install-action@v2.47.11 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.47.7 + uses: taiki-e/install-action@v2.47.11 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 82e18d81f..14b558b42 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.47.7 + uses: taiki-e/install-action@v2.47.11 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.47.7 + uses: taiki-e/install-action@v2.47.11 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 860e399f8..df1b018a8 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.47.7 + uses: taiki-e/install-action@v2.47.11 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 9855134b8..4c63e6373 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.47.7 + uses: taiki-e/install-action@v2.47.11 with: tool: just From 91e29c0ce42e9f5051b1977d362ab040f4cec7aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 14:04:49 +0000 Subject: [PATCH 098/144] build(deps): bump taiki-e/install-action from 2.47.11 to 2.47.18 (#3551) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.47.11 to 2.47.18. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.47.11...v2.47.18) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index d455d8316..e856b0311 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.47.11 + uses: taiki-e/install-action@v2.47.18 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.47.11 + uses: taiki-e/install-action@v2.47.18 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 14b558b42..71d659b37 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.47.11 + uses: taiki-e/install-action@v2.47.18 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.47.11 + uses: taiki-e/install-action@v2.47.18 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index df1b018a8..bf7d5d5c2 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.47.11 + uses: taiki-e/install-action@v2.47.18 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4c63e6373..9445cb566 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.47.11 + uses: taiki-e/install-action@v2.47.18 with: tool: just From 8690f80a08cf064009854d6ff0dcbd108dd39e07 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 16:57:05 +0000 Subject: [PATCH 099/144] build(deps): bump taiki-e/install-action from 2.47.18 to 2.48.1 (#3563) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.47.18 to 2.48.1. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.47.18...v2.48.1) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index e856b0311..529278c0a 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.47.18 + uses: taiki-e/install-action@v2.48.1 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.47.18 + uses: taiki-e/install-action@v2.48.1 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 71d659b37..5f0ccfaf8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.47.18 + uses: taiki-e/install-action@v2.48.1 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.47.18 + uses: taiki-e/install-action@v2.48.1 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index bf7d5d5c2..fa85093ed 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.47.18 + uses: taiki-e/install-action@v2.48.1 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 9445cb566..323a8a5ae 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.47.18 + uses: taiki-e/install-action@v2.48.1 with: tool: just From a36280466c7ffdbc9dca3db5e4484a771df93e86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 18:59:09 +0000 Subject: [PATCH 100/144] build(deps): bump taiki-e/cache-cargo-install-action from 2.0.1 to 2.1.0 (#3555) Bumps [taiki-e/cache-cargo-install-action](https://github.com/taiki-e/cache-cargo-install-action) from 2.0.1 to 2.1.0. - [Release notes](https://github.com/taiki-e/cache-cargo-install-action/releases) - [Changelog](https://github.com/taiki-e/cache-cargo-install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/cache-cargo-install-action/compare/v2.0.1...v2.1.0) --- updated-dependencies: - dependency-name: taiki-e/cache-cargo-install-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 323a8a5ae..94906c852 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -82,7 +82,7 @@ jobs: tool: just - name: Install cargo-check-external-types - uses: taiki-e/cache-cargo-install-action@v2.0.1 + uses: taiki-e/cache-cargo-install-action@v2.1.0 with: tool: cargo-check-external-types From 182055bcb504a60d15ce8d01dba7e26dee439479 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 18:59:22 +0000 Subject: [PATCH 101/144] build(deps): bump codecov/codecov-action from 5.1.2 to 5.3.1 (#3554) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.1.2 to 5.3.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v5.1.2...v5.3.1) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index fa85093ed..7f0a74643 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -32,7 +32,7 @@ jobs: run: just test-coverage-codecov - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.1.2 + uses: codecov/codecov-action@v5.3.1 with: files: codecov.json fail_ci_if_error: true From 33b487e854c592dbd1deca98e4a8d6ce0007890c Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 25 Jan 2025 18:01:21 +0000 Subject: [PATCH 102/144] chore: address clippy lints --- actix-router/src/quoter.rs | 2 +- actix-router/src/resource.rs | 2 ++ actix-router/src/router.rs | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/actix-router/src/quoter.rs b/actix-router/src/quoter.rs index 6c929d3ac..78694ed72 100644 --- a/actix-router/src/quoter.rs +++ b/actix-router/src/quoter.rs @@ -105,7 +105,7 @@ fn hex_pair_to_char(d1: u8, d2: u8) -> Option { let d_low = char::from(d2).to_digit(16)?; // left shift high nibble by 4 bits - Some((d_high as u8) << 4 | (d_low as u8)) + Some(((d_high as u8) << 4) | (d_low as u8)) } #[derive(Debug, Default, Clone)] diff --git a/actix-router/src/resource.rs b/actix-router/src/resource.rs index 3a102945b..7069b5fea 100644 --- a/actix-router/src/resource.rs +++ b/actix-router/src/resource.rs @@ -1021,6 +1021,7 @@ impl ResourceDef { panic!("prefix resource definitions should not have tail segments"); } + #[allow(clippy::literal_string_with_formatting_args)] if unprocessed.ends_with('*') { // unnamed tail segment @@ -1369,6 +1370,7 @@ mod tests { assert_eq!(path.unprocessed(), ""); } + #[expect(clippy::literal_string_with_formatting_args)] #[test] fn newline_patterns_and_paths() { let re = ResourceDef::new("/user/a\nb"); diff --git a/actix-router/src/router.rs b/actix-router/src/router.rs index 1dd4449da..01f92e90b 100644 --- a/actix-router/src/router.rs +++ b/actix-router/src/router.rs @@ -145,6 +145,7 @@ mod tests { }; #[allow(clippy::cognitive_complexity)] + #[expect(clippy::literal_string_with_formatting_args)] #[test] fn test_recognizer_1() { let mut router = Router::::build(); From 59961a58a83e652769a6d26ac17c19422bffa9e7 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 9 Feb 2025 02:15:43 +0000 Subject: [PATCH 103/144] chore: fix msrv errors --- actix-router/src/resource.rs | 2 +- actix-router/src/router.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/actix-router/src/resource.rs b/actix-router/src/resource.rs index 7069b5fea..b5ee01958 100644 --- a/actix-router/src/resource.rs +++ b/actix-router/src/resource.rs @@ -1370,7 +1370,7 @@ mod tests { assert_eq!(path.unprocessed(), ""); } - #[expect(clippy::literal_string_with_formatting_args)] + #[allow(clippy::literal_string_with_formatting_args)] #[test] fn newline_patterns_and_paths() { let re = ResourceDef::new("/user/a\nb"); diff --git a/actix-router/src/router.rs b/actix-router/src/router.rs index 01f92e90b..b20cb7ee3 100644 --- a/actix-router/src/router.rs +++ b/actix-router/src/router.rs @@ -145,7 +145,7 @@ mod tests { }; #[allow(clippy::cognitive_complexity)] - #[expect(clippy::literal_string_with_formatting_args)] + #[allow(clippy::literal_string_with_formatting_args)] #[test] fn test_recognizer_1() { let mut router = Router::::build(); From 66e2afe306a35de08926316707cb44a8e56ca390 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 9 Feb 2025 02:39:22 +0000 Subject: [PATCH 104/144] build(deps): update rand requirement from 0.8 to 0.9 (#3564) * build(deps): update rand requirement from 0.8 to 0.9 Updates the requirements on [rand](https://github.com/rust-random/rand) to permit the latest version. - [Release notes](https://github.com/rust-random/rand/releases) - [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-random/rand/compare/0.8.0...0.9.0) --- updated-dependencies: - dependency-name: rand dependency-type: direct:production ... Signed-off-by: dependabot[bot] * chore: fix rand upgrade * chore: address clippy lint --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Rob Ede --- actix-http/Cargo.toml | 2 +- actix-http/tests/test_server.rs | 6 +++++- actix-multipart/Cargo.toml | 2 +- actix-multipart/src/test.rs | 7 ++---- actix-web/Cargo.toml | 2 +- actix-web/tests/test_server.rs | 38 ++++++--------------------------- awc/Cargo.toml | 2 +- awc/src/ws.rs | 2 +- awc/tests/test_client.rs | 20 ++++------------- 9 files changed, 23 insertions(+), 58 deletions(-) diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index f164d8538..1d9a54a0d 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -132,7 +132,7 @@ h2 = { version = "0.3.26", optional = true } # websockets local-channel = { version = "0.1", optional = true } base64 = { version = "0.22", optional = true } -rand = { version = "0.8", optional = true } +rand = { version = "0.9", optional = true } sha1 = { version = "0.10", optional = true } # openssl/rustls diff --git a/actix-http/tests/test_server.rs b/actix-http/tests/test_server.rs index e93d35598..6f273ef33 100644 --- a/actix-http/tests/test_server.rs +++ b/actix-http/tests/test_server.rs @@ -16,6 +16,7 @@ use actix_utils::future::{err, ok, ready}; use bytes::Bytes; use derive_more::derive::{Display, Error}; use futures_util::{stream::once, FutureExt as _, StreamExt as _}; +use rand::Rng as _; use regex::Regex; #[actix_rt::test] @@ -164,7 +165,10 @@ 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 = rand::rng() + .sample_iter(rand::distr::StandardUniform) + .take(*chunk_size) + .collect::>(); bytes.extend(format!("{:X}\r\n", chunk_size).as_bytes()); bytes.extend(&random_bytes[..]); diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index 62b53eb79..c0e62d8aa 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -50,7 +50,7 @@ local-waker = "0.1" log = "0.4" memchr = "2.5" mime = "0.3" -rand = "0.8" +rand = "0.9" serde = "1" serde_json = "1" serde_plain = "1" diff --git a/actix-multipart/src/test.rs b/actix-multipart/src/test.rs index 7dec85f8e..b0e907266 100644 --- a/actix-multipart/src/test.rs +++ b/actix-multipart/src/test.rs @@ -5,10 +5,7 @@ use actix_web::{ web::{BufMut as _, Bytes, BytesMut}, }; use mime::Mime; -use rand::{ - distributions::{Alphanumeric, DistString as _}, - thread_rng, -}; +use rand::distr::{Alphanumeric, SampleString as _}; const CRLF: &[u8] = b"\r\n"; const CRLF_CRLF: &[u8] = b"\r\n\r\n"; @@ -64,7 +61,7 @@ pub fn create_form_data_payload_and_headers( content_type: Option, file: Bytes, ) -> (Bytes, HeaderMap) { - let boundary = Alphanumeric.sample_string(&mut thread_rng(), 32); + let boundary = Alphanumeric.sample_string(&mut rand::rng(), 32); create_form_data_payload_and_headers_with_boundary( &boundary, diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index f4159cf27..f7d6f56d2 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -180,7 +180,7 @@ criterion = { version = "0.5", features = ["html_reports"] } env_logger = "0.11" flate2 = "1.0.13" futures-util = { version = "0.3.17", default-features = false, features = ["std"] } -rand = "0.8" +rand = "0.9" rcgen = "0.13" rustls-pemfile = "2" serde = { version = "1", features = ["derive"] } diff --git a/actix-web/tests/test_server.rs b/actix-web/tests/test_server.rs index 960cf1e2b..f13aa3cfd 100644 --- a/actix-web/tests/test_server.rs +++ b/actix-web/tests/test_server.rs @@ -25,7 +25,7 @@ use openssl::{ ssl::{SslAcceptor, SslMethod}, x509::X509, }; -use rand::{distributions::Alphanumeric, Rng as _}; +use rand::distr::{Alphanumeric, SampleString as _}; mod utils; @@ -188,11 +188,7 @@ async fn body_gzip_large() { #[actix_rt::test] async fn test_body_gzip_large_random() { - let data = rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(70_000) - .map(char::from) - .collect::(); + let data = Alphanumeric.sample_string(&mut rand::rng(), 70_000); let srv_data = data.clone(); let srv = actix_test::start_with(actix_test::config().h1(), move || { @@ -432,11 +428,7 @@ async fn test_zstd_encoding() { #[actix_rt::test] async fn test_zstd_encoding_large() { - let data = rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(320_000) - .map(char::from) - .collect::(); + let data = Alphanumeric.sample_string(&mut rand::rng(), 320_000); let srv = actix_test::start_with(actix_test::config().h1(), || { App::new().service( @@ -529,11 +521,7 @@ async fn test_gzip_encoding_large() { #[actix_rt::test] async fn test_reading_gzip_encoding_large_random() { - let data = rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(60_000) - .map(char::from) - .collect::(); + let data = Alphanumeric.sample_string(&mut rand::rng(), 60_000); let srv = actix_test::start_with(actix_test::config().h1(), || { App::new().service(web::resource("/").route(web::to(move |body: Bytes| async { @@ -599,11 +587,7 @@ async fn test_reading_deflate_encoding_large() { #[actix_rt::test] async fn test_reading_deflate_encoding_large_random() { - let data = rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(160_000) - .map(char::from) - .collect::(); + let data = Alphanumeric.sample_string(&mut rand::rng(), 160_000); let srv = actix_test::start_with(actix_test::config().h1(), || { App::new().service(web::resource("/").route(web::to(move |body: Bytes| async { @@ -648,11 +632,7 @@ async fn test_brotli_encoding() { #[actix_rt::test] async fn test_brotli_encoding_large() { - let data = rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(320_000) - .map(char::from) - .collect::(); + let data = Alphanumeric.sample_string(&mut rand::rng(), 320_000); let srv = actix_test::start_with(actix_test::config().h1(), || { App::new().service( @@ -737,11 +717,7 @@ mod plus_rustls { #[actix_rt::test] async fn test_reading_deflate_encoding_large_random_rustls() { - let data = rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(160_000) - .map(char::from) - .collect::(); + let data = Alphanumeric.sample_string(&mut rand::rng(), 160_000); let srv = actix_test::start_with(actix_test::config().rustls_0_23(tls_config()), || { App::new().service(web::resource("/").route(web::to(|bytes: Bytes| async { diff --git a/awc/Cargo.toml b/awc/Cargo.toml index d6626f906..e2e2bcd17 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -116,7 +116,7 @@ log =" 0.4" mime = "0.3" percent-encoding = "2.1" pin-project-lite = "0.2" -rand = "0.8" +rand = "0.9" serde = "1.0" serde_json = "1.0" serde_urlencoded = "0.7" diff --git a/awc/src/ws.rs b/awc/src/ws.rs index b05063d22..3ce1d286a 100644 --- a/awc/src/ws.rs +++ b/awc/src/ws.rs @@ -326,7 +326,7 @@ impl WebsocketsRequest { // Generate a random key for the `Sec-WebSocket-Key` header which is a base64-encoded // (see RFC 4648 §4) value that, when decoded, is 16 bytes in length (RFC 6455 §1.3). - let sec_key: [u8; 16] = rand::random(); + let sec_key = rand::random::<[u8; 16]>(); let key = BASE64_STANDARD.encode(sec_key); self.head.headers.insert( diff --git a/awc/tests/test_client.rs b/awc/tests/test_client.rs index 76915630f..43c83891a 100644 --- a/awc/tests/test_client.rs +++ b/awc/tests/test_client.rs @@ -20,7 +20,7 @@ use base64::prelude::*; use bytes::Bytes; use cookie::Cookie; use futures_util::stream; -use rand::Rng; +use rand::distr::{Alphanumeric, SampleString as _}; mod utils; @@ -516,11 +516,7 @@ async fn client_gzip_encoding_large() { #[cfg(feature = "compress-gzip")] #[actix_rt::test] async fn client_gzip_encoding_large_random() { - let data = rand::thread_rng() - .sample_iter(&rand::distributions::Alphanumeric) - .take(100_000) - .map(char::from) - .collect::(); + let data = Alphanumeric.sample_string(&mut rand::rng(), 100_000); let srv = actix_test::start(|| { App::new().service(web::resource("/").route(web::to(|data: Bytes| async { @@ -562,11 +558,7 @@ async fn client_brotli_encoding() { #[cfg(feature = "compress-brotli")] #[actix_rt::test] async fn client_brotli_encoding_large_random() { - let data = rand::thread_rng() - .sample_iter(&rand::distributions::Alphanumeric) - .take(70_000) - .map(char::from) - .collect::(); + let data = Alphanumeric.sample_string(&mut rand::rng(), 70_000); let srv = actix_test::start(|| { App::new().service(web::resource("/").route(web::to(|data: Bytes| async { @@ -607,11 +599,7 @@ async fn client_deflate_encoding() { #[actix_rt::test] async fn client_deflate_encoding_large_random() { - let data = rand::thread_rng() - .sample_iter(rand::distributions::Alphanumeric) - .map(char::from) - .take(70_000) - .collect::(); + let data = Alphanumeric.sample_string(&mut rand::rng(), 70_000); let srv = actix_test::start(|| { App::new().default_service(web::to(|body: Bytes| async { From a4eaa7f0bb963ec6bc67aaadafdda2d638f9ba41 Mon Sep 17 00:00:00 2001 From: Akos Vandra-Meyer Date: Sun, 9 Feb 2025 04:01:39 +0100 Subject: [PATCH 105/144] implement Responder for Result<(), E: Error> (#3560) * implement Responder for Option<()> and Result<(), E: Error> * chore: remove Option<()> impl * chore: fix changelog --------- Co-authored-by: Rob Ede --- actix-web/CHANGES.md | 1 + actix-web/src/response/responder.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index cee14dc4b..edbdc6982 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -2,6 +2,7 @@ ## Unreleased +- Implement `Responder` for `Result<(), E: Into>`. Returning `Ok(())` responds with HTTP 204 No Content. - On Windows, an error is now returned from `HttpServer::bind()` (or TLS variants) when binding to a socket that's already in use. - Update `brotli` dependency to `7`. - Minimum supported Rust version (MSRV) is now 1.75. diff --git a/actix-web/src/response/responder.rs b/actix-web/src/response/responder.rs index 90d8f6e52..82bc38d6b 100644 --- a/actix-web/src/response/responder.rs +++ b/actix-web/src/response/responder.rs @@ -131,6 +131,23 @@ where } } +// Note: see https://github.com/actix/actix-web/issues/1108 for reasoning why Responder is not +// implemented for `()`, and https://github.com/actix/actix-web/pull/3560 for discussion about this +// impl and the decision not to include a similar one for `Option<()>`. +impl Responder for Result<(), E> +where + E: Into, +{ + type Body = BoxBody; + + fn respond_to(self, _req: &HttpRequest) -> HttpResponse { + match self { + Ok(()) => HttpResponse::new(StatusCode::NO_CONTENT), + Err(err) => HttpResponse::from_error(err.into()), + } + } +} + impl Responder for (R, StatusCode) { type Body = R::Body; From 04533a15fa1652e047f51d439aa2fe7be8ccc1de Mon Sep 17 00:00:00 2001 From: Akos Vandra-Meyer Date: Sun, 9 Feb 2025 23:04:21 +0100 Subject: [PATCH 106/144] Add `Extensions::get_or_insert[_with]()` methods (#3561) * add get_or_insert and get_or_insert_with for Extensions * add docs * fix doctest * docs: update changelog * chore: simplify get_or_insert --------- Co-authored-by: Rob Ede --- actix-http/CHANGES.md | 1 + actix-http/src/extensions.rs | 40 ++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 982add26a..23ebe43e1 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -5,6 +5,7 @@ ### Added - Add `header::CLEAR_SITE_DATA` constant. +- Add `Extensions::get_or_insert[_with]()` methods. ### Changed diff --git a/actix-http/src/extensions.rs b/actix-http/src/extensions.rs index 2ed3973bf..9c85caf37 100644 --- a/actix-http/src/extensions.rs +++ b/actix-http/src/extensions.rs @@ -104,6 +104,46 @@ impl Extensions { .and_then(|boxed| boxed.downcast_mut()) } + /// Inserts the given `value` into the extensions if it is not present, then returns a reference + /// to the value in the extensions. + /// + /// ``` + /// # use actix_http::Extensions; + /// let mut map = Extensions::new(); + /// assert_eq!(map.get::>(), None); + /// + /// map.get_or_insert(Vec::::new()).push(1); + /// assert_eq!(map.get::>(), Some(&vec![1])); + /// + /// map.get_or_insert(Vec::::new()).push(2); + /// assert_eq!(map.get::>(), Some(&vec![1,2])); + /// ``` + pub fn get_or_insert(&mut self, value: T) -> &mut T { + self.get_or_insert_with(|| value) + } + + /// Inserts a value computed from `f` into the extensions if the given `value` is not present, + /// then returns a reference to the value in the extensions. + /// + /// ``` + /// # use actix_http::Extensions; + /// let mut map = Extensions::new(); + /// assert_eq!(map.get::>(), None); + /// + /// map.get_or_insert_with(Vec::::new).push(1); + /// assert_eq!(map.get::>(), Some(&vec![1])); + /// + /// map.get_or_insert_with(Vec::::new).push(2); + /// assert_eq!(map.get::>(), Some(&vec![1,2])); + /// ``` + pub fn get_or_insert_with T>(&mut self, default: F) -> &mut T { + self.map + .entry(TypeId::of::()) + .or_insert_with(|| Box::new(default())) + .downcast_mut() + .expect("extensions map should now contain a T value") + } + /// Remove an item from the map of a given type. /// /// If an item of this type was already stored, it will be returned. From eb6f6a1976d436bccbdd21ca6a63ee52dd46b30b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 01:09:53 +0000 Subject: [PATCH 107/144] build(deps): bump taiki-e/cache-cargo-install-action from 2.1.0 to 2.1.1 (#3573) Bumps [taiki-e/cache-cargo-install-action](https://github.com/taiki-e/cache-cargo-install-action) from 2.1.0 to 2.1.1. - [Release notes](https://github.com/taiki-e/cache-cargo-install-action/releases) - [Changelog](https://github.com/taiki-e/cache-cargo-install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/cache-cargo-install-action/compare/v2.1.0...v2.1.1) --- updated-dependencies: - dependency-name: taiki-e/cache-cargo-install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 94906c852..0448c857f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -82,7 +82,7 @@ jobs: tool: just - name: Install cargo-check-external-types - uses: taiki-e/cache-cargo-install-action@v2.1.0 + uses: taiki-e/cache-cargo-install-action@v2.1.1 with: tool: cargo-check-external-types From cee74519156aa75c1b459129cecba1146349be0e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 01:10:23 +0000 Subject: [PATCH 108/144] build(deps): bump taiki-e/install-action from 2.48.1 to 2.48.4 (#3572) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.48.1 to 2.48.4. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.48.1...v2.48.4) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 529278c0a..db7a5c6ba 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.48.1 + uses: taiki-e/install-action@v2.48.4 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.48.1 + uses: taiki-e/install-action@v2.48.4 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f0ccfaf8..ef4fc5aea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.48.1 + uses: taiki-e/install-action@v2.48.4 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.48.1 + uses: taiki-e/install-action@v2.48.4 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 7f0a74643..c5452b282 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.48.1 + uses: taiki-e/install-action@v2.48.4 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0448c857f..b026572f5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.48.1 + uses: taiki-e/install-action@v2.48.4 with: tool: just From 9656383646463e95d33d17458cc4b02ba5930f2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 01:27:56 +0000 Subject: [PATCH 109/144] build(deps): update derive_more requirement from 1 to 2 (#3571) * build(deps): update derive_more requirement from 1 to 2 Updates the requirements on [derive_more](https://github.com/JelteF/derive_more) to permit the latest version. - [Release notes](https://github.com/JelteF/derive_more/releases) - [Changelog](https://github.com/JelteF/derive_more/blob/master/CHANGELOG.md) - [Commits](https://github.com/JelteF/derive_more/compare/v1.0.0...v2.0.1) --- updated-dependencies: - dependency-name: derive_more dependency-type: direct:production ... Signed-off-by: dependabot[bot] * refactor: simplify derive_more calls --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Rob Ede --- actix-files/Cargo.toml | 2 +- actix-files/src/error.rs | 2 +- actix-files/src/named.rs | 2 +- actix-files/src/range.rs | 2 +- actix-http/Cargo.toml | 2 +- actix-http/src/body/body_stream.rs | 2 +- actix-http/src/body/utils.rs | 2 +- actix-http/src/encoding/encoder.rs | 2 +- actix-http/src/error.rs | 2 +- actix-http/src/header/shared/content_encoding.rs | 2 +- actix-http/src/header/shared/quality.rs | 2 +- actix-http/src/ws/mod.rs | 2 +- actix-http/tests/test_client.rs | 2 +- actix-http/tests/test_openssl.rs | 2 +- actix-http/tests/test_rustls.rs | 2 +- actix-http/tests/test_server.rs | 2 +- actix-http/tests/test_ws.rs | 2 +- actix-multipart/Cargo.toml | 2 +- actix-multipart/src/error.rs | 2 +- actix-multipart/src/field.rs | 2 +- actix-multipart/src/form/json.rs | 2 +- actix-multipart/src/form/mod.rs | 2 +- actix-multipart/src/form/tempfile.rs | 2 +- actix-multipart/src/form/text.rs | 2 +- actix-web/Cargo.toml | 2 +- actix-web/src/error/mod.rs | 2 +- actix-web/src/http/header/content_length.rs | 2 +- actix-web/src/info.rs | 2 +- actix-web/src/types/path.rs | 4 ++-- actix-web/src/types/query.rs | 2 +- awc/Cargo.toml | 2 +- awc/src/client/error.rs | 2 +- awc/src/error.rs | 2 +- awc/src/sender.rs | 2 +- 34 files changed, 35 insertions(+), 35 deletions(-) diff --git a/actix-files/Cargo.toml b/actix-files/Cargo.toml index 48d38874f..b2bef2aa6 100644 --- a/actix-files/Cargo.toml +++ b/actix-files/Cargo.toml @@ -33,7 +33,7 @@ actix-web = { version = "4", default-features = false } bitflags = "2" bytes = "1" -derive_more = { version = "1", features = ["display", "error", "from"] } +derive_more = { version = "2", features = ["display", "error", "from"] } futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] } http-range = "0.1.4" log = "0.4" diff --git a/actix-files/src/error.rs b/actix-files/src/error.rs index 1d4818887..e762116e6 100644 --- a/actix-files/src/error.rs +++ b/actix-files/src/error.rs @@ -1,5 +1,5 @@ use actix_web::{http::StatusCode, ResponseError}; -use derive_more::derive::Display; +use derive_more::Display; /// Errors which can occur when serving static files. #[derive(Debug, PartialEq, Eq, Display)] diff --git a/actix-files/src/named.rs b/actix-files/src/named.rs index 7f839890e..9e4a37737 100644 --- a/actix-files/src/named.rs +++ b/actix-files/src/named.rs @@ -21,7 +21,7 @@ use actix_web::{ Error, HttpMessage, HttpRequest, HttpResponse, Responder, }; use bitflags::bitflags; -use derive_more::derive::{Deref, DerefMut}; +use derive_more::{Deref, DerefMut}; use futures_core::future::LocalBoxFuture; use mime::Mime; diff --git a/actix-files/src/range.rs b/actix-files/src/range.rs index c6e346329..528911ae0 100644 --- a/actix-files/src/range.rs +++ b/actix-files/src/range.rs @@ -1,6 +1,6 @@ use std::fmt; -use derive_more::derive::Error; +use derive_more::Error; /// Copy of `http_range::HttpRangeParseError`. #[derive(Debug, Clone)] diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 1d9a54a0d..a1b735179 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -109,7 +109,7 @@ actix-rt = { version = "2.2", default-features = false } bitflags = "2" bytes = "1" bytestring = "1" -derive_more = { version = "1", features = ["as_ref", "deref", "deref_mut", "display", "error", "from"] } +derive_more = { version = "2", features = ["as_ref", "deref", "deref_mut", "display", "error", "from"] } encoding_rs = "0.8" foldhash = "0.1" futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] } diff --git a/actix-http/src/body/body_stream.rs b/actix-http/src/body/body_stream.rs index 2ae12c279..657ffe9c8 100644 --- a/actix-http/src/body/body_stream.rs +++ b/actix-http/src/body/body_stream.rs @@ -75,7 +75,7 @@ mod tests { time::{sleep, Sleep}, }; use actix_utils::future::poll_fn; - use derive_more::derive::{Display, Error}; + use derive_more::{Display, Error}; use futures_core::ready; use futures_util::{stream, FutureExt as _}; use pin_project_lite::pin_project; diff --git a/actix-http/src/body/utils.rs b/actix-http/src/body/utils.rs index 1fdb3ff5a..b8bfa96cf 100644 --- a/actix-http/src/body/utils.rs +++ b/actix-http/src/body/utils.rs @@ -3,7 +3,7 @@ use std::task::Poll; use actix_rt::pin; use actix_utils::future::poll_fn; use bytes::{Bytes, BytesMut}; -use derive_more::derive::{Display, Error}; +use derive_more::{Display, Error}; use futures_core::ready; use super::{BodySize, MessageBody}; diff --git a/actix-http/src/encoding/encoder.rs b/actix-http/src/encoding/encoder.rs index 3c9eec811..735dca679 100644 --- a/actix-http/src/encoding/encoder.rs +++ b/actix-http/src/encoding/encoder.rs @@ -10,7 +10,7 @@ use std::{ use actix_rt::task::{spawn_blocking, JoinHandle}; use bytes::Bytes; -use derive_more::derive::Display; +use derive_more::Display; #[cfg(feature = "compress-gzip")] use flate2::write::{GzEncoder, ZlibEncoder}; use futures_core::ready; diff --git a/actix-http/src/error.rs b/actix-http/src/error.rs index 92126f797..8ef2698a2 100644 --- a/actix-http/src/error.rs +++ b/actix-http/src/error.rs @@ -2,7 +2,7 @@ use std::{error::Error as StdError, fmt, io, str::Utf8Error, string::FromUtf8Error}; -use derive_more::derive::{Display, Error, From}; +use derive_more::{Display, Error, From}; pub use http::{status::InvalidStatusCode, Error as HttpError}; use http::{uri::InvalidUri, StatusCode}; diff --git a/actix-http/src/header/shared/content_encoding.rs b/actix-http/src/header/shared/content_encoding.rs index 0b83659d0..6c4cc9229 100644 --- a/actix-http/src/header/shared/content_encoding.rs +++ b/actix-http/src/header/shared/content_encoding.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use derive_more::derive::{Display, Error}; +use derive_more::{Display, Error}; use http::header::InvalidHeaderValue; use crate::{ diff --git a/actix-http/src/header/shared/quality.rs b/actix-http/src/header/shared/quality.rs index 2a76bc8ca..c9b6c2ae6 100644 --- a/actix-http/src/header/shared/quality.rs +++ b/actix-http/src/header/shared/quality.rs @@ -1,6 +1,6 @@ use std::fmt; -use derive_more::derive::{Display, Error}; +use derive_more::{Display, Error}; const MAX_QUALITY_INT: u16 = 1000; const MAX_QUALITY_FLOAT: f32 = 1.0; diff --git a/actix-http/src/ws/mod.rs b/actix-http/src/ws/mod.rs index 88053b254..c2ae010c2 100644 --- a/actix-http/src/ws/mod.rs +++ b/actix-http/src/ws/mod.rs @@ -5,7 +5,7 @@ use std::io; -use derive_more::derive::{Display, Error, From}; +use derive_more::{Display, Error, From}; use http::{header, Method, StatusCode}; use crate::{body::BoxBody, header::HeaderValue, RequestHead, Response, ResponseBuilder}; diff --git a/actix-http/tests/test_client.rs b/actix-http/tests/test_client.rs index c0019d06b..2d940984d 100644 --- a/actix-http/tests/test_client.rs +++ b/actix-http/tests/test_client.rs @@ -5,7 +5,7 @@ use actix_http_test::test_server; use actix_service::ServiceFactoryExt; use actix_utils::future; use bytes::Bytes; -use derive_more::derive::{Display, Error}; +use derive_more::{Display, Error}; use futures_util::StreamExt as _; const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ diff --git a/actix-http/tests/test_openssl.rs b/actix-http/tests/test_openssl.rs index 77a66f32f..83456b0cb 100644 --- a/actix-http/tests/test_openssl.rs +++ b/actix-http/tests/test_openssl.rs @@ -14,7 +14,7 @@ use actix_http_test::test_server; use actix_service::{fn_service, ServiceFactoryExt}; use actix_utils::future::{err, ok, ready}; use bytes::{Bytes, BytesMut}; -use derive_more::derive::{Display, Error}; +use derive_more::{Display, Error}; use futures_core::Stream; use futures_util::{stream::once, StreamExt as _}; use openssl::{ diff --git a/actix-http/tests/test_rustls.rs b/actix-http/tests/test_rustls.rs index 5b02637dc..43e47c0a4 100644 --- a/actix-http/tests/test_rustls.rs +++ b/actix-http/tests/test_rustls.rs @@ -23,7 +23,7 @@ use actix_service::{fn_factory_with_config, fn_service}; use actix_tls::connect::rustls_0_23::webpki_roots_cert_store; use actix_utils::future::{err, ok, poll_fn}; use bytes::{Bytes, BytesMut}; -use derive_more::derive::{Display, Error}; +use derive_more::{Display, Error}; use futures_core::{ready, Stream}; use futures_util::stream::once; use rustls::{pki_types::ServerName, ServerConfig as RustlsServerConfig}; diff --git a/actix-http/tests/test_server.rs b/actix-http/tests/test_server.rs index 6f273ef33..aafcde19a 100644 --- a/actix-http/tests/test_server.rs +++ b/actix-http/tests/test_server.rs @@ -14,7 +14,7 @@ use actix_rt::{net::TcpStream, time::sleep}; use actix_service::fn_service; use actix_utils::future::{err, ok, ready}; use bytes::Bytes; -use derive_more::derive::{Display, Error}; +use derive_more::{Display, Error}; use futures_util::{stream::once, FutureExt as _, StreamExt as _}; use rand::Rng as _; use regex::Regex; diff --git a/actix-http/tests/test_ws.rs b/actix-http/tests/test_ws.rs index e9c4a01af..da16ab5f5 100644 --- a/actix-http/tests/test_ws.rs +++ b/actix-http/tests/test_ws.rs @@ -14,7 +14,7 @@ use actix_http::{ use actix_http_test::test_server; use actix_service::{fn_factory, Service}; use bytes::Bytes; -use derive_more::derive::{Display, Error, From}; +use derive_more::{Display, Error, From}; use futures_core::future::LocalBoxFuture; use futures_util::{SinkExt as _, StreamExt as _}; diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index c0e62d8aa..f86550f72 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -42,7 +42,7 @@ actix-multipart-derive = { version = "=0.7.0", optional = true } actix-utils = "3" actix-web = { version = "4", default-features = false } -derive_more = { version = "1", features = ["display", "error", "from"] } +derive_more = { version = "2", features = ["display", "error", "from"] } futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] } futures-util = { version = "0.3.17", default-features = false, features = ["alloc"] } httparse = "1.3" diff --git a/actix-multipart/src/error.rs b/actix-multipart/src/error.rs index 8fff5c593..cb4f06d39 100644 --- a/actix-multipart/src/error.rs +++ b/actix-multipart/src/error.rs @@ -5,7 +5,7 @@ use actix_web::{ http::StatusCode, ResponseError, }; -use derive_more::derive::{Display, Error, From}; +use derive_more::{Display, Error, From}; /// A set of errors that can occur during parsing multipart streams. #[derive(Debug, Display, From, Error)] diff --git a/actix-multipart/src/field.rs b/actix-multipart/src/field.rs index b42d8ae1b..0bbb8a657 100644 --- a/actix-multipart/src/field.rs +++ b/actix-multipart/src/field.rs @@ -13,7 +13,7 @@ use actix_web::{ http::header::{self, ContentDisposition, HeaderMap}, web::{Bytes, BytesMut}, }; -use derive_more::derive::{Display, Error}; +use derive_more::{Display, Error}; use futures_core::Stream; use mime::Mime; diff --git a/actix-multipart/src/form/json.rs b/actix-multipart/src/form/json.rs index 8fb1f5ca7..70874e5de 100644 --- a/actix-multipart/src/form/json.rs +++ b/actix-multipart/src/form/json.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use actix_web::{http::StatusCode, web, Error, HttpRequest, ResponseError}; -use derive_more::derive::{Deref, DerefMut, Display, Error}; +use derive_more::{Deref, DerefMut, Display, Error}; use futures_core::future::LocalBoxFuture; use serde::de::DeserializeOwned; diff --git a/actix-multipart/src/form/mod.rs b/actix-multipart/src/form/mod.rs index a9a1ad569..693a45e8e 100644 --- a/actix-multipart/src/form/mod.rs +++ b/actix-multipart/src/form/mod.rs @@ -8,7 +8,7 @@ use std::{ }; use actix_web::{dev, error::PayloadError, web, Error, FromRequest, HttpRequest}; -use derive_more::derive::{Deref, DerefMut}; +use derive_more::{Deref, DerefMut}; use futures_core::future::LocalBoxFuture; use futures_util::{TryFutureExt as _, TryStreamExt as _}; diff --git a/actix-multipart/src/form/tempfile.rs b/actix-multipart/src/form/tempfile.rs index df7a2368a..218b91bff 100644 --- a/actix-multipart/src/form/tempfile.rs +++ b/actix-multipart/src/form/tempfile.rs @@ -7,7 +7,7 @@ use std::{ }; use actix_web::{http::StatusCode, web, Error, HttpRequest, ResponseError}; -use derive_more::derive::{Display, Error}; +use derive_more::{Display, Error}; use futures_core::future::LocalBoxFuture; use futures_util::TryStreamExt as _; use mime::Mime; diff --git a/actix-multipart/src/form/text.rs b/actix-multipart/src/form/text.rs index c4b307f83..b56a20353 100644 --- a/actix-multipart/src/form/text.rs +++ b/actix-multipart/src/form/text.rs @@ -3,7 +3,7 @@ use std::{str, sync::Arc}; use actix_web::{http::StatusCode, web, Error, HttpRequest, ResponseError}; -use derive_more::derive::{Deref, DerefMut, Display, Error}; +use derive_more::{Deref, DerefMut, Display, Error}; use futures_core::future::LocalBoxFuture; use serde::de::DeserializeOwned; diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index f7d6f56d2..d6fd8f5af 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -145,7 +145,7 @@ bytes = "1" bytestring = "1" cfg-if = "1" cookie = { version = "0.16", features = ["percent-encode"], optional = true } -derive_more = { version = "1", features = ["display", "error", "from"] } +derive_more = { version = "2", features = ["display", "error", "from"] } encoding_rs = "0.8" foldhash = "0.1" futures-core = { version = "0.3.17", default-features = false } diff --git a/actix-web/src/error/mod.rs b/actix-web/src/error/mod.rs index fce7ca399..b2f672720 100644 --- a/actix-web/src/error/mod.rs +++ b/actix-web/src/error/mod.rs @@ -6,7 +6,7 @@ // // See pub use actix_http::error::{ContentTypeError, DispatchError, HttpError, ParseError, PayloadError}; -use derive_more::derive::{Display, Error, From}; +use derive_more::{Display, Error, From}; use serde_json::error::Error as JsonError; use serde_urlencoded::{de::Error as FormDeError, ser::Error as FormError}; use url::ParseError as UrlParseError; diff --git a/actix-web/src/http/header/content_length.rs b/actix-web/src/http/header/content_length.rs index 734f4ef38..557c7c9f5 100644 --- a/actix-web/src/http/header/content_length.rs +++ b/actix-web/src/http/header/content_length.rs @@ -1,6 +1,6 @@ use std::{convert::Infallible, str}; -use derive_more::derive::{Deref, DerefMut}; +use derive_more::{Deref, DerefMut}; use crate::{ error::ParseError, diff --git a/actix-web/src/info.rs b/actix-web/src/info.rs index 0655a3df2..76ca28ea7 100644 --- a/actix-web/src/info.rs +++ b/actix-web/src/info.rs @@ -1,7 +1,7 @@ use std::{convert::Infallible, net::SocketAddr}; use actix_utils::future::{err, ok, Ready}; -use derive_more::derive::{Display, Error}; +use derive_more::{Display, Error}; use crate::{ dev::{AppConfig, Payload, RequestHead}, diff --git a/actix-web/src/types/path.rs b/actix-web/src/types/path.rs index ada72a72e..5f22568cc 100644 --- a/actix-web/src/types/path.rs +++ b/actix-web/src/types/path.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use actix_router::PathDeserializer; use actix_utils::future::{ready, Ready}; -use derive_more::derive::{AsRef, Deref, DerefMut, Display, From}; +use derive_more::{AsRef, Deref, DerefMut, Display, From}; use serde::de; use crate::{ @@ -152,7 +152,7 @@ impl PathConfig { #[cfg(test)] mod tests { use actix_router::ResourceDef; - use derive_more::derive::Display; + use derive_more::Display; use serde::Deserialize; use super::*; diff --git a/actix-web/src/types/query.rs b/actix-web/src/types/query.rs index a8e23f78c..e5505131e 100644 --- a/actix-web/src/types/query.rs +++ b/actix-web/src/types/query.rs @@ -187,7 +187,7 @@ impl QueryConfig { #[cfg(test)] mod tests { use actix_http::StatusCode; - use derive_more::derive::Display; + use derive_more::Display; use serde::Deserialize; use super::*; diff --git a/awc/Cargo.toml b/awc/Cargo.toml index e2e2bcd17..b1b1f3d52 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -106,7 +106,7 @@ actix-utils = "3" base64 = "0.22" bytes = "1" cfg-if = "1" -derive_more = { version = "1", features = ["display", "error", "from"] } +derive_more = { version = "2", features = ["display", "error", "from"] } 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.26" diff --git a/awc/src/client/error.rs b/awc/src/client/error.rs index 81543fb7d..6cb595770 100644 --- a/awc/src/client/error.rs +++ b/awc/src/client/error.rs @@ -3,7 +3,7 @@ use std::{fmt, io}; use actix_http::error::{HttpError, ParseError}; #[cfg(feature = "openssl")] use actix_tls::accept::openssl::reexports::Error as OpensslError; -use derive_more::derive::{Display, From}; +use derive_more::{Display, From}; use crate::BoxError; diff --git a/awc/src/error.rs b/awc/src/error.rs index 59dbc8b67..d2d6d71c4 100644 --- a/awc/src/error.rs +++ b/awc/src/error.rs @@ -7,7 +7,7 @@ pub use actix_http::{ ws::{HandshakeError as WsHandshakeError, ProtocolError as WsProtocolError}, StatusCode, }; -use derive_more::derive::{Display, From}; +use derive_more::{Display, From}; use serde_json::error::Error as JsonError; pub use crate::client::{ConnectError, FreezeRequestError, InvalidUrl, SendRequestError}; diff --git a/awc/src/sender.rs b/awc/src/sender.rs index b676ebf28..0015743bd 100644 --- a/awc/src/sender.rs +++ b/awc/src/sender.rs @@ -17,7 +17,7 @@ use actix_http::{ use actix_http::{encoding::Decoder, header::ContentEncoding, Payload}; use actix_rt::time::{sleep, Sleep}; use bytes::Bytes; -use derive_more::derive::From; +use derive_more::From; use futures_core::Stream; use serde::Serialize; From 85843b9b0f41447c883aa104d7d8b207e9ffdcfb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 18:38:45 +0000 Subject: [PATCH 110/144] build(deps): bump taiki-e/install-action from 2.48.4 to 2.48.13 (#3580) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.48.4 to 2.48.13. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.48.4...v2.48.13) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index db7a5c6ba..553408144 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.48.4 + uses: taiki-e/install-action@v2.48.13 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.48.4 + uses: taiki-e/install-action@v2.48.13 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ef4fc5aea..8df255431 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.48.4 + uses: taiki-e/install-action@v2.48.13 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.48.4 + uses: taiki-e/install-action@v2.48.13 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index c5452b282..63f5572e2 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.48.4 + uses: taiki-e/install-action@v2.48.13 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b026572f5..f6aa84b42 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.48.4 + uses: taiki-e/install-action@v2.48.13 with: tool: just From b8bdee0606749cf3641eca2b7064c57c4cf23344 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 00:59:19 +0000 Subject: [PATCH 111/144] build(deps): bump taiki-e/install-action from 2.48.13 to 2.49.0 (#3586) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.48.13 to 2.49.0. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.48.13...v2.49.0) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 553408144..16f6b14e2 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.48.13 + uses: taiki-e/install-action@v2.49.0 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.48.13 + uses: taiki-e/install-action@v2.49.0 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8df255431..ed4b22f24 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.48.13 + uses: taiki-e/install-action@v2.49.0 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.48.13 + uses: taiki-e/install-action@v2.49.0 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 63f5572e2..44273c452 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.48.13 + uses: taiki-e/install-action@v2.49.0 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f6aa84b42..7cf785c37 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.48.13 + uses: taiki-e/install-action@v2.49.0 with: tool: just From 98c263b3eefcc2f4c8d921ddbf7a0ef3479e7ff2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 9 Mar 2025 04:20:55 +0000 Subject: [PATCH 112/144] build(deps): bump taiki-e/install-action from 2.49.0 to 2.49.10 (#3590) * build(deps): bump taiki-e/install-action from 2.49.0 to 2.49.10 Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.49.0 to 2.49.10. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.49.0...v2.49.10) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * ci: fix msrv --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Rob Ede --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- justfile | 2 ++ 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 16f6b14e2..209bad860 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.49.0 + uses: taiki-e/install-action@v2.49.10 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.49.0 + uses: taiki-e/install-action@v2.49.10 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed4b22f24..b08d5f17b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.49.0 + uses: taiki-e/install-action@v2.49.10 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.49.0 + uses: taiki-e/install-action@v2.49.10 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 44273c452..b64cefeb8 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.49.0 + uses: taiki-e/install-action@v2.49.10 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 7cf785c37..f05deb216 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.49.0 + uses: taiki-e/install-action@v2.49.10 with: tool: just diff --git a/justfile b/justfile index 3a5e417fd..2b6d04d18 100644 --- a/justfile +++ b/justfile @@ -13,6 +13,8 @@ downgrade-for-msrv: cargo update -p=parse-size --precise=1.0.0 cargo update -p=clap --precise=4.4.18 cargo update -p=divan --precise=0.1.15 + cargo update -p=litemap --precise=0.7.4 + cargo update -p=zerofrom --precise=0.1.5 msrv := ``` cargo metadata --format-version=1 \ From 98ced477f7b01d7d1f8e2e736d3360ab6d2d3bb1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 9 Mar 2025 04:42:41 +0000 Subject: [PATCH 113/144] build(deps): bump ilammy/setup-nasm from 1.5.1 to 1.5.2 (#3593) Bumps [ilammy/setup-nasm](https://github.com/ilammy/setup-nasm) from 1.5.1 to 1.5.2. - [Release notes](https://github.com/ilammy/setup-nasm/releases) - [Commits](https://github.com/ilammy/setup-nasm/compare/v1.5.1...v1.5.2) --- updated-dependencies: - dependency-name: ilammy/setup-nasm dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 2 +- .github/workflows/ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 209bad860..191a65064 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -32,7 +32,7 @@ jobs: - name: Install nasm if: matrix.target.os == 'windows-latest' - uses: ilammy/setup-nasm@v1.5.1 + uses: ilammy/setup-nasm@v1.5.2 - name: Install OpenSSL if: matrix.target.os == 'windows-latest' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b08d5f17b..4efe301c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,7 +43,7 @@ jobs: - name: Install nasm if: matrix.target.os == 'windows-latest' - uses: ilammy/setup-nasm@v1.5.1 + uses: ilammy/setup-nasm@v1.5.2 - name: Install OpenSSL if: matrix.target.os == 'windows-latest' From a2307fbb86f15117178a8f0b466586bae88fd927 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 9 Mar 2025 04:44:29 +0000 Subject: [PATCH 114/144] build(deps): bump codecov/codecov-action from 5.3.1 to 5.4.0 (#3591) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.3.1 to 5.4.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v5.3.1...v5.4.0) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b64cefeb8..e7c22c1f6 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -32,7 +32,7 @@ jobs: run: just test-coverage-codecov - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.3.1 + uses: codecov/codecov-action@v5.4.0 with: files: codecov.json fail_ci_if_error: true From 0796f8e79630f1a8bf4d9ef445dacf8432f22ad4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 9 Mar 2025 04:50:17 +0000 Subject: [PATCH 115/144] build(deps): bump actions-rust-lang/setup-rust-toolchain from 1.10.1 to 1.11.0 (#3592) build(deps): bump actions-rust-lang/setup-rust-toolchain Bumps [actions-rust-lang/setup-rust-toolchain](https://github.com/actions-rust-lang/setup-rust-toolchain) from 1.10.1 to 1.11.0. - [Release notes](https://github.com/actions-rust-lang/setup-rust-toolchain/releases) - [Changelog](https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions-rust-lang/setup-rust-toolchain/compare/v1.10.1...v1.11.0) --- updated-dependencies: - dependency-name: actions-rust-lang/setup-rust-toolchain dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 6 +++--- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 191a65064..83af66a01 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -44,7 +44,7 @@ jobs: echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV - name: Install Rust (${{ matrix.version.name }}) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 with: toolchain: ${{ matrix.version.version }} @@ -80,7 +80,7 @@ jobs: uses: rui314/setup-mold@v1 - name: Install Rust - uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 - name: Install just, cargo-hack uses: taiki-e/install-action@v2.49.10 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4efe301c2..9a12808a3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,7 @@ jobs: uses: rui314/setup-mold@v1 - name: Install Rust (${{ matrix.version.name }}) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 with: toolchain: ${{ matrix.version.version }} @@ -92,7 +92,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust - uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 with: toolchain: nightly @@ -108,7 +108,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust (nightly) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 with: toolchain: nightly diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index e7c22c1f6..2019df85d 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust (nightly) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 with: toolchain: nightly components: llvm-tools diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f05deb216..727a010bb 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust (nightly) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 with: toolchain: nightly components: rustfmt @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust - uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 with: components: clippy @@ -55,7 +55,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust (nightly) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 with: toolchain: nightly components: rust-docs @@ -72,7 +72,7 @@ jobs: - uses: actions/checkout@v4 - name: Install Rust (${{ vars.RUST_VERSION_EXTERNAL_TYPES }}) - uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 with: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} From df0885cf21856431124326ce144d45a57fa3eb6e Mon Sep 17 00:00:00 2001 From: Bernard Assan Date: Sun, 9 Mar 2025 16:40:00 +0000 Subject: [PATCH 116/144] Add from_bytes/u8_bytes to dev::Payload (#3595) * feat: Add from_bytes/u8_bytes to dev::Payload This allows convinent construction of Payload from bytes which is useful in middlewares closes actix/actix-web#3589 Add doc comment and changelog entry * implement from for payload --------- Co-authored-by: Rob Ede --- actix-http/CHANGES.md | 2 ++ actix-http/src/payload.rs | 23 ++++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 23ebe43e1..703a4cad1 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -6,6 +6,8 @@ - Add `header::CLEAR_SITE_DATA` constant. - Add `Extensions::get_or_insert[_with]()` methods. +- Implement `From` for `Payload`. +- Implement `From>` for `Payload`. ### Changed diff --git a/actix-http/src/payload.rs b/actix-http/src/payload.rs index 7d476c55f..d7a52417e 100644 --- a/actix-http/src/payload.rs +++ b/actix-http/src/payload.rs @@ -41,13 +41,31 @@ pin_project! { } impl From for Payload { + #[inline] fn from(payload: crate::h1::Payload) -> Self { Payload::H1 { payload } } } +impl From for Payload { + #[inline] + fn from(bytes: Bytes) -> Self { + let (_, mut pl) = crate::h1::Payload::create(true); + pl.unread_data(bytes); + self::Payload::from(pl) + } +} + +impl From> for Payload { + #[inline] + fn from(vec: Vec) -> Self { + Payload::from(Bytes::from(vec)) + } +} + #[cfg(feature = "http2")] impl From for Payload { + #[inline] fn from(payload: crate::h2::Payload) -> Self { Payload::H2 { payload } } @@ -55,6 +73,7 @@ impl From for Payload { #[cfg(feature = "http2")] impl From<::h2::RecvStream> for Payload { + #[inline] fn from(stream: ::h2::RecvStream) -> Self { Payload::H2 { payload: crate::h2::Payload::new(stream), @@ -63,13 +82,15 @@ impl From<::h2::RecvStream> for Payload { } impl From for Payload { + #[inline] fn from(payload: BoxedPayloadStream) -> Self { Payload::Stream { payload } } } impl Payload { - /// Takes current payload and replaces it with `None` value + /// Takes current payload and replaces it with `None` value. + #[must_use] pub fn take(&mut self) -> Payload { mem::replace(self, Payload::None) } From aa000b429d0efed0067249b1eaa5a1bede7a9af7 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 9 Mar 2025 19:01:37 +0000 Subject: [PATCH 117/144] chore(actix-http): prepare release 3.10.0 --- actix-http/CHANGES.md | 2 ++ actix-http/Cargo.toml | 2 +- actix-http/README.md | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 703a4cad1..7324cba5a 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -2,6 +2,8 @@ ## Unreleased +## 3.10.0 + ### Added - Add `header::CLEAR_SITE_DATA` constant. diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index a1b735179..06b40172d 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-http" -version = "3.9.0" +version = "3.10.0" authors = [ "Nikolay Kim ", "Rob Ede ", diff --git a/actix-http/README.md b/actix-http/README.md index f78ea86f5..1e81cf33c 100644 --- a/actix-http/README.md +++ b/actix-http/README.md @@ -5,11 +5,11 @@ [![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.9.0)](https://docs.rs/actix-http/3.9.0) +[![Documentation](https://docs.rs/actix-http/badge.svg?version=3.10.0)](https://docs.rs/actix-http/3.10.0) ![Version](https://img.shields.io/badge/rustc-1.72+-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.9.0/status.svg)](https://deps.rs/crate/actix-http/3.9.0) +[![dependency status](https://deps.rs/crate/actix-http/3.10.0/status.svg)](https://deps.rs/crate/actix-http/3.10.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) From 4bb495aba05acedfb90066a9caa0dc754930e8a6 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 9 Mar 2025 19:02:33 +0000 Subject: [PATCH 118/144] chore(actix-web): prepare release 4.10.0 --- actix-web/CHANGES.md | 7 +++++++ actix-web/Cargo.toml | 2 +- actix-web/README.md | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index edbdc6982..f7d84989f 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -2,7 +2,14 @@ ## Unreleased +## 4.10.0 + +### Added + - Implement `Responder` for `Result<(), E: Into>`. Returning `Ok(())` responds with HTTP 204 No Content. + +### Changed + - On Windows, an error is now returned from `HttpServer::bind()` (or TLS variants) when binding to a socket that's already in use. - Update `brotli` dependency to `7`. - Minimum supported Rust version (MSRV) is now 1.75. diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index d6fd8f5af..da4832d75 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-web" -version = "4.9.0" +version = "4.10.0" description = "Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust" authors = [ "Nikolay Kim ", diff --git a/actix-web/README.md b/actix-web/README.md index 70f167dfd..aaae5796a 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.9.0)](https://docs.rs/actix-web/4.9.0) +[![Documentation](https://docs.rs/actix-web/badge.svg?version=4.10.0)](https://docs.rs/actix-web/4.10.0) ![MSRV](https://img.shields.io/badge/rustc-1.72+-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.9.0/status.svg)](https://deps.rs/crate/actix-web/4.9.0) +[![Dependency Status](https://deps.rs/crate/actix-web/4.10.0/status.svg)](https://deps.rs/crate/actix-web/4.10.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/graph/badge.svg?token=dSwOnp9QCv)](https://codecov.io/gh/actix/actix-web) From 92c1e2230dc52a45355361c401ecf504ab625738 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 9 Mar 2025 19:03:27 +0000 Subject: [PATCH 119/144] chore(awc): prepare release 3.6.0 --- awc/CHANGES.md | 6 ++++-- awc/Cargo.toml | 2 +- awc/README.md | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/awc/CHANGES.md b/awc/CHANGES.md index df3003981..d3fd7147b 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -2,10 +2,12 @@ ## Unreleased -- Update `brotli` dependency to `7`. +## 3.6.0 + - Prevent panics on connection pool drop when Tokio runtime is shutdown early. -- Minimum supported Rust version (MSRV) is now 1.75. - Do not send `Host` header on HTTP/2 requests, as it is not required, and some web servers may reject it. +- Update `brotli` dependency to `7`. +- Minimum supported Rust version (MSRV) is now 1.75. ## 3.5.1 diff --git a/awc/Cargo.toml b/awc/Cargo.toml index b1b1f3d52..e399aef76 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "awc" -version = "3.5.1" +version = "3.6.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 28d28ed89..954cc2803 100644 --- a/awc/README.md +++ b/awc/README.md @@ -5,9 +5,9 @@ [![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.5.1)](https://docs.rs/awc/3.5.1) +[![Documentation](https://docs.rs/awc/badge.svg?version=3.6.0)](https://docs.rs/awc/3.6.0) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/awc) -[![Dependency Status](https://deps.rs/crate/awc/3.5.1/status.svg)](https://deps.rs/crate/awc/3.5.1) +[![Dependency Status](https://deps.rs/crate/awc/3.6.0/status.svg)](https://deps.rs/crate/awc/3.6.0) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) From f63cf69e6a7ee453af0a0a560818e1ea8c199e7b Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 9 Mar 2025 19:08:00 +0000 Subject: [PATCH 120/144] docs: remove "copyright" --- actix-web/src/http/header/content_disposition.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-web/src/http/header/content_disposition.rs b/actix-web/src/http/header/content_disposition.rs index ff3bb6761..c836b1073 100644 --- a/actix-web/src/http/header/content_disposition.rs +++ b/actix-web/src/http/header/content_disposition.rs @@ -267,7 +267,7 @@ impl DispositionParam { /// parameters: vec![DispositionParam::FilenameExt(ExtendedValue { /// charset: Charset::Iso_8859_1, // The character set for the bytes of the filename /// language_tag: None, // The optional language tag (see `language-tag` crate) -/// value: b"\xa9 Copyright 1989.txt".to_vec(), // the actual bytes of the filename +/// value: b"\xA9 Ferris 2011.txt".to_vec(), // the actual bytes of the filename /// })], /// }; /// assert!(cd1.is_attachment()); From e8351cc3aa8c91da6baa8ce7977e48eec9e11943 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 00:58:26 +0000 Subject: [PATCH 121/144] build(deps): bump taiki-e/install-action from 2.49.10 to 2.49.17 (#3597) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.49.10 to 2.49.17. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.49.10...v2.49.17) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 83af66a01..d49a09a57 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.49.10 + uses: taiki-e/install-action@v2.49.17 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.49.10 + uses: taiki-e/install-action@v2.49.17 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9a12808a3..657075982 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.49.10 + uses: taiki-e/install-action@v2.49.17 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.49.10 + uses: taiki-e/install-action@v2.49.17 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 2019df85d..bd5b4fcea 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.49.10 + uses: taiki-e/install-action@v2.49.17 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 727a010bb..461fee4ee 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.49.10 + uses: taiki-e/install-action@v2.49.17 with: tool: just From c6e7ebd18529ea3803468943a1a83c26855b6213 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 10 Mar 2025 04:23:03 +0000 Subject: [PATCH 122/144] refactor: use Payload::from internally --- actix-web/src/types/either.rs | 10 ++-------- awc/Cargo.toml | 2 +- awc/src/test.rs | 4 +--- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/actix-web/src/types/either.rs b/actix-web/src/types/either.rs index 7883e89f6..d8b3f1180 100644 --- a/actix-web/src/types/either.rs +++ b/actix-web/src/types/either.rs @@ -238,7 +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 dev::Payload::from(bytes)); EitherExtractState::Left { left, fallback } } Err(err) => break Err(EitherExtractError::Bytes(err)), @@ -251,7 +251,7 @@ where Err(left_err) => { let right = R::from_request( this.req, - &mut payload_from_bytes(mem::take(fallback)), + &mut dev::Payload::from(mem::take(fallback)), ); EitherExtractState::Right { left_err: Some(left_err), @@ -276,12 +276,6 @@ where } } -fn payload_from_bytes(bytes: Bytes) -> dev::Payload { - let (_, mut h1_payload) = actix_http::h1::Payload::create(true); - h1_payload.unread_data(bytes); - dev::Payload::from(h1_payload) -} - #[cfg(test)] mod tests { use serde::{Deserialize, Serialize}; diff --git a/awc/Cargo.toml b/awc/Cargo.toml index e399aef76..94eebcbcf 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -98,7 +98,7 @@ dangerous-h2c = [] [dependencies] actix-codec = "0.5" actix-service = "2" -actix-http = { version = "3.7", features = ["http2", "ws"] } +actix-http = { version = "3.10", features = ["http2", "ws"] } actix-rt = { version = "2.1", default-features = false } actix-tls = { version = "3.4", features = ["connect", "uri"] } actix-utils = "3" diff --git a/awc/src/test.rs b/awc/src/test.rs index 126583179..a7ed3faf0 100644 --- a/awc/src/test.rs +++ b/awc/src/test.rs @@ -65,9 +65,7 @@ impl TestResponse { /// Set response's payload pub fn set_payload>(mut self, data: B) -> Self { - let (_, mut payload) = h1::Payload::create(true); - payload.unread_data(data.into()); - self.payload = Some(payload.into()); + self.payload = Some(Payload::from(data.into())); self } From 1390e2970584cbbb6d7c9a0ed69d5964423d7bd9 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 10 Mar 2025 04:23:20 +0000 Subject: [PATCH 123/144] docs: fix lint --- awc/src/client/connector.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/awc/src/client/connector.rs b/awc/src/client/connector.rs index 15dc34557..a7c606826 100644 --- a/awc/src/client/connector.rs +++ b/awc/src/client/connector.rs @@ -89,9 +89,9 @@ impl Connector<()> { /// # Panics /// /// - When the `rustls-0_23-webpki-roots` or `rustls-0_23-native-roots` features are enabled - /// and no default crypto provider has been loaded, this method will panic. + /// and no default crypto provider has been loaded, this method will panic. /// - When the `rustls-0_23-native-roots` or `rustls-0_22-native-roots` features are enabled - /// and the runtime system has no native root certificates, this method will panic. + /// and the runtime system has no native root certificates, this method will panic. #[allow(clippy::new_ret_no_self, clippy::let_unit_value)] pub fn new() -> Connector< impl Service< From 353873fc0461ce35846d43951597dd293c1153ba Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 10 Mar 2025 04:38:20 +0000 Subject: [PATCH 124/144] chore: fix derive-more feature selection --- actix-web/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index da4832d75..ece87dc20 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -145,7 +145,7 @@ bytes = "1" bytestring = "1" cfg-if = "1" cookie = { version = "0.16", features = ["percent-encode"], optional = true } -derive_more = { version = "2", features = ["display", "error", "from"] } +derive_more = { version = "2", features = ["as_ref", "deref", "deref_mut", "display", "error", "from"] } encoding_rs = "0.8" foldhash = "0.1" futures-core = { version = "0.3.17", default-features = false } From d898e8f739d934fa461f7c912024ee30775c580d Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 10 Mar 2025 04:38:45 +0000 Subject: [PATCH 125/144] chore(actix-web): prepare release 4.10.1 --- actix-web/CHANGES.md | 4 ++++ actix-web/Cargo.toml | 2 +- actix-web/README.md | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index f7d84989f..972a5ffdb 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -2,6 +2,10 @@ ## Unreleased +## 4.10.1 + +- No significant changes since `4.10.0`. + ## 4.10.0 ### Added diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index ece87dc20..c779e774e 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-web" -version = "4.10.0" +version = "4.10.1" description = "Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust" authors = [ "Nikolay Kim ", diff --git a/actix-web/README.md b/actix-web/README.md index aaae5796a..f6df14c3f 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.10.0)](https://docs.rs/actix-web/4.10.0) +[![Documentation](https://docs.rs/actix-web/badge.svg?version=4.10.1)](https://docs.rs/actix-web/4.10.1) ![MSRV](https://img.shields.io/badge/rustc-1.72+-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.10.0/status.svg)](https://deps.rs/crate/actix-web/4.10.0) +[![Dependency Status](https://deps.rs/crate/actix-web/4.10.1/status.svg)](https://deps.rs/crate/actix-web/4.10.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/graph/badge.svg?token=dSwOnp9QCv)](https://codecov.io/gh/actix/actix-web) From 1005b6a12aa36ef57b0329df99deda946d60faef Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 10 Mar 2025 04:51:37 +0000 Subject: [PATCH 126/144] chore: fix actix-http ver req --- actix-web/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index c779e774e..c9f5ab322 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -137,7 +137,7 @@ actix-service = "2" actix-utils = "3" actix-tls = { version = "3.4", default-features = false, optional = true } -actix-http = { version = "3.7", features = ["ws"] } +actix-http = { version = "3.10", features = ["ws"] } actix-router = { version = "0.5.3", default-features = false, features = ["http"] } actix-web-codegen = { version = "4.3", optional = true, default-features = false } From cede0c6dbba08e1f5c882f45155f48fd894c6191 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 10 Mar 2025 04:52:02 +0000 Subject: [PATCH 127/144] chore(actix-web): prepare release 4.10.2 --- actix-web/CHANGES.md | 4 ++++ actix-web/Cargo.toml | 2 +- actix-web/README.md | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 972a5ffdb..394a8c934 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -2,6 +2,10 @@ ## Unreleased +## 4.10.2 + +- No significant changes since `4.10.1`. + ## 4.10.1 - No significant changes since `4.10.0`. diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index c9f5ab322..153934ba6 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-web" -version = "4.10.1" +version = "4.10.2" description = "Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust" authors = [ "Nikolay Kim ", diff --git a/actix-web/README.md b/actix-web/README.md index f6df14c3f..63349a35a 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.10.1)](https://docs.rs/actix-web/4.10.1) +[![Documentation](https://docs.rs/actix-web/badge.svg?version=4.10.2)](https://docs.rs/actix-web/4.10.2) ![MSRV](https://img.shields.io/badge/rustc-1.72+-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.10.1/status.svg)](https://deps.rs/crate/actix-web/4.10.1) +[![Dependency Status](https://deps.rs/crate/actix-web/4.10.2/status.svg)](https://deps.rs/crate/actix-web/4.10.2)
[![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/graph/badge.svg?token=dSwOnp9QCv)](https://codecov.io/gh/actix/actix-web) From ab18efe0ac1734265e94b3abdbeb9c53221acfac Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Fri, 21 Mar 2025 05:51:45 +0000 Subject: [PATCH 128/144] chore: check in lockfile --- .gitignore | 1 - Cargo.lock | 3964 ++++++++++++++++++++++++++++++++++++++++++++++++++++ justfile | 13 +- 3 files changed, 3971 insertions(+), 7 deletions(-) create mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index 48ccccb92..516ee9919 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -Cargo.lock target/ guide/build/ /gh-pages diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..4becc83aa --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,3964 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "actix" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de7fa236829ba0841304542f7614c42b80fca007455315c45c785ccfa873a85b" +dependencies = [ + "actix-rt", + "bitflags 2.9.0", + "bytes", + "crossbeam-channel", + "futures-core", + "futures-sink", + "futures-task", + "futures-util", + "log", + "once_cell", + "parking_lot", + "pin-project-lite", + "smallvec", + "tokio", + "tokio-util", +] + +[[package]] +name = "actix-codec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" +dependencies = [ + "bitflags 2.9.0", + "bytes", + "futures-core", + "futures-sink", + "memchr", + "pin-project-lite", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "actix-files" +version = "0.6.6" +dependencies = [ + "actix-http", + "actix-rt", + "actix-server", + "actix-service", + "actix-test", + "actix-utils", + "actix-web", + "bitflags 2.9.0", + "bytes", + "derive_more", + "env_logger", + "futures-core", + "http-range", + "log", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "tempfile", + "tokio-uring", + "v_htmlescape", +] + +[[package]] +name = "actix-http" +version = "3.10.0" +dependencies = [ + "actix-codec", + "actix-http-test", + "actix-rt", + "actix-server", + "actix-service", + "actix-tls", + "actix-utils", + "actix-web", + "async-stream", + "base64 0.22.1", + "bitflags 2.9.0", + "brotli", + "bytes", + "bytestring", + "criterion", + "derive_more", + "divan", + "encoding_rs", + "env_logger", + "flate2", + "foldhash", + "futures-core", + "futures-util", + "h2", + "http 0.2.12", + "httparse", + "httpdate", + "itoa", + "language-tags", + "local-channel", + "memchr", + "mime", + "once_cell", + "openssl", + "percent-encoding", + "pin-project-lite", + "rand 0.9.0", + "rcgen", + "regex", + "rustls 0.23.25", + "rustls-pemfile", + "rustversion", + "serde", + "serde_json", + "sha1", + "smallvec", + "static_assertions", + "tokio", + "tokio-util", + "tracing", + "zstd", +] + +[[package]] +name = "actix-http-test" +version = "3.2.0" +dependencies = [ + "actix-codec", + "actix-http", + "actix-rt", + "actix-server", + "actix-service", + "actix-tls", + "actix-utils", + "awc", + "bytes", + "futures-core", + "http 0.2.12", + "log", + "openssl", + "serde", + "serde_json", + "serde_urlencoded", + "slab", + "socket2 0.5.8", + "tokio", +] + +[[package]] +name = "actix-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "actix-multipart" +version = "0.7.2" +dependencies = [ + "actix-http", + "actix-multipart-derive", + "actix-multipart-rfc7578", + "actix-rt", + "actix-test", + "actix-utils", + "actix-web", + "assert_matches", + "awc", + "derive_more", + "env_logger", + "futures-core", + "futures-test", + "futures-util", + "httparse", + "local-waker", + "log", + "memchr", + "mime", + "multer", + "rand 0.9.0", + "serde", + "serde_json", + "serde_plain", + "tempfile", + "tokio", + "tokio-stream", +] + +[[package]] +name = "actix-multipart-derive" +version = "0.7.0" +dependencies = [ + "actix-multipart", + "actix-web", + "darling", + "parse-size", + "proc-macro2", + "quote", + "rustversion", + "syn", + "trybuild", +] + +[[package]] +name = "actix-multipart-rfc7578" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af5e8f1e4c6baf42b8b78f3b2a85df02b54f10f5fdf54bf1f9b40211c130e427" +dependencies = [ + "actix-http", + "bytes", + "common-multipart-rfc7578", + "futures-core", + "thiserror", +] + +[[package]] +name = "actix-router" +version = "0.5.3" +dependencies = [ + "bytestring", + "cfg-if", + "criterion", + "http 0.2.12", + "percent-encoding", + "regex", + "regex-lite", + "serde", + "tracing", +] + +[[package]] +name = "actix-rt" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208" +dependencies = [ + "actix-macros", + "futures-core", + "tokio", + "tokio-uring", +] + +[[package]] +name = "actix-server" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6398974fd4284f4768af07965701efbbb5fdc0616bff20cade1bb14b77675e24" +dependencies = [ + "actix-rt", + "actix-service", + "actix-utils", + "futures-core", + "futures-util", + "mio", + "socket2 0.5.8", + "tokio", + "tokio-uring", + "tracing", +] + +[[package]] +name = "actix-service" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e46f36bf0e5af44bdc4bdb36fbbd421aa98c79a9bce724e1edeb3894e10dc7f" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "actix-test" +version = "0.1.5" +dependencies = [ + "actix-codec", + "actix-http", + "actix-http-test", + "actix-rt", + "actix-service", + "actix-utils", + "actix-web", + "awc", + "futures-core", + "futures-util", + "log", + "openssl", + "rustls 0.20.9", + "rustls 0.21.12", + "rustls 0.22.4", + "rustls 0.23.25", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", +] + +[[package]] +name = "actix-tls" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac453898d866cdbecdbc2334fe1738c747b4eba14a677261f2b768ba05329389" +dependencies = [ + "actix-rt", + "actix-service", + "actix-utils", + "futures-core", + "http 0.2.12", + "http 1.3.1", + "impl-more", + "openssl", + "pin-project-lite", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-openssl", + "tokio-rustls 0.23.4", + "tokio-rustls 0.24.1", + "tokio-rustls 0.25.0", + "tokio-rustls 0.26.2", + "tokio-util", + "tracing", + "webpki-roots 0.22.6", + "webpki-roots 0.25.4", + "webpki-roots 0.26.8", +] + +[[package]] +name = "actix-utils" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" +dependencies = [ + "local-waker", + "pin-project-lite", +] + +[[package]] +name = "actix-web" +version = "4.10.2" +dependencies = [ + "actix-codec", + "actix-files", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-test", + "actix-tls", + "actix-utils", + "actix-web-codegen", + "awc", + "brotli", + "bytes", + "bytestring", + "cfg-if", + "const-str", + "cookie", + "core_affinity", + "criterion", + "derive_more", + "encoding_rs", + "env_logger", + "flate2", + "foldhash", + "futures-core", + "futures-util", + "impl-more", + "itoa", + "language-tags", + "log", + "mime", + "once_cell", + "openssl", + "pin-project-lite", + "rand 0.9.0", + "rcgen", + "regex", + "regex-lite", + "rustls 0.23.25", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "smallvec", + "socket2 0.5.8", + "static_assertions", + "time", + "tokio", + "tracing", + "url", + "zstd", +] + +[[package]] +name = "actix-web-actors" +version = "4.3.1+deprecated" +dependencies = [ + "actix", + "actix-codec", + "actix-http", + "actix-rt", + "actix-test", + "actix-web", + "awc", + "bytes", + "bytestring", + "env_logger", + "futures-core", + "futures-util", + "mime", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "actix-web-codegen" +version = "4.3.0" +dependencies = [ + "actix-macros", + "actix-router", + "actix-rt", + "actix-test", + "actix-utils", + "actix-web", + "futures-core", + "proc-macro2", + "quote", + "rustversion", + "syn", + "trybuild", +] + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +dependencies = [ + "anstyle", + "once_cell", + "windows-sys 0.59.0", +] + +[[package]] +name = "assert_matches" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "awc" +version = "3.6.0" +dependencies = [ + "actix-codec", + "actix-http", + "actix-http-test", + "actix-rt", + "actix-server", + "actix-service", + "actix-test", + "actix-tls", + "actix-utils", + "actix-web", + "base64 0.22.1", + "brotli", + "bytes", + "cfg-if", + "const-str", + "cookie", + "derive_more", + "env_logger", + "flate2", + "futures-core", + "futures-util", + "h2", + "http 0.2.12", + "itoa", + "log", + "mime", + "openssl", + "percent-encoding", + "pin-project-lite", + "rand 0.9.0", + "rcgen", + "rustls 0.20.9", + "rustls 0.21.12", + "rustls 0.22.4", + "rustls 0.23.25", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "static_assertions", + "tokio", + "trust-dns-resolver", + "zstd", +] + +[[package]] +name = "aws-lc-rs" +version = "1.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dabb68eb3a7aa08b46fddfd59a3d55c978243557a90ab804769f7e20e67d2b01" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77926887776171ced7d662120a75998e444d3750c951abfe07f90da130514b1f" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", +] + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "base64" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags 2.9.0", + "cexpr", + "clang-sys", + "itertools 0.12.1", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "brotli" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74fa05ad7d803d413eb8380983b092cbbaf9a85f151b871360e7b00cd7060b37" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "bytestring" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e465647ae23b2823b0753f50decb2d5a86d2bb2cac04788fafd1f80e45378e5f" +dependencies = [ + "bytes", +] + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cc" +version = "1.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "4.5.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" +dependencies = [ + "anstyle", + "clap_lex", + "terminal_size", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "common-multipart-rfc7578" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f08d53b5e0c302c5830cfa7511ba0edc3f241c691a95c0d184dfb761e11a6cc2" +dependencies = [ + "bytes", + "futures-core", + "futures-util", + "http 1.3.1", + "mime", + "mime_guess", + "rand 0.8.5", + "thiserror", +] + +[[package]] +name = "condtype" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf0a07a401f374238ab8e2f11a104d2851bf9ce711ec69804834de8af45c7af" + +[[package]] +name = "const-str" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3618cccc083bb987a415d85c02ca6c9994ea5b44731ec28b9ecf09658655fba9" + +[[package]] +name = "cookie" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" +dependencies = [ + "aes-gcm", + "base64 0.20.0", + "hkdf", + "hmac", + "percent-encoding", + "rand 0.8.5", + "sha2", + "subtle", + "time", + "version_check", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core_affinity" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a034b3a7b624016c6e13f5df875747cc25f884156aad2abd12b6c46797971342" +dependencies = [ + "libc", + "num_cpus", + "winapi", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "is-terminal", + "itertools 0.10.5", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools 0.10.5", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "data-encoding" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" + +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "divan" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0583193020b29b03682d8d33bb53a5b0f50df6daacece12ca99b904cfdcb8c4" +dependencies = [ + "cfg-if", + "clap", + "condtype", + "divan-macros", + "libc", + "regex-lite", +] + +[[package]] +name = "divan-macros" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc51d98e636f5e3b0759a39257458b22619cac7e96d932da6eeb052891bb67c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum-as-inner" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "env_filter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "flate2" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-test" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5961fb6311645f46e2cdc2964a8bfae6743fd72315eaec181a71ae3eb2467113" +dependencies = [ + "futures-core", + "futures-executor", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "futures-util", + "pin-project", +] + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "hostname" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba" +dependencies = [ + "cfg-if", + "libc", + "windows", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-range" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "impl-more" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a5a9a0ff0086c7a148acb942baaabeadf9504d10400b5a05645853729b9cd2" + +[[package]] +name = "indexmap" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "io-uring" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595a0399f411a508feb2ec1e970a4a30c249351e30208960d58298de8660b0e5" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + +[[package]] +name = "ipconfig" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +dependencies = [ + "socket2 0.5.8", + "widestring", + "windows-sys 0.48.0", + "winreg", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "is-terminal" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" +dependencies = [ + "hermit-abi 0.5.0", + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jiff" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d699bc6dfc879fb1bf9bdff0d4c56f0884fc6f0d0eb0fba397a6d00cd9a6b85e" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", +] + +[[package]] +name = "jiff-static" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d16e75759ee0aa64c57a56acbf43916987b20c77373cb7e808979e02b93c9f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "language-tags" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.171" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" + +[[package]] +name = "libloading" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" + +[[package]] +name = "litemap" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" + +[[package]] +name = "local-channel" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" +dependencies = [ + "futures-core", + "futures-sink", + "local-waker", +] + +[[package]] +name = "local-waker" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + +[[package]] +name = "multer" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http 1.3.1", + "httparse", + "memchr", + "mime", + "spin 0.9.8", + "version_check", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" + +[[package]] +name = "oorandom" +version = "11.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl" +version = "0.10.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" +dependencies = [ + "bitflags 2.9.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "parse-size" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487f2ccd1e17ce8c1bfab3a65c89525af41cfad4c8659021a1e9a2aacd73b89b" + +[[package]] +name = "pem" +version = "3.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" +dependencies = [ + "base64 0.22.1", + "serde", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5316f57387668042f561aae71480de936257848f9c43ce528e311d89a07cadeb" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", + "zerocopy", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.2", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rcgen" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2" +dependencies = [ + "pem", + "ring 0.17.14", + "rustls-pki-types", + "time", + "yasna", +] + +[[package]] +name = "redox_syscall" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +dependencies = [ + "bitflags 2.9.0", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "resolv-conf" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48375394603e3dd4b2d64371f7148fd8c7baa2680e28741f2cb8d23b59e3d4c4" +dependencies = [ + "hostname", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.15", + "libc", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.9.0", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" +dependencies = [ + "bitflags 2.9.0", + "errno", + "libc", + "linux-raw-sys 0.9.3", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustls" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +dependencies = [ + "log", + "ring 0.16.20", + "sct", + "webpki", +] + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring 0.17.14", + "rustls-webpki 0.101.7", + "sct", +] + +[[package]] +name = "rustls" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +dependencies = [ + "log", + "ring 0.17.14", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls" +version = "0.23.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "rustls-pki-types", + "rustls-webpki 0.103.0", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.14", + "untrusted 0.9.0", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring 0.17.14", + "rustls-pki-types", + "untrusted 0.9.0", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f" +dependencies = [ + "aws-lc-rs", + "ring 0.17.14", + "rustls-pki-types", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.14", + "untrusted 0.9.0", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.9.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_plain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1fc6db65a611022b23a0dec6975d63fb80a302cb3388835ff02c097258d50" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "target-triple" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ac9aa371f599d22256307c24a9d748c041e548cbf599f35d890f9d365361790" + +[[package]] +name = "tempfile" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" +dependencies = [ + "fastrand", + "getrandom 0.3.2", + "once_cell", + "rustix 1.0.3", + "windows-sys 0.59.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "terminal_size" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed" +dependencies = [ + "rustix 1.0.3", + "windows-sys 0.59.0", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.3.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d9c75b47bdff86fa3334a3db91356b8d7d86a9b839dab7d0bdc5c3d3a077618" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29aa485584182073ed57fd5004aa09c371f021325014694e432313345865fd04" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "tinyvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.44.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.8", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-openssl" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59df6849caa43bb7567f9a36f863c447d95a11d5903c9cc334ba32576a27eadd" +dependencies = [ + "openssl", + "openssl-sys", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.9", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls 0.22.4", + "rustls-pki-types", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls 0.23.25", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-uring" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "748482e3e13584a34664a710168ad5068e8cb1d968aa4ffa887e83ca6dd27967" +dependencies = [ + "bytes", + "futures-util", + "io-uring", + "libc", + "slab", + "socket2 0.4.10", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", +] + +[[package]] +name = "trust-dns-proto" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3119112651c157f4488931a01e586aa459736e9d6046d3bd9105ffb69352d374" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.4.0", + "ipnet", + "once_cell", + "rand 0.8.5", + "smallvec", + "thiserror", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a3e6c3aff1718b3c73e395d1f35202ba2ffa847c6a62eea0db8fb4cfe30be6" +dependencies = [ + "cfg-if", + "futures-util", + "ipconfig", + "lru-cache", + "once_cell", + "parking_lot", + "rand 0.8.5", + "resolv-conf", + "smallvec", + "thiserror", + "tokio", + "tracing", + "trust-dns-proto", +] + +[[package]] +name = "trybuild" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ae08be68c056db96f0e6c6dd820727cca756ced9e1f4cc7fdd20e2a55e23898" +dependencies = [ + "glob", + "serde", + "serde_derive", + "serde_json", + "target-triple", + "termcolor", + "toml", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" + +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna 1.0.3", + "percent-encoding", +] + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "v_htmlescape" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e8257fbc510f0a46eb602c10215901938b5c2a7d5e70fc11483b1d3c9b5b18c" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring 0.17.14", + "untrusted 0.9.0", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "webpki-roots" +version = "0.26.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.44", +] + +[[package]] +name = "widestring" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.0", +] + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.15+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/justfile b/justfile index 2b6d04d18..2f259b17b 100644 --- a/justfile +++ b/justfile @@ -7,14 +7,15 @@ fmt: cargo +nightly fmt fd --hidden --type=file --extension=md --extension=yml --exec-batch npx -y prettier --write -# Downgrade dev-dependencies necessary to run MSRV checks/tests. +# Downgrade dependencies necessary to run MSRV checks/tests. [private] downgrade-for-msrv: - cargo update -p=parse-size --precise=1.0.0 - cargo update -p=clap --precise=4.4.18 - cargo update -p=divan --precise=0.1.15 - cargo update -p=litemap --precise=0.7.4 - cargo update -p=zerofrom --precise=0.1.5 + cargo update -p=parse-size --precise=1.0.0 # next ver: 1.81.0 + cargo update -p=clap --precise=4.4.18 # next ver: 1.74.0 + cargo update -p=divan --precise=0.1.15 # next ver: 1.80.0 + cargo update -p=litemap --precise=0.7.4 # next ver: 1.81.0 + cargo update -p=zerofrom --precise=0.1.5 # next ver: 1.81.0 + cargo update -p=half --precise=2.4.1 # next ver: 1.81.0 msrv := ``` cargo metadata --format-version=1 \ From 95b6a81f43bc82bfb779dddbabb613c8620a20ed Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Fri, 21 Mar 2025 06:06:50 +0000 Subject: [PATCH 129/144] refactor: switch size parsing to bytesize crate --- .cspell.yml | 3 +++ Cargo.lock | 24 ++++++++++++------- actix-multipart-derive/Cargo.toml | 4 ++-- actix-multipart-derive/src/lib.rs | 10 ++++---- actix-multipart-derive/tests/trybuild.rs | 2 +- .../trybuild/size-limit-parse-fail.stderr | 6 ++--- actix-web-codegen/Cargo.toml | 2 +- actix-web-codegen/tests/trybuild.rs | 2 +- justfile | 1 - 9 files changed, 31 insertions(+), 23 deletions(-) create mode 100644 .cspell.yml diff --git a/.cspell.yml b/.cspell.yml new file mode 100644 index 000000000..95a3e2f90 --- /dev/null +++ b/.cspell.yml @@ -0,0 +1,3 @@ +version: "0.2" +words: + - actix diff --git a/Cargo.lock b/Cargo.lock index 4becc83aa..5d1a94d14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -200,11 +200,11 @@ version = "0.7.0" dependencies = [ "actix-multipart", "actix-web", + "bytesize", "darling", - "parse-size", "proc-macro2", "quote", - "rustversion", + "rustversion-msrv", "syn", "trybuild", ] @@ -437,7 +437,7 @@ dependencies = [ "futures-core", "proc-macro2", "quote", - "rustversion", + "rustversion-msrv", "syn", "trybuild", ] @@ -793,6 +793,12 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +[[package]] +name = "bytesize" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3c8f83209414aacf0eeae3cf730b18d6981697fba62f200fcfb92b9f082acba" + [[package]] name = "bytestring" version = "1.4.0" @@ -2218,12 +2224,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "parse-size" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487f2ccd1e17ce8c1bfab3a65c89525af41cfad4c8659021a1e9a2aacd73b89b" - [[package]] name = "pem" version = "3.0.5" @@ -2715,6 +2715,12 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +[[package]] +name = "rustversion-msrv" +version = "0.100.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6ceb60223ee771fb5dfe462e29e5ee92bca9a7b9c555584f4d361045dae0e12" + [[package]] name = "ryu" version = "1.0.20" diff --git a/actix-multipart-derive/Cargo.toml b/actix-multipart-derive/Cargo.toml index 964ef2b74..d4b228020 100644 --- a/actix-multipart-derive/Cargo.toml +++ b/actix-multipart-derive/Cargo.toml @@ -18,8 +18,8 @@ all-features = true proc-macro = true [dependencies] +bytesize = "2" darling = "0.20" -parse-size = "1" proc-macro2 = "1" quote = "1" syn = "2" @@ -27,7 +27,7 @@ syn = "2" [dev-dependencies] actix-multipart = "0.7" actix-web = "4" -rustversion = "1" +rustversion-msrv = "0.100" trybuild = "1" [lints] diff --git a/actix-multipart-derive/src/lib.rs b/actix-multipart-derive/src/lib.rs index 57d2fa875..4df9b78aa 100644 --- a/actix-multipart-derive/src/lib.rs +++ b/actix-multipart-derive/src/lib.rs @@ -9,8 +9,8 @@ use std::collections::HashSet; +use bytesize::ByteSize; use darling::{FromDeriveInput, FromField, FromMeta}; -use parse_size::parse_size; use proc_macro::TokenStream; use proc_macro2::Ident; use quote::quote; @@ -103,7 +103,7 @@ struct ParsedField<'t> { /// # Field Limits /// /// You can use the `#[multipart(limit = "")]` attribute to set field level limits. The limit -/// string is parsed using [parse_size]. +/// string is parsed using [`bytesize`]. /// /// Note: the form is also subject to the global limits configured using `MultipartFormConfig`. /// @@ -150,7 +150,7 @@ struct ParsedField<'t> { /// struct Form { } /// ``` /// -/// [parse_size]: https://docs.rs/parse-size/1/parse_size +/// [`bytesize`]: https://docs.rs/bytesize/2 #[proc_macro_derive(MultipartForm, attributes(multipart))] pub fn impl_multipart_form(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input: syn::DeriveInput = parse_macro_input!(input); @@ -191,8 +191,8 @@ pub fn impl_multipart_form(input: proc_macro::TokenStream) -> proc_macro::TokenS let attrs = FieldAttrs::from_field(field).map_err(|err| err.write_errors())?; let serialization_name = attrs.rename.unwrap_or_else(|| rust_name.to_string()); - let limit = match attrs.limit.map(|limit| match parse_size(&limit) { - Ok(size) => Ok(usize::try_from(size).unwrap()), + let limit = match attrs.limit.map(|limit| match limit.parse::() { + Ok(ByteSize(size)) => Ok(usize::try_from(size).unwrap()), Err(err) => Err(syn::Error::new( field.ident.as_ref().unwrap().span(), format!("Could not parse size limit `{}`: {}", limit, err), diff --git a/actix-multipart-derive/tests/trybuild.rs b/actix-multipart-derive/tests/trybuild.rs index 6b25d78df..7bd140324 100644 --- a/actix-multipart-derive/tests/trybuild.rs +++ b/actix-multipart-derive/tests/trybuild.rs @@ -1,4 +1,4 @@ -#[rustversion::stable(1.72)] // MSRV +#[rustversion_msrv::msrv] #[test] fn compile_macros() { let t = trybuild::TestCases::new(); diff --git a/actix-multipart-derive/tests/trybuild/size-limit-parse-fail.stderr b/actix-multipart-derive/tests/trybuild/size-limit-parse-fail.stderr index fc02a78c4..6633086c0 100644 --- a/actix-multipart-derive/tests/trybuild/size-limit-parse-fail.stderr +++ b/actix-multipart-derive/tests/trybuild/size-limit-parse-fail.stderr @@ -1,16 +1,16 @@ -error: Could not parse size limit `2 bytes`: invalid digit found in string +error: Could not parse size limit `2 bytes`: couldn't parse "bytes" into a known SI unit, couldn't parse unit of "bytes" --> tests/trybuild/size-limit-parse-fail.rs:6:5 | 6 | description: Text, | ^^^^^^^^^^^ -error: Could not parse size limit `2 megabytes`: invalid digit found in string +error: Could not parse size limit `2 megabytes`: couldn't parse "megabytes" into a known SI unit, couldn't parse unit of "megabytes" --> tests/trybuild/size-limit-parse-fail.rs:12:5 | 12 | description: Text, | ^^^^^^^^^^^ -error: Could not parse size limit `four meters`: invalid digit found in string +error: Could not parse size limit `four meters`: couldn't parse "four meters" into a ByteSize, cannot parse float from empty string --> tests/trybuild/size-limit-parse-fail.rs:18:5 | 18 | description: Text, diff --git a/actix-web-codegen/Cargo.toml b/actix-web-codegen/Cargo.toml index d3938da8e..b61565951 100644 --- a/actix-web-codegen/Cargo.toml +++ b/actix-web-codegen/Cargo.toml @@ -34,7 +34,7 @@ actix-web = "4" futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] } trybuild = "1" -rustversion = "1" +rustversion-msrv = "0.100" [lints] workspace = true diff --git a/actix-web-codegen/tests/trybuild.rs b/actix-web-codegen/tests/trybuild.rs index 91073cf3b..0150d56f2 100644 --- a/actix-web-codegen/tests/trybuild.rs +++ b/actix-web-codegen/tests/trybuild.rs @@ -1,4 +1,4 @@ -#[rustversion::stable(1.72)] // MSRV +#[rustversion_msrv::msrv] #[test] fn compile_macros() { let t = trybuild::TestCases::new(); diff --git a/justfile b/justfile index 2f259b17b..8449c3056 100644 --- a/justfile +++ b/justfile @@ -10,7 +10,6 @@ fmt: # Downgrade dependencies necessary to run MSRV checks/tests. [private] downgrade-for-msrv: - cargo update -p=parse-size --precise=1.0.0 # next ver: 1.81.0 cargo update -p=clap --precise=4.4.18 # next ver: 1.74.0 cargo update -p=divan --precise=0.1.15 # next ver: 1.80.0 cargo update -p=litemap --precise=0.7.4 # next ver: 1.81.0 From fcd10fbb5ef249ce34333b6992a0c2f85f72021b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Mar 2025 06:58:14 +0000 Subject: [PATCH 130/144] build(deps): bump taiki-e/install-action from 2.49.17 to 2.49.27 (#3600) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.49.17 to 2.49.27. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.49.17...v2.49.27) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index d49a09a57..ce802d94a 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.49.17 + uses: taiki-e/install-action@v2.49.32 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.49.17 + uses: taiki-e/install-action@v2.49.32 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 657075982..492787331 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.49.17 + uses: taiki-e/install-action@v2.49.32 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.49.17 + uses: taiki-e/install-action@v2.49.32 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index bd5b4fcea..453e33859 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.49.17 + uses: taiki-e/install-action@v2.49.32 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 461fee4ee..67347eefe 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.49.17 + uses: taiki-e/install-action@v2.49.32 with: tool: just From adf57d2b24ef10e1a0020a6063cbf5f6bd00038e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 11:51:57 +0000 Subject: [PATCH 131/144] build(deps): bump time from 0.3.40 to 0.3.41 (#3601) Bumps [time](https://github.com/time-rs/time) from 0.3.40 to 0.3.41. - [Release notes](https://github.com/time-rs/time/releases) - [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md) - [Commits](https://github.com/time-rs/time/compare/v0.3.40...v0.3.41) --- updated-dependencies: - dependency-name: time dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5d1a94d14..490daa7a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3036,9 +3036,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.40" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d9c75b47bdff86fa3334a3db91356b8d7d86a9b839dab7d0bdc5c3d3a077618" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -3057,9 +3057,9 @@ checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.21" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29aa485584182073ed57fd5004aa09c371f021325014694e432313345865fd04" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", From 90c19a835dddb04b4df314afa0d5f2bac1c439e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 11:52:08 +0000 Subject: [PATCH 132/144] build(deps): bump taiki-e/install-action from 2.49.32 to 2.49.33 (#3602) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.49.32 to 2.49.33. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.49.32...v2.49.33) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index ce802d94a..6ddf7c24e 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.49.32 + uses: taiki-e/install-action@v2.49.33 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.49.32 + uses: taiki-e/install-action@v2.49.33 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 492787331..44c533ecd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.49.32 + uses: taiki-e/install-action@v2.49.33 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.49.32 + uses: taiki-e/install-action@v2.49.33 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 453e33859..7b196398a 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.49.32 + uses: taiki-e/install-action@v2.49.33 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 67347eefe..f8cbdc288 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.49.32 + uses: taiki-e/install-action@v2.49.33 with: tool: just From 52264448cd2bc46af3972ec588d82402e4004df4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 08:56:34 +0100 Subject: [PATCH 133/144] build(deps): bump socket2 from 0.5.8 to 0.5.9 (#3607) Bumps [socket2](https://github.com/rust-lang/socket2) from 0.5.8 to 0.5.9. - [Release notes](https://github.com/rust-lang/socket2/releases) - [Changelog](https://github.com/rust-lang/socket2/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/socket2/commits) --- updated-dependencies: - dependency-name: socket2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 490daa7a5..d20ff8e95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -147,7 +147,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "slab", - "socket2 0.5.8", + "socket2 0.5.9", "tokio", ] @@ -261,7 +261,7 @@ dependencies = [ "futures-core", "futures-util", "mio", - "socket2 0.5.8", + "socket2 0.5.9", "tokio", "tokio-uring", "tracing", @@ -393,7 +393,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "smallvec", - "socket2 0.5.8", + "socket2 0.5.9", "static_assertions", "time", "tokio", @@ -1833,7 +1833,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.8", + "socket2 0.5.9", "widestring", "windows-sys 0.48.0", "winreg", @@ -2910,9 +2910,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" dependencies = [ "libc", "windows-sys 0.52.0", @@ -3113,7 +3113,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.8", + "socket2 0.5.9", "tokio-macros", "windows-sys 0.52.0", ] From 7fddaae878a49336e6addc6c4240c2ebb57bf5b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 08:57:03 +0100 Subject: [PATCH 134/144] build(deps): bump taiki-e/install-action from 2.49.33 to 2.49.39 (#3609) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.49.33 to 2.49.39. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.49.33...v2.49.39) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 6ddf7c24e..0b4a97752 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.49.33 + uses: taiki-e/install-action@v2.49.39 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.49.33 + uses: taiki-e/install-action@v2.49.39 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 44c533ecd..a2de97e9c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.49.33 + uses: taiki-e/install-action@v2.49.39 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.49.33 + uses: taiki-e/install-action@v2.49.39 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 7b196398a..6adf4906a 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.49.33 + uses: taiki-e/install-action@v2.49.39 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f8cbdc288..b91f7f29b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.49.33 + uses: taiki-e/install-action@v2.49.39 with: tool: just From b75ae11e629eadcb8b19dcb6f9aaccaad43959a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 08:57:04 +0100 Subject: [PATCH 135/144] build(deps): bump log from 0.4.26 to 0.4.27 (#3608) Bumps [log](https://github.com/rust-lang/log) from 0.4.26 to 0.4.27. - [Release notes](https://github.com/rust-lang/log/releases) - [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/log/compare/0.4.26...0.4.27) --- updated-dependencies: - dependency-name: log dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- awc/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d20ff8e95..ba1df2d28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2016,9 +2016,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.26" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "lru-cache" diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 94eebcbcf..106def621 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -112,7 +112,7 @@ futures-util = { version = "0.3.17", default-features = false, features = ["allo h2 = "0.3.26" http = "0.2.7" itoa = "1" -log =" 0.4" +log ="0.4" mime = "0.3" percent-encoding = "2.1" pin-project-lite = "0.2" From c284426698b1d5e5943f6b7e087c97d0c1812866 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 08:57:06 +0100 Subject: [PATCH 136/144] build(deps): bump once_cell from 1.21.1 to 1.21.3 (#3606) Bumps [once_cell](https://github.com/matklad/once_cell) from 1.21.1 to 1.21.3. - [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md) - [Commits](https://github.com/matklad/once_cell/compare/v1.21.1...v1.21.3) --- updated-dependencies: - dependency-name: once_cell dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- actix-http/Cargo.toml | 2 +- actix-web/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba1df2d28..74dbf0930 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2141,9 +2141,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.1" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oorandom" diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 06b40172d..0e5c4b234 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -155,7 +155,7 @@ divan = "0.1.8" env_logger = "0.11" futures-util = { version = "0.3.17", default-features = false, features = ["alloc"] } memchr = "2.4" -once_cell = "1.9" +once_cell = "1.21" rcgen = "0.13" regex = "1.3" rustversion = "1" diff --git a/actix-web/Cargo.toml b/actix-web/Cargo.toml index 153934ba6..29c6970e6 100644 --- a/actix-web/Cargo.toml +++ b/actix-web/Cargo.toml @@ -155,7 +155,7 @@ impl-more = "0.1.4" language-tags = "0.3" log = "0.4" mime = "0.3" -once_cell = "1.5" +once_cell = "1.21" pin-project-lite = "0.2.7" regex = { version = "1.5.5", optional = true } regex-lite = "0.1" From 0ef246a846f478e8d85ad441ab979e13c010d152 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Apr 2025 22:32:30 +0100 Subject: [PATCH 137/144] build(deps): bump openssl from 0.10.71 to 0.10.72 (#3612) Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.71 to 0.10.72. - [Release notes](https://github.com/sfackler/rust-openssl/releases) - [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.71...openssl-v0.10.72) --- updated-dependencies: - dependency-name: openssl dependency-version: 0.10.72 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 74dbf0930..b596c59c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2159,9 +2159,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.71" +version = "0.10.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" +checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" dependencies = [ "bitflags 2.9.0", "cfg-if", @@ -2191,9 +2191,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.106" +version = "0.9.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" +checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" dependencies = [ "cc", "libc", From 9915defca3385b1c347512ba14e462e24289ed05 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Wed, 9 Apr 2025 21:43:19 +0100 Subject: [PATCH 138/144] chore: update deps --- Cargo.lock | 166 +++++++++++++++++++++++++---------------------------- 1 file changed, 77 insertions(+), 89 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b596c59c5..2caac3e90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -668,9 +668,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.12.6" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dabb68eb3a7aa08b46fddfd59a3d55c978243557a90ab804769f7e20e67d2b01" +checksum = "19b756939cb2f8dc900aa6dcd505e6e2428e9cae7ff7b028c49e3946efa70878" dependencies = [ "aws-lc-sys", "zeroize", @@ -678,9 +678,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.27.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77926887776171ced7d662120a75998e444d3750c951abfe07f90da130514b1f" +checksum = "b9f7720b74ed28ca77f90769a71fd8c637a0137f6fae4ae947e1050229cff57f" dependencies = [ "bindgen", "cc", @@ -816,9 +816,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.16" +version = "1.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +checksum = "525046617d8376e3db1deffb079e91cef90a89fc3ca5c185bbf8c9ecdd15cd5c" dependencies = [ "jobserver", "libc", @@ -890,18 +890,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.32" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" +checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.32" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" +checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" dependencies = [ "anstyle", "clap_lex", @@ -1058,9 +1058,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] @@ -1118,9 +1118,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ "darling_core", "darling_macro", @@ -1128,9 +1128,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" dependencies = [ "fnv", "ident_case", @@ -1142,9 +1142,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", @@ -1211,9 +1211,9 @@ dependencies = [ [[package]] name = "divan" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0583193020b29b03682d8d33bb53a5b0f50df6daacece12ca99b904cfdcb8c4" +checksum = "009c56317fe2bd3b5eebe3aa888828c62ed1b085d26c1ef2079a60369795765e" dependencies = [ "cfg-if", "clap", @@ -1225,9 +1225,9 @@ dependencies = [ [[package]] name = "divan-macros" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dc51d98e636f5e3b0759a39257458b22619cac7e96d932da6eeb052891bb67c" +checksum = "0f4de9827ae754db91aedec0277381f5a2d8e2f801564c8d774acfe1ab1b045e" dependencies = [ "proc-macro2", "quote", @@ -1279,9 +1279,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.7" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" dependencies = [ "anstream", "anstyle", @@ -1298,9 +1298,9 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" dependencies = [ "libc", "windows-sys 0.59.0", @@ -1314,9 +1314,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "flate2" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" dependencies = [ "crc32fast", "miniz_oxide", @@ -1527,9 +1527,9 @@ dependencies = [ [[package]] name = "half" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ "cfg-if", "crunchy", @@ -1588,13 +1588,13 @@ dependencies = [ [[package]] name = "hostname" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba" +checksum = "a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65" dependencies = [ "cfg-if", "libc", - "windows", + "windows-link", ] [[package]] @@ -1678,9 +1678,9 @@ dependencies = [ [[package]] name = "icu_locid_transform_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" +checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" [[package]] name = "icu_normalizer" @@ -1702,9 +1702,9 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" [[package]] name = "icu_properties" @@ -1723,9 +1723,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" [[package]] name = "icu_provider" @@ -1800,9 +1800,9 @@ checksum = "e8a5a9a0ff0086c7a148acb942baaabeadf9504d10400b5a05645853729b9cd2" [[package]] name = "indexmap" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", "hashbrown", @@ -1888,9 +1888,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d699bc6dfc879fb1bf9bdff0d4c56f0884fc6f0d0eb0fba397a6d00cd9a6b85e" +checksum = "1f33145a5cbea837164362c7bd596106eb7c5198f97d1ba6f6ebb3223952e488" dependencies = [ "jiff-static", "log", @@ -1901,9 +1901,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d16e75759ee0aa64c57a56acbf43916987b20c77373cb7e808979e02b93c9f9" +checksum = "43ce13c40ec6956157a3635d97a1ee2df323b263f09ea14165131289cb0f5c19" dependencies = [ "proc-macro2", "quote", @@ -1912,10 +1912,11 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" dependencies = [ + "getrandom 0.3.2", "libc", ] @@ -1977,9 +1978,9 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "linux-raw-sys" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "litemap" @@ -2059,9 +2060,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" dependencies = [ "adler2", ] @@ -2350,9 +2351,9 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5316f57387668042f561aae71480de936257848f9c43ce528e311d89a07cadeb" +checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" dependencies = [ "proc-macro2", "syn", @@ -2477,9 +2478,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" dependencies = [ "bitflags 2.9.0", ] @@ -2584,14 +2585,14 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" +checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" dependencies = [ "bitflags 2.9.0", "errno", "libc", - "linux-raw-sys 0.9.3", + "linux-raw-sys 0.9.4", "windows-sys 0.59.0", ] @@ -2643,7 +2644,7 @@ dependencies = [ "log", "once_cell", "rustls-pki-types", - "rustls-webpki 0.103.0", + "rustls-webpki 0.103.1", "subtle", "zeroize", ] @@ -2699,9 +2700,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.0" +version = "0.103.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f" +checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" dependencies = [ "aws-lc-rs", "ring 0.17.14", @@ -2894,9 +2895,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" [[package]] name = "socket2" @@ -2991,7 +2992,7 @@ dependencies = [ "fastrand", "getrandom 0.3.2", "once_cell", - "rustix 1.0.3", + "rustix 1.0.5", "windows-sys 0.59.0", ] @@ -3010,7 +3011,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed" dependencies = [ - "rustix 1.0.3", + "rustix 1.0.5", "windows-sys 0.59.0", ] @@ -3102,9 +3103,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.44.1" +version = "1.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" +checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" dependencies = [ "backtrace", "bytes", @@ -3633,23 +3634,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.52.0" +name = "windows-link" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" -dependencies = [ - "windows-core", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.6", -] +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" [[package]] name = "windows-sys" @@ -3801,9 +3789,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" dependencies = [ "memchr", ] @@ -3874,18 +3862,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.23" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.23" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ "proc-macro2", "quote", From 74c1c3de593ac592fa53d64546b32ef5742b8b82 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Apr 2025 20:34:30 +0000 Subject: [PATCH 140/144] build(deps): bump taiki-e/install-action from 2.49.39 to 2.49.45 (#3618) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.49.39 to 2.49.45. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.49.39...v2.49.45) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-version: 2.49.45 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 0b4a97752..5ae95d5d2 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.49.39 + uses: taiki-e/install-action@v2.49.45 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.49.39 + uses: taiki-e/install-action@v2.49.45 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2de97e9c..a1556d6b3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.49.39 + uses: taiki-e/install-action@v2.49.45 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.49.39 + uses: taiki-e/install-action@v2.49.45 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 6adf4906a..496a22e2a 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.49.39 + uses: taiki-e/install-action@v2.49.45 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b91f7f29b..28fd44494 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.49.39 + uses: taiki-e/install-action@v2.49.45 with: tool: just From b8a612d21e773eff443ef02d7d937b4262eeaaf3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 01:45:57 +0100 Subject: [PATCH 141/144] build(deps): bump rand from 0.9.0 to 0.9.1 (#3625) Bumps [rand](https://github.com/rust-random/rand) from 0.9.0 to 0.9.1. - [Release notes](https://github.com/rust-random/rand/releases) - [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-random/rand/compare/0.9.0...rand_core-0.9.1) --- updated-dependencies: - dependency-name: rand dependency-version: 0.9.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2caac3e90..66055bfef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,7 +109,7 @@ dependencies = [ "openssl", "percent-encoding", "pin-project-lite", - "rand 0.9.0", + "rand 0.9.1", "rcgen", "regex", "rustls 0.23.25", @@ -185,7 +185,7 @@ dependencies = [ "memchr", "mime", "multer", - "rand 0.9.0", + "rand 0.9.1", "serde", "serde_json", "serde_plain", @@ -383,7 +383,7 @@ dependencies = [ "once_cell", "openssl", "pin-project-lite", - "rand 0.9.0", + "rand 0.9.1", "rcgen", "regex", "regex-lite", @@ -650,7 +650,7 @@ dependencies = [ "openssl", "percent-encoding", "pin-project-lite", - "rand 0.9.0", + "rand 0.9.1", "rcgen", "rustls 0.20.9", "rustls 0.21.12", @@ -2396,13 +2396,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", - "zerocopy", ] [[package]] From 741ca85d4ad1511dffa6f97d770aa6c7267bea22 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 01:46:11 +0100 Subject: [PATCH 142/144] build(deps): bump proc-macro2 from 1.0.94 to 1.0.95 (#3626) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.94 to 1.0.95. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.94...1.0.95) --- updated-dependencies: - dependency-name: proc-macro2 dependency-version: 1.0.95 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 66055bfef..96cd56efb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2361,9 +2361,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] From 5939af88b396375567224ea5a0235a11537380a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 01:46:28 +0100 Subject: [PATCH 143/144] build(deps): bump codecov/codecov-action from 5.4.0 to 5.4.2 (#3628) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.4.0 to 5.4.2. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v5.4.0...v5.4.2) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-version: 5.4.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 496a22e2a..c6960e64d 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -32,7 +32,7 @@ jobs: run: just test-coverage-codecov - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.4.0 + uses: codecov/codecov-action@v5.4.2 with: files: codecov.json fail_ci_if_error: true From e27e1e380692575ce08a3b7cb0825ed029385100 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 01:46:43 +0100 Subject: [PATCH 144/144] build(deps): bump taiki-e/install-action from 2.49.45 to 2.49.50 (#3629) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.49.45 to 2.49.50. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/taiki-e/install-action/compare/v2.49.45...v2.49.50) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-version: 2.49.50 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-post-merge.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-post-merge.yml b/.github/workflows/ci-post-merge.yml index 5ae95d5d2..72cffbdc3 100644 --- a/.github/workflows/ci-post-merge.yml +++ b/.github/workflows/ci-post-merge.yml @@ -49,7 +49,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.49.45 + uses: taiki-e/install-action@v2.49.50 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -83,7 +83,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1.11.0 - name: Install just, cargo-hack - uses: taiki-e/install-action@v2.49.45 + uses: taiki-e/install-action@v2.49.50 with: tool: just,cargo-hack diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a1556d6b3..1c2ecdeea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ matrix.version.version }} - name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean - uses: taiki-e/install-action@v2.49.45 + uses: taiki-e/install-action@v2.49.50 with: tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean @@ -113,7 +113,7 @@ jobs: toolchain: nightly - name: Install just - uses: taiki-e/install-action@v2.49.45 + uses: taiki-e/install-action@v2.49.50 with: tool: just diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index c6960e64d..2d2aa1c5e 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -24,7 +24,7 @@ jobs: components: llvm-tools - name: Install just, cargo-llvm-cov, cargo-nextest - uses: taiki-e/install-action@v2.49.45 + uses: taiki-e/install-action@v2.49.50 with: tool: just,cargo-llvm-cov,cargo-nextest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 28fd44494..b1e34a57e 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -77,7 +77,7 @@ jobs: toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }} - name: Install just - uses: taiki-e/install-action@v2.49.45 + uses: taiki-e/install-action@v2.49.50 with: tool: just