├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── examples └── server.rs └── src └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /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.24.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 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 = "async-trait" 31 | version = "0.1.83" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" 34 | dependencies = [ 35 | "proc-macro2", 36 | "quote", 37 | "syn", 38 | ] 39 | 40 | [[package]] 41 | name = "autocfg" 42 | version = "1.4.0" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 45 | 46 | [[package]] 47 | name = "aws-lc-rs" 48 | version = "1.9.0" 49 | source = "registry+https://github.com/rust-lang/crates.io-index" 50 | checksum = "2f95446d919226d587817a7d21379e6eb099b97b45110a7f272a444ca5c54070" 51 | dependencies = [ 52 | "aws-lc-sys", 53 | "mirai-annotations", 54 | "paste", 55 | "zeroize", 56 | ] 57 | 58 | [[package]] 59 | name = "aws-lc-sys" 60 | version = "0.21.1" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "234314bd569802ec87011d653d6815c6d7b9ffb969e9fee5b8b20ef860e8dce9" 63 | dependencies = [ 64 | "bindgen", 65 | "cc", 66 | "cmake", 67 | "dunce", 68 | "fs_extra", 69 | "libc", 70 | "paste", 71 | ] 72 | 73 | [[package]] 74 | name = "axum" 75 | version = "0.7.7" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" 78 | dependencies = [ 79 | "async-trait", 80 | "axum-core", 81 | "base64", 82 | "bytes", 83 | "futures-util", 84 | "http", 85 | "http-body", 86 | "http-body-util", 87 | "hyper", 88 | "hyper-util", 89 | "itoa", 90 | "matchit", 91 | "memchr", 92 | "mime", 93 | "percent-encoding", 94 | "pin-project-lite", 95 | "rustversion", 96 | "serde", 97 | "serde_json", 98 | "serde_path_to_error", 99 | "serde_urlencoded", 100 | "sha1", 101 | "sync_wrapper 1.0.1", 102 | "tokio", 103 | "tokio-tungstenite", 104 | "tower", 105 | "tower-layer", 106 | "tower-service", 107 | "tracing", 108 | ] 109 | 110 | [[package]] 111 | name = "axum-core" 112 | version = "0.4.5" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" 115 | dependencies = [ 116 | "async-trait", 117 | "bytes", 118 | "futures-util", 119 | "http", 120 | "http-body", 121 | "http-body-util", 122 | "mime", 123 | "pin-project-lite", 124 | "rustversion", 125 | "sync_wrapper 1.0.1", 126 | "tower-layer", 127 | "tower-service", 128 | "tracing", 129 | ] 130 | 131 | [[package]] 132 | name = "backtrace" 133 | version = "0.3.74" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 136 | dependencies = [ 137 | "addr2line", 138 | "cfg-if", 139 | "libc", 140 | "miniz_oxide", 141 | "object", 142 | "rustc-demangle", 143 | "windows-targets", 144 | ] 145 | 146 | [[package]] 147 | name = "base64" 148 | version = "0.22.1" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 151 | 152 | [[package]] 153 | name = "bindgen" 154 | version = "0.69.4" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" 157 | dependencies = [ 158 | "bitflags", 159 | "cexpr", 160 | "clang-sys", 161 | "itertools", 162 | "lazy_static", 163 | "lazycell", 164 | "log", 165 | "prettyplease", 166 | "proc-macro2", 167 | "quote", 168 | "regex", 169 | "rustc-hash", 170 | "shlex", 171 | "syn", 172 | "which", 173 | ] 174 | 175 | [[package]] 176 | name = "bitflags" 177 | version = "2.6.0" 178 | source = "registry+https://github.com/rust-lang/crates.io-index" 179 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 180 | 181 | [[package]] 182 | name = "block-buffer" 183 | version = "0.10.4" 184 | source = "registry+https://github.com/rust-lang/crates.io-index" 185 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 186 | dependencies = [ 187 | "generic-array", 188 | ] 189 | 190 | [[package]] 191 | name = "byteorder" 192 | version = "1.5.0" 193 | source = "registry+https://github.com/rust-lang/crates.io-index" 194 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 195 | 196 | [[package]] 197 | name = "bytes" 198 | version = "1.7.2" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" 201 | 202 | [[package]] 203 | name = "cc" 204 | version = "1.1.21" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" 207 | dependencies = [ 208 | "jobserver", 209 | "libc", 210 | "shlex", 211 | ] 212 | 213 | [[package]] 214 | name = "cexpr" 215 | version = "0.6.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" 218 | dependencies = [ 219 | "nom", 220 | ] 221 | 222 | [[package]] 223 | name = "cfg-if" 224 | version = "1.0.0" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 227 | 228 | [[package]] 229 | name = "clang-sys" 230 | version = "1.8.1" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" 233 | dependencies = [ 234 | "glob", 235 | "libc", 236 | "libloading", 237 | ] 238 | 239 | [[package]] 240 | name = "cmake" 241 | version = "0.1.51" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" 244 | dependencies = [ 245 | "cc", 246 | ] 247 | 248 | [[package]] 249 | name = "cpufeatures" 250 | version = "0.2.14" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" 253 | dependencies = [ 254 | "libc", 255 | ] 256 | 257 | [[package]] 258 | name = "crypto-common" 259 | version = "0.1.6" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 262 | dependencies = [ 263 | "generic-array", 264 | "typenum", 265 | ] 266 | 267 | [[package]] 268 | name = "data-encoding" 269 | version = "2.6.0" 270 | source = "registry+https://github.com/rust-lang/crates.io-index" 271 | checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" 272 | 273 | [[package]] 274 | name = "digest" 275 | version = "0.10.7" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 278 | dependencies = [ 279 | "block-buffer", 280 | "crypto-common", 281 | ] 282 | 283 | [[package]] 284 | name = "dunce" 285 | version = "1.0.5" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" 288 | 289 | [[package]] 290 | name = "either" 291 | version = "1.13.0" 292 | source = "registry+https://github.com/rust-lang/crates.io-index" 293 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 294 | 295 | [[package]] 296 | name = "errno" 297 | version = "0.3.9" 298 | source = "registry+https://github.com/rust-lang/crates.io-index" 299 | checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" 300 | dependencies = [ 301 | "libc", 302 | "windows-sys", 303 | ] 304 | 305 | [[package]] 306 | name = "fnv" 307 | version = "1.0.7" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 310 | 311 | [[package]] 312 | name = "form_urlencoded" 313 | version = "1.2.1" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 316 | dependencies = [ 317 | "percent-encoding", 318 | ] 319 | 320 | [[package]] 321 | name = "fs_extra" 322 | version = "1.3.0" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" 325 | 326 | [[package]] 327 | name = "futures" 328 | version = "0.3.30" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" 331 | dependencies = [ 332 | "futures-channel", 333 | "futures-core", 334 | "futures-executor", 335 | "futures-io", 336 | "futures-sink", 337 | "futures-task", 338 | "futures-util", 339 | ] 340 | 341 | [[package]] 342 | name = "futures-channel" 343 | version = "0.3.30" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" 346 | dependencies = [ 347 | "futures-core", 348 | "futures-sink", 349 | ] 350 | 351 | [[package]] 352 | name = "futures-core" 353 | version = "0.3.30" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 356 | 357 | [[package]] 358 | name = "futures-executor" 359 | version = "0.3.30" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" 362 | dependencies = [ 363 | "futures-core", 364 | "futures-task", 365 | "futures-util", 366 | ] 367 | 368 | [[package]] 369 | name = "futures-io" 370 | version = "0.3.30" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" 373 | 374 | [[package]] 375 | name = "futures-macro" 376 | version = "0.3.30" 377 | source = "registry+https://github.com/rust-lang/crates.io-index" 378 | checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" 379 | dependencies = [ 380 | "proc-macro2", 381 | "quote", 382 | "syn", 383 | ] 384 | 385 | [[package]] 386 | name = "futures-sink" 387 | version = "0.3.30" 388 | source = "registry+https://github.com/rust-lang/crates.io-index" 389 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" 390 | 391 | [[package]] 392 | name = "futures-task" 393 | version = "0.3.30" 394 | source = "registry+https://github.com/rust-lang/crates.io-index" 395 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 396 | 397 | [[package]] 398 | name = "futures-util" 399 | version = "0.3.30" 400 | source = "registry+https://github.com/rust-lang/crates.io-index" 401 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 402 | dependencies = [ 403 | "futures-channel", 404 | "futures-core", 405 | "futures-io", 406 | "futures-macro", 407 | "futures-sink", 408 | "futures-task", 409 | "memchr", 410 | "pin-project-lite", 411 | "pin-utils", 412 | "slab", 413 | ] 414 | 415 | [[package]] 416 | name = "generic-array" 417 | version = "0.14.7" 418 | source = "registry+https://github.com/rust-lang/crates.io-index" 419 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 420 | dependencies = [ 421 | "typenum", 422 | "version_check", 423 | ] 424 | 425 | [[package]] 426 | name = "getrandom" 427 | version = "0.2.15" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 430 | dependencies = [ 431 | "cfg-if", 432 | "libc", 433 | "wasi", 434 | ] 435 | 436 | [[package]] 437 | name = "gimli" 438 | version = "0.31.0" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" 441 | 442 | [[package]] 443 | name = "glob" 444 | version = "0.3.1" 445 | source = "registry+https://github.com/rust-lang/crates.io-index" 446 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" 447 | 448 | [[package]] 449 | name = "hermit-abi" 450 | version = "0.3.9" 451 | source = "registry+https://github.com/rust-lang/crates.io-index" 452 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 453 | 454 | [[package]] 455 | name = "home" 456 | version = "0.5.9" 457 | source = "registry+https://github.com/rust-lang/crates.io-index" 458 | checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" 459 | dependencies = [ 460 | "windows-sys", 461 | ] 462 | 463 | [[package]] 464 | name = "http" 465 | version = "1.1.0" 466 | source = "registry+https://github.com/rust-lang/crates.io-index" 467 | checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" 468 | dependencies = [ 469 | "bytes", 470 | "fnv", 471 | "itoa", 472 | ] 473 | 474 | [[package]] 475 | name = "http-body" 476 | version = "1.0.1" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 479 | dependencies = [ 480 | "bytes", 481 | "http", 482 | ] 483 | 484 | [[package]] 485 | name = "http-body-util" 486 | version = "0.1.2" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" 489 | dependencies = [ 490 | "bytes", 491 | "futures-util", 492 | "http", 493 | "http-body", 494 | "pin-project-lite", 495 | ] 496 | 497 | [[package]] 498 | name = "httparse" 499 | version = "1.9.5" 500 | source = "registry+https://github.com/rust-lang/crates.io-index" 501 | checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" 502 | 503 | [[package]] 504 | name = "httpdate" 505 | version = "1.0.3" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 508 | 509 | [[package]] 510 | name = "hyper" 511 | version = "1.4.1" 512 | source = "registry+https://github.com/rust-lang/crates.io-index" 513 | checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" 514 | dependencies = [ 515 | "bytes", 516 | "futures-channel", 517 | "futures-util", 518 | "http", 519 | "http-body", 520 | "httparse", 521 | "httpdate", 522 | "itoa", 523 | "pin-project-lite", 524 | "smallvec", 525 | "tokio", 526 | ] 527 | 528 | [[package]] 529 | name = "hyper-util" 530 | version = "0.1.9" 531 | source = "registry+https://github.com/rust-lang/crates.io-index" 532 | checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" 533 | dependencies = [ 534 | "bytes", 535 | "futures-util", 536 | "http", 537 | "http-body", 538 | "hyper", 539 | "pin-project-lite", 540 | "tokio", 541 | "tower-service", 542 | ] 543 | 544 | [[package]] 545 | name = "idna" 546 | version = "0.5.0" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" 549 | dependencies = [ 550 | "unicode-bidi", 551 | "unicode-normalization", 552 | ] 553 | 554 | [[package]] 555 | name = "itertools" 556 | version = "0.12.1" 557 | source = "registry+https://github.com/rust-lang/crates.io-index" 558 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 559 | dependencies = [ 560 | "either", 561 | ] 562 | 563 | [[package]] 564 | name = "itoa" 565 | version = "1.0.11" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 568 | 569 | [[package]] 570 | name = "jobserver" 571 | version = "0.1.32" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" 574 | dependencies = [ 575 | "libc", 576 | ] 577 | 578 | [[package]] 579 | name = "lazy_static" 580 | version = "1.5.0" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 583 | 584 | [[package]] 585 | name = "lazycell" 586 | version = "1.3.0" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 589 | 590 | [[package]] 591 | name = "libc" 592 | version = "0.2.159" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" 595 | 596 | [[package]] 597 | name = "libloading" 598 | version = "0.8.5" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" 601 | dependencies = [ 602 | "cfg-if", 603 | "windows-targets", 604 | ] 605 | 606 | [[package]] 607 | name = "linux-raw-sys" 608 | version = "0.4.14" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 611 | 612 | [[package]] 613 | name = "log" 614 | version = "0.4.22" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 617 | 618 | [[package]] 619 | name = "matchit" 620 | version = "0.7.3" 621 | source = "registry+https://github.com/rust-lang/crates.io-index" 622 | checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" 623 | 624 | [[package]] 625 | name = "memchr" 626 | version = "2.7.4" 627 | source = "registry+https://github.com/rust-lang/crates.io-index" 628 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 629 | 630 | [[package]] 631 | name = "mime" 632 | version = "0.3.17" 633 | source = "registry+https://github.com/rust-lang/crates.io-index" 634 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 635 | 636 | [[package]] 637 | name = "minimal-lexical" 638 | version = "0.2.1" 639 | source = "registry+https://github.com/rust-lang/crates.io-index" 640 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 641 | 642 | [[package]] 643 | name = "miniz_oxide" 644 | version = "0.8.0" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" 647 | dependencies = [ 648 | "adler2", 649 | ] 650 | 651 | [[package]] 652 | name = "mio" 653 | version = "1.0.2" 654 | source = "registry+https://github.com/rust-lang/crates.io-index" 655 | checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" 656 | dependencies = [ 657 | "hermit-abi", 658 | "libc", 659 | "wasi", 660 | "windows-sys", 661 | ] 662 | 663 | [[package]] 664 | name = "mirai-annotations" 665 | version = "1.12.0" 666 | source = "registry+https://github.com/rust-lang/crates.io-index" 667 | checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" 668 | 669 | [[package]] 670 | name = "nom" 671 | version = "7.1.3" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 674 | dependencies = [ 675 | "memchr", 676 | "minimal-lexical", 677 | ] 678 | 679 | [[package]] 680 | name = "object" 681 | version = "0.36.4" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" 684 | dependencies = [ 685 | "memchr", 686 | ] 687 | 688 | [[package]] 689 | name = "once_cell" 690 | version = "1.20.1" 691 | source = "registry+https://github.com/rust-lang/crates.io-index" 692 | checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" 693 | dependencies = [ 694 | "portable-atomic", 695 | ] 696 | 697 | [[package]] 698 | name = "openai-realtime-proxy" 699 | version = "0.1.0" 700 | dependencies = [ 701 | "axum", 702 | "futures", 703 | "http", 704 | "rustls", 705 | "tokio", 706 | "tokio-tungstenite", 707 | "url", 708 | ] 709 | 710 | [[package]] 711 | name = "paste" 712 | version = "1.0.15" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 715 | 716 | [[package]] 717 | name = "percent-encoding" 718 | version = "2.3.1" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 721 | 722 | [[package]] 723 | name = "pin-project-lite" 724 | version = "0.2.14" 725 | source = "registry+https://github.com/rust-lang/crates.io-index" 726 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 727 | 728 | [[package]] 729 | name = "pin-utils" 730 | version = "0.1.0" 731 | source = "registry+https://github.com/rust-lang/crates.io-index" 732 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 733 | 734 | [[package]] 735 | name = "portable-atomic" 736 | version = "1.9.0" 737 | source = "registry+https://github.com/rust-lang/crates.io-index" 738 | checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" 739 | 740 | [[package]] 741 | name = "ppv-lite86" 742 | version = "0.2.20" 743 | source = "registry+https://github.com/rust-lang/crates.io-index" 744 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 745 | dependencies = [ 746 | "zerocopy", 747 | ] 748 | 749 | [[package]] 750 | name = "prettyplease" 751 | version = "0.2.22" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" 754 | dependencies = [ 755 | "proc-macro2", 756 | "syn", 757 | ] 758 | 759 | [[package]] 760 | name = "proc-macro2" 761 | version = "1.0.86" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" 764 | dependencies = [ 765 | "unicode-ident", 766 | ] 767 | 768 | [[package]] 769 | name = "quote" 770 | version = "1.0.37" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 773 | dependencies = [ 774 | "proc-macro2", 775 | ] 776 | 777 | [[package]] 778 | name = "rand" 779 | version = "0.8.5" 780 | source = "registry+https://github.com/rust-lang/crates.io-index" 781 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 782 | dependencies = [ 783 | "libc", 784 | "rand_chacha", 785 | "rand_core", 786 | ] 787 | 788 | [[package]] 789 | name = "rand_chacha" 790 | version = "0.3.1" 791 | source = "registry+https://github.com/rust-lang/crates.io-index" 792 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 793 | dependencies = [ 794 | "ppv-lite86", 795 | "rand_core", 796 | ] 797 | 798 | [[package]] 799 | name = "rand_core" 800 | version = "0.6.4" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 803 | dependencies = [ 804 | "getrandom", 805 | ] 806 | 807 | [[package]] 808 | name = "regex" 809 | version = "1.10.6" 810 | source = "registry+https://github.com/rust-lang/crates.io-index" 811 | checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" 812 | dependencies = [ 813 | "aho-corasick", 814 | "memchr", 815 | "regex-automata", 816 | "regex-syntax", 817 | ] 818 | 819 | [[package]] 820 | name = "regex-automata" 821 | version = "0.4.7" 822 | source = "registry+https://github.com/rust-lang/crates.io-index" 823 | checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" 824 | dependencies = [ 825 | "aho-corasick", 826 | "memchr", 827 | "regex-syntax", 828 | ] 829 | 830 | [[package]] 831 | name = "regex-syntax" 832 | version = "0.8.4" 833 | source = "registry+https://github.com/rust-lang/crates.io-index" 834 | checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" 835 | 836 | [[package]] 837 | name = "ring" 838 | version = "0.17.8" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" 841 | dependencies = [ 842 | "cc", 843 | "cfg-if", 844 | "getrandom", 845 | "libc", 846 | "spin", 847 | "untrusted", 848 | "windows-sys", 849 | ] 850 | 851 | [[package]] 852 | name = "rustc-demangle" 853 | version = "0.1.24" 854 | source = "registry+https://github.com/rust-lang/crates.io-index" 855 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 856 | 857 | [[package]] 858 | name = "rustc-hash" 859 | version = "1.1.0" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 862 | 863 | [[package]] 864 | name = "rustix" 865 | version = "0.38.37" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" 868 | dependencies = [ 869 | "bitflags", 870 | "errno", 871 | "libc", 872 | "linux-raw-sys", 873 | "windows-sys", 874 | ] 875 | 876 | [[package]] 877 | name = "rustls" 878 | version = "0.23.13" 879 | source = "registry+https://github.com/rust-lang/crates.io-index" 880 | checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" 881 | dependencies = [ 882 | "aws-lc-rs", 883 | "log", 884 | "once_cell", 885 | "rustls-pki-types", 886 | "rustls-webpki", 887 | "subtle", 888 | "zeroize", 889 | ] 890 | 891 | [[package]] 892 | name = "rustls-pki-types" 893 | version = "1.8.0" 894 | source = "registry+https://github.com/rust-lang/crates.io-index" 895 | checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" 896 | 897 | [[package]] 898 | name = "rustls-webpki" 899 | version = "0.102.8" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" 902 | dependencies = [ 903 | "aws-lc-rs", 904 | "ring", 905 | "rustls-pki-types", 906 | "untrusted", 907 | ] 908 | 909 | [[package]] 910 | name = "rustversion" 911 | version = "1.0.17" 912 | source = "registry+https://github.com/rust-lang/crates.io-index" 913 | checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" 914 | 915 | [[package]] 916 | name = "ryu" 917 | version = "1.0.18" 918 | source = "registry+https://github.com/rust-lang/crates.io-index" 919 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 920 | 921 | [[package]] 922 | name = "serde" 923 | version = "1.0.210" 924 | source = "registry+https://github.com/rust-lang/crates.io-index" 925 | checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" 926 | dependencies = [ 927 | "serde_derive", 928 | ] 929 | 930 | [[package]] 931 | name = "serde_derive" 932 | version = "1.0.210" 933 | source = "registry+https://github.com/rust-lang/crates.io-index" 934 | checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" 935 | dependencies = [ 936 | "proc-macro2", 937 | "quote", 938 | "syn", 939 | ] 940 | 941 | [[package]] 942 | name = "serde_json" 943 | version = "1.0.128" 944 | source = "registry+https://github.com/rust-lang/crates.io-index" 945 | checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" 946 | dependencies = [ 947 | "itoa", 948 | "memchr", 949 | "ryu", 950 | "serde", 951 | ] 952 | 953 | [[package]] 954 | name = "serde_path_to_error" 955 | version = "0.1.16" 956 | source = "registry+https://github.com/rust-lang/crates.io-index" 957 | checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" 958 | dependencies = [ 959 | "itoa", 960 | "serde", 961 | ] 962 | 963 | [[package]] 964 | name = "serde_urlencoded" 965 | version = "0.7.1" 966 | source = "registry+https://github.com/rust-lang/crates.io-index" 967 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 968 | dependencies = [ 969 | "form_urlencoded", 970 | "itoa", 971 | "ryu", 972 | "serde", 973 | ] 974 | 975 | [[package]] 976 | name = "sha1" 977 | version = "0.10.6" 978 | source = "registry+https://github.com/rust-lang/crates.io-index" 979 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 980 | dependencies = [ 981 | "cfg-if", 982 | "cpufeatures", 983 | "digest", 984 | ] 985 | 986 | [[package]] 987 | name = "shlex" 988 | version = "1.3.0" 989 | source = "registry+https://github.com/rust-lang/crates.io-index" 990 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 991 | 992 | [[package]] 993 | name = "slab" 994 | version = "0.4.9" 995 | source = "registry+https://github.com/rust-lang/crates.io-index" 996 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 997 | dependencies = [ 998 | "autocfg", 999 | ] 1000 | 1001 | [[package]] 1002 | name = "smallvec" 1003 | version = "1.13.2" 1004 | source = "registry+https://github.com/rust-lang/crates.io-index" 1005 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1006 | 1007 | [[package]] 1008 | name = "socket2" 1009 | version = "0.5.7" 1010 | source = "registry+https://github.com/rust-lang/crates.io-index" 1011 | checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" 1012 | dependencies = [ 1013 | "libc", 1014 | "windows-sys", 1015 | ] 1016 | 1017 | [[package]] 1018 | name = "spin" 1019 | version = "0.9.8" 1020 | source = "registry+https://github.com/rust-lang/crates.io-index" 1021 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1022 | 1023 | [[package]] 1024 | name = "subtle" 1025 | version = "2.6.1" 1026 | source = "registry+https://github.com/rust-lang/crates.io-index" 1027 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 1028 | 1029 | [[package]] 1030 | name = "syn" 1031 | version = "2.0.79" 1032 | source = "registry+https://github.com/rust-lang/crates.io-index" 1033 | checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" 1034 | dependencies = [ 1035 | "proc-macro2", 1036 | "quote", 1037 | "unicode-ident", 1038 | ] 1039 | 1040 | [[package]] 1041 | name = "sync_wrapper" 1042 | version = "0.1.2" 1043 | source = "registry+https://github.com/rust-lang/crates.io-index" 1044 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 1045 | 1046 | [[package]] 1047 | name = "sync_wrapper" 1048 | version = "1.0.1" 1049 | source = "registry+https://github.com/rust-lang/crates.io-index" 1050 | checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" 1051 | 1052 | [[package]] 1053 | name = "thiserror" 1054 | version = "1.0.64" 1055 | source = "registry+https://github.com/rust-lang/crates.io-index" 1056 | checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" 1057 | dependencies = [ 1058 | "thiserror-impl", 1059 | ] 1060 | 1061 | [[package]] 1062 | name = "thiserror-impl" 1063 | version = "1.0.64" 1064 | source = "registry+https://github.com/rust-lang/crates.io-index" 1065 | checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" 1066 | dependencies = [ 1067 | "proc-macro2", 1068 | "quote", 1069 | "syn", 1070 | ] 1071 | 1072 | [[package]] 1073 | name = "tinyvec" 1074 | version = "1.8.0" 1075 | source = "registry+https://github.com/rust-lang/crates.io-index" 1076 | checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" 1077 | dependencies = [ 1078 | "tinyvec_macros", 1079 | ] 1080 | 1081 | [[package]] 1082 | name = "tinyvec_macros" 1083 | version = "0.1.1" 1084 | source = "registry+https://github.com/rust-lang/crates.io-index" 1085 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 1086 | 1087 | [[package]] 1088 | name = "tokio" 1089 | version = "1.40.0" 1090 | source = "registry+https://github.com/rust-lang/crates.io-index" 1091 | checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" 1092 | dependencies = [ 1093 | "backtrace", 1094 | "bytes", 1095 | "libc", 1096 | "mio", 1097 | "pin-project-lite", 1098 | "socket2", 1099 | "tokio-macros", 1100 | "windows-sys", 1101 | ] 1102 | 1103 | [[package]] 1104 | name = "tokio-macros" 1105 | version = "2.4.0" 1106 | source = "registry+https://github.com/rust-lang/crates.io-index" 1107 | checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" 1108 | dependencies = [ 1109 | "proc-macro2", 1110 | "quote", 1111 | "syn", 1112 | ] 1113 | 1114 | [[package]] 1115 | name = "tokio-rustls" 1116 | version = "0.26.0" 1117 | source = "registry+https://github.com/rust-lang/crates.io-index" 1118 | checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" 1119 | dependencies = [ 1120 | "rustls", 1121 | "rustls-pki-types", 1122 | "tokio", 1123 | ] 1124 | 1125 | [[package]] 1126 | name = "tokio-tungstenite" 1127 | version = "0.24.0" 1128 | source = "registry+https://github.com/rust-lang/crates.io-index" 1129 | checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" 1130 | dependencies = [ 1131 | "futures-util", 1132 | "log", 1133 | "rustls", 1134 | "rustls-pki-types", 1135 | "tokio", 1136 | "tokio-rustls", 1137 | "tungstenite", 1138 | "webpki-roots", 1139 | ] 1140 | 1141 | [[package]] 1142 | name = "tower" 1143 | version = "0.5.1" 1144 | source = "registry+https://github.com/rust-lang/crates.io-index" 1145 | checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" 1146 | dependencies = [ 1147 | "futures-core", 1148 | "futures-util", 1149 | "pin-project-lite", 1150 | "sync_wrapper 0.1.2", 1151 | "tokio", 1152 | "tower-layer", 1153 | "tower-service", 1154 | "tracing", 1155 | ] 1156 | 1157 | [[package]] 1158 | name = "tower-layer" 1159 | version = "0.3.3" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 1162 | 1163 | [[package]] 1164 | name = "tower-service" 1165 | version = "0.3.3" 1166 | source = "registry+https://github.com/rust-lang/crates.io-index" 1167 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 1168 | 1169 | [[package]] 1170 | name = "tracing" 1171 | version = "0.1.40" 1172 | source = "registry+https://github.com/rust-lang/crates.io-index" 1173 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 1174 | dependencies = [ 1175 | "log", 1176 | "pin-project-lite", 1177 | "tracing-core", 1178 | ] 1179 | 1180 | [[package]] 1181 | name = "tracing-core" 1182 | version = "0.1.32" 1183 | source = "registry+https://github.com/rust-lang/crates.io-index" 1184 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 1185 | dependencies = [ 1186 | "once_cell", 1187 | ] 1188 | 1189 | [[package]] 1190 | name = "tungstenite" 1191 | version = "0.24.0" 1192 | source = "registry+https://github.com/rust-lang/crates.io-index" 1193 | checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" 1194 | dependencies = [ 1195 | "byteorder", 1196 | "bytes", 1197 | "data-encoding", 1198 | "http", 1199 | "httparse", 1200 | "log", 1201 | "rand", 1202 | "rustls", 1203 | "rustls-pki-types", 1204 | "sha1", 1205 | "thiserror", 1206 | "url", 1207 | "utf-8", 1208 | ] 1209 | 1210 | [[package]] 1211 | name = "typenum" 1212 | version = "1.17.0" 1213 | source = "registry+https://github.com/rust-lang/crates.io-index" 1214 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 1215 | 1216 | [[package]] 1217 | name = "unicode-bidi" 1218 | version = "0.3.15" 1219 | source = "registry+https://github.com/rust-lang/crates.io-index" 1220 | checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" 1221 | 1222 | [[package]] 1223 | name = "unicode-ident" 1224 | version = "1.0.13" 1225 | source = "registry+https://github.com/rust-lang/crates.io-index" 1226 | checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" 1227 | 1228 | [[package]] 1229 | name = "unicode-normalization" 1230 | version = "0.1.24" 1231 | source = "registry+https://github.com/rust-lang/crates.io-index" 1232 | checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" 1233 | dependencies = [ 1234 | "tinyvec", 1235 | ] 1236 | 1237 | [[package]] 1238 | name = "untrusted" 1239 | version = "0.9.0" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 1242 | 1243 | [[package]] 1244 | name = "url" 1245 | version = "2.5.2" 1246 | source = "registry+https://github.com/rust-lang/crates.io-index" 1247 | checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" 1248 | dependencies = [ 1249 | "form_urlencoded", 1250 | "idna", 1251 | "percent-encoding", 1252 | ] 1253 | 1254 | [[package]] 1255 | name = "utf-8" 1256 | version = "0.7.6" 1257 | source = "registry+https://github.com/rust-lang/crates.io-index" 1258 | checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 1259 | 1260 | [[package]] 1261 | name = "version_check" 1262 | version = "0.9.5" 1263 | source = "registry+https://github.com/rust-lang/crates.io-index" 1264 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 1265 | 1266 | [[package]] 1267 | name = "wasi" 1268 | version = "0.11.0+wasi-snapshot-preview1" 1269 | source = "registry+https://github.com/rust-lang/crates.io-index" 1270 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1271 | 1272 | [[package]] 1273 | name = "webpki-roots" 1274 | version = "0.26.5" 1275 | source = "registry+https://github.com/rust-lang/crates.io-index" 1276 | checksum = "0bd24728e5af82c6c4ec1b66ac4844bdf8156257fccda846ec58b42cd0cdbe6a" 1277 | dependencies = [ 1278 | "rustls-pki-types", 1279 | ] 1280 | 1281 | [[package]] 1282 | name = "which" 1283 | version = "4.4.2" 1284 | source = "registry+https://github.com/rust-lang/crates.io-index" 1285 | checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" 1286 | dependencies = [ 1287 | "either", 1288 | "home", 1289 | "once_cell", 1290 | "rustix", 1291 | ] 1292 | 1293 | [[package]] 1294 | name = "windows-sys" 1295 | version = "0.52.0" 1296 | source = "registry+https://github.com/rust-lang/crates.io-index" 1297 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1298 | dependencies = [ 1299 | "windows-targets", 1300 | ] 1301 | 1302 | [[package]] 1303 | name = "windows-targets" 1304 | version = "0.52.6" 1305 | source = "registry+https://github.com/rust-lang/crates.io-index" 1306 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 1307 | dependencies = [ 1308 | "windows_aarch64_gnullvm", 1309 | "windows_aarch64_msvc", 1310 | "windows_i686_gnu", 1311 | "windows_i686_gnullvm", 1312 | "windows_i686_msvc", 1313 | "windows_x86_64_gnu", 1314 | "windows_x86_64_gnullvm", 1315 | "windows_x86_64_msvc", 1316 | ] 1317 | 1318 | [[package]] 1319 | name = "windows_aarch64_gnullvm" 1320 | version = "0.52.6" 1321 | source = "registry+https://github.com/rust-lang/crates.io-index" 1322 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 1323 | 1324 | [[package]] 1325 | name = "windows_aarch64_msvc" 1326 | version = "0.52.6" 1327 | source = "registry+https://github.com/rust-lang/crates.io-index" 1328 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 1329 | 1330 | [[package]] 1331 | name = "windows_i686_gnu" 1332 | version = "0.52.6" 1333 | source = "registry+https://github.com/rust-lang/crates.io-index" 1334 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 1335 | 1336 | [[package]] 1337 | name = "windows_i686_gnullvm" 1338 | version = "0.52.6" 1339 | source = "registry+https://github.com/rust-lang/crates.io-index" 1340 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 1341 | 1342 | [[package]] 1343 | name = "windows_i686_msvc" 1344 | version = "0.52.6" 1345 | source = "registry+https://github.com/rust-lang/crates.io-index" 1346 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 1347 | 1348 | [[package]] 1349 | name = "windows_x86_64_gnu" 1350 | version = "0.52.6" 1351 | source = "registry+https://github.com/rust-lang/crates.io-index" 1352 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1353 | 1354 | [[package]] 1355 | name = "windows_x86_64_gnullvm" 1356 | version = "0.52.6" 1357 | source = "registry+https://github.com/rust-lang/crates.io-index" 1358 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1359 | 1360 | [[package]] 1361 | name = "windows_x86_64_msvc" 1362 | version = "0.52.6" 1363 | source = "registry+https://github.com/rust-lang/crates.io-index" 1364 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1365 | 1366 | [[package]] 1367 | name = "zerocopy" 1368 | version = "0.7.35" 1369 | source = "registry+https://github.com/rust-lang/crates.io-index" 1370 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 1371 | dependencies = [ 1372 | "byteorder", 1373 | "zerocopy-derive", 1374 | ] 1375 | 1376 | [[package]] 1377 | name = "zerocopy-derive" 1378 | version = "0.7.35" 1379 | source = "registry+https://github.com/rust-lang/crates.io-index" 1380 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 1381 | dependencies = [ 1382 | "proc-macro2", 1383 | "quote", 1384 | "syn", 1385 | ] 1386 | 1387 | [[package]] 1388 | name = "zeroize" 1389 | version = "1.8.1" 1390 | source = "registry+https://github.com/rust-lang/crates.io-index" 1391 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 1392 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | license = "MIT" 3 | edition = "2021" 4 | version = "0.1.0" 5 | readme = "README.md" 6 | name = "openai-realtime-proxy" 7 | categories = ["api-bindings", "web-programming"] 8 | authors = ["Miguel Piedrafita "] 9 | keywords = ["machine-learning", "openai", "realtime", "proxy"] 10 | repository = "https://github.com/m1guelpf/openai-realtime-proxy" 11 | description = "Safely deploy OpenAI's Realtime APIs in less than 5 minutes!" 12 | 13 | [dependencies] 14 | url = "2.5.2" 15 | http = "1.1.0" 16 | tokio = "1.40.0" 17 | futures = "0.3.30" 18 | rustls = "0.23.13" 19 | axum = { version = "0.7.7", features = ["ws"] } 20 | tokio-tungstenite = { version = "0.24.0", features = [ 21 | "rustls-tls-webpki-roots", 22 | "url", 23 | ] } 24 | 25 | [dev-dependencies] 26 | tokio = { version = "1.40.0", features = ["macros", "rt", "rt-multi-thread"] } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Miguel Piedrafita 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # openai-realtime-proxy 2 | 3 | > Safely deploy OpenAI's Realtime APIs in less than 5 minutes! 4 | 5 | [![crates.io](https://img.shields.io/crates/v/openai-realtime-proxy.svg)](https://crates.io/crates/openai-realtime-proxy) 6 | [![download count badge](https://img.shields.io/crates/d/openai-realtime-proxy.svg)](https://crates.io/crates/openai-realtime-proxy) 7 | [![docs.rs](https://img.shields.io/badge/docs-latest-blue.svg)](https://docs.rs/openai-realtime-proxy) 8 | 9 | The OpenAI Realtime API provides a seamless voice-to-voice conversation experience. To reduce latency, it establishes a WebSocket connection between the client and the backend. However, production apps likely need a proxy sitting in the middle to handle authentication, rate limiting, and avoid leaking sensitive data. 10 | 11 | This library takes care of the proxying part, allowing you to focus on the rest of your application. 12 | 13 | ```rust 14 | use axum::{extract::WebSocketUpgrade, response::IntoResponse, routing::get, Router}; 15 | 16 | #[tokio::main] 17 | async fn main() { 18 | let app = Router::new().route("/ws", get(ws_handler)); 19 | 20 | let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); 21 | axum::serve(listener, app).await.unwrap(); 22 | } 23 | 24 | async fn ws_handler(ws: WebSocketUpgrade) -> impl IntoResponse { 25 | // check for authentication/access/etc. here 26 | 27 | let proxy = realtime_proxy::Proxy::new( 28 | std::env::var("OPENAI_API_KEY").expect("OPENAI_API_TOKEN env var not set.") 29 | ); 30 | 31 | ws.on_upgrade(|socket| proxy.handle(socket)) 32 | } 33 | ``` 34 | 35 | Refer to the [documentation on docs.rs](https://docs.rs/openai-realtime-proxy) for detailed usage instructions. 36 | 37 | ## License 38 | 39 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 40 | -------------------------------------------------------------------------------- /examples/server.rs: -------------------------------------------------------------------------------- 1 | use std::{env, net::SocketAddr}; 2 | 3 | use axum::{extract::WebSocketUpgrade, response::IntoResponse, routing::get, Router}; 4 | use openai_realtime_proxy::Proxy; 5 | use tokio::net::TcpListener; 6 | 7 | #[tokio::main] 8 | async fn main() { 9 | let app = Router::new().route("/ws", get(ws_handler)); 10 | 11 | let addr = SocketAddr::from(( 12 | [0, 0, 0, 0], 13 | env::var("PORT").map_or(Ok(8000), |p| p.parse()).unwrap(), 14 | )); 15 | let listener = TcpListener::bind(&addr).await.unwrap(); 16 | 17 | println!("listening on http://{}", listener.local_addr().unwrap()); 18 | 19 | axum::serve(listener, app.into_make_service()) 20 | .await 21 | .unwrap() 22 | } 23 | 24 | async fn ws_handler(ws: WebSocketUpgrade) -> impl IntoResponse { 25 | // check for authentication/access/etc. here 26 | 27 | let proxy = Proxy::new(env::var("OPENAI_API_KEY").expect("OPENAI_API_TOKEN env var not set.")); 28 | 29 | ws.on_upgrade(|socket| proxy.handle(socket)) 30 | } 31 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | use axum::extract::ws::WebSocket; 2 | use futures::{SinkExt, StreamExt}; 3 | use http::{header, HeaderValue}; 4 | use tokio::net::TcpStream; 5 | use tokio_tungstenite::{ 6 | tungstenite::{ 7 | client::IntoClientRequest, 8 | handshake::client::Response, 9 | protocol::{frame::coding::CloseCode, CloseFrame}, 10 | Message, 11 | }, 12 | MaybeTlsStream, WebSocketStream, 13 | }; 14 | use url::Url; 15 | 16 | pub struct Proxy { 17 | api_token: String, 18 | } 19 | 20 | impl Proxy { 21 | pub fn new(api_token: String) -> Self { 22 | Self { api_token } 23 | } 24 | 25 | pub async fn handle(self, socket: WebSocket) { 26 | // connect to server 27 | let openai_stream = match self.connect().await { 28 | Ok((stream, response)) => { 29 | println!("Server response was {response:?}"); 30 | stream 31 | } 32 | Err(e) => { 33 | println!("WebSocket handshake failed with {e}!"); 34 | return; 35 | } 36 | }; 37 | 38 | let (mut openai_sender, mut openai_receiver) = openai_stream.split(); 39 | 40 | // ... 41 | let (mut client_sender, mut client_receiver) = socket.split(); 42 | 43 | let mut openai_to_client = tokio::spawn(async move { 44 | while let Some(Ok(msg)) = openai_receiver.next().await { 45 | let Some(msg) = msg.into_axum() else { 46 | continue; 47 | }; 48 | 49 | if let Err(e) = client_sender.send(msg).await { 50 | println!("Error sending message to client {e:?}"); 51 | break; 52 | } 53 | } 54 | }); 55 | 56 | let mut client_to_openai = tokio::spawn(async move { 57 | while let Some(Ok(msg)) = client_receiver.next().await { 58 | if let Err(e) = openai_sender.send(msg.into_tungstenite()).await { 59 | println!("Error sending message to openai {e:?}"); 60 | break; 61 | } 62 | } 63 | }); 64 | 65 | tokio::select! { 66 | result = (&mut openai_to_client) => { 67 | if let Err(error) = result { 68 | println!("Error in openai_to_client {error:?}"); 69 | } 70 | client_to_openai.abort(); 71 | }, 72 | result = (&mut client_to_openai) => { 73 | if let Err(error) = result { 74 | println!("Error in client_to_openai {error:?}"); 75 | } 76 | openai_to_client.abort(); 77 | } 78 | } 79 | } 80 | 81 | async fn connect( 82 | &self, 83 | ) -> Result< 84 | (WebSocketStream>, Response), 85 | tokio_tungstenite::tungstenite::Error, 86 | > { 87 | let url = 88 | Url::parse("wss://api.openai.com/v1/realtime?model=gpt-4o-realtime-preview-2024-10-01") 89 | .unwrap(); 90 | 91 | let mut request = url.into_client_request().unwrap(); 92 | let headers = request.headers_mut(); 93 | 94 | headers.insert("OpenAI-Beta", HeaderValue::from_static("realtime=v1")); 95 | headers.insert( 96 | header::USER_AGENT, 97 | HeaderValue::from_static("rust-openai-proxy"), 98 | ); 99 | headers.insert( 100 | header::AUTHORIZATION, 101 | HeaderValue::from_str(&format!("Bearer {}", self.api_token)).unwrap(), 102 | ); 103 | 104 | tokio_tungstenite::connect_async(request).await 105 | } 106 | } 107 | 108 | trait TungsteniteConverter { 109 | fn into_tungstenite(self) -> Message; 110 | } 111 | 112 | impl TungsteniteConverter for axum::extract::ws::Message { 113 | fn into_tungstenite(self) -> Message { 114 | match self { 115 | Self::Text(text) => Message::Text(text), 116 | Self::Binary(binary) => Message::Binary(binary), 117 | Self::Ping(ping) => Message::Ping(ping), 118 | Self::Pong(pong) => Message::Pong(pong), 119 | Self::Close(Some(close)) => Message::Close(Some(CloseFrame { 120 | code: CloseCode::from(close.code), 121 | reason: close.reason, 122 | })), 123 | Self::Close(None) => Message::Close(None), 124 | } 125 | } 126 | } 127 | 128 | trait AxumConverter { 129 | fn into_axum(self) -> Option; 130 | } 131 | 132 | impl AxumConverter for Message { 133 | fn into_axum(self) -> Option { 134 | match self { 135 | Self::Text(text) => Some(axum::extract::ws::Message::Text(text)), 136 | Self::Binary(binary) => Some(axum::extract::ws::Message::Binary(binary)), 137 | Self::Ping(ping) => Some(axum::extract::ws::Message::Ping(ping)), 138 | Self::Pong(pong) => Some(axum::extract::ws::Message::Pong(pong)), 139 | Self::Close(Some(close)) => Some(axum::extract::ws::Message::Close(Some( 140 | axum::extract::ws::CloseFrame { 141 | code: close.code.into(), 142 | reason: close.reason, 143 | }, 144 | ))), 145 | Self::Close(None) => Some(axum::extract::ws::Message::Close(None)), 146 | Self::Frame(_) => None, 147 | } 148 | } 149 | } 150 | --------------------------------------------------------------------------------