AWS SDK

AWS SDK

rev. 45f7c63234ab3c1e256d57af241ed3cf5f32c495

Files changed:

tmp-codegen-diff/aws-sdk/Cargo.lock

@@ -1,1 +45,45 @@
    3      3   
version = 4
    4      4   
    5      5   
[[package]]
    6      6   
name = "adler2"
    7      7   
version = "2.0.1"
    8      8   
source = "registry+https://github.com/rust-lang/crates.io-index"
    9      9   
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
   10     10   
   11     11   
[[package]]
   12     12   
name = "aho-corasick"
   13         -
version = "1.1.4"
          13  +
version = "1.1.3"
   14     14   
source = "registry+https://github.com/rust-lang/crates.io-index"
   15         -
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
          15  +
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
   16     16   
dependencies = [
   17     17   
 "memchr",
   18     18   
]
   19     19   
   20     20   
[[package]]
   21     21   
name = "allocator-api2"
   22     22   
version = "0.2.21"
   23     23   
source = "registry+https://github.com/rust-lang/crates.io-index"
   24     24   
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
   25     25   
@@ -336,336 +447,447 @@
  356    356   
 "tokio",
  357    357   
 "tracing",
  358    358   
 "tracing-subscriber",
  359    359   
 "tracing-test",
  360    360   
 "url",
  361    361   
 "zeroize",
  362    362   
]
  363    363   
  364    364   
[[package]]
  365    365   
name = "aws-credential-types"
  366         -
version = "1.2.9"
         366  +
version = "1.2.8"
  367    367   
dependencies = [
  368    368   
 "async-trait",
  369    369   
 "aws-smithy-async",
  370    370   
 "aws-smithy-runtime-api",
  371    371   
 "aws-smithy-types",
  372    372   
 "tokio",
  373    373   
 "zeroize",
  374    374   
]
  375    375   
  376    376   
[[package]]
  377    377   
name = "aws-lc-fips-sys"
  378    378   
version = "0.13.9"
  379    379   
source = "registry+https://github.com/rust-lang/crates.io-index"
  380    380   
checksum = "ede71ad84efb06d748d9af3bc500b14957a96282a69a6833b1420dcacb411cc3"
  381    381   
dependencies = [
  382    382   
 "bindgen",
  383    383   
 "cc",
  384    384   
 "cmake",
  385    385   
 "dunce",
  386    386   
 "fs_extra",
  387    387   
 "regex",
  388    388   
]
  389    389   
  390    390   
[[package]]
  391    391   
name = "aws-lc-rs"
  392    392   
version = "1.14.1"
  393    393   
source = "registry+https://github.com/rust-lang/crates.io-index"
  394    394   
checksum = "879b6c89592deb404ba4dc0ae6b58ffd1795c78991cbb5b8bc441c48a070440d"
  395    395   
dependencies = [
  396    396   
 "aws-lc-fips-sys",
  397    397   
 "aws-lc-sys",
  398    398   
 "untrusted 0.7.1",
  399    399   
 "zeroize",
  400    400   
]
  401    401   
  402    402   
[[package]]
  403    403   
name = "aws-lc-sys"
  404    404   
version = "0.32.3"
  405    405   
source = "registry+https://github.com/rust-lang/crates.io-index"
  406    406   
checksum = "107a4e9d9cab9963e04e84bb8dee0e25f2a987f9a8bad5ed054abd439caa8f8c"
  407    407   
dependencies = [
  408    408   
 "bindgen",
  409    409   
 "cc",
  410    410   
 "cmake",
  411    411   
 "dunce",
  412    412   
 "fs_extra",
  413    413   
]
  414    414   
  415    415   
[[package]]
  416    416   
name = "aws-runtime"
  417         -
version = "1.5.14"
         417  +
version = "1.5.13"
  418    418   
dependencies = [
  419    419   
 "arbitrary",
  420    420   
 "aws-credential-types",
  421    421   
 "aws-sigv4",
  422    422   
 "aws-smithy-async",
  423    423   
 "aws-smithy-eventstream",
  424    424   
 "aws-smithy-http",
  425    425   
 "aws-smithy-protocol-test",
  426    426   
 "aws-smithy-runtime",
  427    427   
 "aws-smithy-runtime-api",
@@ -1203,1203 +1263,1263 @@
 1223   1223   
 "http-body 1.0.1",
 1224   1224   
 "http-body-util",
 1225   1225   
 "hyper 0.14.32",
 1226   1226   
 "hyper 1.7.0",
 1227   1227   
 "hyper-rustls 0.24.2",
 1228   1228   
 "hyper-rustls 0.27.7",
 1229   1229   
 "hyper-util",
 1230   1230   
 "indexmap",
 1231   1231   
 "pin-project-lite",
 1232   1232   
 "rustls 0.21.12",
 1233         -
 "rustls 0.23.35",
        1233  +
 "rustls 0.23.33",
 1234   1234   
 "rustls-native-certs 0.8.2",
 1235   1235   
 "rustls-pemfile 2.2.0",
 1236   1236   
 "rustls-pki-types",
 1237   1237   
 "s2n-tls",
 1238   1238   
 "s2n-tls-hyper",
 1239   1239   
 "s2n-tls-tokio",
 1240   1240   
 "serde",
 1241   1241   
 "serde_json",
 1242   1242   
 "serial_test",
 1243   1243   
 "tokio",
@@ -1592,1592 +1654,1654 @@
 1612   1612   
 "num-bigint",
 1613   1613   
 "num-rational",
 1614   1614   
 "num-traits",
 1615   1615   
 "separator",
 1616   1616   
 "url",
 1617   1617   
 "uuid",
 1618   1618   
]
 1619   1619   
 1620   1620   
[[package]]
 1621   1621   
name = "cc"
 1622         -
version = "1.2.44"
        1622  +
version = "1.2.41"
 1623   1623   
source = "registry+https://github.com/rust-lang/crates.io-index"
 1624         -
checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3"
        1624  +
checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7"
 1625   1625   
dependencies = [
 1626   1626   
 "find-msvc-tools",
 1627   1627   
 "jobserver",
 1628   1628   
 "libc",
 1629   1629   
 "shlex",
 1630   1630   
]
 1631   1631   
 1632   1632   
[[package]]
 1633   1633   
name = "cexpr"
 1634   1634   
version = "0.6.0"
@@ -1666,1666 +1737,1737 @@
 1686   1686   
source = "registry+https://github.com/rust-lang/crates.io-index"
 1687   1687   
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
 1688   1688   
dependencies = [
 1689   1689   
 "glob",
 1690   1690   
 "libc",
 1691   1691   
 "libloading",
 1692   1692   
]
 1693   1693   
 1694   1694   
[[package]]
 1695   1695   
name = "clap"
 1696         -
version = "4.5.51"
        1696  +
version = "4.5.50"
 1697   1697   
source = "registry+https://github.com/rust-lang/crates.io-index"
 1698         -
checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5"
        1698  +
checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623"
 1699   1699   
dependencies = [
 1700   1700   
 "clap_builder",
 1701   1701   
]
 1702   1702   
 1703   1703   
[[package]]
 1704   1704   
name = "clap_builder"
 1705         -
version = "4.5.51"
        1705  +
version = "4.5.50"
 1706   1706   
source = "registry+https://github.com/rust-lang/crates.io-index"
 1707         -
checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a"
        1707  +
checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0"
 1708   1708   
dependencies = [
 1709   1709   
 "anstyle",
 1710   1710   
 "clap_lex",
 1711   1711   
]
 1712   1712   
 1713   1713   
[[package]]
 1714   1714   
name = "clap_lex"
 1715   1715   
version = "0.7.6"
 1716   1716   
source = "registry+https://github.com/rust-lang/crates.io-index"
 1717   1717   
checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
@@ -1928,1928 +1990,1990 @@
 1948   1948   
version = "0.6.1"
 1949   1949   
source = "registry+https://github.com/rust-lang/crates.io-index"
 1950   1950   
checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de"
 1951   1951   
dependencies = [
 1952   1952   
 "const-oid",
 1953   1953   
 "zeroize",
 1954   1954   
]
 1955   1955   
 1956   1956   
[[package]]
 1957   1957   
name = "deranged"
 1958         -
version = "0.5.5"
        1958  +
version = "0.5.4"
 1959   1959   
source = "registry+https://github.com/rust-lang/crates.io-index"
 1960         -
checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587"
        1960  +
checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071"
 1961   1961   
dependencies = [
 1962   1962   
 "powerfmt",
 1963   1963   
]
 1964   1964   
 1965   1965   
[[package]]
 1966   1966   
name = "derive_arbitrary"
 1967   1967   
version = "1.4.2"
 1968   1968   
source = "registry+https://github.com/rust-lang/crates.io-index"
 1969   1969   
checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a"
 1970   1970   
dependencies = [
@@ -2117,2117 +2179,2179 @@
 2137   2137   
]
 2138   2138   
 2139   2139   
[[package]]
 2140   2140   
name = "find-msvc-tools"
 2141   2141   
version = "0.1.4"
 2142   2142   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2143   2143   
checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127"
 2144   2144   
 2145   2145   
[[package]]
 2146   2146   
name = "flate2"
 2147         -
version = "1.1.5"
        2147  +
version = "1.1.4"
 2148   2148   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2149         -
checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb"
        2149  +
checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9"
 2150   2150   
dependencies = [
 2151   2151   
 "crc32fast",
 2152   2152   
 "miniz_oxide",
 2153   2153   
]
 2154   2154   
 2155   2155   
[[package]]
 2156   2156   
name = "fnv"
 2157   2157   
version = "1.0.7"
 2158   2158   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2159   2159   
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
@@ -2643,2643 +2810,2815 @@
 2663   2663   
 2664   2664   
[[package]]
 2665   2665   
name = "hyper-rustls"
 2666   2666   
version = "0.27.7"
 2667   2667   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2668   2668   
checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
 2669   2669   
dependencies = [
 2670   2670   
 "http 1.3.1",
 2671   2671   
 "hyper 1.7.0",
 2672   2672   
 "hyper-util",
 2673         -
 "rustls 0.23.35",
        2673  +
 "rustls 0.23.33",
 2674   2674   
 "rustls-native-certs 0.8.2",
 2675   2675   
 "rustls-pki-types",
 2676   2676   
 "tokio",
 2677   2677   
 "tokio-rustls 0.26.4",
 2678   2678   
 "tower-service",
 2679   2679   
]
 2680   2680   
 2681   2681   
[[package]]
 2682   2682   
name = "hyper-util"
 2683   2683   
version = "0.1.17"
 2684   2684   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2685   2685   
checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8"
 2686   2686   
dependencies = [
 2687   2687   
 "base64 0.22.1",
 2688   2688   
 "bytes",
 2689   2689   
 "futures-channel",
 2690   2690   
 "futures-core",
 2691   2691   
 "futures-util",
 2692   2692   
 "http 1.3.1",
 2693   2693   
 "http-body 1.0.1",
 2694   2694   
 "hyper 1.7.0",
 2695   2695   
 "ipnet",
 2696   2696   
 "libc",
 2697   2697   
 "percent-encoding",
 2698   2698   
 "pin-project-lite",
 2699   2699   
 "socket2 0.6.1",
 2700   2700   
 "system-configuration",
 2701   2701   
 "tokio",
 2702   2702   
 "tower-service",
 2703   2703   
 "tracing",
 2704   2704   
 "windows-registry",
 2705   2705   
]
 2706   2706   
 2707   2707   
[[package]]
 2708   2708   
name = "icu_collections"
 2709         -
version = "2.1.1"
        2709  +
version = "2.0.0"
 2710   2710   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2711         -
checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43"
        2711  +
checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
 2712   2712   
dependencies = [
 2713   2713   
 "displaydoc",
 2714   2714   
 "potential_utf",
 2715   2715   
 "yoke",
 2716   2716   
 "zerofrom",
 2717   2717   
 "zerovec",
 2718   2718   
]
 2719   2719   
 2720   2720   
[[package]]
 2721   2721   
name = "icu_locale_core"
 2722         -
version = "2.1.1"
        2722  +
version = "2.0.0"
 2723   2723   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2724         -
checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6"
        2724  +
checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
 2725   2725   
dependencies = [
 2726   2726   
 "displaydoc",
 2727   2727   
 "litemap",
 2728   2728   
 "tinystr",
 2729   2729   
 "writeable",
 2730   2730   
 "zerovec",
 2731   2731   
]
 2732   2732   
 2733   2733   
[[package]]
 2734   2734   
name = "icu_normalizer"
 2735         -
version = "2.1.1"
        2735  +
version = "2.0.0"
 2736   2736   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2737         -
checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599"
        2737  +
checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979"
 2738   2738   
dependencies = [
        2739  +
 "displaydoc",
 2739   2740   
 "icu_collections",
 2740   2741   
 "icu_normalizer_data",
 2741   2742   
 "icu_properties",
 2742   2743   
 "icu_provider",
 2743   2744   
 "smallvec",
 2744   2745   
 "zerovec",
 2745   2746   
]
 2746   2747   
 2747   2748   
