build(deps): bump s3s from 0.12.0-rc.4 to 0.12.0-rc.5 in the s3s group (#1046)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: loverustfs <hello@rustfs.com>
Co-authored-by: houseme <housemecn@gmail.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: houseme <4829346+houseme@users.noreply.github.com>
This commit is contained in:
dependabot[bot]
2025-12-11 15:20:36 +08:00
committed by GitHub
parent fba201df3d
commit 0da943a6a4
26 changed files with 445 additions and 317 deletions

View File

@@ -91,7 +91,7 @@ jobs:
name: Typos name: Typos
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable - uses: dtolnay/rust-toolchain@stable
- name: Typos check with custom config file - name: Typos check with custom config file
uses: crate-ci/typos@master uses: crate-ci/typos@master
@@ -135,7 +135,7 @@ jobs:
timeout-minutes: 30 timeout-minutes: 30
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v5 uses: actions/checkout@v6
- name: Setup Rust environment - name: Setup Rust environment
uses: ./.github/actions/setup uses: ./.github/actions/setup

300
Cargo.lock generated
View File

@@ -222,14 +222,15 @@ checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
[[package]] [[package]]
name = "argon2" name = "argon2"
version = "0.6.0-rc.3" version = "0.6.0-rc.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53fc8992356faa4da0422d552f1dc7d7fda26927165069fd0af2d565f0b0fc6f" checksum = "2318b1fbcb6d8ebe255091dce62990be001b47711191a9400225de50a208fec8"
dependencies = [ dependencies = [
"base64ct", "base64ct",
"blake2 0.11.0-rc.3", "blake2 0.11.0-rc.3",
"cpufeatures", "cpufeatures",
"password-hash", "password-hash",
"phc",
] ]
[[package]] [[package]]
@@ -323,7 +324,7 @@ dependencies = [
"arrow-schema", "arrow-schema",
"arrow-select", "arrow-select",
"atoi", "atoi",
"base64 0.22.1", "base64",
"chrono", "chrono",
"comfy-table", "comfy-table",
"half", "half",
@@ -602,9 +603,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]] [[package]]
name = "aws-config" name = "aws-config"
version = "1.8.11" version = "1.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0149602eeaf915158e14029ba0c78dedb8c08d554b024d54c8f239aab46511d" checksum = "96571e6996817bf3d58f6b569e4b9fd2e9d2fcf9f7424eed07b2ce9bb87535e5"
dependencies = [ dependencies = [
"aws-credential-types", "aws-credential-types",
"aws-runtime", "aws-runtime",
@@ -632,9 +633,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-credential-types" name = "aws-credential-types"
version = "1.2.10" version = "1.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b01c9521fa01558f750d183c8c68c81b0155b9d193a4ba7f84c36bd1b6d04a06" checksum = "3cd362783681b15d136480ad555a099e82ecd8e2d10a841e14dfd0078d67fee3"
dependencies = [ dependencies = [
"aws-smithy-async", "aws-smithy-async",
"aws-smithy-runtime-api", "aws-smithy-runtime-api",
@@ -666,9 +667,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-runtime" name = "aws-runtime"
version = "1.5.16" version = "1.5.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ce527fb7e53ba9626fc47824f25e256250556c40d8f81d27dd92aa38239d632" checksum = "d81b5b2898f6798ad58f484856768bca817e3cd9de0974c24ae0f1113fe88f1b"
dependencies = [ dependencies = [
"aws-credential-types", "aws-credential-types",
"aws-sigv4", "aws-sigv4",
@@ -691,9 +692,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-sdk-s3" name = "aws-sdk-s3"
version = "1.116.0" version = "1.117.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd4c10050aa905b50dc2a1165a9848d598a80c3a724d6f93b5881aa62235e4a5" checksum = "c134e2d1ad1ad23a8cf88ceccf39d515914f385e670ffc12226013bd16dfe825"
dependencies = [ dependencies = [
"aws-credential-types", "aws-credential-types",
"aws-runtime", "aws-runtime",
@@ -725,9 +726,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-sdk-sso" name = "aws-sdk-sso"
version = "1.90.0" version = "1.91.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f18e53542c522459e757f81e274783a78f8c81acdfc8d1522ee8a18b5fb1c66" checksum = "8ee6402a36f27b52fe67661c6732d684b2635152b676aa2babbfb5204f99115d"
dependencies = [ dependencies = [
"aws-credential-types", "aws-credential-types",
"aws-runtime", "aws-runtime",
@@ -747,9 +748,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-sdk-ssooidc" name = "aws-sdk-ssooidc"
version = "1.92.0" version = "1.93.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "532f4d866012ffa724a4385c82e8dd0e59f0ca0e600f3f22d4c03b6824b34e4a" checksum = "a45a7f750bbd170ee3677671ad782d90b894548f4e4ae168302c57ec9de5cb3e"
dependencies = [ dependencies = [
"aws-credential-types", "aws-credential-types",
"aws-runtime", "aws-runtime",
@@ -769,9 +770,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-sdk-sts" name = "aws-sdk-sts"
version = "1.94.0" version = "1.95.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1be6fbbfa1a57724788853a623378223fe828fc4c09b146c992f0c95b6256174" checksum = "55542378e419558e6b1f398ca70adb0b2088077e79ad9f14eb09441f2f7b2164"
dependencies = [ dependencies = [
"aws-credential-types", "aws-credential-types",
"aws-runtime", "aws-runtime",
@@ -792,9 +793,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-sigv4" name = "aws-sigv4"
version = "1.3.6" version = "1.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c35452ec3f001e1f2f6db107b6373f1f48f05ec63ba2c5c9fa91f07dad32af11" checksum = "69e523e1c4e8e7e8ff219d732988e22bfeae8a1cafdbe6d9eca1546fa080be7c"
dependencies = [ dependencies = [
"aws-credential-types", "aws-credential-types",
"aws-smithy-eventstream", "aws-smithy-eventstream",
@@ -820,9 +821,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-smithy-async" name = "aws-smithy-async"
version = "1.2.6" version = "1.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "127fcfad33b7dfc531141fda7e1c402ac65f88aca5511a4d31e2e3d2cd01ce9c" checksum = "9ee19095c7c4dda59f1697d028ce704c24b2d33c6718790c7f1d5a3015b4107c"
dependencies = [ dependencies = [
"futures-util", "futures-util",
"pin-project-lite", "pin-project-lite",
@@ -831,9 +832,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-smithy-checksums" name = "aws-smithy-checksums"
version = "0.63.11" version = "0.63.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95bd108f7b3563598e4dc7b62e1388c9982324a2abd622442167012690184591" checksum = "87294a084b43d649d967efe58aa1f9e0adc260e13a6938eb904c0ae9b45824ae"
dependencies = [ dependencies = [
"aws-smithy-http", "aws-smithy-http",
"aws-smithy-types", "aws-smithy-types",
@@ -851,9 +852,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-smithy-eventstream" name = "aws-smithy-eventstream"
version = "0.60.13" version = "0.60.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e29a304f8319781a39808847efb39561351b1bb76e933da7aa90232673638658" checksum = "dc12f8b310e38cad85cf3bef45ad236f470717393c613266ce0a89512286b650"
dependencies = [ dependencies = [
"aws-smithy-types", "aws-smithy-types",
"bytes", "bytes",
@@ -862,9 +863,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-smithy-http" name = "aws-smithy-http"
version = "0.62.5" version = "0.62.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "445d5d720c99eed0b4aa674ed00d835d9b1427dd73e04adaf2f94c6b2d6f9fca" checksum = "826141069295752372f8203c17f28e30c464d22899a43a0c9fd9c458d469c88b"
dependencies = [ dependencies = [
"aws-smithy-eventstream", "aws-smithy-eventstream",
"aws-smithy-runtime-api", "aws-smithy-runtime-api",
@@ -884,9 +885,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-smithy-http-client" name = "aws-smithy-http-client"
version = "1.1.4" version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "623254723e8dfd535f566ee7b2381645f8981da086b5c4aa26c0c41582bb1d2c" checksum = "59e62db736db19c488966c8d787f52e6270be565727236fd5579eaa301e7bc4a"
dependencies = [ dependencies = [
"aws-smithy-async", "aws-smithy-async",
"aws-smithy-runtime-api", "aws-smithy-runtime-api",
@@ -904,7 +905,7 @@ dependencies = [
"pin-project-lite", "pin-project-lite",
"rustls 0.21.12", "rustls 0.21.12",
"rustls 0.23.35", "rustls 0.23.35",
"rustls-native-certs 0.8.2", "rustls-native-certs",
"rustls-pki-types", "rustls-pki-types",
"tokio", "tokio",
"tokio-rustls 0.26.4", "tokio-rustls 0.26.4",
@@ -914,27 +915,27 @@ dependencies = [
[[package]] [[package]]
name = "aws-smithy-json" name = "aws-smithy-json"
version = "0.61.7" version = "0.61.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2db31f727935fc63c6eeae8b37b438847639ec330a9161ece694efba257e0c54" checksum = "a6864c190cbb8e30cf4b77b2c8f3b6dfffa697a09b7218d2f7cd3d4c4065a9f7"
dependencies = [ dependencies = [
"aws-smithy-types", "aws-smithy-types",
] ]
[[package]] [[package]]
name = "aws-smithy-observability" name = "aws-smithy-observability"
version = "0.1.4" version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d1881b1ea6d313f9890710d65c158bdab6fb08c91ea825f74c1c8c357baf4cc" checksum = "17f616c3f2260612fe44cede278bafa18e73e6479c4e393e2c4518cf2a9a228a"
dependencies = [ dependencies = [
"aws-smithy-runtime-api", "aws-smithy-runtime-api",
] ]
[[package]] [[package]]
name = "aws-smithy-query" name = "aws-smithy-query"
version = "0.60.8" version = "0.60.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d28a63441360c477465f80c7abac3b9c4d075ca638f982e605b7dc2a2c7156c9" checksum = "ae5d689cf437eae90460e944a58b5668530d433b4ff85789e69d2f2a556e057d"
dependencies = [ dependencies = [
"aws-smithy-types", "aws-smithy-types",
"urlencoding", "urlencoding",
@@ -942,9 +943,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-smithy-runtime" name = "aws-smithy-runtime"
version = "1.9.4" version = "1.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bbe9d018d646b96c7be063dd07987849862b0e6d07c778aad7d93d1be6c1ef0" checksum = "a392db6c583ea4a912538afb86b7be7c5d8887d91604f50eb55c262ee1b4a5f5"
dependencies = [ dependencies = [
"aws-smithy-async", "aws-smithy-async",
"aws-smithy-http", "aws-smithy-http",
@@ -966,9 +967,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-smithy-runtime-api" name = "aws-smithy-runtime-api"
version = "1.9.2" version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec7204f9fd94749a7c53b26da1b961b4ac36bf070ef1e0b94bb09f79d4f6c193" checksum = "ab0d43d899f9e508300e587bf582ba54c27a452dd0a9ea294690669138ae14a2"
dependencies = [ dependencies = [
"aws-smithy-async", "aws-smithy-async",
"aws-smithy-types", "aws-smithy-types",
@@ -983,9 +984,9 @@ dependencies = [
[[package]] [[package]]
name = "aws-smithy-types" name = "aws-smithy-types"
version = "1.3.4" version = "1.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25f535879a207fce0db74b679cfc3e91a3159c8144d717d55f5832aea9eef46e" checksum = "905cb13a9895626d49cf2ced759b062d913834c7482c38e49557eac4e6193f01"
dependencies = [ dependencies = [
"base64-simd", "base64-simd",
"bytes", "bytes",
@@ -1009,18 +1010,18 @@ dependencies = [
[[package]] [[package]]
name = "aws-smithy-xml" name = "aws-smithy-xml"
version = "0.60.12" version = "0.60.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eab77cdd036b11056d2a30a7af7b775789fb024bf216acc13884c6c97752ae56" checksum = "11b2f670422ff42bf7065031e72b45bc52a3508bd089f743ea90731ca2b6ea57"
dependencies = [ dependencies = [
"xmlparser", "xmlparser",
] ]
[[package]] [[package]]
name = "aws-types" name = "aws-types"
version = "1.3.10" version = "1.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d79fb68e3d7fe5d4833ea34dc87d2e97d26d3086cb3da660bb6b1f76d98680b6" checksum = "1d980627d2dd7bfc32a3c025685a033eeab8d365cc840c631ef59d1b8f428164"
dependencies = [ dependencies = [
"aws-credential-types", "aws-credential-types",
"aws-smithy-async", "aws-smithy-async",
@@ -1158,12 +1159,6 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b59d472eab27ade8d770dcb11da7201c11234bef9f82ce7aa517be028d462b" checksum = "d8b59d472eab27ade8d770dcb11da7201c11234bef9f82ce7aa517be028d462b"
[[package]]
name = "base64"
version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.22.1" version = "0.22.1"
@@ -1182,9 +1177,9 @@ dependencies = [
[[package]] [[package]]
name = "base64ct" name = "base64ct"
version = "1.8.0" version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a"
[[package]] [[package]]
name = "bigdecimal" name = "bigdecimal"
@@ -1478,9 +1473,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.2.48" version = "1.2.49"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c481bdbf0ed3b892f6f806287d72acd515b352a4ec27a208489b8c1bc839633a" checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215"
dependencies = [ dependencies = [
"find-msvc-tools", "find-msvc-tools",
"jobserver", "jobserver",
@@ -2520,7 +2515,7 @@ checksum = "794a9db7f7b96b3346fc007ff25e994f09b8f0511b4cf7dff651fadfe3ebb28f"
dependencies = [ dependencies = [
"arrow", "arrow",
"arrow-buffer", "arrow-buffer",
"base64 0.22.1", "base64",
"blake2 0.10.6", "blake2 0.10.6",
"blake3", "blake3",
"chrono", "chrono",
@@ -3044,7 +3039,7 @@ dependencies = [
"async-trait", "async-trait",
"aws-config", "aws-config",
"aws-sdk-s3", "aws-sdk-s3",
"base64 0.22.1", "base64",
"bytes", "bytes",
"chrono", "chrono",
"flatbuffers", "flatbuffers",
@@ -3649,20 +3644,20 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
[[package]] [[package]]
name = "google-cloud-auth" name = "google-cloud-auth"
version = "1.2.0" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cc977b20996b87e207b0a004ea34aa5f0f8692c44a1ca8c8802a08f553bf79c" checksum = "590a1c28795779d5da6fda35b149d5271bcddcf2ce1709eae9e9460faf2f2aa9"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"base64 0.22.1", "base64",
"bon", "bon",
"bytes",
"google-cloud-gax", "google-cloud-gax",
"http 1.4.0", "http 1.4.0",
"jsonwebtoken",
"reqwest", "reqwest",
"rustc_version", "rustc_version",
"rustls 0.23.35", "rustls 0.23.35",
"rustls-pemfile 2.2.0", "rustls-pemfile",
"serde", "serde",
"serde_json", "serde_json",
"thiserror 2.0.17", "thiserror 2.0.17",
@@ -3672,11 +3667,11 @@ dependencies = [
[[package]] [[package]]
name = "google-cloud-gax" name = "google-cloud-gax"
version = "1.3.1" version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c26e6f1be47e93e5360a77e67e4e996a2d838b1924ffe0763bcb21d47be68b" checksum = "324fb97d35103787e80a33ed41ccc43d947c376d2ece68ca53e860f5844dbe24"
dependencies = [ dependencies = [
"base64 0.22.1", "base64",
"bytes", "bytes",
"futures", "futures",
"google-cloud-rpc", "google-cloud-rpc",
@@ -3692,20 +3687,23 @@ dependencies = [
[[package]] [[package]]
name = "google-cloud-gax-internal" name = "google-cloud-gax-internal"
version = "0.7.5" version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69168fd1f81869bb8682883d27c56e3e499840d45b27b884b289ec0d5f2b442a" checksum = "7b75b810886ae872aca68a35ad1d4d5e8f2be39e40238116d8aff9d778f04b38"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures",
"google-cloud-auth", "google-cloud-auth",
"google-cloud-gax", "google-cloud-gax",
"google-cloud-rpc", "google-cloud-rpc",
"google-cloud-wkt", "google-cloud-wkt",
"http 1.4.0", "http 1.4.0",
"http-body 1.0.1",
"http-body-util", "http-body-util",
"hyper 1.8.1", "hyper 1.8.1",
"opentelemetry-semantic-conventions", "opentelemetry-semantic-conventions",
"percent-encoding", "percent-encoding",
"pin-project",
"prost 0.14.1", "prost 0.14.1",
"prost-types", "prost-types",
"reqwest", "reqwest",
@@ -3723,9 +3721,9 @@ dependencies = [
[[package]] [[package]]
name = "google-cloud-iam-v1" name = "google-cloud-iam-v1"
version = "1.1.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2f2c6d094d0ed9453de0fba8bb690b0c039a3d056f009d2e6c7909c32a446bb" checksum = "498a68e2a958e8aa9938f7db2c7147aad1b5a0ff2cd47c5ba4e10cb0dcb5bfc5"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bytes", "bytes",
@@ -3743,9 +3741,9 @@ dependencies = [
[[package]] [[package]]
name = "google-cloud-longrunning" name = "google-cloud-longrunning"
version = "1.2.0" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "398201f50d0dd0180105628c370ba5dae77a3f5e842eebce494f451caee96371" checksum = "1c80938e704401a47fdf36b51ec10e1a99b1ec22793d607afd0e67c7b675b8b3"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bytes", "bytes",
@@ -3763,9 +3761,9 @@ dependencies = [
[[package]] [[package]]
name = "google-cloud-lro" name = "google-cloud-lro"
version = "1.1.1" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5259a172f712809460ad10336b322caf0cd37cf1469aecc950bf6bf0026fbd7" checksum = "49747b7b684b804a2d1040c2cdb21238b3d568a41ab9e36c423554509112f61d"
dependencies = [ dependencies = [
"google-cloud-gax", "google-cloud-gax",
"google-cloud-longrunning", "google-cloud-longrunning",
@@ -3777,9 +3775,9 @@ dependencies = [
[[package]] [[package]]
name = "google-cloud-rpc" name = "google-cloud-rpc"
version = "1.1.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5b655e3540a78e18fd753ebd8f11e068210a3fa392892370f932ffcc8774346" checksum = "bd10e97751ca894f9dad6be69fcef1cb72f5bc187329e0254817778fc8235030"
dependencies = [ dependencies = [
"bytes", "bytes",
"google-cloud-wkt", "google-cloud-wkt",
@@ -3790,12 +3788,12 @@ dependencies = [
[[package]] [[package]]
name = "google-cloud-storage" name = "google-cloud-storage"
version = "1.4.0" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "931b69ac5996d0216e74e22e1843e025bef605ba8c062003d40c1565d90594b4" checksum = "043be824d1b105bfdce786c720e45cae04e66436f8e5d0168e98ca8e5715ce9f"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"base64 0.22.1", "base64",
"bytes", "bytes",
"crc32c", "crc32c",
"futures", "futures",
@@ -3833,9 +3831,9 @@ dependencies = [
[[package]] [[package]]
name = "google-cloud-type" name = "google-cloud-type"
version = "1.1.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290760412b63cd266376273e4fbeb13afaa4bc7dadd5340786c916866139e14c" checksum = "9390ac2f3f9882ff42956b25ea65b9f546c8dd44c131726d75a96bf744ec75f6"
dependencies = [ dependencies = [
"bytes", "bytes",
"google-cloud-wkt", "google-cloud-wkt",
@@ -3846,11 +3844,11 @@ dependencies = [
[[package]] [[package]]
name = "google-cloud-wkt" name = "google-cloud-wkt"
version = "1.1.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02931df6af9beda1c852bbbbe5f7b6ba6ae5e4cd49c029fa0ca2cecc787cd9b1" checksum = "c6f270e404be7ce76a3260abe0c3c71492ab2599ccd877f3253f3dd552f48cc9"
dependencies = [ dependencies = [
"base64 0.22.1", "base64",
"bytes", "bytes",
"serde", "serde",
"serde_json", "serde_json",
@@ -4240,7 +4238,6 @@ dependencies = [
"hyper 0.14.32", "hyper 0.14.32",
"log", "log",
"rustls 0.21.12", "rustls 0.21.12",
"rustls-native-certs 0.6.3",
"tokio", "tokio",
"tokio-rustls 0.24.1", "tokio-rustls 0.24.1",
] ]
@@ -4256,7 +4253,7 @@ dependencies = [
"hyper-util", "hyper-util",
"log", "log",
"rustls 0.23.35", "rustls 0.23.35",
"rustls-native-certs 0.8.2", "rustls-native-certs",
"rustls-pki-types", "rustls-pki-types",
"tokio", "tokio",
"tokio-rustls 0.26.4", "tokio-rustls 0.26.4",
@@ -4283,7 +4280,7 @@ version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f"
dependencies = [ dependencies = [
"base64 0.22.1", "base64",
"bytes", "bytes",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
@@ -4375,9 +4372,9 @@ checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a"
[[package]] [[package]]
name = "icu_properties" name = "icu_properties"
version = "2.1.1" version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec"
dependencies = [ dependencies = [
"icu_collections", "icu_collections",
"icu_locale_core", "icu_locale_core",
@@ -4389,9 +4386,9 @@ dependencies = [
[[package]] [[package]]
name = "icu_properties_data" name = "icu_properties_data"
version = "2.1.1" version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af"
[[package]] [[package]]
name = "icu_provider" name = "icu_provider"
@@ -4657,7 +4654,7 @@ version = "10.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c76e1c7d7df3e34443b3621b459b066a7b79644f059fc8b2db7070c825fd417e" checksum = "c76e1c7d7df3e34443b3621b459b066a7b79644f059fc8b2db7070c825fd417e"
dependencies = [ dependencies = [
"base64 0.22.1", "base64",
"ed25519-dalek", "ed25519-dalek",
"getrandom 0.2.16", "getrandom 0.2.16",
"hmac 0.12.1", "hmac 0.12.1",
@@ -5091,9 +5088,9 @@ dependencies = [
[[package]] [[package]]
name = "mio" name = "mio"
version = "1.1.0" version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
dependencies = [ dependencies = [
"libc", "libc",
"log", "log",
@@ -5130,9 +5127,9 @@ checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
[[package]] [[package]]
name = "neli" name = "neli"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87fe4204517c0dafc04a1d99ecb577d52c0ffc81e1bbe5cf322769aa8fbd1b05" checksum = "e23bebbf3e157c402c4d5ee113233e5e0610cc27453b2f07eefce649c7365dcc"
dependencies = [ dependencies = [
"bitflags 2.10.0", "bitflags 2.10.0",
"byteorder", "byteorder",
@@ -5146,9 +5143,9 @@ dependencies = [
[[package]] [[package]]
name = "neli-proc-macros" name = "neli-proc-macros"
version = "0.2.1" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e502fe5db321c6e0ae649ccda600675680125a8e8dee327744fe1910b19332" checksum = "05d8d08c6e98f20a62417478ebf7be8e1425ec9acecc6f63e22da633f6b71609"
dependencies = [ dependencies = [
"either", "either",
"proc-macro2", "proc-macro2",
@@ -5720,7 +5717,7 @@ dependencies = [
"arrow-ipc", "arrow-ipc",
"arrow-schema", "arrow-schema",
"arrow-select", "arrow-select",
"base64 0.22.1", "base64",
"brotli 8.0.2", "brotli 8.0.2",
"bytes", "bytes",
"chrono", "chrono",
@@ -5745,13 +5742,11 @@ dependencies = [
[[package]] [[package]]
name = "password-hash" name = "password-hash"
version = "0.6.0-rc.3" version = "0.6.0-rc.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11ceb29fb5976f752babcc02842a530515b714919233f0912845c742dffb6246" checksum = "fc4087c2ea1e1d8a217af92740e5d49eb3ee0e6d8f0df513b375140d6f6265ee"
dependencies = [ dependencies = [
"base64ct", "phc",
"rand_core 0.10.0-rc-2",
"subtle",
] ]
[[package]] [[package]]
@@ -5802,9 +5797,9 @@ dependencies = [
[[package]] [[package]]
name = "pbkdf2" name = "pbkdf2"
version = "0.13.0-rc.3" version = "0.13.0-rc.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c148c9a0a9a7d256a8ea004fae8356c02ccc44cf8c06e7d68fdbedb48de1beb" checksum = "82bdbf7229e8f41652a6782ecbb457bc3cebe44b5fe19c32ad7249b4a0ce0a37"
dependencies = [ dependencies = [
"digest 0.11.0-rc.4", "digest 0.11.0-rc.4",
"hmac 0.13.0-rc.3", "hmac 0.13.0-rc.3",
@@ -5816,7 +5811,7 @@ version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
dependencies = [ dependencies = [
"base64 0.22.1", "base64",
"serde_core", "serde_core",
] ]
@@ -5866,6 +5861,18 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "phc"
version = "0.6.0-rc.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61f960577aaac5c259bc0866d685ba315c0ed30793c602d7287f54980913863"
dependencies = [
"base64ct",
"getrandom 0.3.4",
"rand_core 0.10.0-rc-2",
"subtle",
]
[[package]] [[package]]
name = "phf" name = "phf"
version = "0.11.3" version = "0.11.3"
@@ -6174,7 +6181,7 @@ version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983"
dependencies = [ dependencies = [
"toml_edit 0.23.7", "toml_edit 0.23.9",
] ]
[[package]] [[package]]
@@ -6691,7 +6698,7 @@ version = "0.12.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6eff9328d40131d43bd911d42d79eb6a47312002a4daefc9e37f17e74a7701a" checksum = "b6eff9328d40131d43bd911d42d79eb6a47312002a4daefc9e37f17e74a7701a"
dependencies = [ dependencies = [
"base64 0.22.1", "base64",
"bytes", "bytes",
"encoding_rs", "encoding_rs",
"futures-channel", "futures-channel",
@@ -6712,7 +6719,7 @@ dependencies = [
"pin-project-lite", "pin-project-lite",
"quinn", "quinn",
"rustls 0.23.35", "rustls 0.23.35",
"rustls-native-certs 0.8.2", "rustls-native-certs",
"rustls-pki-types", "rustls-pki-types",
"serde", "serde",
"serde_json", "serde_json",
@@ -6783,7 +6790,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38b18323edc657390a6ed4d7a9110b0dec2dc3ed128eb2a123edfbafabdbddc5" checksum = "38b18323edc657390a6ed4d7a9110b0dec2dc3ed128eb2a123edfbafabdbddc5"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"base64 0.22.1", "base64",
"chrono", "chrono",
"futures", "futures",
"pastey", "pastey",
@@ -6912,8 +6919,8 @@ dependencies = [
"flume", "flume",
"futures-util", "futures-util",
"log", "log",
"rustls-native-certs 0.8.2", "rustls-native-certs",
"rustls-pemfile 2.2.0", "rustls-pemfile",
"rustls-webpki 0.102.8", "rustls-webpki 0.102.8",
"thiserror 2.0.17", "thiserror 2.0.17",
"tokio", "tokio",
@@ -6989,7 +6996,7 @@ dependencies = [
"axum", "axum",
"axum-extra", "axum-extra",
"axum-server", "axum-server",
"base64 0.22.1", "base64",
"base64-simd", "base64-simd",
"bytes", "bytes",
"chrono", "chrono",
@@ -7178,7 +7185,7 @@ dependencies = [
"cfg-if", "cfg-if",
"chacha20poly1305", "chacha20poly1305",
"jsonwebtoken", "jsonwebtoken",
"pbkdf2 0.13.0-rc.3", "pbkdf2 0.13.0-rc.4",
"rand 0.10.0-rc.5", "rand 0.10.0-rc.5",
"serde_json", "serde_json",
"sha2 0.11.0-rc.3", "sha2 0.11.0-rc.3",
@@ -7198,7 +7205,7 @@ dependencies = [
"aws-credential-types", "aws-credential-types",
"aws-sdk-s3", "aws-sdk-s3",
"aws-smithy-types", "aws-smithy-types",
"base64 0.22.1", "base64",
"base64-simd", "base64-simd",
"byteorder", "byteorder",
"bytes", "bytes",
@@ -7323,7 +7330,7 @@ version = "0.0.5"
dependencies = [ dependencies = [
"aes-gcm", "aes-gcm",
"async-trait", "async-trait",
"base64 0.22.1", "base64",
"chacha20poly1305", "chacha20poly1305",
"chrono", "chrono",
"md5", "md5",
@@ -7494,7 +7501,7 @@ name = "rustfs-rio"
version = "0.0.5" version = "0.0.5"
dependencies = [ dependencies = [
"aes-gcm", "aes-gcm",
"base64 0.22.1", "base64",
"bytes", "bytes",
"crc-fast", "crc-fast",
"faster-hex", "faster-hex",
@@ -7622,7 +7629,7 @@ dependencies = [
"regex", "regex",
"rustfs-config", "rustfs-config",
"rustls 0.23.35", "rustls 0.23.35",
"rustls-pemfile 2.2.0", "rustls-pemfile",
"rustls-pki-types", "rustls-pki-types",
"s3s", "s3s",
"serde", "serde",
@@ -7747,18 +7754,6 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "rustls-native-certs"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
dependencies = [
"openssl-probe",
"rustls-pemfile 1.0.4",
"schannel",
"security-framework 2.11.1",
]
[[package]] [[package]]
name = "rustls-native-certs" name = "rustls-native-certs"
version = "0.8.2" version = "0.8.2"
@@ -7768,16 +7763,7 @@ dependencies = [
"openssl-probe", "openssl-probe",
"rustls-pki-types", "rustls-pki-types",
"schannel", "schannel",
"security-framework 3.5.1", "security-framework",
]
[[package]]
name = "rustls-pemfile"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
dependencies = [
"base64 0.21.7",
] ]
[[package]] [[package]]
@@ -7846,9 +7832,8 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]] [[package]]
name = "s3s" name = "s3s"
version = "0.12.0-rc.4" version = "0.12.0-rc.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/s3s-project/s3s.git?branch=main#0d6fe98f06d91eb86c07c13823b037fec64ae683"
checksum = "538c74372dc8900685cd9bdd122a587fdf63a24f6c9d5878812241f7682338fd"
dependencies = [ dependencies = [
"arrayvec", "arrayvec",
"async-trait", "async-trait",
@@ -8009,19 +7994,6 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "security-framework"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags 2.10.0",
"core-foundation 0.9.4",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]] [[package]]
name = "security-framework" name = "security-framework"
version = "3.5.1" version = "3.5.1"
@@ -8184,7 +8156,7 @@ version = "3.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7"
dependencies = [ dependencies = [
"base64 0.22.1", "base64",
"chrono", "chrono",
"hex", "hex",
"indexmap 1.9.3", "indexmap 1.9.3",
@@ -8367,9 +8339,9 @@ dependencies = [
[[package]] [[package]]
name = "simd-adler32" name = "simd-adler32"
version = "0.3.7" version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
[[package]] [[package]]
name = "simdutf8" name = "simdutf8"
@@ -9207,9 +9179,9 @@ dependencies = [
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.23.7" version = "0.23.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832"
dependencies = [ dependencies = [
"indexmap 2.12.1", "indexmap 2.12.1",
"toml_datetime 0.7.3", "toml_datetime 0.7.3",
@@ -9240,7 +9212,7 @@ checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum", "axum",
"base64 0.22.1", "base64",
"bytes", "bytes",
"flate2", "flate2",
"h2 0.4.12", "h2 0.4.12",
@@ -9252,7 +9224,7 @@ dependencies = [
"hyper-util", "hyper-util",
"percent-encoding", "percent-encoding",
"pin-project", "pin-project",
"rustls-native-certs 0.8.2", "rustls-native-certs",
"socket2 0.6.1", "socket2 0.6.1",
"sync_wrapper", "sync_wrapper",
"tokio", "tokio",

View File

@@ -139,13 +139,13 @@ schemars = "1.1.0"
# Cryptography and Security # Cryptography and Security
aes-gcm = { version = "0.11.0-rc.2", features = ["rand_core"] } aes-gcm = { version = "0.11.0-rc.2", features = ["rand_core"] }
argon2 = { version = "0.6.0-rc.3", features = ["std"] } argon2 = { version = "0.6.0-rc.4", features = ["std"] }
blake3 = { version = "1.8.2", features = ["rayon", "mmap"] } blake3 = { version = "1.8.2", features = ["rayon", "mmap"] }
chacha20poly1305 = { version = "0.11.0-rc.2" } chacha20poly1305 = { version = "0.11.0-rc.2" }
crc-fast = "1.6.0" crc-fast = "1.6.0"
hmac = { version = "0.13.0-rc.3" } hmac = { version = "0.13.0-rc.3" }
jsonwebtoken = { version = "10.2.0", features = ["rust_crypto"] } jsonwebtoken = { version = "10.2.0", features = ["rust_crypto"] }
pbkdf2 = "0.13.0-rc.3" pbkdf2 = "0.13.0-rc.4"
rsa = { version = "0.10.0-rc.10" } rsa = { version = "0.10.0-rc.10" }
rustls = { version = "0.23.35", features = ["ring", "logging", "std", "tls12"], default-features = false } rustls = { version = "0.23.35", features = ["ring", "logging", "std", "tls12"], default-features = false }
rustls-pemfile = "2.2.0" rustls-pemfile = "2.2.0"
@@ -166,10 +166,10 @@ arc-swap = "1.7.1"
astral-tokio-tar = "0.5.6" astral-tokio-tar = "0.5.6"
atoi = "2.0.0" atoi = "2.0.0"
atomic_enum = "0.3.0" atomic_enum = "0.3.0"
aws-config = { version = "1.8.11" } aws-config = { version = "1.8.12" }
aws-credential-types = { version = "1.2.10" } aws-credential-types = { version = "1.2.11" }
aws-sdk-s3 = { version = "1.116.0", default-features = false, features = ["sigv4a", "rustls", "rt-tokio"] } aws-sdk-s3 = { version = "1.117.0", default-features = false, features = ["sigv4a", "rustls", "rt-tokio"] }
aws-smithy-types = { version = "1.3.4" } aws-smithy-types = { version = "1.3.5" }
base64 = "0.22.1" base64 = "0.22.1"
base64-simd = "0.8.0" base64-simd = "0.8.0"
brotli = "8.0.2" brotli = "8.0.2"
@@ -186,8 +186,8 @@ faster-hex = "0.10.0"
flate2 = "1.1.5" flate2 = "1.1.5"
flexi_logger = { version = "0.31.7", features = ["trc", "dont_minimize_extra_stacks", "compress", "kv", "json"] } flexi_logger = { version = "0.31.7", features = ["trc", "dont_minimize_extra_stacks", "compress", "kv", "json"] }
glob = "0.3.3" glob = "0.3.3"
google-cloud-storage = "1.4.0" google-cloud-storage = "1.5.0"
google-cloud-auth = "1.2.0" google-cloud-auth = "1.3.0"
hashbrown = { version = "0.16.1", features = ["serde", "rayon"] } hashbrown = { version = "0.16.1", features = ["serde", "rayon"] }
heed = { version = "0.22.0" } heed = { version = "0.22.0" }
hex-simd = "0.8.0" hex-simd = "0.8.0"
@@ -221,7 +221,7 @@ regex = { version = "1.12.2" }
rumqttc = { version = "0.25.1" } rumqttc = { version = "0.25.1" }
rust-embed = { version = "8.9.0" } rust-embed = { version = "8.9.0" }
rustc-hash = { version = "2.1.1" } rustc-hash = { version = "2.1.1" }
s3s = { version = "0.12.0-rc.4", features = ["minio"] } s3s = { version = "0.12.0-rc.5", features = ["minio"], git = "https://github.com/s3s-project/s3s.git", branch = "main" }
serial_test = "3.2.0" serial_test = "3.2.0"
shadow-rs = { version = "1.4.0", default-features = false } shadow-rs = { version = "1.4.0", default-features = false }
siphasher = "1.0.1" siphasher = "1.0.1"

View File

@@ -0,0 +1,56 @@
// Copyright 2024 RustFS Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Request body size limits for admin API endpoints
//!
//! These limits prevent DoS attacks through unbounded memory allocation
//! while allowing legitimate use cases.
/// Maximum size for standard admin API request bodies (1 MB)
/// Used for: user creation/update, policies, tier config, KMS config, events, groups, service accounts
/// Rationale: Admin API payloads are typically JSON/XML configs under 100KB.
/// AWS IAM policy limit is 6KB-10KB. 1MB provides generous headroom.
pub const MAX_ADMIN_REQUEST_BODY_SIZE: usize = 1024 * 1024; // 1 MB
/// Maximum size for IAM import/export operations (10 MB)
/// Used for: IAM entity imports/exports containing multiple users, policies, groups
/// Rationale: ZIP archives with hundreds of IAM entities. 10MB allows ~10,000 small configs.
pub const MAX_IAM_IMPORT_SIZE: usize = 10 * 1024 * 1024; // 10 MB
/// Maximum size for bucket metadata import operations (100 MB)
/// Used for: Bucket metadata import containing configurations for many buckets
/// Rationale: Large deployments may have thousands of buckets with various configs.
/// 100MB allows importing metadata for ~10,000 buckets with reasonable configs.
pub const MAX_BUCKET_METADATA_IMPORT_SIZE: usize = 100 * 1024 * 1024; // 100 MB
/// Maximum size for healing operation requests (1 MB)
/// Used for: Healing parameters and configuration
/// Rationale: Healing requests contain bucket/object paths and options. Should be small.
pub const MAX_HEAL_REQUEST_SIZE: usize = 1024 * 1024; // 1 MB
/// Maximum size for S3 client response bodies (10 MB)
/// Used for: Reading responses from remote S3-compatible services (ACL, attributes, lists)
/// Rationale: Responses from external services should be bounded.
/// Large responses (>10MB) indicate misconfiguration or potential attack.
/// Typical responses: ACL XML < 10KB, List responses < 1MB
///
/// Rationale: Responses from external S3-compatible services should be bounded.
/// - ACL XML responses: typically < 10KB
/// - Object attributes: typically < 100KB
/// - List responses: typically < 1MB (1000 objects with metadata)
/// - Location/error responses: typically < 10KB
///
/// 10MB provides generous headroom for legitimate responses while preventing
/// memory exhaustion from malicious or misconfigured remote services.
pub const MAX_S3_CLIENT_RESPONSE_SIZE: usize = 10 * 1024 * 1024; // 10 MB

View File

@@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
pub(crate) mod app; pub(crate) mod app;
pub(crate) mod body_limits;
pub(crate) mod console; pub(crate) mod console;
pub(crate) mod env; pub(crate) mod env;
pub(crate) mod heal; pub(crate) mod heal;

View File

@@ -17,6 +17,8 @@ pub mod constants;
#[cfg(feature = "constants")] #[cfg(feature = "constants")]
pub use constants::app::*; pub use constants::app::*;
#[cfg(feature = "constants")] #[cfg(feature = "constants")]
pub use constants::body_limits::*;
#[cfg(feature = "constants")]
pub use constants::console::*; pub use constants::console::*;
#[cfg(feature = "constants")] #[cfg(feature = "constants")]
pub use constants::env::*; pub use constants::env::*;

View File

@@ -18,19 +18,17 @@
#![allow(unused_must_use)] #![allow(unused_must_use)]
#![allow(clippy::all)] #![allow(clippy::all)]
use crate::client::{
api_error_response::http_resp_to_error_response,
api_get_options::GetObjectOptions,
transition_api::{ObjectInfo, ReaderImpl, RequestMetadata, TransitionClient},
};
use bytes::Bytes; use bytes::Bytes;
use http::{HeaderMap, HeaderValue}; use http::{HeaderMap, HeaderValue};
use rustfs_config::MAX_S3_CLIENT_RESPONSE_SIZE;
use rustfs_utils::EMPTY_STRING_SHA256_HASH;
use s3s::dto::Owner; use s3s::dto::Owner;
use std::collections::HashMap; use std::collections::HashMap;
use std::io::Cursor;
use tokio::io::BufReader;
use crate::client::{
api_error_response::{err_invalid_argument, http_resp_to_error_response},
api_get_options::GetObjectOptions,
transition_api::{ObjectInfo, ReadCloser, ReaderImpl, RequestMetadata, TransitionClient, to_object_info},
};
use rustfs_utils::EMPTY_STRING_SHA256_HASH;
#[derive(Clone, Debug, Default, serde::Serialize, serde::Deserialize)] #[derive(Clone, Debug, Default, serde::Serialize, serde::Deserialize)]
pub struct Grantee { pub struct Grantee {
@@ -90,7 +88,12 @@ impl TransitionClient {
return Err(std::io::Error::other(http_resp_to_error_response(&resp, b, bucket_name, object_name))); return Err(std::io::Error::other(http_resp_to_error_response(&resp, b, bucket_name, object_name)));
} }
let b = resp.body_mut().store_all_unlimited().await.unwrap().to_vec(); let b = resp
.body_mut()
.store_all_limited(MAX_S3_CLIENT_RESPONSE_SIZE)
.await
.unwrap()
.to_vec();
let mut res = match quick_xml::de::from_str::<AccessControlPolicy>(&String::from_utf8(b).unwrap()) { let mut res = match quick_xml::de::from_str::<AccessControlPolicy>(&String::from_utf8(b).unwrap()) {
Ok(result) => result, Ok(result) => result,
Err(err) => { Err(err) => {

View File

@@ -21,24 +21,17 @@
use bytes::Bytes; use bytes::Bytes;
use http::{HeaderMap, HeaderValue}; use http::{HeaderMap, HeaderValue};
use std::collections::HashMap; use std::collections::HashMap;
use std::io::Cursor;
use time::OffsetDateTime; use time::OffsetDateTime;
use tokio::io::BufReader;
use crate::client::constants::{GET_OBJECT_ATTRIBUTES_MAX_PARTS, GET_OBJECT_ATTRIBUTES_TAGS, ISO8601_DATEFORMAT}; use crate::client::constants::{GET_OBJECT_ATTRIBUTES_MAX_PARTS, GET_OBJECT_ATTRIBUTES_TAGS, ISO8601_DATEFORMAT};
use rustfs_utils::EMPTY_STRING_SHA256_HASH;
use s3s::header::{
X_AMZ_DELETE_MARKER, X_AMZ_MAX_PARTS, X_AMZ_METADATA_DIRECTIVE, X_AMZ_OBJECT_ATTRIBUTES, X_AMZ_PART_NUMBER_MARKER,
X_AMZ_REQUEST_CHARGED, X_AMZ_RESTORE, X_AMZ_VERSION_ID,
};
use s3s::{Body, dto::Owner};
use crate::client::{ use crate::client::{
api_error_response::err_invalid_argument,
api_get_object_acl::AccessControlPolicy, api_get_object_acl::AccessControlPolicy,
api_get_options::GetObjectOptions, transition_api::{ReaderImpl, RequestMetadata, TransitionClient},
transition_api::{ObjectInfo, ReadCloser, ReaderImpl, RequestMetadata, TransitionClient, to_object_info},
}; };
use rustfs_config::MAX_S3_CLIENT_RESPONSE_SIZE;
use rustfs_utils::EMPTY_STRING_SHA256_HASH;
use s3s::Body;
use s3s::header::{X_AMZ_MAX_PARTS, X_AMZ_OBJECT_ATTRIBUTES, X_AMZ_PART_NUMBER_MARKER, X_AMZ_VERSION_ID};
pub struct ObjectAttributesOptions { pub struct ObjectAttributesOptions {
pub max_parts: i64, pub max_parts: i64,
@@ -143,7 +136,12 @@ impl ObjectAttributes {
self.last_modified = mod_time; self.last_modified = mod_time;
self.version_id = h.get(X_AMZ_VERSION_ID).unwrap().to_str().unwrap().to_string(); self.version_id = h.get(X_AMZ_VERSION_ID).unwrap().to_str().unwrap().to_string();
let b = resp.body_mut().store_all_unlimited().await.unwrap().to_vec(); let b = resp
.body_mut()
.store_all_limited(MAX_S3_CLIENT_RESPONSE_SIZE)
.await
.unwrap()
.to_vec();
let mut response = match quick_xml::de::from_str::<ObjectAttributesResponse>(&String::from_utf8(b).unwrap()) { let mut response = match quick_xml::de::from_str::<ObjectAttributesResponse>(&String::from_utf8(b).unwrap()) {
Ok(result) => result, Ok(result) => result,
Err(err) => { Err(err) => {
@@ -224,7 +222,12 @@ impl TransitionClient {
} }
if resp.status() != http::StatusCode::OK { if resp.status() != http::StatusCode::OK {
let b = resp.body_mut().store_all_unlimited().await.unwrap().to_vec(); let b = resp
.body_mut()
.store_all_limited(MAX_S3_CLIENT_RESPONSE_SIZE)
.await
.unwrap()
.to_vec();
let err_body = String::from_utf8(b).unwrap(); let err_body = String::from_utf8(b).unwrap();
let mut er = match quick_xml::de::from_str::<AccessControlPolicy>(&err_body) { let mut er = match quick_xml::de::from_str::<AccessControlPolicy>(&err_body) {
Ok(result) => result, Ok(result) => result,

View File

@@ -18,10 +18,6 @@
#![allow(unused_must_use)] #![allow(unused_must_use)]
#![allow(clippy::all)] #![allow(clippy::all)]
use bytes::Bytes;
use http::{HeaderMap, StatusCode};
use std::collections::HashMap;
use crate::client::{ use crate::client::{
api_error_response::http_resp_to_error_response, api_error_response::http_resp_to_error_response,
api_s3_datatypes::{ api_s3_datatypes::{
@@ -31,7 +27,11 @@ use crate::client::{
transition_api::{ReaderImpl, RequestMetadata, TransitionClient}, transition_api::{ReaderImpl, RequestMetadata, TransitionClient},
}; };
use crate::store_api::BucketInfo; use crate::store_api::BucketInfo;
use bytes::Bytes;
use http::{HeaderMap, StatusCode};
use rustfs_config::MAX_S3_CLIENT_RESPONSE_SIZE;
use rustfs_utils::hash::EMPTY_STRING_SHA256_HASH; use rustfs_utils::hash::EMPTY_STRING_SHA256_HASH;
use std::collections::HashMap;
impl TransitionClient { impl TransitionClient {
pub fn list_buckets(&self) -> Result<Vec<BucketInfo>, std::io::Error> { pub fn list_buckets(&self) -> Result<Vec<BucketInfo>, std::io::Error> {
@@ -102,7 +102,12 @@ impl TransitionClient {
} }
//let mut list_bucket_result = ListBucketV2Result::default(); //let mut list_bucket_result = ListBucketV2Result::default();
let b = resp.body_mut().store_all_unlimited().await.unwrap().to_vec(); let b = resp
.body_mut()
.store_all_limited(MAX_S3_CLIENT_RESPONSE_SIZE)
.await
.unwrap()
.to_vec();
let mut list_bucket_result = match quick_xml::de::from_str::<ListBucketV2Result>(&String::from_utf8(b).unwrap()) { let mut list_bucket_result = match quick_xml::de::from_str::<ListBucketV2Result>(&String::from_utf8(b).unwrap()) {
Ok(result) => result, Ok(result) => result,
Err(err) => { Err(err) => {

View File

@@ -18,23 +18,19 @@
#![allow(unused_must_use)] #![allow(unused_must_use)]
#![allow(clippy::all)] #![allow(clippy::all)]
use http::Request; use super::constants::UNSIGNED_PAYLOAD;
use hyper::StatusCode; use super::credentials::SignatureType;
use hyper::body::Incoming;
use std::{collections::HashMap, sync::Arc};
use tracing::warn;
use tracing::{debug, error, info};
use crate::client::{ use crate::client::{
api_error_response::{http_resp_to_error_response, to_error_response}, api_error_response::http_resp_to_error_response,
transition_api::{CreateBucketConfiguration, LocationConstraint, TransitionClient}, transition_api::{CreateBucketConfiguration, LocationConstraint, TransitionClient},
}; };
use http::Request;
use hyper::StatusCode;
use rustfs_config::MAX_S3_CLIENT_RESPONSE_SIZE;
use rustfs_utils::hash::EMPTY_STRING_SHA256_HASH; use rustfs_utils::hash::EMPTY_STRING_SHA256_HASH;
use s3s::Body; use s3s::Body;
use s3s::S3ErrorCode; use s3s::S3ErrorCode;
use std::collections::HashMap;
use super::constants::UNSIGNED_PAYLOAD;
use super::credentials::SignatureType;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct BucketLocationCache { pub struct BucketLocationCache {
@@ -212,7 +208,12 @@ async fn process_bucket_location_response(
} }
//} //}
let b = resp.body_mut().store_all_unlimited().await.unwrap().to_vec(); let b = resp
.body_mut()
.store_all_limited(MAX_S3_CLIENT_RESPONSE_SIZE)
.await
.unwrap()
.to_vec();
let mut location = "".to_string(); let mut location = "".to_string();
if tier_type == "huaweicloud" { if tier_type == "huaweicloud" {
let d = quick_xml::de::from_str::<CreateBucketConfiguration>(&String::from_utf8(b).unwrap()).unwrap(); let d = quick_xml::de::from_str::<CreateBucketConfiguration>(&String::from_utf8(b).unwrap()).unwrap();

View File

@@ -18,6 +18,20 @@
#![allow(unused_must_use)] #![allow(unused_must_use)]
#![allow(clippy::all)] #![allow(clippy::all)]
use crate::client::bucket_cache::BucketLocationCache;
use crate::client::{
api_error_response::{err_invalid_argument, http_resp_to_error_response, to_error_response},
api_get_options::GetObjectOptions,
api_put_object::PutObjectOptions,
api_put_object_multipart::UploadPartParams,
api_s3_datatypes::{
CompleteMultipartUpload, CompletePart, ListBucketResult, ListBucketV2Result, ListMultipartUploadsResult,
ListObjectPartsResult, ObjectPart,
},
constants::{UNSIGNED_PAYLOAD, UNSIGNED_PAYLOAD_TRAILER},
credentials::{CredContext, Credentials, SignatureType, Static},
};
use crate::{client::checksum::ChecksumMode, store_api::GetObjectReader};
use bytes::Bytes; use bytes::Bytes;
use futures::{Future, StreamExt}; use futures::{Future, StreamExt};
use http::{HeaderMap, HeaderName}; use http::{HeaderMap, HeaderName};
@@ -30,7 +44,18 @@ use hyper_util::{client::legacy::Client, client::legacy::connect::HttpConnector,
use md5::Digest; use md5::Digest;
use md5::Md5; use md5::Md5;
use rand::Rng; use rand::Rng;
use rustfs_config::MAX_S3_CLIENT_RESPONSE_SIZE;
use rustfs_rio::HashReader;
use rustfs_utils::HashAlgorithm; use rustfs_utils::HashAlgorithm;
use rustfs_utils::{
net::get_endpoint_url,
retry::{
DEFAULT_RETRY_CAP, DEFAULT_RETRY_UNIT, MAX_JITTER, MAX_RETRY, RetryTimer, is_http_status_retryable, is_s3code_retryable,
},
};
use s3s::S3ErrorCode;
use s3s::dto::ReplicationStatus;
use s3s::{Body, dto::Owner};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha2::Sha256; use sha2::Sha256;
use std::io::Cursor; use std::io::Cursor;
@@ -48,31 +73,6 @@ use tracing::{debug, error, warn};
use url::{Url, form_urlencoded}; use url::{Url, form_urlencoded};
use uuid::Uuid; use uuid::Uuid;
use crate::client::bucket_cache::BucketLocationCache;
use crate::client::{
api_error_response::{err_invalid_argument, http_resp_to_error_response, to_error_response},
api_get_options::GetObjectOptions,
api_put_object::PutObjectOptions,
api_put_object_multipart::UploadPartParams,
api_s3_datatypes::{
CompleteMultipartUpload, CompletePart, ListBucketResult, ListBucketV2Result, ListMultipartUploadsResult,
ListObjectPartsResult, ObjectPart,
},
constants::{UNSIGNED_PAYLOAD, UNSIGNED_PAYLOAD_TRAILER},
credentials::{CredContext, Credentials, SignatureType, Static},
};
use crate::{client::checksum::ChecksumMode, store_api::GetObjectReader};
use rustfs_rio::HashReader;
use rustfs_utils::{
net::get_endpoint_url,
retry::{
DEFAULT_RETRY_CAP, DEFAULT_RETRY_UNIT, MAX_JITTER, MAX_RETRY, RetryTimer, is_http_status_retryable, is_s3code_retryable,
},
};
use s3s::S3ErrorCode;
use s3s::dto::ReplicationStatus;
use s3s::{Body, dto::Owner};
const C_USER_AGENT: &str = "RustFS (linux; x86)"; const C_USER_AGENT: &str = "RustFS (linux; x86)";
const SUCCESS_STATUS: [StatusCode; 3] = [StatusCode::OK, StatusCode::NO_CONTENT, StatusCode::PARTIAL_CONTENT]; const SUCCESS_STATUS: [StatusCode; 3] = [StatusCode::OK, StatusCode::NO_CONTENT, StatusCode::PARTIAL_CONTENT];
@@ -291,7 +291,12 @@ impl TransitionClient {
//if self.is_trace_enabled && !(self.trace_errors_only && resp.status() == StatusCode::OK) { //if self.is_trace_enabled && !(self.trace_errors_only && resp.status() == StatusCode::OK) {
if resp.status() != StatusCode::OK { if resp.status() != StatusCode::OK {
//self.dump_http(&cloned_req, &resp)?; //self.dump_http(&cloned_req, &resp)?;
let b = resp.body_mut().store_all_unlimited().await.unwrap().to_vec(); let b = resp
.body_mut()
.store_all_limited(MAX_S3_CLIENT_RESPONSE_SIZE)
.await
.unwrap()
.to_vec();
warn!("err_body: {}", String::from_utf8(b).unwrap()); warn!("err_body: {}", String::from_utf8(b).unwrap());
} }
@@ -334,7 +339,12 @@ impl TransitionClient {
} }
} }
let b = resp.body_mut().store_all_unlimited().await.unwrap().to_vec(); let b = resp
.body_mut()
.store_all_limited(MAX_S3_CLIENT_RESPONSE_SIZE)
.await
.unwrap()
.to_vec();
let mut err_response = http_resp_to_error_response(&resp, b.clone(), &metadata.bucket_name, &metadata.object_name); let mut err_response = http_resp_to_error_response(&resp, b.clone(), &metadata.bucket_name, &metadata.object_name);
err_response.message = format!("remote tier error: {}", err_response.message); err_response.message = format!("remote tier error: {}", err_response.message);

View File

@@ -0,0 +1,42 @@
# DoS Prevention: Request/Response Body Size Limits
## Executive Summary
This document describes the implementation of request and response body size limits in RustFS to prevent Denial of Service (DoS) attacks through unbounded memory allocation. The previous use of `usize::MAX` with `store_all_limited()` posed a critical security risk allowing attackers to exhaust server memory.
## Security Risk Assessment
### Vulnerability: Unbounded Memory Allocation
**Severity**: High
**Impact**: Server memory exhaustion, service unavailability
**Likelihood**: High (easily exploitable)
**Previous Code** (vulnerable):
```rust
let body = input.store_all_limited(usize::MAX).await?;
```
On a 64-bit system, `usize::MAX` is approximately 18 exabytes, effectively unlimited.
## Implemented Limits
| Limit | Size | Use Cases |
|-------|------|-----------|
| `MAX_ADMIN_REQUEST_BODY_SIZE` | 1 MB | User management, policies, tier/KMS/event configs |
| `MAX_IAM_IMPORT_SIZE` | 10 MB | IAM import/export (ZIP archives) |
| `MAX_BUCKET_METADATA_IMPORT_SIZE` | 100 MB | Bucket metadata import |
| `MAX_HEAL_REQUEST_SIZE` | 1 MB | Healing operations |
| `MAX_S3_RESPONSE_SIZE` | 10 MB | S3 client responses from remote services |
## Rationale
- AWS IAM policy limit: 6KB-10KB
- Typical payloads: < 100KB
- 1MB-100MB limits provide generous headroom while preventing DoS
- Based on real-world usage analysis and industry standards
## Files Modified
- 22 files updated across admin handlers and S3 client modules
- 2 new files: `rustfs/src/admin/constants.rs`, `crates/ecstore/src/client/body_limits.rs`

View File

@@ -24,6 +24,7 @@ use http::{HeaderMap, HeaderValue, Uri};
use hyper::StatusCode; use hyper::StatusCode;
use matchit::Params; use matchit::Params;
use rustfs_common::heal_channel::HealOpts; use rustfs_common::heal_channel::HealOpts;
use rustfs_config::{MAX_ADMIN_REQUEST_BODY_SIZE, MAX_HEAL_REQUEST_SIZE};
use rustfs_ecstore::admin_server_info::get_server_info; use rustfs_ecstore::admin_server_info::get_server_info;
use rustfs_ecstore::bucket::bucket_target_sys::BucketTargetSys; use rustfs_ecstore::bucket::bucket_target_sys::BucketTargetSys;
use rustfs_ecstore::bucket::metadata::BUCKET_TARGETS_FILE; use rustfs_ecstore::bucket::metadata::BUCKET_TARGETS_FILE;
@@ -860,11 +861,11 @@ impl Operation for HealHandler {
let Some(cred) = req.credentials else { return Err(s3_error!(InvalidRequest, "get cred failed")) }; let Some(cred) = req.credentials else { return Err(s3_error!(InvalidRequest, "get cred failed")) };
info!("cred: {:?}", cred); info!("cred: {:?}", cred);
let mut input = req.input; let mut input = req.input;
let bytes = match input.store_all_unlimited().await { let bytes = match input.store_all_limited(MAX_HEAL_REQUEST_SIZE).await {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
warn!("get body failed, e: {:?}", e); warn!("get body failed, e: {:?}", e);
return Err(s3_error!(InvalidRequest, "get body failed")); return Err(s3_error!(InvalidRequest, "heal request body too large or failed to read"));
} }
}; };
info!("bytes: {:?}", bytes); info!("bytes: {:?}", bytes);
@@ -1052,11 +1053,11 @@ impl Operation for SetRemoteTargetHandler {
.map_err(ApiError::from)?; .map_err(ApiError::from)?;
let mut input = req.input; let mut input = req.input;
let body = match input.store_all_unlimited().await { let body = match input.store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE).await {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
warn!("get body failed, e: {:?}", e); warn!("get body failed, e: {:?}", e);
return Err(s3_error!(InvalidRequest, "get body failed")); return Err(s3_error!(InvalidRequest, "remote target configuration body too large or failed to read"));
} }
}; };

View File

@@ -21,9 +21,9 @@ use crate::{
admin::{auth::validate_admin_request, router::Operation}, admin::{auth::validate_admin_request, router::Operation},
auth::{check_key_valid, get_session_token}, auth::{check_key_valid, get_session_token},
}; };
use http::{HeaderMap, StatusCode}; use http::{HeaderMap, StatusCode};
use matchit::Params; use matchit::Params;
use rustfs_config::MAX_BUCKET_METADATA_IMPORT_SIZE;
use rustfs_ecstore::{ use rustfs_ecstore::{
StorageAPI, StorageAPI,
bucket::{ bucket::{
@@ -393,11 +393,11 @@ impl Operation for ImportBucketMetadata {
.await?; .await?;
let mut input = req.input; let mut input = req.input;
let body = match input.store_all_unlimited().await { let body = match input.store_all_limited(MAX_BUCKET_METADATA_IMPORT_SIZE).await {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
warn!("get body failed, e: {:?}", e); warn!("get body failed, e: {:?}", e);
return Err(s3_error!(InvalidRequest, "get body failed")); return Err(s3_error!(InvalidRequest, "bucket metadata import body too large or failed to read"));
} }
}; };

View File

@@ -17,7 +17,7 @@ use crate::auth::{check_key_valid, get_session_token};
use http::{HeaderMap, StatusCode}; use http::{HeaderMap, StatusCode};
use matchit::Params; use matchit::Params;
use rustfs_config::notify::{NOTIFY_MQTT_SUB_SYS, NOTIFY_WEBHOOK_SUB_SYS}; use rustfs_config::notify::{NOTIFY_MQTT_SUB_SYS, NOTIFY_WEBHOOK_SUB_SYS};
use rustfs_config::{ENABLE_KEY, EnableState}; use rustfs_config::{ENABLE_KEY, EnableState, MAX_ADMIN_REQUEST_BODY_SIZE};
use rustfs_targets::check_mqtt_broker_available; use rustfs_targets::check_mqtt_broker_available;
use s3s::header::CONTENT_LENGTH; use s3s::header::CONTENT_LENGTH;
use s3s::{Body, S3Error, S3ErrorCode, S3Request, S3Response, S3Result, header::CONTENT_TYPE, s3_error}; use s3s::{Body, S3Error, S3ErrorCode, S3Request, S3Response, S3Result, header::CONTENT_TYPE, s3_error};
@@ -140,7 +140,7 @@ impl Operation for NotificationTarget {
// 4. The parsing request body is KVS (Key-Value Store) // 4. The parsing request body is KVS (Key-Value Store)
let mut input = req.input; let mut input = req.input;
let body = input.store_all_unlimited().await.map_err(|e| { let body = input.store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE).await.map_err(|e| {
warn!("failed to read request body: {:?}", e); warn!("failed to read request body: {:?}", e);
s3_error!(InvalidRequest, "failed to read request body") s3_error!(InvalidRequest, "failed to read request body")
})?; })?;

View File

@@ -12,8 +12,13 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use crate::{
admin::{auth::validate_admin_request, router::Operation, utils::has_space_be},
auth::{check_key_valid, constant_time_eq, get_session_token},
};
use http::{HeaderMap, StatusCode}; use http::{HeaderMap, StatusCode};
use matchit::Params; use matchit::Params;
use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE;
use rustfs_ecstore::global::get_global_action_cred; use rustfs_ecstore::global::get_global_action_cred;
use rustfs_iam::error::{is_err_no_such_group, is_err_no_such_user}; use rustfs_iam::error::{is_err_no_such_group, is_err_no_such_user};
use rustfs_madmin::GroupAddRemove; use rustfs_madmin::GroupAddRemove;
@@ -27,11 +32,6 @@ use serde::Deserialize;
use serde_urlencoded::from_bytes; use serde_urlencoded::from_bytes;
use tracing::warn; use tracing::warn;
use crate::{
admin::{auth::validate_admin_request, router::Operation, utils::has_space_be},
auth::{check_key_valid, constant_time_eq, get_session_token},
};
#[derive(Debug, Deserialize, Default)] #[derive(Debug, Deserialize, Default)]
pub struct GroupQuery { pub struct GroupQuery {
pub group: String, pub group: String,
@@ -213,11 +213,11 @@ impl Operation for UpdateGroupMembers {
.await?; .await?;
let mut input = req.input; let mut input = req.input;
let body = match input.store_all_unlimited().await { let body = match input.store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE).await {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
warn!("get body failed, e: {:?}", e); warn!("get body failed, e: {:?}", e);
return Err(s3_error!(InvalidRequest, "get body failed")); return Err(s3_error!(InvalidRequest, "group configuration body too large or failed to read"));
} }
}; };

View File

@@ -20,6 +20,7 @@ use crate::auth::{check_key_valid, get_session_token};
use base64::Engine; use base64::Engine;
use hyper::{HeaderMap, StatusCode}; use hyper::{HeaderMap, StatusCode};
use matchit::Params; use matchit::Params;
use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE;
use rustfs_kms::{get_global_encryption_service, types::*}; use rustfs_kms::{get_global_encryption_service, types::*};
use rustfs_policy::policy::action::{Action, AdminAction}; use rustfs_policy::policy::action::{Action, AdminAction};
use s3s::header::CONTENT_TYPE; use s3s::header::CONTENT_TYPE;
@@ -131,7 +132,7 @@ impl Operation for CreateKeyHandler {
let body = req let body = req
.input .input
.store_all_unlimited() .store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE)
.await .await
.map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?; .map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?;
@@ -325,7 +326,7 @@ impl Operation for GenerateDataKeyHandler {
let body = req let body = req
.input .input
.store_all_unlimited() .store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE)
.await .await
.map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?; .map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?;

View File

@@ -19,6 +19,7 @@ use crate::admin::auth::validate_admin_request;
use crate::auth::{check_key_valid, get_session_token}; use crate::auth::{check_key_valid, get_session_token};
use hyper::StatusCode; use hyper::StatusCode;
use matchit::Params; use matchit::Params;
use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE;
use rustfs_ecstore::config::com::{read_config, save_config}; use rustfs_ecstore::config::com::{read_config, save_config};
use rustfs_ecstore::new_object_layer_fn; use rustfs_ecstore::new_object_layer_fn;
use rustfs_kms::{ use rustfs_kms::{
@@ -102,7 +103,7 @@ impl Operation for ConfigureKmsHandler {
let body = req let body = req
.input .input
.store_all_unlimited() .store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE)
.await .await
.map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?; .map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?;
@@ -200,7 +201,7 @@ impl Operation for StartKmsHandler {
let body = req let body = req
.input .input
.store_all_unlimited() .store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE)
.await .await
.map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?; .map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?;
@@ -469,7 +470,7 @@ impl Operation for ReconfigureKmsHandler {
let body = req let body = req
.input .input
.store_all_unlimited() .store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE)
.await .await
.map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?; .map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?;

View File

@@ -19,6 +19,7 @@ use crate::admin::auth::validate_admin_request;
use crate::auth::{check_key_valid, get_session_token}; use crate::auth::{check_key_valid, get_session_token};
use hyper::{HeaderMap, StatusCode}; use hyper::{HeaderMap, StatusCode};
use matchit::Params; use matchit::Params;
use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE;
use rustfs_kms::{KmsError, get_global_kms_service_manager, types::*}; use rustfs_kms::{KmsError, get_global_kms_service_manager, types::*};
use rustfs_policy::policy::action::{Action, AdminAction}; use rustfs_policy::policy::action::{Action, AdminAction};
use s3s::header::CONTENT_TYPE; use s3s::header::CONTENT_TYPE;
@@ -83,7 +84,7 @@ impl Operation for CreateKmsKeyHandler {
let body = req let body = req
.input .input
.store_all_unlimited() .store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE)
.await .await
.map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?; .map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?;
@@ -216,7 +217,7 @@ impl Operation for DeleteKmsKeyHandler {
let body = req let body = req
.input .input
.store_all_unlimited() .store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE)
.await .await
.map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?; .map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?;
@@ -364,7 +365,7 @@ impl Operation for CancelKmsKeyDeletionHandler {
let body = req let body = req
.input .input
.store_all_unlimited() .store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE)
.await .await
.map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?; .map_err(|e| s3_error!(InvalidRequest, "failed to read request body: {}", e))?;

View File

@@ -18,6 +18,7 @@ use crate::{
}; };
use http::{HeaderMap, StatusCode}; use http::{HeaderMap, StatusCode};
use matchit::Params; use matchit::Params;
use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE;
use rustfs_ecstore::global::get_global_action_cred; use rustfs_ecstore::global::get_global_action_cred;
use rustfs_iam::error::is_err_no_such_user; use rustfs_iam::error::is_err_no_such_user;
use rustfs_iam::store::MappedPolicy; use rustfs_iam::store::MappedPolicy;
@@ -139,11 +140,11 @@ impl Operation for AddCannedPolicy {
} }
let mut input = req.input; let mut input = req.input;
let policy_bytes = match input.store_all_unlimited().await { let policy_bytes = match input.store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE).await {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
warn!("get body failed, e: {:?}", e); warn!("get body failed, e: {:?}", e);
return Err(s3_error!(InvalidRequest, "get body failed")); return Err(s3_error!(InvalidRequest, "policy configuration body too large or failed to read"));
} }
}; };

View File

@@ -18,6 +18,7 @@ use crate::{admin::router::Operation, auth::check_key_valid};
use http::HeaderMap; use http::HeaderMap;
use hyper::StatusCode; use hyper::StatusCode;
use matchit::Params; use matchit::Params;
use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE;
use rustfs_ecstore::global::get_global_action_cred; use rustfs_ecstore::global::get_global_action_cred;
use rustfs_iam::error::is_err_no_such_service_account; use rustfs_iam::error::is_err_no_such_service_account;
use rustfs_iam::sys::{NewServiceAccountOpts, UpdateServiceAccountOpts}; use rustfs_iam::sys::{NewServiceAccountOpts, UpdateServiceAccountOpts};
@@ -48,11 +49,14 @@ impl Operation for AddServiceAccount {
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &req_cred.access_key).await?; check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &req_cred.access_key).await?;
let mut input = req.input; let mut input = req.input;
let body = match input.store_all_unlimited().await { let body = match input.store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE).await {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
warn!("get body failed, e: {:?}", e); warn!("get body failed, e: {:?}", e);
return Err(s3_error!(InvalidRequest, "get body failed")); return Err(s3_error!(
InvalidRequest,
"service account configuration body too large or failed to read"
));
} }
}; };
@@ -235,11 +239,14 @@ impl Operation for UpdateServiceAccount {
// })?; // })?;
let mut input = req.input; let mut input = req.input;
let body = match input.store_all_unlimited().await { let body = match input.store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE).await {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
warn!("get body failed, e: {:?}", e); warn!("get body failed, e: {:?}", e);
return Err(s3_error!(InvalidRequest, "get body failed")); return Err(s3_error!(
InvalidRequest,
"service account configuration body too large or failed to read"
));
} }
}; };
@@ -439,8 +446,8 @@ impl Operation for ListServiceAccount {
let query = { let query = {
if let Some(query) = req.uri.query() { if let Some(query) = req.uri.query() {
let input: ListServiceAccountQuery = let input: ListServiceAccountQuery = from_bytes(query.as_bytes())
from_bytes(query.as_bytes()).map_err(|_e| s3_error!(InvalidArgument, "get body failed"))?; .map_err(|_e| s3_error!(InvalidArgument, "invalid service account query parameters"))?;
input input
} else { } else {
ListServiceAccountQuery::default() ListServiceAccountQuery::default()
@@ -549,8 +556,8 @@ impl Operation for DeleteServiceAccount {
let query = { let query = {
if let Some(query) = req.uri.query() { if let Some(query) = req.uri.query() {
let input: AccessKeyQuery = let input: AccessKeyQuery = from_bytes(query.as_bytes())
from_bytes(query.as_bytes()).map_err(|_e| s3_error!(InvalidArgument, "get body failed"))?; .map_err(|_e| s3_error!(InvalidArgument, "invalid access key query parameters"))?;
input input
} else { } else {
AccessKeyQuery::default() AccessKeyQuery::default()

View File

@@ -18,6 +18,7 @@ use crate::{
}; };
use http::StatusCode; use http::StatusCode;
use matchit::Params; use matchit::Params;
use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE;
use rustfs_ecstore::bucket::utils::serialize; use rustfs_ecstore::bucket::utils::serialize;
use rustfs_iam::{manager::get_token_signing_key, sys::SESSION_POLICY_NAME}; use rustfs_iam::{manager::get_token_signing_key, sys::SESSION_POLICY_NAME};
use rustfs_policy::{auth::get_new_credentials_with_metadata, policy::Policy}; use rustfs_policy::{auth::get_new_credentials_with_metadata, policy::Policy};
@@ -71,15 +72,15 @@ impl Operation for AssumeRoleHandle {
let mut input = req.input; let mut input = req.input;
let bytes = match input.store_all_unlimited().await { let bytes = match input.store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE).await {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
warn!("get body failed, e: {:?}", e); warn!("get body failed, e: {:?}", e);
return Err(s3_error!(InvalidRequest, "get body failed")); return Err(s3_error!(InvalidRequest, "STS request body too large or failed to read"));
} }
}; };
let body: AssumeRoleRequest = from_bytes(&bytes).map_err(|_e| s3_error!(InvalidRequest, "get body failed"))?; let body: AssumeRoleRequest = from_bytes(&bytes).map_err(|_e| s3_error!(InvalidRequest, "invalid STS request format"))?;
if body.action.as_str() != ASSUME_ROLE_ACTION { if body.action.as_str() != ASSUME_ROLE_ACTION {
return Err(s3_error!(InvalidArgument, "not support action")); return Err(s3_error!(InvalidArgument, "not support action"));

View File

@@ -13,24 +13,13 @@
// limitations under the License. // limitations under the License.
#![allow(unused_variables, unused_mut, unused_must_use)] #![allow(unused_variables, unused_mut, unused_must_use)]
use http::{HeaderMap, StatusCode};
//use iam::get_global_action_cred;
use matchit::Params;
use rustfs_policy::policy::action::{Action, AdminAction};
use s3s::{
Body, S3Error, S3ErrorCode, S3Request, S3Response, S3Result,
header::{CONTENT_LENGTH, CONTENT_TYPE},
s3_error,
};
use serde_urlencoded::from_bytes;
use time::OffsetDateTime;
use tracing::{debug, warn};
use crate::{ use crate::{
admin::{auth::validate_admin_request, router::Operation}, admin::{auth::validate_admin_request, router::Operation},
auth::{check_key_valid, get_session_token}, auth::{check_key_valid, get_session_token},
}; };
use http::{HeaderMap, StatusCode};
use matchit::Params;
use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE;
use rustfs_ecstore::{ use rustfs_ecstore::{
config::storageclass, config::storageclass,
global::GLOBAL_TierConfigMgr, global::GLOBAL_TierConfigMgr,
@@ -44,6 +33,15 @@ use rustfs_ecstore::{
}, },
}, },
}; };
use rustfs_policy::policy::action::{Action, AdminAction};
use s3s::{
Body, S3Error, S3ErrorCode, S3Request, S3Response, S3Result,
header::{CONTENT_LENGTH, CONTENT_TYPE},
s3_error,
};
use serde_urlencoded::from_bytes;
use time::OffsetDateTime;
use tracing::{debug, warn};
#[derive(Debug, Clone, serde::Deserialize, Default)] #[derive(Debug, Clone, serde::Deserialize, Default)]
pub struct AddTierQuery { pub struct AddTierQuery {
@@ -95,11 +93,11 @@ impl Operation for AddTier {
validate_admin_request(&req.headers, &cred, owner, false, vec![Action::AdminAction(AdminAction::SetTierAction)]).await?; validate_admin_request(&req.headers, &cred, owner, false, vec![Action::AdminAction(AdminAction::SetTierAction)]).await?;
let mut input = req.input; let mut input = req.input;
let body = match input.store_all_unlimited().await { let body = match input.store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE).await {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
warn!("get body failed, e: {:?}", e); warn!("get body failed, e: {:?}", e);
return Err(s3_error!(InvalidRequest, "get body failed")); return Err(s3_error!(InvalidRequest, "tier configuration body too large or failed to read"));
} }
}; };
@@ -223,11 +221,11 @@ impl Operation for EditTier {
validate_admin_request(&req.headers, &cred, owner, false, vec![Action::AdminAction(AdminAction::SetTierAction)]).await?; validate_admin_request(&req.headers, &cred, owner, false, vec![Action::AdminAction(AdminAction::SetTierAction)]).await?;
let mut input = req.input; let mut input = req.input;
let body = match input.store_all_unlimited().await { let body = match input.store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE).await {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
warn!("get body failed, e: {:?}", e); warn!("get body failed, e: {:?}", e);
return Err(s3_error!(InvalidRequest, "get body failed")); return Err(s3_error!(InvalidRequest, "tier configuration body too large or failed to read"));
} }
}; };

View File

@@ -18,6 +18,7 @@ use crate::{
}; };
use http::{HeaderMap, StatusCode}; use http::{HeaderMap, StatusCode};
use matchit::Params; use matchit::Params;
use rustfs_config::{MAX_ADMIN_REQUEST_BODY_SIZE, MAX_IAM_IMPORT_SIZE};
use rustfs_ecstore::global::get_global_action_cred; use rustfs_ecstore::global::get_global_action_cred;
use rustfs_iam::{ use rustfs_iam::{
store::{GroupInfo, MappedPolicy, UserType}, store::{GroupInfo, MappedPolicy, UserType},
@@ -76,7 +77,7 @@ impl Operation for AddUser {
} }
let mut input = req.input; let mut input = req.input;
let body = match input.store_all_unlimited().await { let body = match input.store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE).await {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
warn!("get body failed, e: {:?}", e); warn!("get body failed, e: {:?}", e);
@@ -636,7 +637,7 @@ impl Operation for ImportIam {
.await?; .await?;
let mut input = req.input; let mut input = req.input;
let body = match input.store_all_unlimited().await { let body = match input.store_all_limited(MAX_IAM_IMPORT_SIZE).await {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
warn!("get body failed, e: {:?}", e); warn!("get body failed, e: {:?}", e);

View File

@@ -19,6 +19,7 @@ use futures::StreamExt;
use http::StatusCode; use http::StatusCode;
use hyper::Method; use hyper::Method;
use matchit::Params; use matchit::Params;
use rustfs_config::MAX_ADMIN_REQUEST_BODY_SIZE;
use rustfs_ecstore::disk::DiskAPI; use rustfs_ecstore::disk::DiskAPI;
use rustfs_ecstore::disk::WalkDirOptions; use rustfs_ecstore::disk::WalkDirOptions;
use rustfs_ecstore::set_disk::DEFAULT_READ_BUFFER_SIZE; use rustfs_ecstore::set_disk::DEFAULT_READ_BUFFER_SIZE;
@@ -141,11 +142,11 @@ impl Operation for WalkDir {
}; };
let mut input = req.input; let mut input = req.input;
let body = match input.store_all_unlimited().await { let body = match input.store_all_limited(MAX_ADMIN_REQUEST_BODY_SIZE).await {
Ok(b) => b, Ok(b) => b,
Err(e) => { Err(e) => {
warn!("get body failed, e: {:?}", e); warn!("get body failed, e: {:?}", e);
return Err(s3_error!(InvalidRequest, "get body failed")); return Err(s3_error!(InvalidRequest, "RPC request body too large or failed to read"));
} }
}; };

View File

@@ -2389,8 +2389,10 @@ impl S3 for FS {
let info = store.get_object_info(&bucket, &key, &opts).await.map_err(ApiError::from)?; let info = store.get_object_info(&bucket, &key, &opts).await.map_err(ApiError::from)?;
if let Some(match_etag) = if_none_match { if let Some(match_etag) = if_none_match {
if info.etag.as_ref().is_some_and(|etag| etag == match_etag.as_str()) { if let Some(strong_etag) = match_etag.as_strong() {
return Err(S3Error::new(S3ErrorCode::NotModified)); if info.etag.as_ref().is_some_and(|etag| etag == strong_etag) {
return Err(S3Error::new(S3ErrorCode::NotModified));
}
} }
} }
@@ -2405,8 +2407,10 @@ impl S3 for FS {
} }
if let Some(match_etag) = if_match { if let Some(match_etag) = if_match {
if info.etag.as_ref().is_some_and(|etag| etag != match_etag.as_str()) { if let Some(strong_etag) = match_etag.as_strong() {
return Err(S3Error::new(S3ErrorCode::PreconditionFailed)); if info.etag.as_ref().is_some_and(|etag| etag != strong_etag) {
return Err(S3Error::new(S3ErrorCode::PreconditionFailed));
}
} }
} else if let Some(unmodified_since) = if_unmodified_since { } else if let Some(unmodified_since) = if_unmodified_since {
if info.mod_time.is_some_and(|mod_time| { if info.mod_time.is_some_and(|mod_time| {
@@ -2856,13 +2860,17 @@ impl S3 for FS {
Ok(info) => { Ok(info) => {
if !info.delete_marker { if !info.delete_marker {
if let Some(ifmatch) = if_match { if let Some(ifmatch) = if_match {
if info.etag.as_ref().is_some_and(|etag| etag != ifmatch.as_str()) { if let Some(strong_etag) = ifmatch.as_strong() {
return Err(s3_error!(PreconditionFailed)); if info.etag.as_ref().is_some_and(|etag| etag != strong_etag) {
return Err(s3_error!(PreconditionFailed));
}
} }
} }
if let Some(ifnonematch) = if_none_match { if let Some(ifnonematch) = if_none_match {
if info.etag.as_ref().is_some_and(|etag| etag == ifnonematch.as_str()) { if let Some(strong_etag) = ifnonematch.as_strong() {
return Err(s3_error!(PreconditionFailed)); if info.etag.as_ref().is_some_and(|etag| etag == strong_etag) {
return Err(s3_error!(PreconditionFailed));
}
} }
} }
} }
@@ -3655,7 +3663,12 @@ impl S3 for FS {
// Validate copy conditions (simplified for now) // Validate copy conditions (simplified for now)
if let Some(if_match) = copy_source_if_match { if let Some(if_match) = copy_source_if_match {
if let Some(ref etag) = src_info.etag { if let Some(ref etag) = src_info.etag {
if etag != &if_match { if let Some(strong_etag) = if_match.as_strong() {
if etag != strong_etag {
return Err(s3_error!(PreconditionFailed));
}
} else {
// Weak ETag in If-Match should fail
return Err(s3_error!(PreconditionFailed)); return Err(s3_error!(PreconditionFailed));
} }
} else { } else {
@@ -3665,9 +3678,12 @@ impl S3 for FS {
if let Some(if_none_match) = copy_source_if_none_match { if let Some(if_none_match) = copy_source_if_none_match {
if let Some(ref etag) = src_info.etag { if let Some(ref etag) = src_info.etag {
if etag == &if_none_match { if let Some(strong_etag) = if_none_match.as_strong() {
return Err(s3_error!(PreconditionFailed)); if etag == strong_etag {
return Err(s3_error!(PreconditionFailed));
}
} }
// Weak ETag in If-None-Match is ignored (doesn't match)
} }
} }
@@ -3939,13 +3955,17 @@ impl S3 for FS {
Ok(info) => { Ok(info) => {
if !info.delete_marker { if !info.delete_marker {
if let Some(ifmatch) = if_match { if let Some(ifmatch) = if_match {
if info.etag.as_ref().is_some_and(|etag| etag != ifmatch.as_str()) { if let Some(strong_etag) = ifmatch.as_strong() {
return Err(s3_error!(PreconditionFailed)); if info.etag.as_ref().is_some_and(|etag| etag != strong_etag) {
return Err(s3_error!(PreconditionFailed));
}
} }
} }
if let Some(ifnonematch) = if_none_match { if let Some(ifnonematch) = if_none_match {
if info.etag.as_ref().is_some_and(|etag| etag == ifnonematch.as_str()) { if let Some(strong_etag) = ifnonematch.as_strong() {
return Err(s3_error!(PreconditionFailed)); if info.etag.as_ref().is_some_and(|etag| etag == strong_etag) {
return Err(s3_error!(PreconditionFailed));
}
} }
} }
} }