├── .cargo └── config.toml ├── .gitignore ├── .rustfmt.toml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── config.yaml.example └── src ├── config.rs ├── config_tests.rs ├── lib.rs ├── lib_tests.rs └── main.rs /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.x86_64-unknown-linux-musl] 2 | linker = "x86_64-linux-musl-gcc" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .idea 3 | .aider* 4 | config.yaml -------------------------------------------------------------------------------- /.rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width=120 2 | reorder_imports = true 3 | edition = "2021" -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.21.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.1.3" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "anstream" 31 | version = "0.6.15" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" 34 | dependencies = [ 35 | "anstyle", 36 | "anstyle-parse", 37 | "anstyle-query", 38 | "anstyle-wincon", 39 | "colorchoice", 40 | "is_terminal_polyfill", 41 | "utf8parse", 42 | ] 43 | 44 | [[package]] 45 | name = "anstyle" 46 | version = "1.0.8" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" 49 | 50 | [[package]] 51 | name = "anstyle-parse" 52 | version = "0.2.5" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" 55 | dependencies = [ 56 | "utf8parse", 57 | ] 58 | 59 | [[package]] 60 | name = "anstyle-query" 61 | version = "1.1.1" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" 64 | dependencies = [ 65 | "windows-sys 0.52.0", 66 | ] 67 | 68 | [[package]] 69 | name = "anstyle-wincon" 70 | version = "3.0.4" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" 73 | dependencies = [ 74 | "anstyle", 75 | "windows-sys 0.52.0", 76 | ] 77 | 78 | [[package]] 79 | name = "async-trait" 80 | version = "0.1.80" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" 83 | dependencies = [ 84 | "proc-macro2", 85 | "quote", 86 | "syn 2.0.60", 87 | ] 88 | 89 | [[package]] 90 | name = "autocfg" 91 | version = "1.2.0" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" 94 | 95 | [[package]] 96 | name = "aws-config" 97 | version = "1.5.5" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "4e95816a168520d72c0e7680c405a5a8c1fb6a035b4bc4b9d7b0de8e1a941697" 100 | dependencies = [ 101 | "aws-credential-types", 102 | "aws-runtime", 103 | "aws-sdk-sso", 104 | "aws-sdk-ssooidc", 105 | "aws-sdk-sts", 106 | "aws-smithy-async", 107 | "aws-smithy-http", 108 | "aws-smithy-json", 109 | "aws-smithy-runtime", 110 | "aws-smithy-runtime-api", 111 | "aws-smithy-types", 112 | "aws-types", 113 | "bytes", 114 | "fastrand", 115 | "hex", 116 | "http 0.2.12", 117 | "ring", 118 | "time", 119 | "tokio", 120 | "tracing", 121 | "url", 122 | "zeroize", 123 | ] 124 | 125 | [[package]] 126 | name = "aws-credential-types" 127 | version = "1.2.0" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "e16838e6c9e12125face1c1eff1343c75e3ff540de98ff7ebd61874a89bcfeb9" 130 | dependencies = [ 131 | "aws-smithy-async", 132 | "aws-smithy-runtime-api", 133 | "aws-smithy-types", 134 | "zeroize", 135 | ] 136 | 137 | [[package]] 138 | name = "aws-lc-rs" 139 | version = "1.7.0" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "5509d663b2c00ee421bda8d6a24d6c42e15970957de1701b8df9f6fbe5707df1" 142 | dependencies = [ 143 | "aws-lc-sys", 144 | "mirai-annotations", 145 | "paste", 146 | "zeroize", 147 | ] 148 | 149 | [[package]] 150 | name = "aws-lc-sys" 151 | version = "0.15.0" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "8d5d317212c2a78d86ba6622e969413c38847b62f48111f8b763af3dac2f9840" 154 | dependencies = [ 155 | "bindgen", 156 | "cc", 157 | "cmake", 158 | "dunce", 159 | "fs_extra", 160 | "libc", 161 | "paste", 162 | ] 163 | 164 | [[package]] 165 | name = "aws-runtime" 166 | version = "1.4.0" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "f42c2d4218de4dcd890a109461e2f799a1a2ba3bcd2cde9af88360f5df9266c6" 169 | dependencies = [ 170 | "aws-credential-types", 171 | "aws-sigv4", 172 | "aws-smithy-async", 173 | "aws-smithy-eventstream", 174 | "aws-smithy-http", 175 | "aws-smithy-runtime-api", 176 | "aws-smithy-types", 177 | "aws-types", 178 | "bytes", 179 | "fastrand", 180 | "http 0.2.12", 181 | "http-body 0.4.6", 182 | "once_cell", 183 | "percent-encoding", 184 | "pin-project-lite", 185 | "tracing", 186 | "uuid", 187 | ] 188 | 189 | [[package]] 190 | name = "aws-sdk-lambda" 191 | version = "1.42.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "2d6602299f9bf60b45cb38a57cafee59e4356a5127ca289d19a2ef0335bee9ac" 194 | dependencies = [ 195 | "aws-credential-types", 196 | "aws-runtime", 197 | "aws-smithy-async", 198 | "aws-smithy-eventstream", 199 | "aws-smithy-http", 200 | "aws-smithy-json", 201 | "aws-smithy-runtime", 202 | "aws-smithy-runtime-api", 203 | "aws-smithy-types", 204 | "aws-types", 205 | "bytes", 206 | "http 0.2.12", 207 | "once_cell", 208 | "regex-lite", 209 | "tracing", 210 | ] 211 | 212 | [[package]] 213 | name = "aws-sdk-sso" 214 | version = "1.39.0" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "11822090cf501c316c6f75711d77b96fba30658e3867a7762e5e2f5d32d31e81" 217 | dependencies = [ 218 | "aws-credential-types", 219 | "aws-runtime", 220 | "aws-smithy-async", 221 | "aws-smithy-http", 222 | "aws-smithy-json", 223 | "aws-smithy-runtime", 224 | "aws-smithy-runtime-api", 225 | "aws-smithy-types", 226 | "aws-types", 227 | "bytes", 228 | "http 0.2.12", 229 | "once_cell", 230 | "regex-lite", 231 | "tracing", 232 | ] 233 | 234 | [[package]] 235 | name = "aws-sdk-ssooidc" 236 | version = "1.40.0" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | checksum = "78a2a06ff89176123945d1bbe865603c4d7101bea216a550bb4d2e4e9ba74d74" 239 | dependencies = [ 240 | "aws-credential-types", 241 | "aws-runtime", 242 | "aws-smithy-async", 243 | "aws-smithy-http", 244 | "aws-smithy-json", 245 | "aws-smithy-runtime", 246 | "aws-smithy-runtime-api", 247 | "aws-smithy-types", 248 | "aws-types", 249 | "bytes", 250 | "http 0.2.12", 251 | "once_cell", 252 | "regex-lite", 253 | "tracing", 254 | ] 255 | 256 | [[package]] 257 | name = "aws-sdk-sts" 258 | version = "1.39.0" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | checksum = "a20a91795850826a6f456f4a48eff1dfa59a0e69bdbf5b8c50518fd372106574" 261 | dependencies = [ 262 | "aws-credential-types", 263 | "aws-runtime", 264 | "aws-smithy-async", 265 | "aws-smithy-http", 266 | "aws-smithy-json", 267 | "aws-smithy-query", 268 | "aws-smithy-runtime", 269 | "aws-smithy-runtime-api", 270 | "aws-smithy-types", 271 | "aws-smithy-xml", 272 | "aws-types", 273 | "http 0.2.12", 274 | "once_cell", 275 | "regex-lite", 276 | "tracing", 277 | ] 278 | 279 | [[package]] 280 | name = "aws-sigv4" 281 | version = "1.2.3" 282 | source = "registry+https://github.com/rust-lang/crates.io-index" 283 | checksum = "5df1b0fa6be58efe9d4ccc257df0a53b89cd8909e86591a13ca54817c87517be" 284 | dependencies = [ 285 | "aws-credential-types", 286 | "aws-smithy-eventstream", 287 | "aws-smithy-http", 288 | "aws-smithy-runtime-api", 289 | "aws-smithy-types", 290 | "bytes", 291 | "form_urlencoded", 292 | "hex", 293 | "hmac", 294 | "http 0.2.12", 295 | "http 1.1.0", 296 | "once_cell", 297 | "percent-encoding", 298 | "sha2", 299 | "time", 300 | "tracing", 301 | ] 302 | 303 | [[package]] 304 | name = "aws-smithy-async" 305 | version = "1.2.1" 306 | source = "registry+https://github.com/rust-lang/crates.io-index" 307 | checksum = "62220bc6e97f946ddd51b5f1361f78996e704677afc518a4ff66b7a72ea1378c" 308 | dependencies = [ 309 | "futures-util", 310 | "pin-project-lite", 311 | "tokio", 312 | ] 313 | 314 | [[package]] 315 | name = "aws-smithy-eventstream" 316 | version = "0.60.4" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "e6363078f927f612b970edf9d1903ef5cef9a64d1e8423525ebb1f0a1633c858" 319 | dependencies = [ 320 | "aws-smithy-types", 321 | "bytes", 322 | "crc32fast", 323 | ] 324 | 325 | [[package]] 326 | name = "aws-smithy-http" 327 | version = "0.60.9" 328 | source = "registry+https://github.com/rust-lang/crates.io-index" 329 | checksum = "d9cd0ae3d97daa0a2bf377a4d8e8e1362cae590c4a1aad0d40058ebca18eb91e" 330 | dependencies = [ 331 | "aws-smithy-eventstream", 332 | "aws-smithy-runtime-api", 333 | "aws-smithy-types", 334 | "bytes", 335 | "bytes-utils", 336 | "futures-core", 337 | "http 0.2.12", 338 | "http-body 0.4.6", 339 | "once_cell", 340 | "percent-encoding", 341 | "pin-project-lite", 342 | "pin-utils", 343 | "tracing", 344 | ] 345 | 346 | [[package]] 347 | name = "aws-smithy-json" 348 | version = "0.60.7" 349 | source = "registry+https://github.com/rust-lang/crates.io-index" 350 | checksum = "4683df9469ef09468dad3473d129960119a0d3593617542b7d52086c8486f2d6" 351 | dependencies = [ 352 | "aws-smithy-types", 353 | ] 354 | 355 | [[package]] 356 | name = "aws-smithy-query" 357 | version = "0.60.7" 358 | source = "registry+https://github.com/rust-lang/crates.io-index" 359 | checksum = "f2fbd61ceb3fe8a1cb7352e42689cec5335833cd9f94103a61e98f9bb61c64bb" 360 | dependencies = [ 361 | "aws-smithy-types", 362 | "urlencoding", 363 | ] 364 | 365 | [[package]] 366 | name = "aws-smithy-runtime" 367 | version = "1.6.3" 368 | source = "registry+https://github.com/rust-lang/crates.io-index" 369 | checksum = "0abbf454960d0db2ad12684a1640120e7557294b0ff8e2f11236290a1b293225" 370 | dependencies = [ 371 | "aws-smithy-async", 372 | "aws-smithy-http", 373 | "aws-smithy-runtime-api", 374 | "aws-smithy-types", 375 | "bytes", 376 | "fastrand", 377 | "h2", 378 | "http 0.2.12", 379 | "http-body 0.4.6", 380 | "http-body 1.0.0", 381 | "httparse", 382 | "hyper 0.14.28", 383 | "hyper-rustls", 384 | "once_cell", 385 | "pin-project-lite", 386 | "pin-utils", 387 | "rustls 0.21.11", 388 | "tokio", 389 | "tracing", 390 | ] 391 | 392 | [[package]] 393 | name = "aws-smithy-runtime-api" 394 | version = "1.7.2" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "e086682a53d3aa241192aa110fa8dfce98f2f5ac2ead0de84d41582c7e8fdb96" 397 | dependencies = [ 398 | "aws-smithy-async", 399 | "aws-smithy-types", 400 | "bytes", 401 | "http 0.2.12", 402 | "http 1.1.0", 403 | "pin-project-lite", 404 | "tokio", 405 | "tracing", 406 | "zeroize", 407 | ] 408 | 409 | [[package]] 410 | name = "aws-smithy-types" 411 | version = "1.2.2" 412 | source = "registry+https://github.com/rust-lang/crates.io-index" 413 | checksum = "6cee7cadb433c781d3299b916fbf620fea813bf38f49db282fb6858141a05cc8" 414 | dependencies = [ 415 | "base64-simd", 416 | "bytes", 417 | "bytes-utils", 418 | "futures-core", 419 | "http 0.2.12", 420 | "http 1.1.0", 421 | "http-body 0.4.6", 422 | "http-body 1.0.0", 423 | "http-body-util", 424 | "itoa 1.0.11", 425 | "num-integer", 426 | "pin-project-lite", 427 | "pin-utils", 428 | "ryu", 429 | "serde", 430 | "time", 431 | "tokio", 432 | "tokio-util", 433 | ] 434 | 435 | [[package]] 436 | name = "aws-smithy-xml" 437 | version = "0.60.8" 438 | source = "registry+https://github.com/rust-lang/crates.io-index" 439 | checksum = "d123fbc2a4adc3c301652ba8e149bf4bc1d1725affb9784eb20c953ace06bf55" 440 | dependencies = [ 441 | "xmlparser", 442 | ] 443 | 444 | [[package]] 445 | name = "aws-types" 446 | version = "1.3.3" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "5221b91b3e441e6675310829fd8984801b772cb1546ef6c0e54dec9f1ac13fef" 449 | dependencies = [ 450 | "aws-credential-types", 451 | "aws-smithy-async", 452 | "aws-smithy-runtime-api", 453 | "aws-smithy-types", 454 | "rustc_version", 455 | "tracing", 456 | ] 457 | 458 | [[package]] 459 | name = "axum" 460 | version = "0.7.5" 461 | source = "registry+https://github.com/rust-lang/crates.io-index" 462 | checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" 463 | dependencies = [ 464 | "async-trait", 465 | "axum-core", 466 | "bytes", 467 | "futures-util", 468 | "http 1.1.0", 469 | "http-body 1.0.0", 470 | "http-body-util", 471 | "hyper 1.3.1", 472 | "hyper-util", 473 | "itoa 1.0.11", 474 | "matchit", 475 | "memchr", 476 | "mime", 477 | "percent-encoding", 478 | "pin-project-lite", 479 | "rustversion", 480 | "serde", 481 | "serde_json", 482 | "serde_path_to_error", 483 | "serde_urlencoded", 484 | "sync_wrapper 1.0.1", 485 | "tokio", 486 | "tower", 487 | "tower-layer", 488 | "tower-service", 489 | "tracing", 490 | ] 491 | 492 | [[package]] 493 | name = "axum-core" 494 | version = "0.4.3" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" 497 | dependencies = [ 498 | "async-trait", 499 | "bytes", 500 | "futures-util", 501 | "http 1.1.0", 502 | "http-body 1.0.0", 503 | "http-body-util", 504 | "mime", 505 | "pin-project-lite", 506 | "rustversion", 507 | "sync_wrapper 0.1.2", 508 | "tower-layer", 509 | "tower-service", 510 | "tracing", 511 | ] 512 | 513 | [[package]] 514 | name = "backtrace" 515 | version = "0.3.71" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" 518 | dependencies = [ 519 | "addr2line", 520 | "cc", 521 | "cfg-if", 522 | "libc", 523 | "miniz_oxide", 524 | "object", 525 | "rustc-demangle", 526 | ] 527 | 528 | [[package]] 529 | name = "base64" 530 | version = "0.21.7" 531 | source = "registry+https://github.com/rust-lang/crates.io-index" 532 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 533 | 534 | [[package]] 535 | name = "base64" 536 | version = "0.22.0" 537 | source = "registry+https://github.com/rust-lang/crates.io-index" 538 | checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" 539 | 540 | [[package]] 541 | name = "base64-simd" 542 | version = "0.8.0" 543 | source = "registry+https://github.com/rust-lang/crates.io-index" 544 | checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" 545 | dependencies = [ 546 | "outref", 547 | "vsimd", 548 | ] 549 | 550 | [[package]] 551 | name = "bindgen" 552 | version = "0.69.4" 553 | source = "registry+https://github.com/rust-lang/crates.io-index" 554 | checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" 555 | dependencies = [ 556 | "bitflags 2.5.0", 557 | "cexpr", 558 | "clang-sys", 559 | "itertools", 560 | "lazy_static", 561 | "lazycell", 562 | "log", 563 | "prettyplease", 564 | "proc-macro2", 565 | "quote", 566 | "regex", 567 | "rustc-hash", 568 | "shlex", 569 | "syn 2.0.60", 570 | "which", 571 | ] 572 | 573 | [[package]] 574 | name = "bitflags" 575 | version = "1.2.1" 576 | source = "registry+https://github.com/rust-lang/crates.io-index" 577 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 578 | 579 | [[package]] 580 | name = "bitflags" 581 | version = "2.5.0" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" 584 | 585 | [[package]] 586 | name = "block-buffer" 587 | version = "0.10.4" 588 | source = "registry+https://github.com/rust-lang/crates.io-index" 589 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 590 | dependencies = [ 591 | "generic-array", 592 | ] 593 | 594 | [[package]] 595 | name = "bytes" 596 | version = "1.6.0" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" 599 | 600 | [[package]] 601 | name = "bytes-utils" 602 | version = "0.1.4" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" 605 | dependencies = [ 606 | "bytes", 607 | "either", 608 | ] 609 | 610 | [[package]] 611 | name = "cc" 612 | version = "1.0.95" 613 | source = "registry+https://github.com/rust-lang/crates.io-index" 614 | checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b" 615 | dependencies = [ 616 | "jobserver", 617 | "libc", 618 | "once_cell", 619 | ] 620 | 621 | [[package]] 622 | name = "cexpr" 623 | version = "0.6.0" 624 | source = "registry+https://github.com/rust-lang/crates.io-index" 625 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" 626 | dependencies = [ 627 | "nom", 628 | ] 629 | 630 | [[package]] 631 | name = "cfg-if" 632 | version = "1.0.0" 633 | source = "registry+https://github.com/rust-lang/crates.io-index" 634 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 635 | 636 | [[package]] 637 | name = "clang-sys" 638 | version = "1.7.0" 639 | source = "registry+https://github.com/rust-lang/crates.io-index" 640 | checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" 641 | dependencies = [ 642 | "glob", 643 | "libc", 644 | "libloading", 645 | ] 646 | 647 | [[package]] 648 | name = "clap" 649 | version = "4.5.13" 650 | source = "registry+https://github.com/rust-lang/crates.io-index" 651 | checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" 652 | dependencies = [ 653 | "clap_builder", 654 | "clap_derive", 655 | ] 656 | 657 | [[package]] 658 | name = "clap_builder" 659 | version = "4.5.13" 660 | source = "registry+https://github.com/rust-lang/crates.io-index" 661 | checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" 662 | dependencies = [ 663 | "anstream", 664 | "anstyle", 665 | "clap_lex", 666 | "strsim", 667 | ] 668 | 669 | [[package]] 670 | name = "clap_derive" 671 | version = "4.5.13" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" 674 | dependencies = [ 675 | "heck", 676 | "proc-macro2", 677 | "quote", 678 | "syn 2.0.60", 679 | ] 680 | 681 | [[package]] 682 | name = "clap_lex" 683 | version = "0.7.2" 684 | source = "registry+https://github.com/rust-lang/crates.io-index" 685 | checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" 686 | 687 | [[package]] 688 | name = "cmake" 689 | version = "0.1.50" 690 | source = "registry+https://github.com/rust-lang/crates.io-index" 691 | checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" 692 | dependencies = [ 693 | "cc", 694 | ] 695 | 696 | [[package]] 697 | name = "colorchoice" 698 | version = "1.0.2" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" 701 | 702 | [[package]] 703 | name = "core-foundation" 704 | version = "0.9.4" 705 | source = "registry+https://github.com/rust-lang/crates.io-index" 706 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 707 | dependencies = [ 708 | "core-foundation-sys", 709 | "libc", 710 | ] 711 | 712 | [[package]] 713 | name = "core-foundation-sys" 714 | version = "0.8.6" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" 717 | 718 | [[package]] 719 | name = "cpufeatures" 720 | version = "0.2.12" 721 | source = "registry+https://github.com/rust-lang/crates.io-index" 722 | checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" 723 | dependencies = [ 724 | "libc", 725 | ] 726 | 727 | [[package]] 728 | name = "crc32fast" 729 | version = "1.4.0" 730 | source = "registry+https://github.com/rust-lang/crates.io-index" 731 | checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" 732 | dependencies = [ 733 | "cfg-if", 734 | ] 735 | 736 | [[package]] 737 | name = "crypto-common" 738 | version = "0.1.6" 739 | source = "registry+https://github.com/rust-lang/crates.io-index" 740 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 741 | dependencies = [ 742 | "generic-array", 743 | "typenum", 744 | ] 745 | 746 | [[package]] 747 | name = "deranged" 748 | version = "0.3.11" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" 751 | dependencies = [ 752 | "powerfmt", 753 | ] 754 | 755 | [[package]] 756 | name = "digest" 757 | version = "0.10.7" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 760 | dependencies = [ 761 | "block-buffer", 762 | "crypto-common", 763 | "subtle", 764 | ] 765 | 766 | [[package]] 767 | name = "dunce" 768 | version = "1.0.4" 769 | source = "registry+https://github.com/rust-lang/crates.io-index" 770 | checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" 771 | 772 | [[package]] 773 | name = "either" 774 | version = "1.6.1" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 777 | 778 | [[package]] 779 | name = "equivalent" 780 | version = "1.0.1" 781 | source = "registry+https://github.com/rust-lang/crates.io-index" 782 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 783 | 784 | [[package]] 785 | name = "errno" 786 | version = "0.3.8" 787 | source = "registry+https://github.com/rust-lang/crates.io-index" 788 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" 789 | dependencies = [ 790 | "libc", 791 | "windows-sys 0.52.0", 792 | ] 793 | 794 | [[package]] 795 | name = "fastrand" 796 | version = "2.0.2" 797 | source = "registry+https://github.com/rust-lang/crates.io-index" 798 | checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" 799 | 800 | [[package]] 801 | name = "fnv" 802 | version = "1.0.7" 803 | source = "registry+https://github.com/rust-lang/crates.io-index" 804 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 805 | 806 | [[package]] 807 | name = "form_urlencoded" 808 | version = "1.2.1" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 811 | dependencies = [ 812 | "percent-encoding", 813 | ] 814 | 815 | [[package]] 816 | name = "fs_extra" 817 | version = "1.3.0" 818 | source = "registry+https://github.com/rust-lang/crates.io-index" 819 | checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" 820 | 821 | [[package]] 822 | name = "futures" 823 | version = "0.3.14" 824 | source = "registry+https://github.com/rust-lang/crates.io-index" 825 | checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253" 826 | dependencies = [ 827 | "futures-channel", 828 | "futures-core", 829 | "futures-executor", 830 | "futures-io", 831 | "futures-sink", 832 | "futures-task", 833 | "futures-util", 834 | ] 835 | 836 | [[package]] 837 | name = "futures-channel" 838 | version = "0.3.30" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" 841 | dependencies = [ 842 | "futures-core", 843 | "futures-sink", 844 | ] 845 | 846 | [[package]] 847 | name = "futures-core" 848 | version = "0.3.30" 849 | source = "registry+https://github.com/rust-lang/crates.io-index" 850 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 851 | 852 | [[package]] 853 | name = "futures-executor" 854 | version = "0.3.14" 855 | source = "registry+https://github.com/rust-lang/crates.io-index" 856 | checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d" 857 | dependencies = [ 858 | "futures-core", 859 | "futures-task", 860 | "futures-util", 861 | ] 862 | 863 | [[package]] 864 | name = "futures-io" 865 | version = "0.3.30" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" 868 | 869 | [[package]] 870 | name = "futures-macro" 871 | version = "0.3.30" 872 | source = "registry+https://github.com/rust-lang/crates.io-index" 873 | checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" 874 | dependencies = [ 875 | "proc-macro2", 876 | "quote", 877 | "syn 2.0.60", 878 | ] 879 | 880 | [[package]] 881 | name = "futures-sink" 882 | version = "0.3.30" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" 885 | 886 | [[package]] 887 | name = "futures-task" 888 | version = "0.3.30" 889 | source = "registry+https://github.com/rust-lang/crates.io-index" 890 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 891 | 892 | [[package]] 893 | name = "futures-util" 894 | version = "0.3.30" 895 | source = "registry+https://github.com/rust-lang/crates.io-index" 896 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 897 | dependencies = [ 898 | "futures-channel", 899 | "futures-core", 900 | "futures-io", 901 | "futures-macro", 902 | "futures-sink", 903 | "futures-task", 904 | "memchr", 905 | "pin-project-lite", 906 | "pin-utils", 907 | "slab", 908 | ] 909 | 910 | [[package]] 911 | name = "generic-array" 912 | version = "0.14.4" 913 | source = "registry+https://github.com/rust-lang/crates.io-index" 914 | checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" 915 | dependencies = [ 916 | "typenum", 917 | "version_check", 918 | ] 919 | 920 | [[package]] 921 | name = "getrandom" 922 | version = "0.2.14" 923 | source = "registry+https://github.com/rust-lang/crates.io-index" 924 | checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" 925 | dependencies = [ 926 | "cfg-if", 927 | "libc", 928 | "wasi", 929 | ] 930 | 931 | [[package]] 932 | name = "gimli" 933 | version = "0.28.1" 934 | source = "registry+https://github.com/rust-lang/crates.io-index" 935 | checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" 936 | 937 | [[package]] 938 | name = "glob" 939 | version = "0.3.1" 940 | source = "registry+https://github.com/rust-lang/crates.io-index" 941 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" 942 | 943 | [[package]] 944 | name = "h2" 945 | version = "0.3.26" 946 | source = "registry+https://github.com/rust-lang/crates.io-index" 947 | checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" 948 | dependencies = [ 949 | "bytes", 950 | "fnv", 951 | "futures-core", 952 | "futures-sink", 953 | "futures-util", 954 | "http 0.2.12", 955 | "indexmap", 956 | "slab", 957 | "tokio", 958 | "tokio-util", 959 | "tracing", 960 | ] 961 | 962 | [[package]] 963 | name = "hashbrown" 964 | version = "0.14.3" 965 | source = "registry+https://github.com/rust-lang/crates.io-index" 966 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 967 | 968 | [[package]] 969 | name = "heck" 970 | version = "0.5.0" 971 | source = "registry+https://github.com/rust-lang/crates.io-index" 972 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 973 | 974 | [[package]] 975 | name = "hermit-abi" 976 | version = "0.3.9" 977 | source = "registry+https://github.com/rust-lang/crates.io-index" 978 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 979 | 980 | [[package]] 981 | name = "hex" 982 | version = "0.4.3" 983 | source = "registry+https://github.com/rust-lang/crates.io-index" 984 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 985 | 986 | [[package]] 987 | name = "hmac" 988 | version = "0.12.1" 989 | source = "registry+https://github.com/rust-lang/crates.io-index" 990 | checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 991 | dependencies = [ 992 | "digest", 993 | ] 994 | 995 | [[package]] 996 | name = "home" 997 | version = "0.5.9" 998 | source = "registry+https://github.com/rust-lang/crates.io-index" 999 | checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" 1000 | dependencies = [ 1001 | "windows-sys 0.52.0", 1002 | ] 1003 | 1004 | [[package]] 1005 | name = "http" 1006 | version = "0.2.12" 1007 | source = "registry+https://github.com/rust-lang/crates.io-index" 1008 | checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" 1009 | dependencies = [ 1010 | "bytes", 1011 | "fnv", 1012 | "itoa 1.0.11", 1013 | ] 1014 | 1015 | [[package]] 1016 | name = "http" 1017 | version = "1.1.0" 1018 | source = "registry+https://github.com/rust-lang/crates.io-index" 1019 | checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" 1020 | dependencies = [ 1021 | "bytes", 1022 | "fnv", 1023 | "itoa 1.0.11", 1024 | ] 1025 | 1026 | [[package]] 1027 | name = "http-body" 1028 | version = "0.4.6" 1029 | source = "registry+https://github.com/rust-lang/crates.io-index" 1030 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" 1031 | dependencies = [ 1032 | "bytes", 1033 | "http 0.2.12", 1034 | "pin-project-lite", 1035 | ] 1036 | 1037 | [[package]] 1038 | name = "http-body" 1039 | version = "1.0.0" 1040 | source = "registry+https://github.com/rust-lang/crates.io-index" 1041 | checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" 1042 | dependencies = [ 1043 | "bytes", 1044 | "http 1.1.0", 1045 | ] 1046 | 1047 | [[package]] 1048 | name = "http-body-util" 1049 | version = "0.1.1" 1050 | source = "registry+https://github.com/rust-lang/crates.io-index" 1051 | checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" 1052 | dependencies = [ 1053 | "bytes", 1054 | "futures-core", 1055 | "http 1.1.0", 1056 | "http-body 1.0.0", 1057 | "pin-project-lite", 1058 | ] 1059 | 1060 | [[package]] 1061 | name = "http-serde" 1062 | version = "2.1.1" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | checksum = "0f056c8559e3757392c8d091e796416e4649d8e49e88b8d76df6c002f05027fd" 1065 | dependencies = [ 1066 | "http 1.1.0", 1067 | "serde", 1068 | ] 1069 | 1070 | [[package]] 1071 | name = "httparse" 1072 | version = "1.8.0" 1073 | source = "registry+https://github.com/rust-lang/crates.io-index" 1074 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 1075 | 1076 | [[package]] 1077 | name = "httpdate" 1078 | version = "1.0.3" 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" 1080 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 1081 | 1082 | [[package]] 1083 | name = "hyper" 1084 | version = "0.14.28" 1085 | source = "registry+https://github.com/rust-lang/crates.io-index" 1086 | checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" 1087 | dependencies = [ 1088 | "bytes", 1089 | "futures-channel", 1090 | "futures-core", 1091 | "futures-util", 1092 | "h2", 1093 | "http 0.2.12", 1094 | "http-body 0.4.6", 1095 | "httparse", 1096 | "httpdate", 1097 | "itoa 1.0.11", 1098 | "pin-project-lite", 1099 | "socket2", 1100 | "tokio", 1101 | "tower-service", 1102 | "tracing", 1103 | "want", 1104 | ] 1105 | 1106 | [[package]] 1107 | name = "hyper" 1108 | version = "1.3.1" 1109 | source = "registry+https://github.com/rust-lang/crates.io-index" 1110 | checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" 1111 | dependencies = [ 1112 | "bytes", 1113 | "futures-channel", 1114 | "futures-util", 1115 | "http 1.1.0", 1116 | "http-body 1.0.0", 1117 | "httparse", 1118 | "httpdate", 1119 | "itoa 1.0.11", 1120 | "pin-project-lite", 1121 | "smallvec", 1122 | "tokio", 1123 | ] 1124 | 1125 | [[package]] 1126 | name = "hyper-rustls" 1127 | version = "0.24.2" 1128 | source = "registry+https://github.com/rust-lang/crates.io-index" 1129 | checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" 1130 | dependencies = [ 1131 | "futures-util", 1132 | "http 0.2.12", 1133 | "hyper 0.14.28", 1134 | "log", 1135 | "rustls 0.21.11", 1136 | "rustls-native-certs", 1137 | "tokio", 1138 | "tokio-rustls", 1139 | ] 1140 | 1141 | [[package]] 1142 | name = "hyper-util" 1143 | version = "0.1.3" 1144 | source = "registry+https://github.com/rust-lang/crates.io-index" 1145 | checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" 1146 | dependencies = [ 1147 | "bytes", 1148 | "futures-util", 1149 | "http 1.1.0", 1150 | "http-body 1.0.0", 1151 | "hyper 1.3.1", 1152 | "pin-project-lite", 1153 | "socket2", 1154 | "tokio", 1155 | ] 1156 | 1157 | [[package]] 1158 | name = "idna" 1159 | version = "0.5.0" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" 1162 | dependencies = [ 1163 | "unicode-bidi", 1164 | "unicode-normalization", 1165 | ] 1166 | 1167 | [[package]] 1168 | name = "indexmap" 1169 | version = "2.2.6" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" 1172 | dependencies = [ 1173 | "equivalent", 1174 | "hashbrown", 1175 | ] 1176 | 1177 | [[package]] 1178 | name = "is_terminal_polyfill" 1179 | version = "1.70.1" 1180 | source = "registry+https://github.com/rust-lang/crates.io-index" 1181 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 1182 | 1183 | [[package]] 1184 | name = "itertools" 1185 | version = "0.12.1" 1186 | source = "registry+https://github.com/rust-lang/crates.io-index" 1187 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 1188 | dependencies = [ 1189 | "either", 1190 | ] 1191 | 1192 | [[package]] 1193 | name = "itoa" 1194 | version = "0.4.7" 1195 | source = "registry+https://github.com/rust-lang/crates.io-index" 1196 | checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" 1197 | 1198 | [[package]] 1199 | name = "itoa" 1200 | version = "1.0.11" 1201 | source = "registry+https://github.com/rust-lang/crates.io-index" 1202 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 1203 | 1204 | [[package]] 1205 | name = "jobserver" 1206 | version = "0.1.30" 1207 | source = "registry+https://github.com/rust-lang/crates.io-index" 1208 | checksum = "685a7d121ee3f65ae4fddd72b25a04bb36b6af81bc0828f7d5434c0fe60fa3a2" 1209 | dependencies = [ 1210 | "libc", 1211 | ] 1212 | 1213 | [[package]] 1214 | name = "lambda-web-gateway" 1215 | version = "0.1.0" 1216 | dependencies = [ 1217 | "aws-config", 1218 | "aws-sdk-lambda", 1219 | "aws-smithy-types", 1220 | "axum", 1221 | "base64 0.22.0", 1222 | "bytes", 1223 | "clap", 1224 | "futures", 1225 | "futures-util", 1226 | "http-serde", 1227 | "log", 1228 | "rustls 0.23.5", 1229 | "serde", 1230 | "serde_json", 1231 | "serde_yaml", 1232 | "tempfile", 1233 | "tokio", 1234 | "tokio-stream", 1235 | "tower-http", 1236 | "tracing", 1237 | "tracing-subscriber", 1238 | "url", 1239 | ] 1240 | 1241 | [[package]] 1242 | name = "lazy_static" 1243 | version = "1.4.0" 1244 | source = "registry+https://github.com/rust-lang/crates.io-index" 1245 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1246 | 1247 | [[package]] 1248 | name = "lazycell" 1249 | version = "1.3.0" 1250 | source = "registry+https://github.com/rust-lang/crates.io-index" 1251 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 1252 | 1253 | [[package]] 1254 | name = "libc" 1255 | version = "0.2.153" 1256 | source = "registry+https://github.com/rust-lang/crates.io-index" 1257 | checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" 1258 | 1259 | [[package]] 1260 | name = "libloading" 1261 | version = "0.8.3" 1262 | source = "registry+https://github.com/rust-lang/crates.io-index" 1263 | checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" 1264 | dependencies = [ 1265 | "cfg-if", 1266 | "windows-targets 0.52.6", 1267 | ] 1268 | 1269 | [[package]] 1270 | name = "linux-raw-sys" 1271 | version = "0.4.13" 1272 | source = "registry+https://github.com/rust-lang/crates.io-index" 1273 | checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" 1274 | 1275 | [[package]] 1276 | name = "lock_api" 1277 | version = "0.4.11" 1278 | source = "registry+https://github.com/rust-lang/crates.io-index" 1279 | checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" 1280 | dependencies = [ 1281 | "autocfg", 1282 | "scopeguard", 1283 | ] 1284 | 1285 | [[package]] 1286 | name = "log" 1287 | version = "0.4.21" 1288 | source = "registry+https://github.com/rust-lang/crates.io-index" 1289 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 1290 | 1291 | [[package]] 1292 | name = "matchit" 1293 | version = "0.7.3" 1294 | source = "registry+https://github.com/rust-lang/crates.io-index" 1295 | checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" 1296 | 1297 | [[package]] 1298 | name = "memchr" 1299 | version = "2.7.2" 1300 | source = "registry+https://github.com/rust-lang/crates.io-index" 1301 | checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" 1302 | 1303 | [[package]] 1304 | name = "mime" 1305 | version = "0.3.16" 1306 | source = "registry+https://github.com/rust-lang/crates.io-index" 1307 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 1308 | 1309 | [[package]] 1310 | name = "minimal-lexical" 1311 | version = "0.2.1" 1312 | source = "registry+https://github.com/rust-lang/crates.io-index" 1313 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 1314 | 1315 | [[package]] 1316 | name = "miniz_oxide" 1317 | version = "0.7.2" 1318 | source = "registry+https://github.com/rust-lang/crates.io-index" 1319 | checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" 1320 | dependencies = [ 1321 | "adler", 1322 | ] 1323 | 1324 | [[package]] 1325 | name = "mio" 1326 | version = "1.0.2" 1327 | source = "registry+https://github.com/rust-lang/crates.io-index" 1328 | checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" 1329 | dependencies = [ 1330 | "hermit-abi", 1331 | "libc", 1332 | "wasi", 1333 | "windows-sys 0.52.0", 1334 | ] 1335 | 1336 | [[package]] 1337 | name = "mirai-annotations" 1338 | version = "1.12.0" 1339 | source = "registry+https://github.com/rust-lang/crates.io-index" 1340 | checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" 1341 | 1342 | [[package]] 1343 | name = "nom" 1344 | version = "7.1.3" 1345 | source = "registry+https://github.com/rust-lang/crates.io-index" 1346 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 1347 | dependencies = [ 1348 | "memchr", 1349 | "minimal-lexical", 1350 | ] 1351 | 1352 | [[package]] 1353 | name = "nu-ansi-term" 1354 | version = "0.46.0" 1355 | source = "registry+https://github.com/rust-lang/crates.io-index" 1356 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 1357 | dependencies = [ 1358 | "overload", 1359 | "winapi", 1360 | ] 1361 | 1362 | [[package]] 1363 | name = "num-conv" 1364 | version = "0.1.0" 1365 | source = "registry+https://github.com/rust-lang/crates.io-index" 1366 | checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 1367 | 1368 | [[package]] 1369 | name = "num-integer" 1370 | version = "0.1.46" 1371 | source = "registry+https://github.com/rust-lang/crates.io-index" 1372 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 1373 | dependencies = [ 1374 | "num-traits", 1375 | ] 1376 | 1377 | [[package]] 1378 | name = "num-traits" 1379 | version = "0.2.18" 1380 | source = "registry+https://github.com/rust-lang/crates.io-index" 1381 | checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" 1382 | dependencies = [ 1383 | "autocfg", 1384 | ] 1385 | 1386 | [[package]] 1387 | name = "object" 1388 | version = "0.32.2" 1389 | source = "registry+https://github.com/rust-lang/crates.io-index" 1390 | checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" 1391 | dependencies = [ 1392 | "memchr", 1393 | ] 1394 | 1395 | [[package]] 1396 | name = "once_cell" 1397 | version = "1.19.0" 1398 | source = "registry+https://github.com/rust-lang/crates.io-index" 1399 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 1400 | 1401 | [[package]] 1402 | name = "openssl-probe" 1403 | version = "0.1.5" 1404 | source = "registry+https://github.com/rust-lang/crates.io-index" 1405 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 1406 | 1407 | [[package]] 1408 | name = "outref" 1409 | version = "0.5.1" 1410 | source = "registry+https://github.com/rust-lang/crates.io-index" 1411 | checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a" 1412 | 1413 | [[package]] 1414 | name = "overload" 1415 | version = "0.1.1" 1416 | source = "registry+https://github.com/rust-lang/crates.io-index" 1417 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 1418 | 1419 | [[package]] 1420 | name = "parking_lot" 1421 | version = "0.12.1" 1422 | source = "registry+https://github.com/rust-lang/crates.io-index" 1423 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 1424 | dependencies = [ 1425 | "lock_api", 1426 | "parking_lot_core", 1427 | ] 1428 | 1429 | [[package]] 1430 | name = "parking_lot_core" 1431 | version = "0.9.9" 1432 | source = "registry+https://github.com/rust-lang/crates.io-index" 1433 | checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" 1434 | dependencies = [ 1435 | "cfg-if", 1436 | "libc", 1437 | "redox_syscall", 1438 | "smallvec", 1439 | "windows-targets 0.48.5", 1440 | ] 1441 | 1442 | [[package]] 1443 | name = "paste" 1444 | version = "1.0.14" 1445 | source = "registry+https://github.com/rust-lang/crates.io-index" 1446 | checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" 1447 | 1448 | [[package]] 1449 | name = "percent-encoding" 1450 | version = "2.3.1" 1451 | source = "registry+https://github.com/rust-lang/crates.io-index" 1452 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1453 | 1454 | [[package]] 1455 | name = "pin-project" 1456 | version = "1.0.7" 1457 | source = "registry+https://github.com/rust-lang/crates.io-index" 1458 | checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4" 1459 | dependencies = [ 1460 | "pin-project-internal", 1461 | ] 1462 | 1463 | [[package]] 1464 | name = "pin-project-internal" 1465 | version = "1.0.7" 1466 | source = "registry+https://github.com/rust-lang/crates.io-index" 1467 | checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f" 1468 | dependencies = [ 1469 | "proc-macro2", 1470 | "quote", 1471 | "syn 1.0.72", 1472 | ] 1473 | 1474 | [[package]] 1475 | name = "pin-project-lite" 1476 | version = "0.2.14" 1477 | source = "registry+https://github.com/rust-lang/crates.io-index" 1478 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 1479 | 1480 | [[package]] 1481 | name = "pin-utils" 1482 | version = "0.1.0" 1483 | source = "registry+https://github.com/rust-lang/crates.io-index" 1484 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1485 | 1486 | [[package]] 1487 | name = "powerfmt" 1488 | version = "0.2.0" 1489 | source = "registry+https://github.com/rust-lang/crates.io-index" 1490 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 1491 | 1492 | [[package]] 1493 | name = "prettyplease" 1494 | version = "0.2.19" 1495 | source = "registry+https://github.com/rust-lang/crates.io-index" 1496 | checksum = "5ac2cf0f2e4f42b49f5ffd07dae8d746508ef7526c13940e5f524012ae6c6550" 1497 | dependencies = [ 1498 | "proc-macro2", 1499 | "syn 2.0.60", 1500 | ] 1501 | 1502 | [[package]] 1503 | name = "proc-macro2" 1504 | version = "1.0.81" 1505 | source = "registry+https://github.com/rust-lang/crates.io-index" 1506 | checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" 1507 | dependencies = [ 1508 | "unicode-ident", 1509 | ] 1510 | 1511 | [[package]] 1512 | name = "quote" 1513 | version = "1.0.36" 1514 | source = "registry+https://github.com/rust-lang/crates.io-index" 1515 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" 1516 | dependencies = [ 1517 | "proc-macro2", 1518 | ] 1519 | 1520 | [[package]] 1521 | name = "redox_syscall" 1522 | version = "0.4.1" 1523 | source = "registry+https://github.com/rust-lang/crates.io-index" 1524 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 1525 | dependencies = [ 1526 | "bitflags 1.2.1", 1527 | ] 1528 | 1529 | [[package]] 1530 | name = "regex" 1531 | version = "1.10.6" 1532 | source = "registry+https://github.com/rust-lang/crates.io-index" 1533 | checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" 1534 | dependencies = [ 1535 | "aho-corasick", 1536 | "memchr", 1537 | "regex-automata", 1538 | "regex-syntax", 1539 | ] 1540 | 1541 | [[package]] 1542 | name = "regex-automata" 1543 | version = "0.4.7" 1544 | source = "registry+https://github.com/rust-lang/crates.io-index" 1545 | checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" 1546 | dependencies = [ 1547 | "aho-corasick", 1548 | "memchr", 1549 | "regex-syntax", 1550 | ] 1551 | 1552 | [[package]] 1553 | name = "regex-lite" 1554 | version = "0.1.5" 1555 | source = "registry+https://github.com/rust-lang/crates.io-index" 1556 | checksum = "30b661b2f27137bdbc16f00eda72866a92bb28af1753ffbd56744fb6e2e9cd8e" 1557 | 1558 | [[package]] 1559 | name = "regex-syntax" 1560 | version = "0.8.4" 1561 | source = "registry+https://github.com/rust-lang/crates.io-index" 1562 | checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" 1563 | 1564 | [[package]] 1565 | name = "ring" 1566 | version = "0.17.8" 1567 | source = "registry+https://github.com/rust-lang/crates.io-index" 1568 | checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" 1569 | dependencies = [ 1570 | "cc", 1571 | "cfg-if", 1572 | "getrandom", 1573 | "libc", 1574 | "spin", 1575 | "untrusted", 1576 | "windows-sys 0.52.0", 1577 | ] 1578 | 1579 | [[package]] 1580 | name = "rustc-demangle" 1581 | version = "0.1.23" 1582 | source = "registry+https://github.com/rust-lang/crates.io-index" 1583 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 1584 | 1585 | [[package]] 1586 | name = "rustc-hash" 1587 | version = "1.1.0" 1588 | source = "registry+https://github.com/rust-lang/crates.io-index" 1589 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 1590 | 1591 | [[package]] 1592 | name = "rustc_version" 1593 | version = "0.4.0" 1594 | source = "registry+https://github.com/rust-lang/crates.io-index" 1595 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 1596 | dependencies = [ 1597 | "semver", 1598 | ] 1599 | 1600 | [[package]] 1601 | name = "rustix" 1602 | version = "0.38.33" 1603 | source = "registry+https://github.com/rust-lang/crates.io-index" 1604 | checksum = "e3cc72858054fcff6d7dea32df2aeaee6a7c24227366d7ea429aada2f26b16ad" 1605 | dependencies = [ 1606 | "bitflags 2.5.0", 1607 | "errno", 1608 | "libc", 1609 | "linux-raw-sys", 1610 | "windows-sys 0.52.0", 1611 | ] 1612 | 1613 | [[package]] 1614 | name = "rustls" 1615 | version = "0.21.11" 1616 | source = "registry+https://github.com/rust-lang/crates.io-index" 1617 | checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" 1618 | dependencies = [ 1619 | "log", 1620 | "ring", 1621 | "rustls-webpki 0.101.7", 1622 | "sct", 1623 | ] 1624 | 1625 | [[package]] 1626 | name = "rustls" 1627 | version = "0.23.5" 1628 | source = "registry+https://github.com/rust-lang/crates.io-index" 1629 | checksum = "afabcee0551bd1aa3e18e5adbf2c0544722014b899adb31bd186ec638d3da97e" 1630 | dependencies = [ 1631 | "aws-lc-rs", 1632 | "log", 1633 | "once_cell", 1634 | "rustls-pki-types", 1635 | "rustls-webpki 0.102.3", 1636 | "subtle", 1637 | "zeroize", 1638 | ] 1639 | 1640 | [[package]] 1641 | name = "rustls-native-certs" 1642 | version = "0.6.3" 1643 | source = "registry+https://github.com/rust-lang/crates.io-index" 1644 | checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" 1645 | dependencies = [ 1646 | "openssl-probe", 1647 | "rustls-pemfile", 1648 | "schannel", 1649 | "security-framework", 1650 | ] 1651 | 1652 | [[package]] 1653 | name = "rustls-pemfile" 1654 | version = "1.0.4" 1655 | source = "registry+https://github.com/rust-lang/crates.io-index" 1656 | checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" 1657 | dependencies = [ 1658 | "base64 0.21.7", 1659 | ] 1660 | 1661 | [[package]] 1662 | name = "rustls-pki-types" 1663 | version = "1.4.1" 1664 | source = "registry+https://github.com/rust-lang/crates.io-index" 1665 | checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" 1666 | 1667 | [[package]] 1668 | name = "rustls-webpki" 1669 | version = "0.101.7" 1670 | source = "registry+https://github.com/rust-lang/crates.io-index" 1671 | checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" 1672 | dependencies = [ 1673 | "ring", 1674 | "untrusted", 1675 | ] 1676 | 1677 | [[package]] 1678 | name = "rustls-webpki" 1679 | version = "0.102.3" 1680 | source = "registry+https://github.com/rust-lang/crates.io-index" 1681 | checksum = "f3bce581c0dd41bce533ce695a1437fa16a7ab5ac3ccfa99fe1a620a7885eabf" 1682 | dependencies = [ 1683 | "aws-lc-rs", 1684 | "ring", 1685 | "rustls-pki-types", 1686 | "untrusted", 1687 | ] 1688 | 1689 | [[package]] 1690 | name = "rustversion" 1691 | version = "1.0.15" 1692 | source = "registry+https://github.com/rust-lang/crates.io-index" 1693 | checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" 1694 | 1695 | [[package]] 1696 | name = "ryu" 1697 | version = "1.0.5" 1698 | source = "registry+https://github.com/rust-lang/crates.io-index" 1699 | checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 1700 | 1701 | [[package]] 1702 | name = "schannel" 1703 | version = "0.1.23" 1704 | source = "registry+https://github.com/rust-lang/crates.io-index" 1705 | checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" 1706 | dependencies = [ 1707 | "windows-sys 0.52.0", 1708 | ] 1709 | 1710 | [[package]] 1711 | name = "scopeguard" 1712 | version = "1.1.0" 1713 | source = "registry+https://github.com/rust-lang/crates.io-index" 1714 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1715 | 1716 | [[package]] 1717 | name = "sct" 1718 | version = "0.7.1" 1719 | source = "registry+https://github.com/rust-lang/crates.io-index" 1720 | checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" 1721 | dependencies = [ 1722 | "ring", 1723 | "untrusted", 1724 | ] 1725 | 1726 | [[package]] 1727 | name = "security-framework" 1728 | version = "2.3.1" 1729 | source = "registry+https://github.com/rust-lang/crates.io-index" 1730 | checksum = "23a2ac85147a3a11d77ecf1bc7166ec0b92febfa4461c37944e180f319ece467" 1731 | dependencies = [ 1732 | "bitflags 1.2.1", 1733 | "core-foundation", 1734 | "core-foundation-sys", 1735 | "libc", 1736 | "security-framework-sys", 1737 | ] 1738 | 1739 | [[package]] 1740 | name = "security-framework-sys" 1741 | version = "2.10.0" 1742 | source = "registry+https://github.com/rust-lang/crates.io-index" 1743 | checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" 1744 | dependencies = [ 1745 | "core-foundation-sys", 1746 | "libc", 1747 | ] 1748 | 1749 | [[package]] 1750 | name = "semver" 1751 | version = "1.0.22" 1752 | source = "registry+https://github.com/rust-lang/crates.io-index" 1753 | checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" 1754 | 1755 | [[package]] 1756 | name = "serde" 1757 | version = "1.0.209" 1758 | source = "registry+https://github.com/rust-lang/crates.io-index" 1759 | checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" 1760 | dependencies = [ 1761 | "serde_derive", 1762 | ] 1763 | 1764 | [[package]] 1765 | name = "serde_derive" 1766 | version = "1.0.209" 1767 | source = "registry+https://github.com/rust-lang/crates.io-index" 1768 | checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" 1769 | dependencies = [ 1770 | "proc-macro2", 1771 | "quote", 1772 | "syn 2.0.60", 1773 | ] 1774 | 1775 | [[package]] 1776 | name = "serde_json" 1777 | version = "1.0.116" 1778 | source = "registry+https://github.com/rust-lang/crates.io-index" 1779 | checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" 1780 | dependencies = [ 1781 | "itoa 1.0.11", 1782 | "ryu", 1783 | "serde", 1784 | ] 1785 | 1786 | [[package]] 1787 | name = "serde_path_to_error" 1788 | version = "0.1.16" 1789 | source = "registry+https://github.com/rust-lang/crates.io-index" 1790 | checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" 1791 | dependencies = [ 1792 | "itoa 1.0.11", 1793 | "serde", 1794 | ] 1795 | 1796 | [[package]] 1797 | name = "serde_urlencoded" 1798 | version = "0.7.0" 1799 | source = "registry+https://github.com/rust-lang/crates.io-index" 1800 | checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" 1801 | dependencies = [ 1802 | "form_urlencoded", 1803 | "itoa 0.4.7", 1804 | "ryu", 1805 | "serde", 1806 | ] 1807 | 1808 | [[package]] 1809 | name = "serde_yaml" 1810 | version = "0.9.34+deprecated" 1811 | source = "registry+https://github.com/rust-lang/crates.io-index" 1812 | checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" 1813 | dependencies = [ 1814 | "indexmap", 1815 | "itoa 1.0.11", 1816 | "ryu", 1817 | "serde", 1818 | "unsafe-libyaml", 1819 | ] 1820 | 1821 | [[package]] 1822 | name = "sha2" 1823 | version = "0.10.8" 1824 | source = "registry+https://github.com/rust-lang/crates.io-index" 1825 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 1826 | dependencies = [ 1827 | "cfg-if", 1828 | "cpufeatures", 1829 | "digest", 1830 | ] 1831 | 1832 | [[package]] 1833 | name = "sharded-slab" 1834 | version = "0.1.7" 1835 | source = "registry+https://github.com/rust-lang/crates.io-index" 1836 | checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" 1837 | dependencies = [ 1838 | "lazy_static", 1839 | ] 1840 | 1841 | [[package]] 1842 | name = "shlex" 1843 | version = "1.3.0" 1844 | source = "registry+https://github.com/rust-lang/crates.io-index" 1845 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1846 | 1847 | [[package]] 1848 | name = "signal-hook-registry" 1849 | version = "1.3.0" 1850 | source = "registry+https://github.com/rust-lang/crates.io-index" 1851 | checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" 1852 | dependencies = [ 1853 | "libc", 1854 | ] 1855 | 1856 | [[package]] 1857 | name = "slab" 1858 | version = "0.4.3" 1859 | source = "registry+https://github.com/rust-lang/crates.io-index" 1860 | checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" 1861 | 1862 | [[package]] 1863 | name = "smallvec" 1864 | version = "1.13.2" 1865 | source = "registry+https://github.com/rust-lang/crates.io-index" 1866 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1867 | 1868 | [[package]] 1869 | name = "socket2" 1870 | version = "0.5.6" 1871 | source = "registry+https://github.com/rust-lang/crates.io-index" 1872 | checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" 1873 | dependencies = [ 1874 | "libc", 1875 | "windows-sys 0.52.0", 1876 | ] 1877 | 1878 | [[package]] 1879 | name = "spin" 1880 | version = "0.9.8" 1881 | source = "registry+https://github.com/rust-lang/crates.io-index" 1882 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1883 | 1884 | [[package]] 1885 | name = "strsim" 1886 | version = "0.11.1" 1887 | source = "registry+https://github.com/rust-lang/crates.io-index" 1888 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1889 | 1890 | [[package]] 1891 | name = "subtle" 1892 | version = "2.5.0" 1893 | source = "registry+https://github.com/rust-lang/crates.io-index" 1894 | checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" 1895 | 1896 | [[package]] 1897 | name = "syn" 1898 | version = "1.0.72" 1899 | source = "registry+https://github.com/rust-lang/crates.io-index" 1900 | checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" 1901 | dependencies = [ 1902 | "proc-macro2", 1903 | "quote", 1904 | "unicode-xid", 1905 | ] 1906 | 1907 | [[package]] 1908 | name = "syn" 1909 | version = "2.0.60" 1910 | source = "registry+https://github.com/rust-lang/crates.io-index" 1911 | checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" 1912 | dependencies = [ 1913 | "proc-macro2", 1914 | "quote", 1915 | "unicode-ident", 1916 | ] 1917 | 1918 | [[package]] 1919 | name = "sync_wrapper" 1920 | version = "0.1.2" 1921 | source = "registry+https://github.com/rust-lang/crates.io-index" 1922 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 1923 | 1924 | [[package]] 1925 | name = "sync_wrapper" 1926 | version = "1.0.1" 1927 | source = "registry+https://github.com/rust-lang/crates.io-index" 1928 | checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" 1929 | 1930 | [[package]] 1931 | name = "tempfile" 1932 | version = "3.12.0" 1933 | source = "registry+https://github.com/rust-lang/crates.io-index" 1934 | checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" 1935 | dependencies = [ 1936 | "cfg-if", 1937 | "fastrand", 1938 | "once_cell", 1939 | "rustix", 1940 | "windows-sys 0.59.0", 1941 | ] 1942 | 1943 | [[package]] 1944 | name = "thread_local" 1945 | version = "1.1.8" 1946 | source = "registry+https://github.com/rust-lang/crates.io-index" 1947 | checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" 1948 | dependencies = [ 1949 | "cfg-if", 1950 | "once_cell", 1951 | ] 1952 | 1953 | [[package]] 1954 | name = "time" 1955 | version = "0.3.36" 1956 | source = "registry+https://github.com/rust-lang/crates.io-index" 1957 | checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" 1958 | dependencies = [ 1959 | "deranged", 1960 | "num-conv", 1961 | "powerfmt", 1962 | "serde", 1963 | "time-core", 1964 | "time-macros", 1965 | ] 1966 | 1967 | [[package]] 1968 | name = "time-core" 1969 | version = "0.1.2" 1970 | source = "registry+https://github.com/rust-lang/crates.io-index" 1971 | checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" 1972 | 1973 | [[package]] 1974 | name = "time-macros" 1975 | version = "0.2.18" 1976 | source = "registry+https://github.com/rust-lang/crates.io-index" 1977 | checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" 1978 | dependencies = [ 1979 | "num-conv", 1980 | "time-core", 1981 | ] 1982 | 1983 | [[package]] 1984 | name = "tinyvec" 1985 | version = "1.2.0" 1986 | source = "registry+https://github.com/rust-lang/crates.io-index" 1987 | checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342" 1988 | dependencies = [ 1989 | "tinyvec_macros", 1990 | ] 1991 | 1992 | [[package]] 1993 | name = "tinyvec_macros" 1994 | version = "0.1.0" 1995 | source = "registry+https://github.com/rust-lang/crates.io-index" 1996 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 1997 | 1998 | [[package]] 1999 | name = "tokio" 2000 | version = "1.39.3" 2001 | source = "registry+https://github.com/rust-lang/crates.io-index" 2002 | checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" 2003 | dependencies = [ 2004 | "backtrace", 2005 | "bytes", 2006 | "libc", 2007 | "mio", 2008 | "parking_lot", 2009 | "pin-project-lite", 2010 | "signal-hook-registry", 2011 | "socket2", 2012 | "tokio-macros", 2013 | "windows-sys 0.52.0", 2014 | ] 2015 | 2016 | [[package]] 2017 | name = "tokio-macros" 2018 | version = "2.4.0" 2019 | source = "registry+https://github.com/rust-lang/crates.io-index" 2020 | checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" 2021 | dependencies = [ 2022 | "proc-macro2", 2023 | "quote", 2024 | "syn 2.0.60", 2025 | ] 2026 | 2027 | [[package]] 2028 | name = "tokio-rustls" 2029 | version = "0.24.1" 2030 | source = "registry+https://github.com/rust-lang/crates.io-index" 2031 | checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" 2032 | dependencies = [ 2033 | "rustls 0.21.11", 2034 | "tokio", 2035 | ] 2036 | 2037 | [[package]] 2038 | name = "tokio-stream" 2039 | version = "0.1.15" 2040 | source = "registry+https://github.com/rust-lang/crates.io-index" 2041 | checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" 2042 | dependencies = [ 2043 | "futures-core", 2044 | "pin-project-lite", 2045 | "tokio", 2046 | ] 2047 | 2048 | [[package]] 2049 | name = "tokio-util" 2050 | version = "0.7.10" 2051 | source = "registry+https://github.com/rust-lang/crates.io-index" 2052 | checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" 2053 | dependencies = [ 2054 | "bytes", 2055 | "futures-core", 2056 | "futures-sink", 2057 | "pin-project-lite", 2058 | "tokio", 2059 | "tracing", 2060 | ] 2061 | 2062 | [[package]] 2063 | name = "tower" 2064 | version = "0.4.13" 2065 | source = "registry+https://github.com/rust-lang/crates.io-index" 2066 | checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" 2067 | dependencies = [ 2068 | "futures-core", 2069 | "futures-util", 2070 | "pin-project", 2071 | "pin-project-lite", 2072 | "tokio", 2073 | "tower-layer", 2074 | "tower-service", 2075 | "tracing", 2076 | ] 2077 | 2078 | [[package]] 2079 | name = "tower-http" 2080 | version = "0.5.2" 2081 | source = "registry+https://github.com/rust-lang/crates.io-index" 2082 | checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" 2083 | dependencies = [ 2084 | "bitflags 2.5.0", 2085 | "bytes", 2086 | "http 1.1.0", 2087 | "http-body 1.0.0", 2088 | "http-body-util", 2089 | "pin-project-lite", 2090 | "tower-layer", 2091 | "tower-service", 2092 | "tracing", 2093 | ] 2094 | 2095 | [[package]] 2096 | name = "tower-layer" 2097 | version = "0.3.2" 2098 | source = "registry+https://github.com/rust-lang/crates.io-index" 2099 | checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" 2100 | 2101 | [[package]] 2102 | name = "tower-service" 2103 | version = "0.3.2" 2104 | source = "registry+https://github.com/rust-lang/crates.io-index" 2105 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 2106 | 2107 | [[package]] 2108 | name = "tracing" 2109 | version = "0.1.40" 2110 | source = "registry+https://github.com/rust-lang/crates.io-index" 2111 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 2112 | dependencies = [ 2113 | "log", 2114 | "pin-project-lite", 2115 | "tracing-attributes", 2116 | "tracing-core", 2117 | ] 2118 | 2119 | [[package]] 2120 | name = "tracing-attributes" 2121 | version = "0.1.27" 2122 | source = "registry+https://github.com/rust-lang/crates.io-index" 2123 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" 2124 | dependencies = [ 2125 | "proc-macro2", 2126 | "quote", 2127 | "syn 2.0.60", 2128 | ] 2129 | 2130 | [[package]] 2131 | name = "tracing-core" 2132 | version = "0.1.32" 2133 | source = "registry+https://github.com/rust-lang/crates.io-index" 2134 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 2135 | dependencies = [ 2136 | "once_cell", 2137 | "valuable", 2138 | ] 2139 | 2140 | [[package]] 2141 | name = "tracing-log" 2142 | version = "0.2.0" 2143 | source = "registry+https://github.com/rust-lang/crates.io-index" 2144 | checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" 2145 | dependencies = [ 2146 | "log", 2147 | "once_cell", 2148 | "tracing-core", 2149 | ] 2150 | 2151 | [[package]] 2152 | name = "tracing-serde" 2153 | version = "0.1.3" 2154 | source = "registry+https://github.com/rust-lang/crates.io-index" 2155 | checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" 2156 | dependencies = [ 2157 | "serde", 2158 | "tracing-core", 2159 | ] 2160 | 2161 | [[package]] 2162 | name = "tracing-subscriber" 2163 | version = "0.3.18" 2164 | source = "registry+https://github.com/rust-lang/crates.io-index" 2165 | checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" 2166 | dependencies = [ 2167 | "nu-ansi-term", 2168 | "serde", 2169 | "serde_json", 2170 | "sharded-slab", 2171 | "smallvec", 2172 | "thread_local", 2173 | "tracing-core", 2174 | "tracing-log", 2175 | "tracing-serde", 2176 | ] 2177 | 2178 | [[package]] 2179 | name = "try-lock" 2180 | version = "0.2.5" 2181 | source = "registry+https://github.com/rust-lang/crates.io-index" 2182 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 2183 | 2184 | [[package]] 2185 | name = "typenum" 2186 | version = "1.17.0" 2187 | source = "registry+https://github.com/rust-lang/crates.io-index" 2188 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 2189 | 2190 | [[package]] 2191 | name = "unicode-bidi" 2192 | version = "0.3.15" 2193 | source = "registry+https://github.com/rust-lang/crates.io-index" 2194 | checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" 2195 | 2196 | [[package]] 2197 | name = "unicode-ident" 2198 | version = "1.0.12" 2199 | source = "registry+https://github.com/rust-lang/crates.io-index" 2200 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 2201 | 2202 | [[package]] 2203 | name = "unicode-normalization" 2204 | version = "0.1.23" 2205 | source = "registry+https://github.com/rust-lang/crates.io-index" 2206 | checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" 2207 | dependencies = [ 2208 | "tinyvec", 2209 | ] 2210 | 2211 | [[package]] 2212 | name = "unicode-xid" 2213 | version = "0.2.2" 2214 | source = "registry+https://github.com/rust-lang/crates.io-index" 2215 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 2216 | 2217 | [[package]] 2218 | name = "unsafe-libyaml" 2219 | version = "0.2.11" 2220 | source = "registry+https://github.com/rust-lang/crates.io-index" 2221 | checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" 2222 | 2223 | [[package]] 2224 | name = "untrusted" 2225 | version = "0.9.0" 2226 | source = "registry+https://github.com/rust-lang/crates.io-index" 2227 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 2228 | 2229 | [[package]] 2230 | name = "url" 2231 | version = "2.5.0" 2232 | source = "registry+https://github.com/rust-lang/crates.io-index" 2233 | checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" 2234 | dependencies = [ 2235 | "form_urlencoded", 2236 | "idna", 2237 | "percent-encoding", 2238 | ] 2239 | 2240 | [[package]] 2241 | name = "urlencoding" 2242 | version = "2.1.3" 2243 | source = "registry+https://github.com/rust-lang/crates.io-index" 2244 | checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" 2245 | 2246 | [[package]] 2247 | name = "utf8parse" 2248 | version = "0.2.2" 2249 | source = "registry+https://github.com/rust-lang/crates.io-index" 2250 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 2251 | 2252 | [[package]] 2253 | name = "uuid" 2254 | version = "1.8.0" 2255 | source = "registry+https://github.com/rust-lang/crates.io-index" 2256 | checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" 2257 | 2258 | [[package]] 2259 | name = "valuable" 2260 | version = "0.1.0" 2261 | source = "registry+https://github.com/rust-lang/crates.io-index" 2262 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 2263 | 2264 | [[package]] 2265 | name = "version_check" 2266 | version = "0.9.3" 2267 | source = "registry+https://github.com/rust-lang/crates.io-index" 2268 | checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" 2269 | 2270 | [[package]] 2271 | name = "vsimd" 2272 | version = "0.8.0" 2273 | source = "registry+https://github.com/rust-lang/crates.io-index" 2274 | checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" 2275 | 2276 | [[package]] 2277 | name = "want" 2278 | version = "0.3.1" 2279 | source = "registry+https://github.com/rust-lang/crates.io-index" 2280 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 2281 | dependencies = [ 2282 | "try-lock", 2283 | ] 2284 | 2285 | [[package]] 2286 | name = "wasi" 2287 | version = "0.11.0+wasi-snapshot-preview1" 2288 | source = "registry+https://github.com/rust-lang/crates.io-index" 2289 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2290 | 2291 | [[package]] 2292 | name = "which" 2293 | version = "4.4.2" 2294 | source = "registry+https://github.com/rust-lang/crates.io-index" 2295 | checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" 2296 | dependencies = [ 2297 | "either", 2298 | "home", 2299 | "once_cell", 2300 | "rustix", 2301 | ] 2302 | 2303 | [[package]] 2304 | name = "winapi" 2305 | version = "0.3.9" 2306 | source = "registry+https://github.com/rust-lang/crates.io-index" 2307 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2308 | dependencies = [ 2309 | "winapi-i686-pc-windows-gnu", 2310 | "winapi-x86_64-pc-windows-gnu", 2311 | ] 2312 | 2313 | [[package]] 2314 | name = "winapi-i686-pc-windows-gnu" 2315 | version = "0.4.0" 2316 | source = "registry+https://github.com/rust-lang/crates.io-index" 2317 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2318 | 2319 | [[package]] 2320 | name = "winapi-x86_64-pc-windows-gnu" 2321 | version = "0.4.0" 2322 | source = "registry+https://github.com/rust-lang/crates.io-index" 2323 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2324 | 2325 | [[package]] 2326 | name = "windows-sys" 2327 | version = "0.52.0" 2328 | source = "registry+https://github.com/rust-lang/crates.io-index" 2329 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2330 | dependencies = [ 2331 | "windows-targets 0.52.6", 2332 | ] 2333 | 2334 | [[package]] 2335 | name = "windows-sys" 2336 | version = "0.59.0" 2337 | source = "registry+https://github.com/rust-lang/crates.io-index" 2338 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2339 | dependencies = [ 2340 | "windows-targets 0.52.6", 2341 | ] 2342 | 2343 | [[package]] 2344 | name = "windows-targets" 2345 | version = "0.48.5" 2346 | source = "registry+https://github.com/rust-lang/crates.io-index" 2347 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 2348 | dependencies = [ 2349 | "windows_aarch64_gnullvm 0.48.5", 2350 | "windows_aarch64_msvc 0.48.5", 2351 | "windows_i686_gnu 0.48.5", 2352 | "windows_i686_msvc 0.48.5", 2353 | "windows_x86_64_gnu 0.48.5", 2354 | "windows_x86_64_gnullvm 0.48.5", 2355 | "windows_x86_64_msvc 0.48.5", 2356 | ] 2357 | 2358 | [[package]] 2359 | name = "windows-targets" 2360 | version = "0.52.6" 2361 | source = "registry+https://github.com/rust-lang/crates.io-index" 2362 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2363 | dependencies = [ 2364 | "windows_aarch64_gnullvm 0.52.6", 2365 | "windows_aarch64_msvc 0.52.6", 2366 | "windows_i686_gnu 0.52.6", 2367 | "windows_i686_gnullvm", 2368 | "windows_i686_msvc 0.52.6", 2369 | "windows_x86_64_gnu 0.52.6", 2370 | "windows_x86_64_gnullvm 0.52.6", 2371 | "windows_x86_64_msvc 0.52.6", 2372 | ] 2373 | 2374 | [[package]] 2375 | name = "windows_aarch64_gnullvm" 2376 | version = "0.48.5" 2377 | source = "registry+https://github.com/rust-lang/crates.io-index" 2378 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 2379 | 2380 | [[package]] 2381 | name = "windows_aarch64_gnullvm" 2382 | version = "0.52.6" 2383 | source = "registry+https://github.com/rust-lang/crates.io-index" 2384 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2385 | 2386 | [[package]] 2387 | name = "windows_aarch64_msvc" 2388 | version = "0.48.5" 2389 | source = "registry+https://github.com/rust-lang/crates.io-index" 2390 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 2391 | 2392 | [[package]] 2393 | name = "windows_aarch64_msvc" 2394 | version = "0.52.6" 2395 | source = "registry+https://github.com/rust-lang/crates.io-index" 2396 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2397 | 2398 | [[package]] 2399 | name = "windows_i686_gnu" 2400 | version = "0.48.5" 2401 | source = "registry+https://github.com/rust-lang/crates.io-index" 2402 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2403 | 2404 | [[package]] 2405 | name = "windows_i686_gnu" 2406 | version = "0.52.6" 2407 | source = "registry+https://github.com/rust-lang/crates.io-index" 2408 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2409 | 2410 | [[package]] 2411 | name = "windows_i686_gnullvm" 2412 | version = "0.52.6" 2413 | source = "registry+https://github.com/rust-lang/crates.io-index" 2414 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2415 | 2416 | [[package]] 2417 | name = "windows_i686_msvc" 2418 | version = "0.48.5" 2419 | source = "registry+https://github.com/rust-lang/crates.io-index" 2420 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 2421 | 2422 | [[package]] 2423 | name = "windows_i686_msvc" 2424 | version = "0.52.6" 2425 | source = "registry+https://github.com/rust-lang/crates.io-index" 2426 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2427 | 2428 | [[package]] 2429 | name = "windows_x86_64_gnu" 2430 | version = "0.48.5" 2431 | source = "registry+https://github.com/rust-lang/crates.io-index" 2432 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 2433 | 2434 | [[package]] 2435 | name = "windows_x86_64_gnu" 2436 | version = "0.52.6" 2437 | source = "registry+https://github.com/rust-lang/crates.io-index" 2438 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2439 | 2440 | [[package]] 2441 | name = "windows_x86_64_gnullvm" 2442 | version = "0.48.5" 2443 | source = "registry+https://github.com/rust-lang/crates.io-index" 2444 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 2445 | 2446 | [[package]] 2447 | name = "windows_x86_64_gnullvm" 2448 | version = "0.52.6" 2449 | source = "registry+https://github.com/rust-lang/crates.io-index" 2450 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2451 | 2452 | [[package]] 2453 | name = "windows_x86_64_msvc" 2454 | version = "0.48.5" 2455 | source = "registry+https://github.com/rust-lang/crates.io-index" 2456 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 2457 | 2458 | [[package]] 2459 | name = "windows_x86_64_msvc" 2460 | version = "0.52.6" 2461 | source = "registry+https://github.com/rust-lang/crates.io-index" 2462 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2463 | 2464 | [[package]] 2465 | name = "xmlparser" 2466 | version = "0.13.6" 2467 | source = "registry+https://github.com/rust-lang/crates.io-index" 2468 | checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" 2469 | 2470 | [[package]] 2471 | name = "zeroize" 2472 | version = "1.7.0" 2473 | source = "registry+https://github.com/rust-lang/crates.io-index" 2474 | checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" 2475 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lambda-web-gateway" 3 | version = "0.1.0" 4 | authors = ["Harold Sun "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | base64 = "0.22.0" 11 | bytes = "1.6.0" 12 | log = "0.4.14" 13 | futures = "0.3.14" 14 | rustls = "0.23.5" 15 | serde = { version = "1.0", features = ["derive"] } 16 | serde_yaml = "0.9" 17 | clap = { version = "4.0", features = ["derive"] } 18 | serde_json = "1" 19 | url = "2.5.0" 20 | axum ={ version = "0.7.5"} 21 | aws-config = { version = "1.5.5" } 22 | aws-sdk-lambda = { version = "1.42.0" } 23 | aws-smithy-types = { version="1.2.2", features = ["serde-serialize"] } 24 | tokio = { version = "1.39.3", features = ["full"] } 25 | tower-http = { version = "0.5.2", features = ["trace"] } 26 | tracing-subscriber = { version= "0.3.18", features = ["json"]} 27 | tracing ={ version = "0.1.40"} 28 | tokio-stream = "0.1.15" 29 | futures-util = "0.3.30" 30 | http-serde = "2.1.1" 31 | 32 | [dev-dependencies] 33 | tempfile = "3.8.1" 34 | 35 | [[bin]] 36 | name = "lambda-web-gateway" 37 | path = "src/main.rs" 38 | 39 | [lib] 40 | name = "lambda_web_gateway" 41 | path = "src/lib.rs" 42 | 43 | [profile.release] 44 | strip = true 45 | lto = true 46 | codegen-units = 1 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT No Attribution 2 | 3 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 13 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 15 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lambda Web Gateway 2 | 3 | A high-performance web gateway for AWS Lambda functions, written in Rust. 4 | 5 | ## Features 6 | 7 | - Seamless integration with AWS Lambda functions 8 | - Support for both buffered and streaming Lambda invocations 9 | - Configurable authentication (Open or API Key) 10 | - Request transformation from HTTP to Lambda-compatible format 11 | - Automatic handling of base64 encoding/decoding for request/response bodies 12 | - Built with Rust and Axum for high performance and reliability 13 | - Health check endpoint for monitoring 14 | - Flexible configuration via YAML file or environment variables 15 | 16 | ## Prerequisites 17 | 18 | - Rust (latest stable version) 19 | - AWS account and credentials configured 20 | - AWS Lambda function(s) to be exposed via the gateway 21 | 22 | ## Configuration 23 | 24 | The gateway can be configured using a YAML file (`config.yaml`) or environment variables. Configuration options include: 25 | 26 | - Lambda function name (required) 27 | - Lambda invoke mode (Buffered or ResponseStream, default: Buffered) 28 | - API keys (for API Key authentication mode) 29 | - Authorization mode (Open or ApiKey, default: Open) 30 | - Bind address (default: "0.0.0.0:8000") 31 | 32 | Example `config.yaml`: 33 | 34 | ```yaml 35 | lambda_function_name: "my-lambda-function" 36 | lambda_invoke_mode: "ResponseStream" 37 | auth_mode: "ApiKey" 38 | api_keys: 39 | - "key1" 40 | - "key2" 41 | addr: "0.0.0.0:8000" 42 | ``` 43 | 44 | Alternatively, you can use environment variables: 45 | 46 | - `LAMBDA_FUNCTION_NAME` 47 | - `LAMBDA_INVOKE_MODE` 48 | - `API_KEYS` (comma-separated list) 49 | - `AUTH_MODE` (default: Open) 50 | - `ADDR` 51 | 52 | Environment variables take precedence over the configuration file when both are present. 53 | 54 | ## Building and Running 55 | 56 | 1. Clone the repository: 57 | ``` 58 | git clone https://github.com/aws-samples/aws-lambda-web-gateway.git 59 | cd aws-lambda-web-gateway 60 | ``` 61 | 62 | 2. Build the project: 63 | ``` 64 | cargo build --release 65 | ``` 66 | 67 | 3. Create a `config.yaml` file in the project root or set the necessary environment variables. 68 | 69 | 4. Run the gateway: 70 | ``` 71 | ./target/release/lambda-web-gateway 72 | ``` 73 | 74 | ## Usage 75 | 76 | Once running, the gateway listens for HTTP requests on the configured address (default: `0.0.0.0:8000`). All requests (except `/healthz`) are forwarded to the configured Lambda function. 77 | 78 | - Health check: `GET /healthz` 79 | - Lambda invocation: Any method on `/` or `/*path` 80 | 81 | For API Key authentication, include the key in the `x-api-key` header or as a Bearer token in the `Authorization` header. 82 | 83 | ## Performance Considerations 84 | 85 | - The gateway is optimized for high throughput and low latency. 86 | - Streaming responses are supported for improved performance with large payloads. 87 | - The use of Rust and Axum ensures efficient resource utilization. 88 | 89 | ## Development 90 | 91 | To contribute to the project: 92 | 93 | 1. Fork the repository 94 | 2. Create a new branch for your feature 95 | 3. Implement your changes 96 | 4. Write tests for your new functionality 97 | 5. Submit a pull request 98 | 99 | Please refer to [CONTRIBUTING.md](CONTRIBUTING.md) for more details on the contribution process. 100 | 101 | ## Security 102 | 103 | See [CONTRIBUTING.md](CONTRIBUTING.md#security-issue-notifications) for more information on reporting security issues. 104 | 105 | ## License 106 | 107 | This project is licensed under the MIT-0 License. See the [LICENSE](LICENSE) file for details. 108 | -------------------------------------------------------------------------------- /config.yaml.example: -------------------------------------------------------------------------------- 1 | # Lambda function name or ARN (required) 2 | lambda_function_name: "my-lambda-function" 3 | 4 | # Lambda invoke mode: "ResponseStream" or "Buffered" (optional, defaults to "Buffered") 5 | lambda_invoke_mode: "ResponseStream" 6 | 7 | # Server address (optional, defaults to "0.0.0.0:8000") 8 | addr: "0.0.0.0:8000" 9 | 10 | # Authentication mode: "ApiKey" or "Open" (optional, defaults to "Open") 11 | auth_mode: "ApiKey" 12 | 13 | # API keys (required if auth_mode is "ApiKey", ignored if "Open") 14 | api_keys: 15 | - "key1" 16 | - "key2" 17 | -------------------------------------------------------------------------------- /src/config.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | use std::collections::HashSet; 3 | use std::str::FromStr; 4 | use std::fs; 5 | use std::path::Path; 6 | 7 | #[derive(Clone, Debug, Serialize, Deserialize)] 8 | pub struct Config { 9 | pub lambda_function_name: String, 10 | #[serde(default = "default_lambda_invoke_mode")] 11 | pub lambda_invoke_mode: LambdaInvokeMode, 12 | #[serde(default)] 13 | pub api_keys: HashSet, 14 | #[serde(default = "default_auth_mode")] 15 | pub auth_mode: AuthMode, 16 | #[serde(default = "default_addr")] 17 | pub addr: String, 18 | } 19 | 20 | impl Default for Config { 21 | fn default() -> Self { 22 | Self { 23 | lambda_function_name: String::new(), 24 | lambda_invoke_mode: default_lambda_invoke_mode(), 25 | api_keys: HashSet::new(), 26 | auth_mode: default_auth_mode(), 27 | addr: default_addr(), 28 | } 29 | } 30 | } 31 | 32 | impl Config { 33 | pub fn load>(path: P) -> Self { 34 | let mut config = Self::load_from_file(path).unwrap_or_else(|e| { 35 | tracing::warn!("Failed to load config from file: {}. Using default values.", e); 36 | Config::default() 37 | }); 38 | config.apply_env_overrides(); 39 | config 40 | } 41 | 42 | fn apply_env_overrides(&mut self) { 43 | if let Ok(val) = std::env::var("LAMBDA_FUNCTION_NAME") { 44 | self.lambda_function_name = val; 45 | } 46 | if self.lambda_function_name.is_empty() { 47 | panic!("No lambda_function_name provided. Please set it in the config file or LAMBDA_FUNCTION_NAME environment variable."); 48 | } 49 | if let Ok(val) = std::env::var("LAMBDA_INVOKE_MODE") { 50 | if let Ok(mode) = val.parse() { 51 | self.lambda_invoke_mode = mode; 52 | } 53 | } 54 | if let Ok(val) = std::env::var("API_KEYS") { 55 | self.api_keys = val.split(',').filter(|s| !s.is_empty()).map(String::from).collect(); 56 | } 57 | if let Ok(val) = std::env::var("AUTH_MODE") { 58 | if let Ok(mode) = val.parse() { 59 | self.auth_mode = mode; 60 | } 61 | } 62 | if let Ok(val) = std::env::var("ADDR") { 63 | self.addr = val; 64 | } 65 | } 66 | 67 | pub fn load_from_file>(path: P) -> Result> { 68 | let contents = fs::read_to_string(path)?; 69 | let config: Config = serde_yaml::from_str(&contents)?; 70 | Ok(config) 71 | } 72 | } 73 | 74 | #[cfg(test)] 75 | mod tests { 76 | include!("config_tests.rs"); 77 | } 78 | 79 | fn default_auth_mode() -> AuthMode { 80 | AuthMode::Open 81 | } 82 | 83 | fn default_lambda_invoke_mode() -> LambdaInvokeMode { 84 | LambdaInvokeMode::Buffered 85 | } 86 | 87 | fn default_addr() -> String { 88 | "0.0.0.0:8000".to_string() 89 | } 90 | 91 | #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] 92 | pub enum AuthMode { 93 | Open, 94 | ApiKey, 95 | } 96 | 97 | impl Default for AuthMode { 98 | fn default() -> Self { 99 | AuthMode::Open 100 | } 101 | } 102 | 103 | #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] 104 | pub enum LambdaInvokeMode { 105 | Buffered, 106 | ResponseStream, 107 | } 108 | 109 | impl Default for LambdaInvokeMode { 110 | fn default() -> Self { 111 | LambdaInvokeMode::Buffered 112 | } 113 | } 114 | 115 | impl FromStr for AuthMode { 116 | type Err = String; 117 | 118 | fn from_str(s: &str) -> Result { 119 | match s.to_lowercase().as_str() { 120 | "open" => Ok(AuthMode::Open), 121 | "apikey" => Ok(AuthMode::ApiKey), 122 | _ => Err(format!("Invalid AuthMode: {}", s)), 123 | } 124 | } 125 | } 126 | 127 | impl FromStr for LambdaInvokeMode { 128 | type Err = String; 129 | 130 | fn from_str(s: &str) -> Result { 131 | match s.to_lowercase().as_str() { 132 | "buffered" => Ok(LambdaInvokeMode::Buffered), 133 | "responsestream" => Ok(LambdaInvokeMode::ResponseStream), 134 | _ => Err(format!("Invalid LambdaInvokeMode: {}", s)), 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/config_tests.rs: -------------------------------------------------------------------------------- 1 | use super::*; 2 | use std::collections::HashSet; 3 | use std::env; 4 | use tempfile::NamedTempFile; 5 | use std::io::Write; 6 | 7 | #[test] 8 | fn test_auth_mode_from_str() { 9 | assert_eq!("open".parse::().unwrap(), AuthMode::Open); 10 | assert_eq!("apikey".parse::().unwrap(), AuthMode::ApiKey); 11 | assert_eq!("OPEN".parse::().unwrap(), AuthMode::Open); 12 | assert_eq!("APIKEY".parse::().unwrap(), AuthMode::ApiKey); 13 | assert!("invalid".parse::().is_err()); 14 | } 15 | 16 | #[test] 17 | fn test_lambda_invoke_mode_from_str() { 18 | assert_eq!("buffered".parse::().unwrap(), LambdaInvokeMode::Buffered); 19 | assert_eq!("responsestream".parse::().unwrap(), LambdaInvokeMode::ResponseStream); 20 | assert_eq!("BUFFERED".parse::().unwrap(), LambdaInvokeMode::Buffered); 21 | assert_eq!("RESPONSESTREAM".parse::().unwrap(), LambdaInvokeMode::ResponseStream); 22 | assert!("invalid".parse::().is_err()); 23 | } 24 | 25 | #[test] 26 | fn test_config_default() { 27 | let config = Config::default(); 28 | assert_eq!(config.lambda_function_name, ""); 29 | assert_eq!(config.lambda_invoke_mode, LambdaInvokeMode::Buffered); 30 | assert!(config.api_keys.is_empty()); 31 | assert_eq!(config.auth_mode, AuthMode::Open); 32 | assert_eq!(config.addr, "0.0.0.0:8000"); 33 | } 34 | 35 | #[test] 36 | #[should_panic(expected = "No lambda_function_name provided")] 37 | fn test_config_panic_on_empty_lambda_function_name() { 38 | let mut config = Config::default(); 39 | config.apply_env_overrides(); 40 | } 41 | 42 | #[test] 43 | fn test_config_apply_env_overrides() { 44 | env::set_var("LAMBDA_FUNCTION_NAME", "test-function"); 45 | env::set_var("LAMBDA_INVOKE_MODE", "responsestream"); 46 | env::set_var("API_KEYS", "key1,key2"); 47 | env::set_var("AUTH_MODE", "apikey"); 48 | env::set_var("ADDR", "127.0.0.1:3000"); 49 | 50 | let mut config = Config::default(); 51 | config.apply_env_overrides(); 52 | 53 | assert_eq!(config.lambda_function_name, "test-function"); 54 | assert_eq!(config.lambda_invoke_mode, LambdaInvokeMode::ResponseStream); 55 | assert_eq!(config.api_keys, vec!["key1", "key2"].into_iter().map(String::from).collect::>()); 56 | assert_eq!(config.auth_mode, AuthMode::ApiKey); 57 | assert_eq!(config.addr, "127.0.0.1:3000"); 58 | 59 | // Clean up environment variables 60 | env::remove_var("LAMBDA_FUNCTION_NAME"); 61 | env::remove_var("LAMBDA_INVOKE_MODE"); 62 | env::remove_var("API_KEYS"); 63 | env::remove_var("AUTH_MODE"); 64 | env::remove_var("ADDR"); 65 | } 66 | 67 | #[test] 68 | fn test_config_load() { 69 | let config_content = r#" 70 | lambda_function_name: test-function 71 | lambda_invoke_mode: ResponseStream 72 | api_keys: 73 | - key1 74 | - key2 75 | auth_mode: ApiKey 76 | addr: 127.0.0.1:3000 77 | "#; 78 | 79 | let mut temp_file = NamedTempFile::new().unwrap(); 80 | write!(temp_file, "{}", config_content).unwrap(); 81 | 82 | let config = Config::load_from_file(temp_file.path()).unwrap(); 83 | 84 | assert_eq!(config.lambda_function_name, "test-function"); 85 | assert_eq!(config.lambda_invoke_mode, LambdaInvokeMode::ResponseStream); 86 | assert_eq!(config.api_keys, vec!["key1", "key2"].into_iter().map(String::from).collect::>()); 87 | assert_eq!(config.auth_mode, AuthMode::ApiKey); 88 | assert_eq!(config.addr, "127.0.0.1:3000"); 89 | } 90 | 91 | #[test] 92 | fn test_config_load_with_env_override() { 93 | let config_content = r#" 94 | lambda_function_name: file-function 95 | lambda_invoke_mode: Buffered 96 | api_keys: 97 | - file-key 98 | auth_mode: Open 99 | addr: 0.0.0.0:8000 100 | "#; 101 | 102 | let mut temp_file = NamedTempFile::new().unwrap(); 103 | write!(temp_file, "{}", config_content).unwrap(); 104 | 105 | // Test with environment variables set 106 | env::set_var("LAMBDA_FUNCTION_NAME", "env-function"); 107 | env::set_var("AUTH_MODE", "apikey"); 108 | env::set_var("LAMBDA_INVOKE_MODE", "responsestream"); 109 | 110 | let config = Config::load(temp_file.path()); 111 | 112 | assert_eq!(config.lambda_function_name, "env-function"); 113 | assert_eq!(config.lambda_invoke_mode, LambdaInvokeMode::ResponseStream); 114 | assert_eq!(config.api_keys, vec!["file-key"].into_iter().map(String::from).collect::>()); 115 | assert_eq!(config.auth_mode, AuthMode::ApiKey); 116 | assert_eq!(config.addr, "0.0.0.0:8000"); 117 | 118 | // Clean up environment variables 119 | env::remove_var("LAMBDA_FUNCTION_NAME"); 120 | env::remove_var("AUTH_MODE"); 121 | env::remove_var("LAMBDA_INVOKE_MODE"); 122 | 123 | // Test with no environment variables set 124 | let config = Config::load(temp_file.path()); 125 | assert_eq!(config.lambda_function_name, "file-function"); 126 | assert_eq!(config.auth_mode, AuthMode::Open); 127 | assert_eq!(config.lambda_invoke_mode, LambdaInvokeMode::Buffered); 128 | 129 | // Test with empty LAMBDA_FUNCTION_NAME 130 | env::set_var("LAMBDA_FUNCTION_NAME", ""); 131 | assert!(std::panic::catch_unwind(|| Config::load(temp_file.path())).is_err()); 132 | env::remove_var("LAMBDA_FUNCTION_NAME"); 133 | } 134 | 135 | #[test] 136 | fn test_config_load_invalid_file() { 137 | env::set_var("LAMBDA_FUNCTION_NAME", "env-function"); 138 | env::set_var("AUTH_MODE", "apikey"); 139 | env::set_var("LAMBDA_INVOKE_MODE", "responsestream"); 140 | 141 | let config = Config::load("non_existent_file.yaml"); 142 | 143 | assert_eq!(config.lambda_function_name, "env-function"); 144 | assert_eq!(config.auth_mode, AuthMode::ApiKey); 145 | assert_eq!(config.lambda_invoke_mode, LambdaInvokeMode::ResponseStream); 146 | assert!(config.api_keys.is_empty()); 147 | assert_eq!(config.addr, "0.0.0.0:8000"); 148 | 149 | // Clean up environment variables 150 | env::remove_var("LAMBDA_FUNCTION_NAME"); 151 | env::remove_var("AUTH_MODE"); 152 | env::remove_var("LAMBDA_INVOKE_MODE"); 153 | } 154 | 155 | #[test] 156 | fn test_config_load_invalid_yaml() { 157 | let config_content = "invalid: yaml: content"; 158 | 159 | let mut temp_file = NamedTempFile::new().unwrap(); 160 | write!(temp_file, "{}", config_content).unwrap(); 161 | 162 | env::set_var("LAMBDA_FUNCTION_NAME", "env-function"); 163 | env::set_var("AUTH_MODE", "apikey"); 164 | env::set_var("LAMBDA_INVOKE_MODE", "responsestream"); 165 | 166 | let config = Config::load(temp_file.path()); 167 | 168 | assert_eq!(config.lambda_function_name, "env-function"); 169 | assert_eq!(config.auth_mode, AuthMode::ApiKey); 170 | assert_eq!(config.lambda_invoke_mode, LambdaInvokeMode::ResponseStream); 171 | assert!(config.api_keys.is_empty()); 172 | assert_eq!(config.addr, "0.0.0.0:8000"); 173 | 174 | // Clean up environment variables 175 | env::remove_var("LAMBDA_FUNCTION_NAME"); 176 | env::remove_var("AUTH_MODE"); 177 | env::remove_var("LAMBDA_INVOKE_MODE"); 178 | } 179 | 180 | #[test] 181 | fn test_config_load_empty_api_keys() { 182 | env::set_var("API_KEYS", ""); 183 | env::set_var("LAMBDA_FUNCTION_NAME", "test-function"); // Add this line 184 | 185 | let config = Config::load("non_existent_file.yaml"); 186 | 187 | assert!(config.api_keys.is_empty()); 188 | 189 | env::remove_var("API_KEYS"); 190 | env::remove_var("LAMBDA_FUNCTION_NAME"); // Add this line 191 | } 192 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | 3 | #[cfg(test)] 4 | mod tests { 5 | include!("lib_tests.rs"); 6 | } 7 | 8 | use crate::config::{Config, LambdaInvokeMode}; 9 | use aws_config::BehaviorVersion; 10 | use aws_sdk_lambda::types::InvokeWithResponseStreamResponseEvent::{InvokeComplete, PayloadChunk}; 11 | use aws_sdk_lambda::types::{InvokeResponseStreamUpdate, ResponseStreamingInvocationType}; 12 | use aws_sdk_lambda::Client; 13 | use aws_smithy_types::Blob; 14 | use axum::body::Body; 15 | use axum::{ 16 | body::Bytes, 17 | extract::{Path, Query, State}, 18 | http::{HeaderMap, Method, StatusCode}, 19 | response::{IntoResponse, Response}, 20 | routing::any, 21 | routing::get, 22 | Router, 23 | }; 24 | use base64::Engine; 25 | use futures_util::stream::StreamExt; 26 | use serde::{Deserialize, Serialize}; 27 | use serde_json::json; 28 | use std::collections::HashMap; 29 | use tokio::sync::mpsc; 30 | use tokio_stream::wrappers::ReceiverStream; 31 | use tower_http::trace::TraceLayer; 32 | 33 | #[derive(Clone)] 34 | pub struct ApplicationState { 35 | client: Client, 36 | config: Config, 37 | } 38 | 39 | pub async fn run_app() { 40 | tracing_subscriber::fmt::init(); 41 | 42 | let config = Config::load("config.yaml"); 43 | let aws_config = aws_config::load_defaults(BehaviorVersion::latest()).await; 44 | let client = Client::new(&aws_config); 45 | 46 | let app_state = ApplicationState { client, config }; 47 | 48 | let app = Router::new() 49 | .route("/healthz", get(health)) 50 | .route("/", any(handler)) 51 | .route("/*path", any(handler)) 52 | .layer(TraceLayer::new_for_http()) 53 | .with_state(app_state.clone()); 54 | 55 | let addr = &app_state.config.addr; 56 | let listener = tokio::net::TcpListener::bind(addr).await.unwrap(); 57 | tracing::info!("Listening on {}", addr); 58 | axum::serve(listener, app).await.unwrap(); 59 | } 60 | 61 | async fn health() -> impl IntoResponse { 62 | StatusCode::OK 63 | } 64 | 65 | async fn handler( 66 | path: Option>, 67 | Query(query_string_parameters): Query>, 68 | State(state): State, 69 | method: Method, 70 | headers: HeaderMap, 71 | body: Bytes, 72 | ) -> Response { 73 | let client = &state.client; 74 | let config = &state.config; 75 | let path = "/".to_string() + path.map(|p| p.0).unwrap_or_default().as_str(); 76 | 77 | let http_method = method.to_string(); 78 | 79 | let content_type = headers 80 | .get("content-type") 81 | .and_then(|v| v.to_str().ok().map(Some).flatten()) 82 | .unwrap_or_default(); 83 | 84 | let is_base64_encoded = match content_type { 85 | "application/json" => false, 86 | "application/xml" => false, 87 | "application/javascript" => false, 88 | _ if content_type.starts_with("text/") => false, 89 | _ => true, 90 | }; 91 | 92 | let body = if is_base64_encoded { 93 | base64::engine::general_purpose::STANDARD.encode(body) 94 | } else { 95 | String::from_utf8_lossy(&body).to_string() 96 | }; 97 | 98 | match config.auth_mode { 99 | config::AuthMode::Open => {} 100 | config::AuthMode::ApiKey => { 101 | let api_key = headers 102 | .get("x-api-key") 103 | .and_then(|v| v.to_str().ok()) 104 | .or_else(|| { 105 | headers 106 | .get("authorization") 107 | .and_then(|v| v.to_str().ok().and_then(|s| s.strip_prefix("Bearer "))) 108 | }) 109 | .unwrap_or_default(); 110 | 111 | if !config.api_keys.contains(api_key) { 112 | return Response::builder() 113 | .status(StatusCode::UNAUTHORIZED) 114 | .body(Body::empty()) 115 | .unwrap(); 116 | } 117 | } 118 | } 119 | 120 | let lambda_request_body = json!({ 121 | "httpMethod": http_method, 122 | "headers": to_string_map(&headers), 123 | "path": path, 124 | "queryStringParameters": query_string_parameters, 125 | "isBase64Encoded": is_base64_encoded, 126 | "body": body, 127 | "requestContext": { 128 | "elb": { 129 | "targetGroupArn": "", 130 | }, 131 | }, 132 | }) 133 | .to_string(); 134 | 135 | let resp = match config.lambda_invoke_mode { 136 | LambdaInvokeMode::Buffered => { 137 | let resp = client 138 | .invoke() 139 | .function_name(config.lambda_function_name.as_str()) 140 | .payload(Blob::new(lambda_request_body)) 141 | .send() 142 | .await 143 | .unwrap(); 144 | handle_buffered_response(resp).await 145 | } 146 | LambdaInvokeMode::ResponseStream => { 147 | let resp = client 148 | .invoke_with_response_stream() 149 | .function_name(config.lambda_function_name.as_str()) 150 | .invocation_type(ResponseStreamingInvocationType::RequestResponse) 151 | .payload(Blob::new(lambda_request_body)) 152 | .send() 153 | .await 154 | .unwrap(); 155 | handle_streaming_response(resp).await 156 | } 157 | }; 158 | 159 | resp 160 | } 161 | 162 | fn to_string_map(headers: &HeaderMap) -> HashMap { 163 | headers 164 | .iter() 165 | .map(|(k, v)| { 166 | ( 167 | k.as_str().to_owned(), 168 | String::from_utf8_lossy(v.as_bytes()).into_owned(), 169 | ) 170 | }) 171 | .collect() 172 | } 173 | 174 | #[derive(Serialize, Deserialize, Debug)] 175 | #[serde(rename_all = "camelCase")] 176 | struct LambdaResponse { 177 | status_code: u16, 178 | status_description: Option, 179 | is_base64_encoded: Option, 180 | headers: Option>, 181 | body: String, 182 | } 183 | 184 | #[derive(Debug, Default, Serialize, Deserialize)] 185 | #[serde(rename_all = "camelCase")] 186 | struct MetadataPrelude { 187 | #[serde(with = "http_serde::status_code")] 188 | /// The HTTP status code. 189 | pub status_code: StatusCode, 190 | #[serde(with = "http_serde::header_map")] 191 | /// The HTTP headers. 192 | pub headers: HeaderMap, 193 | /// The HTTP cookies. 194 | pub cookies: Vec, 195 | } 196 | 197 | async fn handle_buffered_response(resp: aws_sdk_lambda::operation::invoke::InvokeOutput) -> Response { 198 | // Parse the InvokeOutput payload to extract the LambdaResponse 199 | let payload = resp.payload().unwrap().as_ref().to_vec(); 200 | let lambda_response: LambdaResponse = serde_json::from_slice(&payload).unwrap(); 201 | 202 | // Build the response using the extracted information 203 | let mut resp_builder = Response::builder().status(StatusCode::from_u16(lambda_response.status_code).unwrap()); 204 | 205 | if let Some(headers) = lambda_response.headers { 206 | for (key, value) in headers { 207 | resp_builder = resp_builder.header(key, value); 208 | } 209 | } 210 | 211 | let body = if lambda_response.is_base64_encoded.unwrap_or(false) { 212 | base64::engine::general_purpose::STANDARD 213 | .decode(lambda_response.body) 214 | .unwrap() 215 | } else { 216 | lambda_response.body.into_bytes() 217 | }; 218 | resp_builder.body(Body::from(body)).unwrap() 219 | } 220 | 221 | async fn handle_streaming_response( 222 | mut resp: aws_sdk_lambda::operation::invoke_with_response_stream::InvokeWithResponseStreamOutput, 223 | ) -> Response { 224 | let (tx, rx) = mpsc::channel(1); 225 | let mut metadata_buffer = Vec::new(); 226 | let mut metadata_prelude: Option = None; 227 | let mut remaining_data = Vec::new(); 228 | 229 | // Step 1: Detect if metadata exists and get the first chunk 230 | let (has_metadata, first_chunk) = detect_metadata(&mut resp).await; 231 | 232 | // Step 2: Process the first chunk 233 | if let Some(chunk) = first_chunk { 234 | if has_metadata { 235 | metadata_buffer.extend_from_slice(&chunk); 236 | (metadata_prelude, remaining_data) = collect_metadata(&mut resp, &mut metadata_buffer).await; 237 | } else { 238 | // No metadata prelude, treat first chunk as payload 239 | remaining_data = chunk; 240 | } 241 | } 242 | 243 | // Spawn task to handle remaining stream 244 | tokio::spawn(async move { 245 | // Send remaining data after metadata first 246 | if !remaining_data.is_empty() { 247 | let stream_update = InvokeResponseStreamUpdate::builder() 248 | .payload(Blob::new(remaining_data)) 249 | .build(); 250 | let _ = tx.send(PayloadChunk(stream_update)).await; 251 | } 252 | 253 | while let Some(event) = resp.event_stream.recv().await.unwrap() { 254 | match event { 255 | PayloadChunk(chunk) => { 256 | if let Some(data) = chunk.payload() { 257 | let stream_update = InvokeResponseStreamUpdate::builder().payload(data.clone()).build(); 258 | let _ = tx.send(PayloadChunk(stream_update)).await; 259 | } 260 | } 261 | InvokeComplete(_) => { 262 | let _ = tx.send(event).await; 263 | } 264 | _ => {} 265 | } 266 | } 267 | }); 268 | 269 | let stream = ReceiverStream::new(rx).map(|event| { 270 | match event { 271 | PayloadChunk(chunk) => { 272 | if let Some(data) = chunk.payload() { 273 | let bytes = data.clone().into_inner(); 274 | Ok::<_, std::convert::Infallible>(Bytes::from(bytes)) 275 | } else { 276 | Ok(Bytes::default()) 277 | } 278 | }, 279 | InvokeComplete(_) => Ok(Bytes::default()), 280 | _ => Ok(Bytes::default()), // Handle other event types 281 | } 282 | }); 283 | 284 | let mut resp_builder = Response::builder(); 285 | 286 | if let Some(metadata_prelude) = metadata_prelude { 287 | resp_builder = resp_builder.status(metadata_prelude.status_code); 288 | 289 | for (k, v) in metadata_prelude.headers.iter() { 290 | if k != "content-length" { 291 | resp_builder = resp_builder.header(k, v); 292 | } 293 | } 294 | 295 | for cookie in &metadata_prelude.cookies { 296 | resp_builder = resp_builder.header("set-cookie", cookie); 297 | } 298 | } else { 299 | // Default response if no metadata 300 | resp_builder = resp_builder.status(StatusCode::OK); 301 | resp_builder = resp_builder.header("content-type", "application/octet-stream"); 302 | } 303 | 304 | resp_builder.body(Body::from_stream(stream)).unwrap() 305 | } 306 | 307 | async fn detect_metadata( 308 | resp: &mut aws_sdk_lambda::operation::invoke_with_response_stream::InvokeWithResponseStreamOutput, 309 | ) -> (bool, Option>) { 310 | if let Ok(Some(event)) = resp.event_stream.recv().await { 311 | if let PayloadChunk(chunk) = event { 312 | if let Some(data) = chunk.payload() { 313 | let bytes = data.clone().into_inner(); 314 | let has_metadata = !bytes.is_empty() && bytes[0] == b'{'; 315 | return (has_metadata, Some(bytes)); 316 | } 317 | } 318 | } 319 | (false, None) 320 | } 321 | 322 | async fn collect_metadata( 323 | resp: &mut aws_sdk_lambda::operation::invoke_with_response_stream::InvokeWithResponseStreamOutput, 324 | metadata_buffer: &mut Vec, 325 | ) -> (Option, Vec) { 326 | let mut metadata_prelude = None; 327 | let mut remaining_data = Vec::new(); 328 | 329 | // Process the metadata_buffer first 330 | let (prelude, remaining) = process_buffer(metadata_buffer); 331 | if let Some(p) = prelude { 332 | return (Some(p), remaining); 333 | } 334 | 335 | // If metadata is not complete, continue processing the stream 336 | while let Ok(Some(event)) = resp.event_stream.recv().await { 337 | if let PayloadChunk(chunk) = event { 338 | if let Some(data) = chunk.payload() { 339 | let bytes = data.clone().into_inner(); 340 | metadata_buffer.extend_from_slice(&bytes); 341 | let (prelude, remaining) = process_buffer(metadata_buffer); 342 | if let Some(p) = prelude { 343 | metadata_prelude = Some(p); 344 | remaining_data = remaining; 345 | break; 346 | } 347 | } 348 | } 349 | } 350 | (metadata_prelude, remaining_data) 351 | } 352 | 353 | fn process_buffer(buffer: &[u8]) -> (Option, Vec) { 354 | let mut null_count = 0; 355 | for (i, &byte) in buffer.iter().enumerate() { 356 | if byte == 0 { 357 | null_count += 1; 358 | if null_count == 8 { 359 | let metadata_str = String::from_utf8_lossy(&buffer[..i]); 360 | let metadata_prelude = serde_json::from_str(&metadata_str).unwrap_or_default(); 361 | tracing::debug!(metadata_prelude=?metadata_prelude); 362 | // Save remaining data after metadata 363 | let remaining_data = buffer[i + 1..].to_vec(); 364 | return (Some(metadata_prelude), remaining_data); 365 | } 366 | } else { 367 | null_count = 0; 368 | } 369 | } 370 | (None, Vec::new()) 371 | } 372 | -------------------------------------------------------------------------------- /src/lib_tests.rs: -------------------------------------------------------------------------------- 1 | use super::*; 2 | // use axum::http::StatusCode; 3 | // use aws_smithy_types::Blob; 4 | // use std::collections::HashMap; 5 | // use aws_sdk_lambda::types::InvokeWithResponseStreamResponseEvent; 6 | // use aws_sdk_lambda::operation::invoke_with_response_stream::InvokeWithResponseStreamOutput; 7 | // use aws_sdk_lambda::primitives::event_stream::EventReceiver; 8 | // use aws_sdk_lambda::operation::invoke_with_response_stream::InvokeWithResponseStreamError; 9 | 10 | #[tokio::test] 11 | async fn test_health() { 12 | let response = health().await.into_response(); 13 | assert_eq!(response.status(), StatusCode::OK); 14 | } 15 | 16 | #[tokio::test] 17 | async fn test_to_string_map() { 18 | let mut headers = HeaderMap::new(); 19 | headers.insert("Content-Type", "application/json".parse().unwrap()); 20 | headers.insert("X-Custom-Header", "test-value".parse().unwrap()); 21 | 22 | let result = to_string_map(&headers); 23 | 24 | assert_eq!(result.len(), 2); 25 | assert_eq!(result.get("content-type"), Some(&"application/json".to_string())); 26 | assert_eq!(result.get("x-custom-header"), Some(&"test-value".to_string())); 27 | } 28 | 29 | #[tokio::test] 30 | async fn test_handle_buffered_response() { 31 | let lambda_response = LambdaResponse { 32 | status_code: 200, 33 | status_description: Some("OK".to_string()), 34 | is_base64_encoded: Some(false), 35 | headers: Some(HashMap::from([ 36 | ("Content-Type".to_string(), "text/plain".to_string()), 37 | ])), 38 | body: "Hello, World!".to_string(), 39 | }; 40 | 41 | let payload = serde_json::to_vec(&lambda_response).unwrap(); 42 | let invoke_output = aws_sdk_lambda::operation::invoke::InvokeOutput::builder() 43 | .payload(Blob::new(payload)) 44 | .status_code(200) 45 | .build(); 46 | 47 | let response = handle_buffered_response(invoke_output).await; 48 | 49 | assert_eq!(response.status(), StatusCode::OK); 50 | assert_eq!( 51 | response.headers().get("Content-Type").unwrap(), 52 | "text/plain" 53 | ); 54 | let body = axum::body::to_bytes(response.into_body(), usize::MAX).await.unwrap(); 55 | assert_eq!(body, "Hello, World!"); 56 | } 57 | 58 | // #[tokio::test] 59 | // async fn test_detect_metadata() { 60 | // let payload = r#"{"statusCode": 200, "headers": {"Content-Type": "text/plain"}, "body": "Hello"}"#; 61 | // let full_payload = payload.as_bytes().to_vec(); 62 | // let chunk = InvokeWithResponseStreamResponseEvent::PayloadChunk( 63 | // aws_sdk_lambda::types::InvokeResponseStreamUpdate::builder() 64 | // .payload(Blob::new(full_payload.clone())) 65 | // .build(), 66 | // ); 67 | 68 | // let event_receiver = EventReceiver { 69 | // inner: vec![chunk], 70 | // }; 71 | 72 | // let mut resp = InvokeWithResponseStreamOutput::builder() 73 | // .event_stream(event_receiver) 74 | // .build() 75 | // .unwrap(); 76 | 77 | // // Type annotation to help the compiler 78 | // let resp: InvokeWithResponseStreamOutput = resp; 79 | 80 | // let (has_metadata, first_chunk) = detect_metadata(&mut resp).await; 81 | 82 | // assert!(has_metadata); 83 | // assert_eq!(first_chunk.unwrap(), full_payload); 84 | // } 85 | 86 | // #[tokio::test] 87 | // async fn test_collect_metadata() { 88 | // let payload = r#"{"statusCode": 200, "headers": {"Content-Type": "text/plain"}, "body": "Hello"}"#; 89 | // let null_padding = vec![0u8; 8]; 90 | // let remaining_data = b"Remaining data"; 91 | 92 | // let mut full_payload = payload.as_bytes().to_vec(); 93 | // full_payload.extend_from_slice(&null_padding); 94 | // full_payload.extend_from_slice(remaining_data); 95 | 96 | // let chunk = InvokeWithResponseStreamResponseEvent::PayloadChunk( 97 | // aws_sdk_lambda::types::InvokeResponseStreamUpdate::builder() 98 | // .payload(Blob::new(full_payload)) 99 | // .build(), 100 | // ); 101 | 102 | // let event_receiver =EventReceiver { 103 | // inner: vec![chunk], 104 | // }; 105 | 106 | // let mut resp = InvokeWithResponseStreamOutput::builder() 107 | // .event_stream(event_receiver) 108 | // .build() 109 | // .unwrap(); 110 | 111 | // let mut metadata_buffer = Vec::new(); 112 | // let (metadata_prelude, remaining) = collect_metadata(&mut resp, &mut metadata_buffer).await; 113 | 114 | // assert!(metadata_prelude.is_some()); 115 | // let prelude = metadata_prelude.unwrap(); 116 | // assert_eq!(prelude.status_code, StatusCode::OK); 117 | // assert_eq!(prelude.headers.get("content-type").unwrap(), "text/plain"); 118 | // assert_eq!(remaining, remaining_data); 119 | // } 120 | 121 | // #[tokio::test] 122 | // async fn test_process_buffer() { 123 | // let payload = r#"{"statusCode": 200, "headers": {"Content-Type": "text/plain"}, "body": "Hello"}"#; 124 | // let null_padding = vec![0u8; 8]; 125 | // let remaining_data = b"Remaining data"; 126 | // 127 | // let mut buffer = payload.as_bytes().to_vec(); 128 | // buffer.extend_from_slice(&null_padding); 129 | // buffer.extend_from_slice(remaining_data); 130 | // 131 | // let (metadata_prelude, remaining) = process_buffer(&buffer); 132 | // 133 | // assert!(metadata_prelude.is_some()); 134 | // let prelude = metadata_prelude.unwrap(); 135 | // assert_eq!(prelude.status_code, StatusCode::OK); 136 | // assert_eq!(prelude.headers.get("content-type").unwrap(), "text/plain"); 137 | // assert_eq!(remaining, remaining_data); 138 | // } 139 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use lambda_web_gateway::run_app; 2 | 3 | #[tokio::main] 4 | async fn main() { 5 | run_app().await; 6 | } 7 | --------------------------------------------------------------------------------