[[package]]
 2748   2749   
name = "icu_normalizer_data"
 2749         -
version = "2.1.1"
        2750  +
version = "2.0.0"
 2750   2751   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2751         -
checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a"
        2752  +
checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
 2752   2753   
 2753   2754   
[[package]]
 2754   2755   
name = "icu_properties"
 2755         -
version = "2.1.1"
        2756  +
version = "2.0.1"
 2756   2757   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2757         -
checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99"
        2758  +
checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b"
 2758   2759   
dependencies = [
        2760  +
 "displaydoc",
 2759   2761   
 "icu_collections",
 2760   2762   
 "icu_locale_core",
 2761   2763   
 "icu_properties_data",
 2762   2764   
 "icu_provider",
        2765  +
 "potential_utf",
 2763   2766   
 "zerotrie",
 2764   2767   
 "zerovec",
 2765   2768   
]
 2766   2769   
 2767   2770   
[[package]]
 2768   2771   
name = "icu_properties_data"
 2769         -
version = "2.1.1"
        2772  +
version = "2.0.1"
 2770   2773   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2771         -
checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899"
        2774  +
checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632"
 2772   2775   
 2773   2776   
[[package]]
 2774   2777   
name = "icu_provider"
 2775         -
version = "2.1.1"
        2778  +
version = "2.0.0"
 2776   2779   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2777         -
checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614"
        2780  +
checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
 2778   2781   
dependencies = [
 2779   2782   
 "displaydoc",
 2780   2783   
 "icu_locale_core",
        2784  +
 "stable_deref_trait",
        2785  +
 "tinystr",
 2781   2786   
 "writeable",
 2782   2787   
 "yoke",
 2783   2788   
 "zerofrom",
 2784   2789   
 "zerotrie",
 2785   2790   
 "zerovec",
 2786   2791   
]
 2787   2792   
 2788   2793   
[[package]]
 2789   2794   
name = "idna"
 2790   2795   
version = "1.1.0"
@@ -2831,2836 +2958,2963 @@
 2851   2856   
]
 2852   2857   
 2853   2858   
[[package]]
 2854   2859   
name = "ipnet"
 2855   2860   
version = "2.11.0"
 2856   2861   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2857   2862   
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
 2858   2863   
 2859   2864   
[[package]]
 2860   2865   
name = "is-terminal"
 2861         -
version = "0.4.17"
        2866  +
version = "0.4.16"
 2862   2867   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2863         -
checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46"
        2868  +
checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
 2864   2869   
dependencies = [
 2865   2870   
 "hermit-abi 0.5.2",
 2866   2871   
 "libc",
 2867         -
 "windows-sys 0.61.2",
        2872  +
 "windows-sys 0.59.0",
 2868   2873   
]
 2869   2874   
 2870   2875   
[[package]]
 2871   2876   
name = "itertools"
 2872   2877   
version = "0.10.5"
 2873   2878   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2874   2879   
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
 2875   2880   
dependencies = [
 2876   2881   
 "either",
 2877   2882   
]
 2878   2883   
 2879   2884   
[[package]]
 2880   2885   
name = "itertools"
 2881   2886   
version = "0.13.0"
 2882   2887   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2883   2888   
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
 2884   2889   
dependencies = [
 2885   2890   
 "either",
 2886   2891   
]
 2887   2892   
 2888   2893   
[[package]]
 2889   2894   
name = "itoa"
 2890   2895   
version = "1.0.15"
 2891   2896   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2892   2897   
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
 2893   2898   
 2894   2899   
[[package]]
 2895   2900   
name = "jemalloc-sys"
 2896   2901   
version = "0.5.4+5.3.0-patched"
 2897   2902   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2898   2903   
checksum = "ac6c1946e1cea1788cbfde01c993b52a10e2da07f4bac608228d1bed20bfebf2"
 2899   2904   
dependencies = [
 2900   2905   
 "cc",
 2901   2906   
 "libc",
 2902   2907   
]
 2903   2908   
 2904   2909   
[[package]]
 2905   2910   
name = "jemallocator"
 2906   2911   
version = "0.5.4"
 2907   2912   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2908   2913   
checksum = "a0de374a9f8e63150e6f5e8a60cc14c668226d7a347d8aee1a45766e3c4dd3bc"
 2909   2914   
dependencies = [
 2910   2915   
 "jemalloc-sys",
 2911   2916   
 "libc",
 2912   2917   
]
 2913   2918   
 2914   2919   
[[package]]
 2915   2920   
name = "jobserver"
 2916   2921   
version = "0.1.34"
 2917   2922   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2918   2923   
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
 2919   2924   
dependencies = [
 2920   2925   
 "getrandom 0.3.4",
 2921   2926   
 "libc",
 2922   2927   
]
 2923   2928   
 2924   2929   
[[package]]
 2925   2930   
name = "js-sys"
 2926         -
version = "0.3.82"
        2931  +
version = "0.3.81"
 2927   2932   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2928         -
checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65"
        2933  +
checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305"
 2929   2934   
dependencies = [
 2930   2935   
 "once_cell",
 2931   2936   
 "wasm-bindgen",
 2932   2937   
]
 2933   2938   
 2934   2939   
[[package]]
 2935   2940   
name = "kv-log-macro"
 2936   2941   
version = "1.0.7"
 2937   2942   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2938   2943   
checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
@@ -2965,2970 +3027,3032 @@
 2985   2990   
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
 2986   2991   
 2987   2992   
[[package]]
 2988   2993   
name = "linux-raw-sys"
 2989   2994   
version = "0.11.0"
 2990   2995   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2991   2996   
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
 2992   2997   
 2993   2998   
[[package]]
 2994   2999   
name = "litemap"
 2995         -
version = "0.8.1"
        3000  +
version = "0.8.0"
 2996   3001   
source = "registry+https://github.com/rust-lang/crates.io-index"
 2997         -
checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77"
        3002  +
checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
 2998   3003   
 2999   3004   
[[package]]
 3000   3005   
name = "lock_api"
 3001   3006   
version = "0.4.14"
 3002   3007   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3003   3008   
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
 3004   3009   
dependencies = [
 3005   3010   
 "scopeguard",
 3006   3011   
]
 3007   3012   
@@ -3369,3374 +3488,3494 @@
 3389   3394   
]
 3390   3395   
 3391   3396   
[[package]]
 3392   3397   
name = "portable-atomic"
 3393   3398   
version = "1.11.1"
 3394   3399   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3395   3400   
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
 3396   3401   
 3397   3402   
[[package]]
 3398   3403   
name = "potential_utf"
 3399         -
version = "0.1.4"
        3404  +
version = "0.1.3"
 3400   3405   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3401         -
checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77"
        3406  +
checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a"
 3402   3407   
dependencies = [
 3403   3408   
 "zerovec",
 3404   3409   
]
 3405   3410   
 3406   3411   
[[package]]
 3407   3412   
name = "powerfmt"
 3408   3413   
version = "0.2.0"
 3409   3414   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3410   3415   
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
 3411   3416   
 3412   3417   
[[package]]
 3413   3418   
name = "ppv-lite86"
 3414   3419   
version = "0.2.21"
 3415   3420   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3416   3421   
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
 3417   3422   
dependencies = [
 3418   3423   
 "zerocopy",
 3419   3424   
]
 3420   3425   
 3421   3426   
[[package]]
 3422   3427   
name = "pretty_assertions"
 3423   3428   
version = "1.4.1"
 3424   3429   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3425   3430   
checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d"
 3426   3431   
dependencies = [
 3427   3432   
 "diff",
 3428   3433   
 "yansi",
 3429   3434   
]
 3430   3435   
 3431   3436   
[[package]]
 3432   3437   
name = "prettyplease"
 3433   3438   
version = "0.2.37"
 3434   3439   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3435   3440   
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
 3436   3441   
dependencies = [
 3437   3442   
 "proc-macro2",
 3438   3443   
 "syn",
 3439   3444   
]
 3440   3445   
 3441   3446   
[[package]]
 3442   3447   
name = "proc-macro2"
 3443         -
version = "1.0.103"
        3448  +
version = "1.0.101"
 3444   3449   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3445         -
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
        3450  +
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
 3446   3451   
dependencies = [
 3447   3452   
 "unicode-ident",
 3448   3453   
]
 3449   3454   
 3450   3455   
[[package]]
 3451   3456   
name = "proptest"
 3452         -
version = "1.9.0"
        3457  +
version = "1.8.0"
 3453   3458   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3454         -
checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40"
        3459  +
checksum = "2bb0be07becd10686a0bb407298fb425360a5c44a663774406340c59a22de4ce"
 3455   3460   
dependencies = [
 3456   3461   
 "bit-set",
 3457   3462   
 "bit-vec",
 3458   3463   
 "bitflags 2.10.0",
        3464  +
 "lazy_static",
 3459   3465   
 "num-traits",
 3460   3466   
 "rand 0.9.2",
 3461   3467   
 "rand_chacha 0.9.0",
 3462   3468   
 "rand_xorshift",
 3463   3469   
 "regex-syntax",
 3464   3470   
 "rusty-fork",
 3465   3471   
 "tempfile",
 3466   3472   
 "unarray",
 3467   3473   
]
 3468   3474   
@@ -3701,3707 +3840,3846 @@
 3721   3727   
checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
 3722   3728   
dependencies = [
 3723   3729   
 "log",
 3724   3730   
 "ring",
 3725   3731   
 "rustls-webpki 0.101.7",
 3726   3732   
 "sct",
 3727   3733   
]
 3728   3734   
 3729   3735   
[[package]]
 3730   3736   
name = "rustls"
 3731         -
version = "0.23.35"
        3737  +
version = "0.23.33"
 3732   3738   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3733         -
checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f"
        3739  +
checksum = "751e04a496ca00bb97a5e043158d23d66b5aabf2e1d5aa2a0aaebb1aafe6f82c"
 3734   3740   
dependencies = [
 3735   3741   
 "aws-lc-rs",
 3736   3742   
 "log",
 3737   3743   
 "once_cell",
 3738   3744   
 "ring",
 3739   3745   
 "rustls-pki-types",
 3740         -
 "rustls-webpki 0.103.8",
        3746  +
 "rustls-webpki 0.103.7",
 3741   3747   
 "subtle",
 3742   3748   
 "zeroize",
 3743   3749   
]
 3744   3750   
 3745   3751   
[[package]]
 3746   3752   
name = "rustls-native-certs"
 3747   3753   
version = "0.6.3"
 3748   3754   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3749   3755   
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
 3750   3756   
dependencies = [
 3751   3757   
 "openssl-probe",
 3752   3758   
 "rustls-pemfile 1.0.4",
 3753   3759   
 "schannel",
 3754   3760   
 "security-framework 2.11.1",
 3755   3761   
]
 3756   3762   
 3757   3763   
[[package]]
 3758   3764   
name = "rustls-native-certs"
 3759   3765   
version = "0.8.2"
 3760   3766   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3761   3767   
checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923"
 3762   3768   
dependencies = [
 3763   3769   
 "openssl-probe",
 3764   3770   
 "rustls-pki-types",
 3765   3771   
 "schannel",
 3766   3772   
 "security-framework 3.5.1",
 3767   3773   
]
 3768   3774   
 3769   3775   
[[package]]
 3770   3776   
name = "rustls-pemfile"
 3771   3777   
version = "1.0.4"
 3772   3778   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3773   3779   
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
 3774   3780   
dependencies = [
 3775   3781   
 "base64 0.21.7",
 3776   3782   
]
 3777   3783   
 3778   3784   
[[package]]
 3779   3785   
name = "rustls-pemfile"
 3780   3786   
version = "2.2.0"
 3781   3787   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3782   3788   
checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
 3783   3789   
dependencies = [
 3784   3790   
 "rustls-pki-types",
 3785   3791   
]
 3786   3792   
 3787   3793   
[[package]]
 3788   3794   
name = "rustls-pki-types"
 3789         -
version = "1.13.0"
        3795  +
version = "1.12.0"
 3790   3796   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3791         -
checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a"
        3797  +
checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
 3792   3798   
dependencies = [
 3793   3799   
 "zeroize",
 3794   3800   
]
 3795   3801   
 3796   3802   
[[package]]
 3797   3803   
name = "rustls-webpki"
 3798   3804   
version = "0.101.7"
 3799   3805   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3800   3806   
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
 3801   3807   
dependencies = [
 3802   3808   
 "ring",
 3803   3809   
 "untrusted 0.9.0",
 3804   3810   
]
 3805   3811   
 3806   3812   
[[package]]
 3807   3813   
name = "rustls-webpki"
 3808         -
version = "0.103.8"
        3814  +
version = "0.103.7"
 3809   3815   
source = "registry+https://github.com/rust-lang/crates.io-index"
 3810         -
checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52"
        3816  +
checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf"
 3811   3817   
dependencies = [
 3812   3818   
 "aws-lc-rs",
 3813   3819   
 "ring",
 3814   3820   
 "rustls-pki-types",
 3815   3821   
 "untrusted 0.9.0",
 3816   3822   
]
 3817   3823   
 3818   3824   
[[package]]
 3819   3825   
name = "rustversion"
 3820   3826   
version = "1.0.22"
@@ -4194,4200 +4256,4262 @@
 4214   4220   
checksum = "5c0e04424e733e69714ca1bbb9204c1a57f09f5493439520f9f68c132ad25eec"
 4215   4221   
 4216   4222   
[[package]]
 4217   4223   
name = "subtle"
 4218   4224   
version = "2.6.1"
 4219   4225   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4220   4226   
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
 4221   4227   
 4222   4228   
[[package]]
 4223   4229   
name = "syn"
 4224         -
version = "2.0.108"
        4230  +
version = "2.0.107"
 4225   4231   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4226         -
checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917"
        4232  +
checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b"
 4227   4233   
dependencies = [
 4228   4234   
 "proc-macro2",
 4229   4235   
 "quote",
 4230   4236   
 "unicode-ident",
 4231   4237   
]
 4232   4238   
 4233   4239   
[[package]]
 4234   4240   
name = "synstructure"
 4235   4241   
version = "0.13.2"
 4236   4242   
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4336,4342 +4398,4404 @@
 4356   4362   
version = "0.2.24"
 4357   4363   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4358   4364   
checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3"
 4359   4365   
dependencies = [
 4360   4366   
 "num-conv",
 4361   4367   
 "time-core",
 4362   4368   
]
 4363   4369   
 4364   4370   
[[package]]
 4365   4371   
name = "tinystr"
 4366         -
version = "0.8.2"
        4372  +
version = "0.8.1"
 4367   4373   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4368         -
checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869"
        4374  +
checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
 4369   4375   
dependencies = [
 4370   4376   
 "displaydoc",
 4371   4377   
 "zerovec",
 4372   4378   
]
 4373   4379   
 4374   4380   
[[package]]
 4375   4381   
name = "tinytemplate"
 4376   4382   
version = "1.2.1"
 4377   4383   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4378   4384   
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
@@ -4413,4419 +4505,4511 @@
 4433   4439   
 "rustls 0.21.12",
 4434   4440   
 "tokio",
 4435   4441   
]
 4436   4442   
 4437   4443   
[[package]]
 4438   4444   
name = "tokio-rustls"
 4439   4445   
version = "0.26.4"
 4440   4446   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4441   4447   
checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
 4442   4448   
dependencies = [
 4443         -
 "rustls 0.23.35",
        4449  +
 "rustls 0.23.33",
 4444   4450   
 "tokio",
 4445   4451   
]
 4446   4452   
 4447   4453   
[[package]]
 4448   4454   
name = "tokio-stream"
 4449   4455   
version = "0.1.17"
 4450   4456   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4451   4457   
checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047"
 4452   4458   
dependencies = [
 4453   4459   
 "futures-core",
 4454   4460   
 "pin-project-lite",
 4455   4461   
 "tokio",
 4456   4462   
]
 4457   4463   
 4458   4464   
[[package]]
 4459   4465   
name = "tokio-test"
 4460   4466   
version = "0.4.4"
 4461   4467   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4462   4468   
checksum = "2468baabc3311435b55dd935f702f42cd1b8abb7e754fb7dfb16bd36aa88f9f7"
 4463   4469   
dependencies = [
 4464   4470   
 "async-stream",
 4465   4471   
 "bytes",
 4466   4472   
 "futures-core",
 4467   4473   
 "tokio",
 4468   4474   
 "tokio-stream",
 4469   4475   
]
 4470   4476   
 4471   4477   
[[package]]
 4472   4478   
name = "tokio-util"
 4473         -
version = "0.7.17"
        4479  +
version = "0.7.16"
 4474   4480   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4475         -
checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594"
        4481  +
checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5"
 4476   4482   
dependencies = [
 4477   4483   
 "bytes",
 4478   4484   
 "futures-core",
 4479   4485   
 "futures-sink",
 4480   4486   
 "pin-project-lite",
 4481   4487   
 "tokio",
 4482   4488   
]
 4483   4489   
 4484   4490   
[[package]]
 4485   4491   
name = "tower"
@@ -4603,4609 +4665,4671 @@
 4623   4629   
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
 4624   4630   
 4625   4631   
[[package]]
 4626   4632   
name = "unarray"
 4627   4633   
version = "0.1.4"
 4628   4634   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4629   4635   
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
 4630   4636   
 4631   4637   
[[package]]
 4632   4638   
name = "unicode-ident"
 4633         -
version = "1.0.22"
        4639  +
version = "1.0.20"
 4634   4640   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4635         -
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
        4641  +
checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06"
 4636   4642   
 4637   4643   
[[package]]
 4638   4644   
name = "unicode-segmentation"
 4639   4645   
version = "1.12.0"
 4640   4646   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4641   4647   
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
 4642   4648   
 4643   4649   
[[package]]
 4644   4650   
name = "untrusted"
 4645   4651   
version = "0.7.1"
@@ -4744,4750 +4864,4884 @@
 4764   4770   
name = "wasip2"
 4765   4771   
version = "1.0.1+wasi-0.2.4"
 4766   4772   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4767   4773   
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
 4768   4774   
dependencies = [
 4769   4775   
 "wit-bindgen 0.46.0",
 4770   4776   
]
 4771   4777   
 4772   4778   
[[package]]
 4773   4779   
name = "wasm-bindgen"
 4774         -
version = "0.2.105"
        4780  +
version = "0.2.104"
 4775   4781   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4776         -
checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60"
        4782  +
checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d"
 4777   4783   
dependencies = [
 4778   4784   
 "cfg-if",
 4779   4785   
 "once_cell",
 4780   4786   
 "rustversion",
 4781   4787   
 "wasm-bindgen-macro",
 4782   4788   
 "wasm-bindgen-shared",
 4783   4789   
]
 4784   4790   
        4791  +
[[package]]
        4792  +
name = "wasm-bindgen-backend"
        4793  +
version = "0.2.104"
        4794  +
source = "registry+https://github.com/rust-lang/crates.io-index"
        4795  +
checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19"
        4796  +
dependencies = [
        4797  +
 "bumpalo",
        4798  +
 "log",
        4799  +
 "proc-macro2",
        4800  +
 "quote",
        4801  +
 "syn",
        4802  +
 "wasm-bindgen-shared",
        4803  +
]
        4804  +
 4785   4805   
[[package]]
 4786   4806   
name = "wasm-bindgen-futures"
 4787         -
version = "0.4.55"
        4807  +
version = "0.4.54"
 4788   4808   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4789         -
checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0"
        4809  +
checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c"
 4790   4810   
dependencies = [
 4791   4811   
 "cfg-if",
 4792   4812   
 "js-sys",
 4793   4813   
 "once_cell",
 4794   4814   
 "wasm-bindgen",
 4795   4815   
 "web-sys",
 4796   4816   
]
 4797   4817   
 4798   4818   
[[package]]
 4799   4819   
name = "wasm-bindgen-macro"
 4800         -
version = "0.2.105"
        4820  +
version = "0.2.104"
 4801   4821   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4802         -
checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2"
        4822  +
checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119"
 4803   4823   
dependencies = [
 4804   4824   
 "quote",
 4805   4825   
 "wasm-bindgen-macro-support",
 4806   4826   
]
 4807   4827   
 4808   4828   
[[package]]
 4809   4829   
name = "wasm-bindgen-macro-support"
 4810         -
version = "0.2.105"
        4830  +
version = "0.2.104"
 4811   4831   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4812         -
checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc"
        4832  +
checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7"
 4813   4833   
dependencies = [
 4814         -
 "bumpalo",
 4815   4834   
 "proc-macro2",
 4816   4835   
 "quote",
 4817   4836   
 "syn",
        4837  +
 "wasm-bindgen-backend",
 4818   4838   
 "wasm-bindgen-shared",
 4819   4839   
]
 4820   4840   
 4821   4841   
[[package]]
 4822   4842   
name = "wasm-bindgen-shared"
 4823         -
version = "0.2.105"
        4843  +
version = "0.2.104"
 4824   4844   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4825         -
checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76"
        4845  +
checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1"
 4826   4846   
dependencies = [
 4827   4847   
 "unicode-ident",
 4828   4848   
]
 4829   4849   
 4830   4850   
[[package]]
 4831   4851   
name = "web-sys"
 4832         -
version = "0.3.82"
        4852  +
version = "0.3.81"
 4833   4853   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4834         -
checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1"
        4854  +
checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120"
 4835   4855   
dependencies = [
 4836   4856   
 "js-sys",
 4837   4857   
 "wasm-bindgen",
 4838   4858   
]
 4839   4859   
 4840   4860   
[[package]]
 4841   4861   
name = "webpki-roots"
 4842   4862   
version = "0.25.4"
 4843   4863   
source = "registry+https://github.com/rust-lang/crates.io-index"
 4844   4864   
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
@@ -5152,5172 +5299,5320 @@
 5172   5192   
]
 5173   5193   
 5174   5194   
[[package]]
 5175   5195   
name = "wit-bindgen"
 5176   5196   
version = "0.46.0"
 5177   5197   
source = "registry+https://github.com/rust-lang/crates.io-index"
 5178   5198   
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
 5179   5199   
 5180   5200   
[[package]]
 5181   5201   
name = "writeable"
 5182         -
version = "0.6.2"
        5202  +
version = "0.6.1"
 5183   5203   
source = "registry+https://github.com/rust-lang/crates.io-index"
 5184         -
checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9"
        5204  +
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
 5185   5205   
 5186   5206   
[[package]]
 5187   5207   
name = "xmlparser"
 5188   5208   
version = "0.13.6"
 5189   5209   
source = "registry+https://github.com/rust-lang/crates.io-index"
 5190   5210   
checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4"
 5191   5211   
 5192   5212   
[[package]]
 5193   5213   
name = "yansi"
 5194   5214   
version = "1.0.1"
 5195   5215   
source = "registry+https://github.com/rust-lang/crates.io-index"
 5196   5216   
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
 5197   5217   
 5198   5218   
[[package]]
 5199   5219   
name = "yoke"
 5200         -
version = "0.8.1"
        5220  +
version = "0.8.0"
 5201   5221   
source = "registry+https://github.com/rust-lang/crates.io-index"
 5202         -
checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954"
        5222  +
checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
 5203   5223   
dependencies = [
        5224  +
 "serde",
 5204   5225   
 "stable_deref_trait",
 5205   5226   
 "yoke-derive",
 5206   5227   
 "zerofrom",
 5207   5228   
]
 5208   5229   
 5209   5230   
[[package]]
 5210   5231   
name = "yoke-derive"
 5211         -
version = "0.8.1"
        5232  +
version = "0.8.0"
 5212   5233   
source = "registry+https://github.com/rust-lang/crates.io-index"
 5213         -
checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
        5234  +
checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
 5214   5235   
dependencies = [
 5215   5236   
 "proc-macro2",
 5216   5237   
 "quote",
 5217   5238   
 "syn",
 5218   5239   
 "synstructure",
 5219   5240   
]
 5220   5241   
 5221   5242   
[[package]]
 5222   5243   
name = "zerocopy"
 5223   5244   
version = "0.8.27"
 5224   5245   
source = "registry+https://github.com/rust-lang/crates.io-index"
 5225   5246   
checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c"
 5226   5247   
dependencies = [
 5227   5248   
 "zerocopy-derive",
 5228   5249   
]
 5229   5250   
 5230   5251   
[[package]]
 5231   5252   
name = "zerocopy-derive"
 5232   5253   
version = "0.8.27"
 5233   5254   
source = "registry+https://github.com/rust-lang/crates.io-index"
 5234   5255   
checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
 5235   5256   
dependencies = [
 5236   5257   
 "proc-macro2",
 5237   5258   
 "quote",
 5238   5259   
 "syn",
 5239   5260   
]
 5240   5261   
 5241   5262   
[[package]]
 5242   5263   
name = "zerofrom"
 5243   5264   
version = "0.1.6"
 5244   5265   
source = "registry+https://github.com/rust-lang/crates.io-index"
 5245   5266   
checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
 5246   5267   
dependencies = [
 5247   5268   
 "zerofrom-derive",
 5248   5269   
]
 5249   5270   
 5250   5271   
[[package]]
 5251   5272   
name = "zerofrom-derive"
 5252   5273   
version = "0.1.6"
 5253   5274   
source = "registry+https://github.com/rust-lang/crates.io-index"
 5254   5275   
checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
 5255   5276   
dependencies = [
 5256   5277   
 "proc-macro2",
 5257   5278   
 "quote",
 5258   5279   
 "syn",
 5259   5280   
 "synstructure",
 5260   5281   
]
 5261   5282   
 5262   5283   
[[package]]
 5263   5284   
name = "zeroize"
 5264   5285   
version = "1.8.2"
 5265   5286   
source = "registry+https://github.com/rust-lang/crates.io-index"
 5266   5287   
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
 5267   5288   
 5268   5289   
[[package]]
 5269   5290   
name = "zerotrie"
 5270         -
version = "0.2.3"
        5291  +
version = "0.2.2"
 5271   5292   
source = "registry+https://github.com/rust-lang/crates.io-index"
 5272         -
checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851"
        5293  +
checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
 5273   5294   
dependencies = [
 5274   5295   
 "displaydoc",
 5275   5296   
 "yoke",
 5276   5297   
 "zerofrom",
 5277   5298   
]
 5278   5299   
 5279   5300   
[[package]]
 5280   5301   
name = "zerovec"
 5281         -
version = "0.11.5"
        5302  +
version = "0.11.4"
 5282   5303   
source = "registry+https://github.com/rust-lang/crates.io-index"
 5283         -
checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002"
        5304  +
checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b"
 5284   5305   
dependencies = [
 5285   5306   
 "yoke",
 5286   5307   
 "zerofrom",
 5287   5308   
 "zerovec-derive",
 5288   5309   
]
 5289   5310   
 5290   5311   
[[package]]
 5291   5312   
name = "zerovec-derive"
 5292         -
version = "0.11.2"
        5313  +
version = "0.11.1"
 5293   5314   
source = "registry+https://github.com/rust-lang/crates.io-index"
 5294         -
checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3"
        5315  +
checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
 5295   5316   
dependencies = [
 5296   5317   
 "proc-macro2",
 5297   5318   
 "quote",
 5298   5319   
 "syn",
 5299   5320   
]

tmp-codegen-diff/aws-sdk/sdk/aws-runtime/src/content_encoding.rs

@@ -1,1 +166,197 @@
    1      1   
/*
    2      2   
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
    3      3   
 * SPDX-License-Identifier: Apache-2.0
    4      4   
 */
    5      5   
           6  +
use aws_smithy_types::config_bag::{Storable, StoreReplace};
    6      7   
use bytes::{Bytes, BytesMut};
    7      8   
use http_02x::{HeaderMap, HeaderValue};
    8      9   
use http_body_04x::{Body, SizeHint};
    9     10   
use pin_project_lite::pin_project;
   10     11   
   11     12   
use std::pin::Pin;
   12     13   
use std::task::{Context, Poll};
   13     14   
   14     15   
const CRLF: &str = "\r\n";
   15     16   
const CHUNK_TERMINATOR: &str = "0\r\n";
   16     17   
const TRAILER_SEPARATOR: &[u8] = b":";
   17     18   
   18     19   
/// Content encoding header value constants
   19     20   
pub mod header_value {
   20     21   
    /// Header value denoting "aws-chunked" encoding
   21     22   
    pub const AWS_CHUNKED: &str = "aws-chunked";
   22     23   
}
   23     24   
   24     25   
/// Options used when constructing an [`AwsChunkedBody`].
   25         -
#[derive(Debug, Default)]
          26  +
#[derive(Clone, Debug, Default)]
   26     27   
#[non_exhaustive]
   27     28   
pub struct AwsChunkedBodyOptions {
   28     29   
    /// The total size of the stream. Because we only support unsigned encoding
   29     30   
    /// this implies that there will only be a single chunk containing the
   30     31   
    /// underlying payload.
   31     32   
    stream_length: u64,
   32     33   
    /// The length of each trailer sent within an `AwsChunkedBody`. Necessary in
   33     34   
    /// order to correctly calculate the total size of the body accurately.
   34     35   
    trailer_lengths: Vec<u64>,
          36  +
    /// Whether the aws-chunked encoding is disabled. This could occur, for instance,
          37  +
    /// if a user specifies a custom checksum, rendering aws-chunked encoding unnecessary.
          38  +
    disabled: bool,
          39  +
}
          40  +
          41  +
impl Storable for AwsChunkedBodyOptions {
          42  +
    type Storer = StoreReplace<Self>;
   35     43   
}
   36     44   
   37     45   
impl AwsChunkedBodyOptions {
   38     46   
    /// Create a new [`AwsChunkedBodyOptions`].
   39     47   
    pub fn new(stream_length: u64, trailer_lengths: Vec<u64>) -> Self {
   40     48   
        Self {
   41     49   
            stream_length,
   42     50   
            trailer_lengths,
          51  +
            disabled: false,
   43     52   
        }
   44     53   
    }
   45     54   
   46     55   
    fn total_trailer_length(&self) -> u64 {
   47     56   
        self.trailer_lengths.iter().sum::<u64>()
   48     57   
            // We need to account for a CRLF after each trailer name/value pair
   49     58   
            + (self.trailer_lengths.len() * CRLF.len()) as u64
   50     59   
    }
   51     60   
   52         -
    /// Set a trailer len
          61  +
    /// Set the stream length in the options
          62  +
    pub fn with_stream_length(mut self, stream_length: u64) -> Self {
          63  +
        self.stream_length = stream_length;
          64  +
        self
          65  +
    }
          66  +
          67  +
    /// Append a trailer length to the options
   53     68   
    pub fn with_trailer_len(mut self, trailer_len: u64) -> Self {
   54     69   
        self.trailer_lengths.push(trailer_len);
   55     70   
        self
   56     71   
    }
          72  +
          73  +
    /// Create a new [`AwsChunkedBodyOptions`] with aws-chunked encoding disabled.
          74  +
    ///
          75  +
    /// When the option is disabled, the body must not be wrapped in an `AwsChunkedBody`.
          76  +
    pub fn disable_chunked_encoding() -> Self {
          77  +
        Self {
          78  +
            disabled: true,
          79  +
            ..Default::default()
          80  +
        }
          81  +
    }
          82  +
          83  +
    /// Return whether aws-chunked encoding is disabled.
          84  +
    pub fn disabled(&self) -> bool {
          85  +
        self.disabled
          86  +
    }
          87  +
          88  +
    /// Return the length of the body after `aws-chunked` encoding is applied
          89  +
    pub fn encoded_length(&self) -> u64 {
          90  +
        let mut length = 0;
          91  +
        if self.stream_length != 0 {
          92  +
            length += get_unsigned_chunk_bytes_length(self.stream_length);
          93  +
        }
          94  +
          95  +
        // End chunk
          96  +
        length += CHUNK_TERMINATOR.len() as u64;
          97  +
          98  +
        // Trailers
          99  +
        for len in self.trailer_lengths.iter() {
         100  +
            length += len + CRLF.len() as u64;
         101  +
        }
         102  +
         103  +
        // Encoding terminator
         104  +
        length += CRLF.len() as u64;
         105  +
         106  +
        length
         107  +
    }
   57    108   
}
   58    109   
   59    110   
#[derive(Debug, PartialEq, Eq)]
   60    111   
enum AwsChunkedBodyState {
   61    112   
    /// Write out the size of the chunk that will follow. Then, transition into the
   62    113   
    /// `WritingChunk` state.
   63    114   
    WritingChunkSize,
   64    115   
    /// Write out the next chunk of data. Multiple polls of the inner body may need to occur before
   65    116   
    /// all data is written out. Once there is no more data to write, transition into the
   66    117   
    /// `WritingTrailers` state.
   67    118   
    WritingChunk,
   68    119   
    /// Write out all trailers associated with this `AwsChunkedBody` and then transition into the
   69    120   
    /// `Closed` state.
   70    121   
    WritingTrailers,
   71    122   
    /// This is the final state. Write out the body terminator and then remain in this state.
   72    123   
    Closed,
   73    124   
}
   74    125   
   75    126   
pin_project! {
   76    127   
    /// A request body compatible with `Content-Encoding: aws-chunked`. This implementation is only
   77    128   
    /// capable of writing a single chunk and does not support signed chunks.
   78    129   
    ///
   79    130   
    /// Chunked-Body grammar is defined in [ABNF] as:
   80    131   
    ///
   81    132   
    /// ```txt
   82    133   
    /// Chunked-Body    = *chunk
   83    134   
    ///                   last-chunk
   84    135   
    ///                   chunked-trailer
   85    136   
    ///                   CRLF
   86    137   
    ///
   87    138   
    /// chunk           = chunk-size CRLF chunk-data CRLF
   88    139   
    /// chunk-size      = 1*HEXDIG
   89    140   
    /// last-chunk      = 1*("0") CRLF
   90    141   
    /// chunked-trailer = *( entity-header CRLF )
   91    142   
    /// entity-header   = field-name ":" OWS field-value OWS
   92    143   
    /// ```
   93    144   
    /// For more info on what the abbreviations mean, see https://datatracker.ietf.org/doc/html/rfc7230#section-1.2
   94    145   
    ///
   95    146   
    /// [ABNF]:https://en.wikipedia.org/wiki/Augmented_Backus%E2%80%93Naur_form
   96    147   
    #[derive(Debug)]
   97    148   
    pub struct AwsChunkedBody<InnerBody> {
   98    149   
        #[pin]
   99    150   
        inner: InnerBody,
  100    151   
        #[pin]
  101    152   
        state: AwsChunkedBodyState,
  102    153   
        options: AwsChunkedBodyOptions,
  103    154   
        inner_body_bytes_read_so_far: usize,
  104    155   
    }
  105    156   
}
  106    157   
  107    158   
impl<Inner> AwsChunkedBody<Inner> {
  108    159   
    /// Wrap the given body in an outer body compatible with `Content-Encoding: aws-chunked`
  109    160   
    pub fn new(body: Inner, options: AwsChunkedBodyOptions) -> Self {
  110    161   
        Self {
  111    162   
            inner: body,
  112    163   
            state: AwsChunkedBodyState::WritingChunkSize,
  113    164   
            options,
  114    165   
            inner_body_bytes_read_so_far: 0,
  115    166   
        }
  116    167   
    }
  117         -
  118         -
    fn encoded_length(&self) -> u64 {
  119         -
        let mut length = 0;
  120         -
        if self.options.stream_length != 0 {
  121         -
            length += get_unsigned_chunk_bytes_length(self.options.stream_length);
  122         -
        }
  123         -
  124         -
        // End chunk
  125         -
        length += CHUNK_TERMINATOR.len() as u64;
  126         -
  127         -
        // Trailers
  128         -
        for len in self.options.trailer_lengths.iter() {
  129         -
            length += len + CRLF.len() as u64;
  130         -
        }
  131         -
  132         -
        // Encoding terminator
  133         -
        length += CRLF.len() as u64;
  134         -
  135         -
        length
  136         -
    }
  137    168   
}
  138    169   
  139    170   
fn get_unsigned_chunk_bytes_length(payload_length: u64) -> u64 {
  140    171   
    let hex_repr_len = int_log16(payload_length);
  141    172   
    hex_repr_len + CRLF.len() as u64 + payload_length + CRLF.len() as u64
  142    173   
}
  143    174   
  144    175   
/// Writes trailers out into a `string` and then converts that `String` to a `Bytes` before
  145    176   
/// returning.
  146    177   
///
@@ -270,301 +330,361 @@
  290    321   
    ) -> Poll<Result<Option<HeaderMap<HeaderValue>>, Self::Error>> {
  291    322   
        // Trailers were already appended to the body because of the content encoding scheme
  292    323   
        Poll::Ready(Ok(None))
  293    324   
    }
  294    325   
  295    326   
    fn is_end_stream(&self) -> bool {
  296    327   
        self.state == AwsChunkedBodyState::Closed
  297    328   
    }
  298    329   
  299    330   
    fn size_hint(&self) -> SizeHint {
  300         -
        SizeHint::with_exact(self.encoded_length())
         331  +
        SizeHint::with_exact(self.options.encoded_length())
  301    332   
    }
  302    333   
}
  303    334   
  304    335   
/// Errors related to `AwsChunkedBody`
  305    336   
#[derive(Debug)]
  306    337   
enum AwsChunkedBodyError {
  307    338   
    /// Error that occurs when the sum of `trailer_lengths` set when creating an `AwsChunkedBody` is
  308    339   
    /// not equal to the actual length of the trailers returned by the inner `http_body::Body`
  309    340   
    /// implementor. These trailer lengths are necessary in order to correctly calculate the total
  310    341   
    /// size of the body for setting the content length header.

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-checksums/Cargo.toml

@@ -1,1 +43,43 @@
    1      1   
# Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT.
    2      2   
[package]
    3      3   
name = "aws-smithy-checksums"
    4         -
version = "0.63.11"
           4  +
version = "0.63.10"
    5      5   
authors = ["AWS Rust SDK Team <aws-sdk-rust@amazon.com>", "Zelda Hessler <zhessler@amazon.com>"]
    6      6   
description = "Checksum calculation and verification callbacks"
    7      7   
edition = "2021"
    8      8   
license = "Apache-2.0"
    9      9   
repository = "https://github.com/smithy-lang/smithy-rs"
   10     10   
[package.metadata.docs.rs]
   11     11   
all-features = true
   12     12   
targets = ["x86_64-unknown-linux-gnu"]
   13     13   
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
   14     14   
rustdoc-args = ["--cfg", "docsrs"]
   15     15   
   16     16   
[dependencies]
   17     17   
bytes = "1.10.0"
   18         -
crc-fast = "~1.6.0"
          18  +
crc-fast = "~1.3.0"
   19     19   
hex = "0.4.3"
   20     20   
http = "0.2.9"
   21     21   
http-body = "0.4.5"
   22     22   
md-5 = "0.10"
   23     23   
pin-project-lite = "0.2.14"
   24     24   
sha1 = "0.10"
   25     25   
sha2 = "0.10"
   26     26   
tracing = "0.1.40"
   27     27   
   28     28   
[dependencies.aws-smithy-http]

tmp-codegen-diff/aws-sdk/sdk/s3/Cargo.toml

@@ -7,7 +67,67 @@
   27     27   
[dependencies.aws-sigv4]
   28     28   
path = "../aws-sigv4"
   29     29   
version = "1.3.6"
   30     30   
   31     31   
[dependencies.aws-smithy-async]
   32     32   
path = "../aws-smithy-async"
   33     33   
version = "1.2.6"
   34     34   
   35     35   
[dependencies.aws-smithy-checksums]
   36     36   
path = "../aws-smithy-checksums"
   37         -
version = "0.63.11"
          37  +
version = "0.63.10"
   38     38   
   39     39   
[dependencies.aws-smithy-eventstream]
   40     40   
path = "../aws-smithy-eventstream"
   41     41   
version = "0.60.13"
   42     42   
   43     43   
[dependencies.aws-smithy-http]
   44     44   
path = "../aws-smithy-http"
   45     45   
features = ["event-stream"]
   46     46   
version = "0.62.5"
   47     47   

tmp-codegen-diff/aws-sdk/sdk/s3/src/aws_chunked.rs

@@ -0,1 +0,288 @@
           1  +
// Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT.
           2  +
/*
           3  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           4  +
 * SPDX-License-Identifier: Apache-2.0
           5  +
 */
           6  +
           7  +
#![allow(dead_code)]
           8  +
           9  +
use std::fmt;
          10  +
          11  +
use aws_runtime::{
          12  +
    auth::PayloadSigningOverride,
          13  +
    content_encoding::{header_value::AWS_CHUNKED, AwsChunkedBody, AwsChunkedBodyOptions},
          14  +
};
          15  +
use aws_smithy_runtime_api::{
          16  +
    box_error::BoxError,
          17  +
    client::{
          18  +
        interceptors::{context::BeforeTransmitInterceptorContextMut, Intercept},
          19  +
        runtime_components::RuntimeComponents,
          20  +
    },
          21  +
    http::Request,
          22  +
};
          23  +
use aws_smithy_types::{body::SdkBody, config_bag::ConfigBag, error::operation::BuildError};
          24  +
use http::{header, HeaderValue};
          25  +
use http_body::Body;
          26  +
          27  +
const X_AMZ_DECODED_CONTENT_LENGTH: &str = "x-amz-decoded-content-length";
          28  +
          29  +
/// Errors related to constructing aws-chunked encoded HTTP requests.
          30  +
#[derive(Debug)]
          31  +
enum Error {
          32  +
    UnsizedRequestBody,
          33  +
}
          34  +
          35  +
impl fmt::Display for Error {
          36  +
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
          37  +
        match self {
          38  +
            Self::UnsizedRequestBody => write!(f, "Only request bodies with a known size can be chunk-encoded."),
          39  +
        }
          40  +
    }
          41  +
}
          42  +
          43  +
impl std::error::Error for Error {}
          44  +
          45  +
#[derive(Debug)]
          46  +
pub(crate) struct AwsChunkedContentEncodingInterceptor;
          47  +
          48  +
impl Intercept for AwsChunkedContentEncodingInterceptor {
          49  +
    fn name(&self) -> &'static str {
          50  +
        "AwsChunkedContentEncodingInterceptor"
          51  +
    }
          52  +
          53  +
    fn modify_before_signing(
          54  +
        &self,
          55  +
        context: &mut BeforeTransmitInterceptorContextMut<'_>,
          56  +
        _runtime_components: &RuntimeComponents,
          57  +
        cfg: &mut ConfigBag,
          58  +
    ) -> Result<(), BoxError> {
          59  +
        if must_not_use_chunked_encoding(context.request(), cfg) {
          60  +
            tracing::debug!("short-circuiting modify_before_signing because chunked encoding must not be used");
          61  +
            return Ok(());
          62  +
        }
          63  +
          64  +
        let original_body_size = if let Some(size) = context
          65  +
            .request()
          66  +
            .headers()
          67  +
            .get(header::CONTENT_LENGTH)
          68  +
            .and_then(|s| s.parse::<u64>().ok())
          69  +
            .or_else(|| context.request().body().size_hint().exact())
          70  +
        {
          71  +
            size
          72  +
        } else {
          73  +
            return Err(BuildError::other(Error::UnsizedRequestBody))?;
          74  +
        };
          75  +
          76  +
        let chunked_body_options = if let Some(chunked_body_options) = cfg.get_mut_from_interceptor_state::<AwsChunkedBodyOptions>() {
          77  +
            let chunked_body_options = std::mem::take(chunked_body_options);
          78  +
            chunked_body_options.with_stream_length(original_body_size)
          79  +
        } else {
          80  +
            AwsChunkedBodyOptions::default().with_stream_length(original_body_size)
          81  +
        };
          82  +
          83  +
        let request = context.request_mut();
          84  +
        // For for aws-chunked encoding, `x-amz-decoded-content-length` must be set to the original body size.
          85  +
        request.headers_mut().insert(
          86  +
            header::HeaderName::from_static(X_AMZ_DECODED_CONTENT_LENGTH),
          87  +
            HeaderValue::from(original_body_size),
          88  +
        );
          89  +
        // Other than `x-amz-decoded-content-length`, either `content-length` or `transfer-encoding`
          90  +
        // must be set, but not both. For uses cases we support, we know the original body size and
          91  +
        // can calculate the encoded size, so we set `content-length`.
          92  +
        request
          93  +
            .headers_mut()
          94  +
            .insert(header::CONTENT_LENGTH, HeaderValue::from(chunked_body_options.encoded_length()));
          95  +
        // Setting `content-length` above means we must unset `transfer-encoding`.
          96  +
        request.headers_mut().remove(header::TRANSFER_ENCODING);
          97  +
        request.headers_mut().append(
          98  +
            header::CONTENT_ENCODING,
          99  +
            HeaderValue::from_str(AWS_CHUNKED)
         100  +
                .map_err(BuildError::other)
         101  +
                .expect("\"aws-chunked\" will always be a valid HeaderValue"),
         102  +
        );
         103  +
         104  +
        cfg.interceptor_state().store_put(chunked_body_options);
         105  +
        cfg.interceptor_state().store_put(PayloadSigningOverride::StreamingUnsignedPayloadTrailer);
         106  +
         107  +
        Ok(())
         108  +
    }
         109  +
         110  +
    fn modify_before_transmit(
         111  +
        &self,
         112  +
        ctx: &mut BeforeTransmitInterceptorContextMut<'_>,
         113  +
        _runtime_components: &RuntimeComponents,
         114  +
        cfg: &mut ConfigBag,
         115  +
    ) -> Result<(), BoxError> {
         116  +
        if must_not_use_chunked_encoding(ctx.request(), cfg) {
         117  +
            tracing::debug!("short-circuiting modify_before_transmit because chunked encoding must not be used");
         118  +
            return Ok(());
         119  +
        }
         120  +
         121  +
        let request = ctx.request_mut();
         122  +
         123  +
        let mut body = {
         124  +
            let body = std::mem::replace(request.body_mut(), SdkBody::taken());
         125  +
            let opt = cfg
         126  +
                .get_mut_from_interceptor_state::<AwsChunkedBodyOptions>()
         127  +
                .ok_or_else(|| BuildError::other("AwsChunkedBodyOptions missing from config bag"))?;
         128  +
            let aws_chunked_body_options = std::mem::take(opt);
         129  +
            body.map(move |body| {
         130  +
                let body = AwsChunkedBody::new(body, aws_chunked_body_options.clone());
         131  +
                SdkBody::from_body_0_4(body)
         132  +
            })
         133  +
        };
         134  +
         135  +
        std::mem::swap(request.body_mut(), &mut body);
         136  +
         137  +
        Ok(())
         138  +
    }
         139  +
}
         140  +
         141  +
// Determine if chunked encoding must not be used; returns true when any of the following is true:
         142  +
// - If the body is in-memory
         143  +
// - If chunked encoding is disabled via `AwsChunkedBodyOptions`
         144  +
fn must_not_use_chunked_encoding(request: &Request, cfg: &ConfigBag) -> bool {
         145  +
    match (request.body().bytes(), cfg.load::<AwsChunkedBodyOptions>()) {
         146  +
        (Some(_), _) => true,
         147  +
        (_, Some(options)) if options.disabled() => true,
         148  +
        _ => false,
         149  +
    }
         150  +
}
         151  +
         152  +
#[cfg(test)]
         153  +
mod tests {
         154  +
    use super::*;
         155  +
    use aws_smithy_runtime_api::client::interceptors::context::{BeforeTransmitInterceptorContextMut, Input, InterceptorContext};
         156  +
    use aws_smithy_runtime_api::client::orchestrator::HttpRequest;
         157  +
    use aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder;
         158  +
    use aws_smithy_types::byte_stream::ByteStream;
         159  +
    use bytes::BytesMut;
         160  +
    use http_body::Body;
         161  +
    use tempfile::NamedTempFile;
         162  +
         163  +
    #[tokio::test]
         164  +
    async fn test_aws_chunked_body_is_retryable() {
         165  +
        use std::io::Write;
         166  +
        let mut file = NamedTempFile::new().unwrap();
         167  +
         168  +
        for i in 0..10000 {
         169  +
            let line = format!("This is a large file created for testing purposes {}", i);
         170  +
            file.as_file_mut().write_all(line.as_bytes()).unwrap();
         171  +
        }
         172  +
         173  +
        let request = HttpRequest::new(ByteStream::read_from().path(&file).buffer_size(1024).build().await.unwrap().into_inner());
         174  +
         175  +
        // ensure original SdkBody is retryable
         176  +
        assert!(request.body().try_clone().is_some());
         177  +
         178  +
        let interceptor = AwsChunkedContentEncodingInterceptor;
         179  +
        let mut cfg = ConfigBag::base();
         180  +
        cfg.interceptor_state().store_put(AwsChunkedBodyOptions::default());
         181  +
        let runtime_components = RuntimeComponentsBuilder::for_tests().build().unwrap();
         182  +
        let mut ctx = InterceptorContext::new(Input::doesnt_matter());
         183  +
        ctx.enter_serialization_phase();
         184  +
        let _ = ctx.take_input();
         185  +
        ctx.set_request(request);
         186  +
        ctx.enter_before_transmit_phase();
         187  +
        let mut ctx: BeforeTransmitInterceptorContextMut<'_> = (&mut ctx).into();
         188  +
        interceptor.modify_before_transmit(&mut ctx, &runtime_components, &mut cfg).unwrap();
         189  +
         190  +
        // ensure wrapped SdkBody is retryable
         191  +
        let mut body = ctx.request().body().try_clone().expect("body is retryable");
         192  +
         193  +
        let mut body_data = BytesMut::new();
         194  +
        while let Some(data) = body.data().await {
         195  +
            body_data.extend_from_slice(&data.unwrap())
         196  +
        }
         197  +
        let body_str = std::str::from_utf8(&body_data).unwrap();
         198  +
        assert!(body_str.ends_with("0\r\n\r\n"));
         199  +
    }
         200  +
         201  +
    #[tokio::test]
         202  +
    async fn test_short_circuit_modify_before_signing() {
         203  +
        let mut ctx = InterceptorContext::new(Input::doesnt_matter());
         204  +
        ctx.enter_serialization_phase();
         205  +
        let _ = ctx.take_input();
         206  +
        let request = HttpRequest::new(SdkBody::from("in-memory body, must not use chunked encoding"));
         207  +
        ctx.set_request(request);
         208  +
        ctx.enter_before_transmit_phase();
         209  +
        let mut ctx: BeforeTransmitInterceptorContextMut<'_> = (&mut ctx).into();
         210  +
         211  +
        let runtime_components = RuntimeComponentsBuilder::for_tests().build().unwrap();
         212  +
         213  +
        let mut cfg = ConfigBag::base();
         214  +
        cfg.interceptor_state().store_put(AwsChunkedBodyOptions::default());
         215  +
         216  +
        let interceptor = AwsChunkedContentEncodingInterceptor;
         217  +
        interceptor.modify_before_signing(&mut ctx, &runtime_components, &mut cfg).unwrap();
         218  +
         219  +
        let request = ctx.request();
         220  +
        assert!(request.headers().get(header::CONTENT_ENCODING).is_none());
         221  +
        assert!(request
         222  +
            .headers()
         223  +
            .get(header::HeaderName::from_static(X_AMZ_DECODED_CONTENT_LENGTH))
         224  +
            .is_none());
         225  +
    }
         226  +
         227  +
    #[tokio::test]
         228  +
    async fn test_short_circuit_modify_before_transmit() {
         229  +
        let mut ctx = InterceptorContext::new(Input::doesnt_matter());
         230  +
        ctx.enter_serialization_phase();
         231  +
        let _ = ctx.take_input();
         232  +
        let request = HttpRequest::new(SdkBody::from("in-memory body, must not use chunked encoding"));
         233  +
        ctx.set_request(request);
         234  +
        ctx.enter_before_transmit_phase();
         235  +
        let mut ctx: BeforeTransmitInterceptorContextMut<'_> = (&mut ctx).into();
         236  +
         237  +
        let runtime_components = RuntimeComponentsBuilder::for_tests().build().unwrap();
         238  +
         239  +
        let mut cfg = ConfigBag::base();
         240  +
        // Don't need to set the stream length properly because we expect the body won't be wrapped by `AwsChunkedBody`.
         241  +
        cfg.interceptor_state().store_put(AwsChunkedBodyOptions::default());
         242  +
         243  +
        let interceptor = AwsChunkedContentEncodingInterceptor;
         244  +
        interceptor.modify_before_transmit(&mut ctx, &runtime_components, &mut cfg).unwrap();
         245  +
         246  +
        let mut body = ctx.request().body().try_clone().expect("body is retryable");
         247  +
         248  +
        let mut body_data = BytesMut::new();
         249  +
        while let Some(data) = body.data().await {
         250  +
            body_data.extend_from_slice(&data.unwrap())
         251  +
        }
         252  +
        let body_str = std::str::from_utf8(&body_data).unwrap();
         253  +
        // Also implies that `assert!(!body_str.ends_with("0\r\n\r\n"));`, i.e., shouldn't see chunked encoding epilogue.
         254  +
        assert_eq!("in-memory body, must not use chunked encoding", body_str);
         255  +
    }
         256  +
         257  +
    #[test]
         258  +
    fn test_must_not_use_chunked_encoding_with_in_memory_body() {
         259  +
        let request = HttpRequest::new(SdkBody::from("test body"));
         260  +
        let cfg = ConfigBag::base();
         261  +
         262  +
        assert!(must_not_use_chunked_encoding(&request, &cfg));
         263  +
    }
         264  +
         265  +
    async fn streaming_body(path: impl AsRef<std::path::Path>) -> SdkBody {
         266  +
        let file = path.as_ref();
         267  +
        ByteStream::read_from().path(&file).build().await.unwrap().into_inner()
         268  +
    }
         269  +
         270  +
    #[tokio::test]
         271  +
    async fn test_must_not_use_chunked_encoding_with_disabled_option() {
         272  +
        let file = NamedTempFile::new().unwrap();
         273  +
        let request = HttpRequest::new(streaming_body(&file).await);
         274  +
        let mut cfg = ConfigBag::base();
         275  +
        cfg.interceptor_state().store_put(AwsChunkedBodyOptions::disable_chunked_encoding());
         276  +
         277  +
        assert!(must_not_use_chunked_encoding(&request, &cfg));
         278  +
    }
         279  +
         280  +
    #[tokio::test]
         281  +
    async fn test_chunked_encoding_is_used() {
         282  +
        let file = NamedTempFile::new().unwrap();
         283  +
        let request = HttpRequest::new(streaming_body(&file).await);
         284  +
        let cfg = ConfigBag::base();
         285  +
         286  +
        assert!(!must_not_use_chunked_encoding(&request, &cfg));
         287  +
    }
         288  +
}

tmp-codegen-diff/aws-sdk/sdk/s3/src/http_request_checksum.rs

@@ -1,1 +98,104 @@
    2      2   
/*
    3      3   
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
    4      4   
 * SPDX-License-Identifier: Apache-2.0
    5      5   
 */
    6      6   
    7      7   
#![allow(dead_code)]
    8      8   
    9      9   
//! Interceptor for handling Smithy `@httpChecksum` request checksumming with AWS SigV4
   10     10   
   11     11   
use crate::presigning::PresigningMarker;
   12         -
use aws_runtime::auth::PayloadSigningOverride;
   13         -
use aws_runtime::content_encoding::header_value::AWS_CHUNKED;
   14         -
use aws_runtime::content_encoding::{AwsChunkedBody, AwsChunkedBodyOptions};
          12  +
use aws_runtime::content_encoding::AwsChunkedBodyOptions;
          13  +
use aws_smithy_checksums::body::calculate;
   15     14   
use aws_smithy_checksums::body::ChecksumCache;
          15  +
use aws_smithy_checksums::http::HttpChecksum;
   16     16   
use aws_smithy_checksums::ChecksumAlgorithm;
   17         -
use aws_smithy_checksums::{body::calculate, http::HttpChecksum};
   18     17   
use aws_smithy_runtime::client::sdk_feature::SmithySdkFeature;
   19     18   
use aws_smithy_runtime_api::box_error::BoxError;
   20     19   
use aws_smithy_runtime_api::client::interceptors::context::{BeforeSerializationInterceptorContextMut, BeforeTransmitInterceptorContextMut, Input};
   21     20   
use aws_smithy_runtime_api::client::interceptors::Intercept;
   22         -
use aws_smithy_runtime_api::client::orchestrator::HttpRequest;
   23     21   
use aws_smithy_runtime_api::client::runtime_components::RuntimeComponents;
   24     22   
use aws_smithy_runtime_api::http::Request;
   25     23   
use aws_smithy_types::body::SdkBody;
   26     24   
use aws_smithy_types::checksum_config::RequestChecksumCalculation;
   27         -
use aws_smithy_types::config_bag::{ConfigBag, Layer, Storable, StoreReplace};
   28         -
use aws_smithy_types::error::operation::BuildError;
   29         -
use http::HeaderValue;
   30         -
use http_body::Body;
          25  +
use aws_smithy_types::config_bag::{ConfigBag, Storable, StoreReplace};
          26  +
use http::HeaderMap;
   31     27   
use std::str::FromStr;
   32     28   
use std::sync::atomic::AtomicBool;
   33     29   
use std::sync::atomic::Ordering;
   34     30   
use std::sync::Arc;
   35     31   
use std::{fmt, mem};
   36     32   
   37     33   
/// Errors related to constructing checksum-validated HTTP requests
   38     34   
#[derive(Debug)]
   39     35   
pub(crate) enum Error {
   40         -
    /// Only request bodies with a known size can be checksum validated
   41         -
    UnsizedRequestBody,
   42     36   
    ChecksumHeadersAreUnsupportedForStreamingBody,
   43     37   
}
   44     38   
   45     39   
impl fmt::Display for Error {
   46     40   
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
   47     41   
        match self {
   48         -
            Self::UnsizedRequestBody => write!(f, "Only request bodies with a known size can be checksum validated."),
   49     42   
            Self::ChecksumHeadersAreUnsupportedForStreamingBody => write!(
   50     43   
                f,
   51     44   
                "Checksum header insertion is only supported for non-streaming HTTP bodies. \
   52     45   
                   To checksum validate a streaming body, the checksums must be sent as trailers."
   53     46   
            ),
   54     47   
        }
   55     48   
    }
   56     49   
}
   57     50   
   58     51   
impl std::error::Error for Error {}
   59     52   
   60         -
#[derive(Debug, Clone)]
          53  +
#[derive(Debug, Default, Clone)]
   61     54   
struct RequestChecksumInterceptorState {
   62     55   
    /// The checksum algorithm to calculate
   63     56   
    checksum_algorithm: Option<String>,
   64     57   
    /// This value is set in the model on the `httpChecksum` trait
   65     58   
    request_checksum_required: bool,
   66     59   
    calculate_checksum: Arc<AtomicBool>,
   67     60   
    checksum_cache: ChecksumCache,
   68     61   
}
          62  +
          63  +
impl RequestChecksumInterceptorState {
          64  +
    fn checksum_algorithm(&self) -> Option<ChecksumAlgorithm> {
          65  +
        self.checksum_algorithm
          66  +
            .as_ref()
          67  +
            .and_then(|s| ChecksumAlgorithm::from_str(s.as_str()).ok())
          68  +
    }
          69  +
          70  +
    fn calculate_checksum(&self) -> bool {
          71  +
        self.calculate_checksum.load(Ordering::SeqCst)
          72  +
    }
          73  +
}
          74  +
   69     75   
impl Storable for RequestChecksumInterceptorState {
   70     76   
    type Storer = StoreReplace<Self>;
   71     77   
}
   72     78   
   73     79   
type CustomDefaultFn = Box<dyn Fn(Option<ChecksumAlgorithm>, &ConfigBag) -> Option<ChecksumAlgorithm> + Send + Sync + 'static>;
   74     80   
   75     81   
pub(crate) struct DefaultRequestChecksumOverride {
   76     82   
    custom_default: CustomDefaultFn,
   77     83   
}
   78     84   
impl fmt::Debug for DefaultRequestChecksumOverride {
@@ -107,113 +482,448 @@
  127    133   
    }
  128    134   
  129    135   
    fn modify_before_serialization(
  130    136   
        &self,
  131    137   
        context: &mut BeforeSerializationInterceptorContextMut<'_>,
  132    138   
        _runtime_components: &RuntimeComponents,
  133    139   
        cfg: &mut ConfigBag,
  134    140   
    ) -> Result<(), BoxError> {
  135    141   
        let (checksum_algorithm, request_checksum_required) = (self.algorithm_provider)(context.input());
  136    142   
  137         -
        let mut layer = Layer::new("RequestChecksumInterceptor");
  138         -
        layer.store_put(RequestChecksumInterceptorState {
         143  +
        cfg.interceptor_state().store_put(RequestChecksumInterceptorState {
  139    144   
            checksum_algorithm,
  140    145   
            request_checksum_required,
  141    146   
            checksum_cache: ChecksumCache::new(),
  142    147   
            calculate_checksum: Arc::new(AtomicBool::new(false)),
  143    148   
        });
  144         -
        cfg.push_layer(layer);
  145    149   
  146    150   
        Ok(())
  147    151   
    }
  148    152   
  149    153   
    /// Setup state for calculating checksum and setting UA features
  150    154   
    fn modify_before_retry_loop(
  151    155   
        &self,
  152    156   
        context: &mut BeforeTransmitInterceptorContextMut<'_>,
  153    157   
        _runtime_components: &RuntimeComponents,
  154    158   
        cfg: &mut ConfigBag,
  155    159   
    ) -> Result<(), BoxError> {
  156         -
        let state = cfg.load::<RequestChecksumInterceptorState>().expect("set in `read_before_serialization`");
  157         -
  158    160   
        let user_set_checksum_value = (self.checksum_mutator)(context.request_mut(), cfg).expect("Checksum header mutation should not fail");
         161  +
        let is_presigned = cfg.load::<PresigningMarker>().is_some();
  159    162   
  160         -
        // If the user manually set a checksum header we short circuit
  161         -
        if user_set_checksum_value {
         163  +
        // If the user manually set a checksum header or if this is a presigned request, we short circuit
         164  +
        if user_set_checksum_value || is_presigned {
         165  +
            // Disable aws-chunked encoding since either the user has set a custom checksum
         166  +
            cfg.interceptor_state().store_put(AwsChunkedBodyOptions::disable_chunked_encoding());
  162    167   
            return Ok(());
  163    168   
        }
  164    169   
  165         -
        // This value is from the trait, but is needed for runtime logic
  166         -
        let request_checksum_required = state.request_checksum_required;
         170  +
        let state = cfg
         171  +
            .get_mut_from_interceptor_state::<RequestChecksumInterceptorState>()
         172  +
            .expect("set in `read_before_serialization`");
  167    173   
  168    174   
        // If the algorithm fails to parse it is not one we support and we error
  169    175   
        let checksum_algorithm = state
  170    176   
            .checksum_algorithm
  171    177   
            .clone()
  172    178   
            .map(|s| ChecksumAlgorithm::from_str(s.as_str()))
  173    179   
            .transpose()?;
  174    180   
  175         -
        // This value is set by the user on the SdkConfig to indicate their preference
  176         -
        // We provide a default here for users that use a client config instead of the SdkConfig
  177         -
        let request_checksum_calculation = cfg
  178         -
            .load::<RequestChecksumCalculation>()
  179         -
            .unwrap_or(&RequestChecksumCalculation::WhenSupported);
  180         -
  181         -
        // Need to know if this is a presigned req because we do not calculate checksums for those.
  182         -
        let is_presigned_req = cfg.load::<PresigningMarker>().is_some();
  183         -
  184         -
        // Determine if we actually calculate the checksum. If this is a presigned request we do not
  185         -
        // If the user setting is WhenSupported (the default) we always calculate it (because this interceptor
  186         -
        // isn't added if it isn't supported). If it is WhenRequired we only calculate it if the checksum
  187         -
        // is marked required on the trait.
  188         -
        let calculate_checksum = match (request_checksum_calculation, is_presigned_req) {
  189         -
            (_, true) => false,
  190         -
            (RequestChecksumCalculation::WhenRequired, false) => request_checksum_required,
  191         -
            (RequestChecksumCalculation::WhenSupported, false) => true,
  192         -
            _ => true,
  193         -
        };
  194         -
  195         -
        // If a checksum override is set in the ConfigBag we use that instead (currently only used by S3Express)
  196         -
        // If we have made it this far without a checksum being set we set the default (currently Crc32)
  197         -
        let checksum_algorithm = incorporate_custom_default(checksum_algorithm, cfg).unwrap_or_default();
         181  +
        let mut state = std::mem::take(state);
  198    182   
  199         -
        if calculate_checksum {
         183  +
        if calculate_checksum(cfg, &state) {
  200    184   
            state.calculate_checksum.store(true, Ordering::Release);
  201    185   
  202         -
            // Set the user-agent metric for the selected checksum algorithm
         186  +
            // If a checksum override is set in the ConfigBag we use that instead (currently only used by S3Express)
         187  +
            // If we have made it this far without a checksum being set we set the default (currently Crc32)
         188  +
            let checksum_algorithm = incorporate_custom_default(checksum_algorithm, cfg).unwrap_or_default();
         189  +
            state.checksum_algorithm = Some(checksum_algorithm.as_str().to_owned());
         190  +
  203    191   
            // NOTE: We have to do this in modify_before_retry_loop since UA interceptor also runs
  204    192   
            // in modify_before_signing but is registered before this interceptor (client level vs operation level).
  205         -
            match checksum_algorithm {
  206         -
                ChecksumAlgorithm::Crc32 => {
  207         -
                    cfg.interceptor_state().store_append(SmithySdkFeature::FlexibleChecksumsReqCrc32);
  208         -
                }
  209         -
                ChecksumAlgorithm::Crc32c => {
  210         -
                    cfg.interceptor_state().store_append(SmithySdkFeature::FlexibleChecksumsReqCrc32c);
  211         -
                }
  212         -
                ChecksumAlgorithm::Crc64Nvme => {
  213         -
                    cfg.interceptor_state().store_append(SmithySdkFeature::FlexibleChecksumsReqCrc64);
  214         -
                }
  215         -
                #[allow(deprecated)]
  216         -
                ChecksumAlgorithm::Md5 => {
  217         -
                    tracing::warn!(more_info = "Unsupported ChecksumAlgorithm MD5 set");
  218         -
                }
  219         -
                ChecksumAlgorithm::Sha1 => {
  220         -
                    cfg.interceptor_state().store_append(SmithySdkFeature::FlexibleChecksumsReqSha1);
  221         -
                }
  222         -
                ChecksumAlgorithm::Sha256 => {
  223         -
                    cfg.interceptor_state().store_append(SmithySdkFeature::FlexibleChecksumsReqSha256);
  224         -
                }
  225         -
                unsupported => tracing::warn!(
  226         -
                        more_info = "Unsupported value of ChecksumAlgorithm detected when setting user-agent metrics",
  227         -
                        unsupported = ?unsupported),
  228         -
            }
         193  +
            track_metric_for_selected_checksum_algorithm(cfg, &checksum_algorithm);
         194  +
        } else {
         195  +
            // No checksum calculation needed so disable aws-chunked encoding
         196  +
            cfg.interceptor_state().store_put(AwsChunkedBodyOptions::disable_chunked_encoding());
  229    197   
        }
  230    198   
         199  +
        cfg.interceptor_state().store_put(state);
         200  +
  231    201   
        Ok(())
  232    202   
    }
  233    203   
  234         -
    /// Calculate a checksum and modify the request to include the checksum as a header
  235         -
    /// (for in-memory request bodies) or a trailer (for streaming request bodies).
  236         -
    /// Streaming bodies must be sized or this will return an error.
         204  +
    /// Calculate a checksum and modify the request to do either of the following:
         205  +
    /// - include the checksum as a header for signing with in-memory request bodies.
         206  +
    /// - include the checksum as a trailer for streaming request bodies.
  237    207   
    fn modify_before_signing(
  238    208   
        &self,
  239    209   
        context: &mut BeforeTransmitInterceptorContextMut<'_>,
  240    210   
        _runtime_components: &RuntimeComponents,
  241    211   
        cfg: &mut ConfigBag,
  242    212   
    ) -> Result<(), BoxError> {
  243    213   
        let state = cfg.load::<RequestChecksumInterceptorState>().expect("set in `read_before_serialization`");
  244    214   
  245         -
        let checksum_cache = state.checksum_cache.clone();
  246         -
  247         -
        let checksum_algorithm = state
  248         -
            .checksum_algorithm
  249         -
            .clone()
  250         -
            .map(|s| ChecksumAlgorithm::from_str(s.as_str()))
  251         -
            .transpose()?;
         215  +
        if !state.calculate_checksum() {
         216  +
            return Ok(());
         217  +
        }
  252    218   
  253         -
        let calculate_checksum = state.calculate_checksum.load(Ordering::SeqCst);
         219  +
        let checksum_algorithm = state.checksum_algorithm().expect("set in `modify_before_retry_loop`");
         220  +
        let mut checksum = checksum_algorithm.into_impl();
  254    221   
  255         -
        // Calculate the checksum if necessary
  256         -
        if calculate_checksum {
  257         -
            // If a checksum override is set in the ConfigBag we use that instead (currently only used by S3Express)
  258         -
            // If we have made it this far without a checksum being set we set the default (currently Crc32)
  259         -
            let checksum_algorithm = incorporate_custom_default(checksum_algorithm, cfg).unwrap_or_default();
         222  +
        match context.request().body().bytes() {
         223  +
            Some(data) => {
         224  +
                tracing::debug!("applying {checksum_algorithm:?} of the request body as a header");
         225  +
                checksum.update(data);
  260    226   
  261         -
            let request = context.request_mut();
  262         -
            add_checksum_for_request_body(request, checksum_algorithm, checksum_cache, cfg)?;
         227  +
                for (hdr_name, hdr_value) in get_or_cache_headers(checksum.headers(), &state.checksum_cache).iter() {
         228  +
                    context.request_mut().headers_mut().insert(hdr_name.clone(), hdr_value.clone());
         229  +
                }
         230  +
            }
         231  +
            None => {
         232  +
                tracing::debug!("applying {checksum_algorithm:?} of the request body as a trailer");
         233  +
                context
         234  +
                    .request_mut()
         235  +
                    .headers_mut()
         236  +
                    .insert(http::header::HeaderName::from_static("x-amz-trailer"), checksum.header_name());
         237  +
         238  +
                // Take checksum header into account for `AwsChunkedBodyOptions`'s trailer length
         239  +
                let trailer_len = HttpChecksum::size(checksum.as_ref());
         240  +
                let chunked_body_options = AwsChunkedBodyOptions::default().with_trailer_len(trailer_len);
         241  +
                cfg.interceptor_state().store_put(chunked_body_options);
         242  +
            }
  263    243   
        }
  264    244   
  265    245   
        Ok(())
  266    246   
    }
  267    247   
  268         -
    /// Set the user-agent metrics for `RequestChecksumCalculation` here to avoid ownership issues
  269         -
    /// with the mutable borrow of cfg in `modify_before_signing`
  270         -
    fn read_after_serialization(
         248  +
    fn modify_before_transmit(
  271    249   
        &self,
  272         -
        _context: &aws_smithy_runtime_api::client::interceptors::context::BeforeTransmitInterceptorContextRef<'_>,
         250  +
        ctx: &mut BeforeTransmitInterceptorContextMut<'_>,
  273    251   
        _runtime_components: &RuntimeComponents,
  274    252   
        cfg: &mut ConfigBag,
  275    253   
    ) -> Result<(), BoxError> {
  276         -
        let request_checksum_calculation = cfg
  277         -
            .load::<RequestChecksumCalculation>()
  278         -
            .unwrap_or(&RequestChecksumCalculation::WhenSupported);
         254  +
        if ctx.request().body().bytes().is_some() {
         255  +
            // Nothing to do for non-streaming bodies since the checksum was added to the the header
         256  +
            // in `modify_before_signing` and signing has already been done by the time this hook is called.
         257  +
            return Ok(());
         258  +
        }
  279    259   
  280         -
        match request_checksum_calculation {
  281         -
            RequestChecksumCalculation::WhenSupported => {
  282         -
                cfg.interceptor_state().store_append(SmithySdkFeature::FlexibleChecksumsReqWhenSupported);
  283         -
            }
  284         -
            RequestChecksumCalculation::WhenRequired => {
  285         -
                cfg.interceptor_state().store_append(SmithySdkFeature::FlexibleChecksumsReqWhenRequired);
  286         -
            }
  287         -
            unsupported => tracing::warn!(
  288         -
                    more_info = "Unsupported value of RequestChecksumCalculation when setting user-agent metrics",
  289         -
                    unsupported = ?unsupported),
         260  +
        let state = cfg.load::<RequestChecksumInterceptorState>().expect("set in `read_before_serialization`");
         261  +
         262  +
        if !state.calculate_checksum() {
         263  +
            return Ok(());
         264  +
        }
         265  +
         266  +
        let request = ctx.request_mut();
         267  +
         268  +
        let mut body = {
         269  +
            let body = mem::replace(request.body_mut(), SdkBody::taken());
         270  +
         271  +
            let checksum_algorithm = state.checksum_algorithm().expect("set in `modify_before_retry_loop`");
         272  +
            let checksum_cache = state.checksum_cache.clone();
         273  +
         274  +
            body.map(move |body| {
         275  +
                let checksum = checksum_algorithm.into_impl();
         276  +
                let body = calculate::ChecksumBody::new(body, checksum).with_cache(checksum_cache.clone());
         277  +
         278  +
                SdkBody::from_body_0_4(body)
         279  +
            })
  290    280   
        };
  291    281   
         282  +
        mem::swap(request.body_mut(), &mut body);
         283  +
  292    284   
        Ok(())
  293    285   
    }
  294    286   
}
  295    287   
  296    288   
fn incorporate_custom_default(checksum: Option<ChecksumAlgorithm>, cfg: &ConfigBag) -> Option<ChecksumAlgorithm> {
  297    289   
    match cfg.load::<DefaultRequestChecksumOverride>() {
  298    290   
        Some(checksum_override) => checksum_override.custom_default(checksum, cfg),
  299    291   
        None => checksum,
  300    292   
    }
  301    293   
}
  302    294   
  303         -
fn add_checksum_for_request_body(
  304         -
    request: &mut HttpRequest,
  305         -
    checksum_algorithm: ChecksumAlgorithm,
  306         -
    checksum_cache: ChecksumCache,
  307         -
    cfg: &mut ConfigBag,
  308         -
) -> Result<(), BoxError> {
  309         -
    match request.body().bytes() {
  310         -
        // Body is in-memory: read it and insert the checksum as a header.
  311         -
        Some(data) => {
  312         -
            let mut checksum = checksum_algorithm.into_impl();
  313         -
  314         -
            // If the header has not already been set we set it. If it was already set by the user
  315         -
            // we do nothing and maintain their set value.
  316         -
            if request.headers().get(checksum.header_name()).is_none() {
  317         -
                tracing::debug!("applying {checksum_algorithm:?} of the request body as a header");
  318         -
                checksum.update(data);
         295  +
fn get_or_cache_headers(calculated_headers: HeaderMap, checksum_cache: &ChecksumCache) -> HeaderMap {
         296  +
    if let Some(cached_headers) = checksum_cache.get() {
         297  +
        if cached_headers != calculated_headers {
         298  +
            tracing::warn!(cached = ?cached_headers, calculated = ?calculated_headers, "calculated checksum differs from cached checksum!");
         299  +
        }
         300  +
        cached_headers
         301  +
    } else {
         302  +
        checksum_cache.set(calculated_headers.clone());
         303  +
        calculated_headers
         304  +
    }
         305  +
}
  319    306   
  320         -
                let calculated_headers = checksum.headers();
  321         -
                let checksum_headers = if let Some(cached_headers) = checksum_cache.get() {
  322         -
                    if cached_headers != calculated_headers {
  323         -
                        tracing::warn!(cached = ?cached_headers, calculated = ?calculated_headers, "calculated checksum differs from cached checksum!");
  324         -
                    }
  325         -
                    cached_headers
  326         -
                } else {
  327         -
                    checksum_cache.set(calculated_headers.clone());
  328         -
                    calculated_headers
  329         -
                };
  330         -
  331         -
                for (hdr_name, hdr_value) in checksum_headers.iter() {
  332         -
                    request.headers_mut().insert(hdr_name.clone(), hdr_value.clone());
  333         -
                }
  334         -
            }
         307  +
// Determine if we actually calculate the checksum
         308  +
fn calculate_checksum(cfg: &mut ConfigBag, state: &RequestChecksumInterceptorState) -> bool {
         309  +
    // This value is set by the user on the SdkConfig to indicate their preference
         310  +
    // We provide a default here for users that use a client config instead of the SdkConfig
         311  +
    let request_checksum_calculation = cfg
         312  +
        .load::<RequestChecksumCalculation>()
         313  +
        .unwrap_or(&RequestChecksumCalculation::WhenSupported);
         314  +
         315  +
    // If the user setting is WhenSupported (the default) we always calculate it (because this interceptor
         316  +
    // isn't added if it isn't supported). If it is WhenRequired we only calculate it if the checksum
         317  +
    // is marked required on the trait.
         318  +
    match request_checksum_calculation {
         319  +
        RequestChecksumCalculation::WhenRequired => {
         320  +
            cfg.interceptor_state().store_append(SmithySdkFeature::FlexibleChecksumsReqWhenRequired);
         321  +
            state.request_checksum_required
         322  +
        }
         323  +
        RequestChecksumCalculation::WhenSupported => {
         324  +
            cfg.interceptor_state().store_append(SmithySdkFeature::FlexibleChecksumsReqWhenSupported);
         325  +
            true
  335    326   
        }
  336         -
        // Body is streaming: wrap the body so it will emit a checksum as a trailer.
  337         -
        None => {
  338         -
            tracing::debug!("applying {checksum_algorithm:?} of the request body as a trailer");
  339         -
            cfg.interceptor_state().store_put(PayloadSigningOverride::StreamingUnsignedPayloadTrailer);
  340         -
            wrap_streaming_request_body_in_checksum_calculating_body(request, checksum_algorithm, checksum_cache.clone())?;
         327  +
        unsupported => {
         328  +
            tracing::warn!(
         329  +
                more_info = "Unsupported value of RequestChecksumCalculation when setting user-agent metrics",
         330  +
                unsupported = ?unsupported
         331  +
            );
         332  +
            true
  341    333   
        }
  342    334   
    }
  343         -
    Ok(())
  344    335   
}
  345    336   
  346         -
fn wrap_streaming_request_body_in_checksum_calculating_body(
  347         -
    request: &mut HttpRequest,
  348         -
    checksum_algorithm: ChecksumAlgorithm,
  349         -
    checksum_cache: ChecksumCache,
  350         -
) -> Result<(), BuildError> {
  351         -
    let checksum = checksum_algorithm.into_impl();
  352         -
  353         -
    // If the user already set the header value then do nothing and return early
  354         -
    if request.headers().get(checksum.header_name()).is_some() {
  355         -
        return Ok(());
         337  +
// Set the user-agent metric for the selected checksum algorithm
         338  +
fn track_metric_for_selected_checksum_algorithm(cfg: &mut ConfigBag, checksum_algorithm: &ChecksumAlgorithm) {
         339  +
    match checksum_algorithm {
         340  +
        ChecksumAlgorithm::Crc32 => {
         341  +
            cfg.interceptor_state().store_append(SmithySdkFeature::FlexibleChecksumsReqCrc32);
         342  +
        }
         343  +
        ChecksumAlgorithm::Crc32c => {
         344  +
            cfg.interceptor_state().store_append(SmithySdkFeature::FlexibleChecksumsReqCrc32c);
         345  +
        }
         346  +
        ChecksumAlgorithm::Crc64Nvme => {
         347  +
            cfg.interceptor_state().store_append(SmithySdkFeature::FlexibleChecksumsReqCrc64);
         348  +
        }
         349  +
        #[allow(deprecated)]
         350  +
        ChecksumAlgorithm::Md5 => {
         351  +
            tracing::warn!(more_info = "Unsupported ChecksumAlgorithm MD5 set");
         352  +
        }
         353  +
        ChecksumAlgorithm::Sha1 => {
         354  +
            cfg.interceptor_state().store_append(SmithySdkFeature::FlexibleChecksumsReqSha1);
         355  +
        }
         356  +
        ChecksumAlgorithm::Sha256 => {
         357  +
            cfg.interceptor_state().store_append(SmithySdkFeature::FlexibleChecksumsReqSha256);
         358  +
        }
         359  +
        unsupported => tracing::warn!(
         360  +
                more_info = "Unsupported value of ChecksumAlgorithm detected when setting user-agent metrics",
         361  +
                unsupported = ?unsupported),
  356    362   
    }
  357         -
  358         -
    let original_body_size = request
  359         -
        .body()
  360         -
        .size_hint()
  361         -
        .exact()
  362         -
        .ok_or_else(|| BuildError::other(Error::UnsizedRequestBody))?;
  363         -
  364         -
    let mut body = {
  365         -
        let body = mem::replace(request.body_mut(), SdkBody::taken());
  366         -
  367         -
        body.map(move |body| {
  368         -
            let checksum = checksum_algorithm.into_impl();
  369         -
            let trailer_len = HttpChecksum::size(checksum.as_ref());
  370         -
            let body = calculate::ChecksumBody::new(body, checksum).with_cache(checksum_cache.clone());
  371         -
            let aws_chunked_body_options = AwsChunkedBodyOptions::new(original_body_size, vec![trailer_len]);
  372         -
  373         -
            let body = AwsChunkedBody::new(body, aws_chunked_body_options);
  374         -
  375         -
            SdkBody::from_body_0_4(body)
  376         -
        })
  377         -
    };
  378         -
  379         -
    let encoded_content_length = body.size_hint().exact().ok_or_else(|| BuildError::other(Error::UnsizedRequestBody))?;
  380         -
  381         -
    let headers = request.headers_mut();
  382         -
  383         -
    headers.insert(http::header::HeaderName::from_static("x-amz-trailer"), checksum.header_name());
  384         -
  385         -
    headers.insert(http::header::CONTENT_LENGTH, HeaderValue::from(encoded_content_length));
  386         -
    headers.insert(
  387         -
        http::header::HeaderName::from_static("x-amz-decoded-content-length"),
  388         -
        HeaderValue::from(original_body_size),
  389         -
    );
  390         -
    // The target service does not depend on where `aws-chunked` appears in the `Content-Encoding` header,
  391         -
    // as it will ultimately be stripped.
  392         -
    headers.append(
  393         -
        http::header::CONTENT_ENCODING,
  394         -
        HeaderValue::from_str(AWS_CHUNKED)
  395         -
            .map_err(BuildError::other)
  396         -
            .expect("\"aws-chunked\" will always be a valid HeaderValue"),
  397         -
    );
  398         -
  399         -
    mem::swap(request.body_mut(), &mut body);
  400         -
  401         -
    Ok(())
  402    363   
}
  403    364   
  404    365   
#[cfg(test)]
  405    366   
mod tests {
  406         -
    use crate::http_request_checksum::wrap_streaming_request_body_in_checksum_calculating_body;
  407         -
    use aws_smithy_checksums::body::ChecksumCache;
         367  +
    use super::*;
  408    368   
    use aws_smithy_checksums::ChecksumAlgorithm;
         369  +
    use aws_smithy_runtime_api::client::interceptors::context::{BeforeTransmitInterceptorContextMut, InterceptorContext};
  409    370   
    use aws_smithy_runtime_api::client::orchestrator::HttpRequest;
         371  +
    use aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder;
  410    372   
    use aws_smithy_types::base64;
  411         -
    use aws_smithy_types::body::SdkBody;
  412    373   
    use aws_smithy_types::byte_stream::ByteStream;
  413    374   
    use bytes::BytesMut;
  414    375   
    use http_body::Body;
  415    376   
    use tempfile::NamedTempFile;
  416    377   
  417         -
    #[tokio::test]
  418         -
    async fn test_checksum_body_is_retryable() {
  419         -
        let input_text = "Hello world";
  420         -
        let chunk_len_hex = format!("{:X}", input_text.len());
  421         -
        let mut request: HttpRequest = http::Request::builder()
  422         -
            .body(SdkBody::retryable(move || SdkBody::from(input_text)))
  423         -
            .unwrap()
  424         -
            .try_into()
  425         -
            .unwrap();
  426         -
  427         -
        // ensure original SdkBody is retryable
  428         -
        assert!(request.body().try_clone().is_some());
  429         -
  430         -
        let checksum_algorithm: ChecksumAlgorithm = "crc32".parse().unwrap();
  431         -
        let checksum_cache = ChecksumCache::new();
  432         -
        wrap_streaming_request_body_in_checksum_calculating_body(&mut request, checksum_algorithm, checksum_cache).unwrap();
  433         -
  434         -
        // ensure wrapped SdkBody is retryable
  435         -
        let mut body = request.body().try_clone().expect("body is retryable");
  436         -
  437         -
        let mut body_data = BytesMut::new();
  438         -
        while let Some(data) = body.data().await {
  439         -
            body_data.extend_from_slice(&data.unwrap())
         378  +
    fn create_test_interceptor() -> RequestChecksumInterceptor<
         379  +
        impl Fn(&Input) -> (Option<String>, bool) + Send + Sync,
         380  +
        impl Fn(&mut Request, &ConfigBag) -> Result<bool, BoxError> + Send + Sync,
         381  +
    > {
         382  +
        fn algo(_: &Input) -> (Option<String>, bool) {
         383  +
            (Some("crc32".to_string()), false)
         384  +
        }
         385  +
        fn mutator(_: &mut Request, _: &ConfigBag) -> Result<bool, BoxError> {
         386  +
            Ok(false)
  440    387   
        }
  441         -
        let body = std::str::from_utf8(&body_data).unwrap();
  442         -
        assert_eq!(
  443         -
            format!("{chunk_len_hex}\r\n{input_text}\r\n0\r\nx-amz-checksum-crc32:i9aeUg==\r\n\r\n"),
  444         -
            body
  445         -
        );
         388  +
        RequestChecksumInterceptor::new(algo, mutator)
  446    389   
    }
  447    390   
  448    391   
    #[tokio::test]
  449         -
    async fn test_checksum_body_from_file_is_retryable() {
         392  +
    async fn test_checksum_body_is_retryable() {
  450    393   
        use std::io::Write;
  451    394   
        let mut file = NamedTempFile::new().unwrap();
  452         -
        let checksum_algorithm: ChecksumAlgorithm = "crc32c".parse().unwrap();
         395  +
        let algorithm_str = "crc32c";
         396  +
        let checksum_algorithm: ChecksumAlgorithm = algorithm_str.parse().unwrap();
  453    397   
  454    398   
        let mut crc32c_checksum = checksum_algorithm.into_impl();
  455    399   
        for i in 0..10000 {
  456    400   
            let line = format!("This is a large file created for testing purposes {}", i);
  457    401   
            file.as_file_mut().write_all(line.as_bytes()).unwrap();
  458    402   
            crc32c_checksum.update(line.as_bytes());
  459    403   
        }
  460    404   
        let crc32c_checksum = crc32c_checksum.finalize();
  461    405   
  462         -
        let mut request = HttpRequest::new(ByteStream::read_from().path(&file).buffer_size(1024).build().await.unwrap().into_inner());
         406  +
        let request = HttpRequest::new(ByteStream::read_from().path(&file).buffer_size(1024).build().await.unwrap().into_inner());
  463    407   
  464    408   
        // ensure original SdkBody is retryable
  465    409   
        assert!(request.body().try_clone().is_some());
  466    410   
  467         -
        let checksum_cache = ChecksumCache::new();
  468         -
        wrap_streaming_request_body_in_checksum_calculating_body(&mut request, checksum_algorithm, checksum_cache).unwrap();
         411  +
        let interceptor = create_test_interceptor();
         412  +
        let mut cfg = ConfigBag::base();
         413  +
        cfg.interceptor_state().store_put(RequestChecksumInterceptorState {
         414  +
            checksum_algorithm: Some(algorithm_str.to_string()),
         415  +
            calculate_checksum: Arc::new(AtomicBool::new(true)),
         416  +
            ..Default::default()
         417  +
        });
         418  +
        let runtime_components = RuntimeComponentsBuilder::for_tests().build().unwrap();
         419  +
        let mut ctx = InterceptorContext::new(Input::doesnt_matter());
         420  +
        ctx.enter_serialization_phase();
         421  +
        let _ = ctx.take_input();
         422  +
        ctx.set_request(request);
         423  +
        ctx.enter_before_transmit_phase();
         424  +
        let mut ctx: BeforeTransmitInterceptorContextMut<'_> = (&mut ctx).into();
         425  +
        interceptor.modify_before_transmit(&mut ctx, &runtime_components, &mut cfg).unwrap();
  469    426   
  470    427   
        // ensure wrapped SdkBody is retryable
  471         -
        let mut body = request.body().try_clone().expect("body is retryable");
         428  +
        let mut body = ctx.request().body().try_clone().expect("body is retryable");
  472    429   
  473    430   
        let mut body_data = BytesMut::new();
  474    431   
        while let Some(data) = body.data().await {
  475    432   
            body_data.extend_from_slice(&data.unwrap())
  476    433   
        }
  477         -
        let body = std::str::from_utf8(&body_data).unwrap();
         434  +
        let body_str = std::str::from_utf8(&body_data).unwrap();
         435  +
        let expected = format!("This is a large file created for testing purposes 9999");
         436  +
        assert!(body_str.ends_with(&expected), "expected '{body_str}' to end with '{expected}'");
  478    437   
        let expected_checksum = base64::encode(&crc32c_checksum);
  479         -
        let expected = format!("This is a large file created for testing purposes 9999\r\n0\r\nx-amz-checksum-crc32c:{expected_checksum}\r\n\r\n");
  480         -
        assert!(body.ends_with(&expected), "expected {body} to end with '{expected}'");
         438  +
        while let Ok(Some(trailer)) = body.trailers().await {
         439  +
            if let Some(header_value) = trailer.get("x-amz-checksum-crc32c") {
         440  +
                let header_value = header_value.to_str().unwrap();
         441  +
                assert_eq!(
         442  +
                    header_value, expected_checksum,
         443  +
                    "expected checksum '{header_value}' to match '{expected_checksum}'"
         444  +
                );
         445  +
            }
         446  +
        }
  481    447   
    }
  482    448   
}