├── .env ├── .gitattributes ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md └── src ├── cl.rs ├── main.rs ├── model.rs └── utils.rs /.env: -------------------------------------------------------------------------------- 1 | RUST_LOG=info -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target -------------------------------------------------------------------------------- /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.13" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" 34 | dependencies = [ 35 | "anstyle", 36 | "anstyle-parse", 37 | "anstyle-query", 38 | "anstyle-wincon", 39 | "colorchoice", 40 | "utf8parse", 41 | ] 42 | 43 | [[package]] 44 | name = "anstyle" 45 | version = "1.0.6" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" 48 | 49 | [[package]] 50 | name = "anstyle-parse" 51 | version = "0.2.3" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" 54 | dependencies = [ 55 | "utf8parse", 56 | ] 57 | 58 | [[package]] 59 | name = "anstyle-query" 60 | version = "1.0.2" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" 63 | dependencies = [ 64 | "windows-sys 0.52.0", 65 | ] 66 | 67 | [[package]] 68 | name = "anstyle-wincon" 69 | version = "3.0.2" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" 72 | dependencies = [ 73 | "anstyle", 74 | "windows-sys 0.52.0", 75 | ] 76 | 77 | [[package]] 78 | name = "autocfg" 79 | version = "1.2.0" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" 82 | 83 | [[package]] 84 | name = "backtrace" 85 | version = "0.3.71" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" 88 | dependencies = [ 89 | "addr2line", 90 | "cc", 91 | "cfg-if", 92 | "libc", 93 | "miniz_oxide", 94 | "object", 95 | "rustc-demangle", 96 | ] 97 | 98 | [[package]] 99 | name = "base64" 100 | version = "0.21.7" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 103 | 104 | [[package]] 105 | name = "bitflags" 106 | version = "1.3.2" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 109 | 110 | [[package]] 111 | name = "bitflags" 112 | version = "2.5.0" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" 115 | 116 | [[package]] 117 | name = "bumpalo" 118 | version = "3.16.0" 119 | source = "registry+https://github.com/rust-lang/crates.io-index" 120 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 121 | 122 | [[package]] 123 | name = "bytes" 124 | version = "1.6.0" 125 | source = "registry+https://github.com/rust-lang/crates.io-index" 126 | checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" 127 | 128 | [[package]] 129 | name = "cc" 130 | version = "1.0.94" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" 133 | 134 | [[package]] 135 | name = "cfg-if" 136 | version = "1.0.0" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 139 | 140 | [[package]] 141 | name = "colorchoice" 142 | version = "1.0.0" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 145 | 146 | [[package]] 147 | name = "core-foundation" 148 | version = "0.9.4" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 151 | dependencies = [ 152 | "core-foundation-sys", 153 | "libc", 154 | ] 155 | 156 | [[package]] 157 | name = "core-foundation-sys" 158 | version = "0.8.6" 159 | source = "registry+https://github.com/rust-lang/crates.io-index" 160 | checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" 161 | 162 | [[package]] 163 | name = "crypto-http-protcols" 164 | version = "0.1.0" 165 | dependencies = [ 166 | "dashmap", 167 | "dotenv", 168 | "env_logger", 169 | "futures", 170 | "h3", 171 | "h3-quinn", 172 | "http 1.1.0", 173 | "log", 174 | "quinn", 175 | "reqwest", 176 | "rustls", 177 | "rustls-native-certs", 178 | "tokio", 179 | ] 180 | 181 | [[package]] 182 | name = "dashmap" 183 | version = "5.5.3" 184 | source = "registry+https://github.com/rust-lang/crates.io-index" 185 | checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" 186 | dependencies = [ 187 | "cfg-if", 188 | "hashbrown", 189 | "lock_api", 190 | "once_cell", 191 | "parking_lot_core", 192 | ] 193 | 194 | [[package]] 195 | name = "dotenv" 196 | version = "0.15.0" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" 199 | 200 | [[package]] 201 | name = "encoding_rs" 202 | version = "0.8.34" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" 205 | dependencies = [ 206 | "cfg-if", 207 | ] 208 | 209 | [[package]] 210 | name = "env_filter" 211 | version = "0.1.0" 212 | source = "registry+https://github.com/rust-lang/crates.io-index" 213 | checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" 214 | dependencies = [ 215 | "log", 216 | "regex", 217 | ] 218 | 219 | [[package]] 220 | name = "env_logger" 221 | version = "0.11.3" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" 224 | dependencies = [ 225 | "anstream", 226 | "anstyle", 227 | "env_filter", 228 | "humantime", 229 | "log", 230 | ] 231 | 232 | [[package]] 233 | name = "equivalent" 234 | version = "1.0.1" 235 | source = "registry+https://github.com/rust-lang/crates.io-index" 236 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 237 | 238 | [[package]] 239 | name = "errno" 240 | version = "0.3.8" 241 | source = "registry+https://github.com/rust-lang/crates.io-index" 242 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" 243 | dependencies = [ 244 | "libc", 245 | "windows-sys 0.52.0", 246 | ] 247 | 248 | [[package]] 249 | name = "fastrand" 250 | version = "2.0.2" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" 253 | 254 | [[package]] 255 | name = "fnv" 256 | version = "1.0.7" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 259 | 260 | [[package]] 261 | name = "foreign-types" 262 | version = "0.3.2" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 265 | dependencies = [ 266 | "foreign-types-shared", 267 | ] 268 | 269 | [[package]] 270 | name = "foreign-types-shared" 271 | version = "0.1.1" 272 | source = "registry+https://github.com/rust-lang/crates.io-index" 273 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 274 | 275 | [[package]] 276 | name = "form_urlencoded" 277 | version = "1.2.1" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 280 | dependencies = [ 281 | "percent-encoding", 282 | ] 283 | 284 | [[package]] 285 | name = "futures" 286 | version = "0.3.30" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" 289 | dependencies = [ 290 | "futures-channel", 291 | "futures-core", 292 | "futures-executor", 293 | "futures-io", 294 | "futures-sink", 295 | "futures-task", 296 | "futures-util", 297 | ] 298 | 299 | [[package]] 300 | name = "futures-channel" 301 | version = "0.3.30" 302 | source = "registry+https://github.com/rust-lang/crates.io-index" 303 | checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" 304 | dependencies = [ 305 | "futures-core", 306 | "futures-sink", 307 | ] 308 | 309 | [[package]] 310 | name = "futures-core" 311 | version = "0.3.30" 312 | source = "registry+https://github.com/rust-lang/crates.io-index" 313 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 314 | 315 | [[package]] 316 | name = "futures-executor" 317 | version = "0.3.30" 318 | source = "registry+https://github.com/rust-lang/crates.io-index" 319 | checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" 320 | dependencies = [ 321 | "futures-core", 322 | "futures-task", 323 | "futures-util", 324 | ] 325 | 326 | [[package]] 327 | name = "futures-io" 328 | version = "0.3.30" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" 331 | 332 | [[package]] 333 | name = "futures-macro" 334 | version = "0.3.30" 335 | source = "registry+https://github.com/rust-lang/crates.io-index" 336 | checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" 337 | dependencies = [ 338 | "proc-macro2", 339 | "quote", 340 | "syn", 341 | ] 342 | 343 | [[package]] 344 | name = "futures-sink" 345 | version = "0.3.30" 346 | source = "registry+https://github.com/rust-lang/crates.io-index" 347 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" 348 | 349 | [[package]] 350 | name = "futures-task" 351 | version = "0.3.30" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 354 | 355 | [[package]] 356 | name = "futures-util" 357 | version = "0.3.30" 358 | source = "registry+https://github.com/rust-lang/crates.io-index" 359 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 360 | dependencies = [ 361 | "futures-channel", 362 | "futures-core", 363 | "futures-io", 364 | "futures-macro", 365 | "futures-sink", 366 | "futures-task", 367 | "memchr", 368 | "pin-project-lite", 369 | "pin-utils", 370 | "slab", 371 | ] 372 | 373 | [[package]] 374 | name = "getrandom" 375 | version = "0.2.14" 376 | source = "registry+https://github.com/rust-lang/crates.io-index" 377 | checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" 378 | dependencies = [ 379 | "cfg-if", 380 | "libc", 381 | "wasi", 382 | ] 383 | 384 | [[package]] 385 | name = "gimli" 386 | version = "0.28.1" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" 389 | 390 | [[package]] 391 | name = "h2" 392 | version = "0.3.26" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" 395 | dependencies = [ 396 | "bytes", 397 | "fnv", 398 | "futures-core", 399 | "futures-sink", 400 | "futures-util", 401 | "http 0.2.12", 402 | "indexmap", 403 | "slab", 404 | "tokio", 405 | "tokio-util", 406 | "tracing", 407 | ] 408 | 409 | [[package]] 410 | name = "h3" 411 | version = "0.0.4" 412 | source = "registry+https://github.com/rust-lang/crates.io-index" 413 | checksum = "b1c8886b9e6e93e7ed93d9433f3779e8d07e3ff96bc67b977d14c7b20c849411" 414 | dependencies = [ 415 | "bytes", 416 | "fastrand", 417 | "futures-util", 418 | "http 1.1.0", 419 | "pin-project-lite", 420 | "tokio", 421 | "tracing", 422 | ] 423 | 424 | [[package]] 425 | name = "h3-quinn" 426 | version = "0.0.5" 427 | source = "registry+https://github.com/rust-lang/crates.io-index" 428 | checksum = "73786bcc0e4c2692ba62c650f7b950ac236e5300c5de3b1d26330555e2322046" 429 | dependencies = [ 430 | "bytes", 431 | "futures", 432 | "h3", 433 | "quinn", 434 | "quinn-proto", 435 | "tokio", 436 | "tokio-util", 437 | ] 438 | 439 | [[package]] 440 | name = "hashbrown" 441 | version = "0.14.3" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 444 | 445 | [[package]] 446 | name = "hermit-abi" 447 | version = "0.3.9" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 450 | 451 | [[package]] 452 | name = "http" 453 | version = "0.2.12" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" 456 | dependencies = [ 457 | "bytes", 458 | "fnv", 459 | "itoa", 460 | ] 461 | 462 | [[package]] 463 | name = "http" 464 | version = "1.1.0" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" 467 | dependencies = [ 468 | "bytes", 469 | "fnv", 470 | "itoa", 471 | ] 472 | 473 | [[package]] 474 | name = "http-body" 475 | version = "0.4.6" 476 | source = "registry+https://github.com/rust-lang/crates.io-index" 477 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" 478 | dependencies = [ 479 | "bytes", 480 | "http 0.2.12", 481 | "pin-project-lite", 482 | ] 483 | 484 | [[package]] 485 | name = "httparse" 486 | version = "1.8.0" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 489 | 490 | [[package]] 491 | name = "httpdate" 492 | version = "1.0.3" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 495 | 496 | [[package]] 497 | name = "humantime" 498 | version = "2.1.0" 499 | source = "registry+https://github.com/rust-lang/crates.io-index" 500 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 501 | 502 | [[package]] 503 | name = "hyper" 504 | version = "0.14.28" 505 | source = "registry+https://github.com/rust-lang/crates.io-index" 506 | checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" 507 | dependencies = [ 508 | "bytes", 509 | "futures-channel", 510 | "futures-core", 511 | "futures-util", 512 | "h2", 513 | "http 0.2.12", 514 | "http-body", 515 | "httparse", 516 | "httpdate", 517 | "itoa", 518 | "pin-project-lite", 519 | "socket2", 520 | "tokio", 521 | "tower-service", 522 | "tracing", 523 | "want", 524 | ] 525 | 526 | [[package]] 527 | name = "hyper-rustls" 528 | version = "0.24.2" 529 | source = "registry+https://github.com/rust-lang/crates.io-index" 530 | checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" 531 | dependencies = [ 532 | "futures-util", 533 | "http 0.2.12", 534 | "hyper", 535 | "rustls", 536 | "tokio", 537 | "tokio-rustls", 538 | ] 539 | 540 | [[package]] 541 | name = "hyper-tls" 542 | version = "0.5.0" 543 | source = "registry+https://github.com/rust-lang/crates.io-index" 544 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 545 | dependencies = [ 546 | "bytes", 547 | "hyper", 548 | "native-tls", 549 | "tokio", 550 | "tokio-native-tls", 551 | ] 552 | 553 | [[package]] 554 | name = "idna" 555 | version = "0.5.0" 556 | source = "registry+https://github.com/rust-lang/crates.io-index" 557 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" 558 | dependencies = [ 559 | "unicode-bidi", 560 | "unicode-normalization", 561 | ] 562 | 563 | [[package]] 564 | name = "indexmap" 565 | version = "2.2.6" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" 568 | dependencies = [ 569 | "equivalent", 570 | "hashbrown", 571 | ] 572 | 573 | [[package]] 574 | name = "ipnet" 575 | version = "2.9.0" 576 | source = "registry+https://github.com/rust-lang/crates.io-index" 577 | checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" 578 | 579 | [[package]] 580 | name = "itoa" 581 | version = "1.0.11" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 584 | 585 | [[package]] 586 | name = "js-sys" 587 | version = "0.3.69" 588 | source = "registry+https://github.com/rust-lang/crates.io-index" 589 | checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" 590 | dependencies = [ 591 | "wasm-bindgen", 592 | ] 593 | 594 | [[package]] 595 | name = "lazy_static" 596 | version = "1.4.0" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 599 | 600 | [[package]] 601 | name = "libc" 602 | version = "0.2.153" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" 605 | 606 | [[package]] 607 | name = "linux-raw-sys" 608 | version = "0.4.13" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" 611 | 612 | [[package]] 613 | name = "lock_api" 614 | version = "0.4.11" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" 617 | dependencies = [ 618 | "autocfg", 619 | "scopeguard", 620 | ] 621 | 622 | [[package]] 623 | name = "log" 624 | version = "0.4.21" 625 | source = "registry+https://github.com/rust-lang/crates.io-index" 626 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 627 | 628 | [[package]] 629 | name = "memchr" 630 | version = "2.7.2" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" 633 | 634 | [[package]] 635 | name = "mime" 636 | version = "0.3.17" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 639 | 640 | [[package]] 641 | name = "miniz_oxide" 642 | version = "0.7.2" 643 | source = "registry+https://github.com/rust-lang/crates.io-index" 644 | checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" 645 | dependencies = [ 646 | "adler", 647 | ] 648 | 649 | [[package]] 650 | name = "mio" 651 | version = "0.8.11" 652 | source = "registry+https://github.com/rust-lang/crates.io-index" 653 | checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" 654 | dependencies = [ 655 | "libc", 656 | "wasi", 657 | "windows-sys 0.48.0", 658 | ] 659 | 660 | [[package]] 661 | name = "native-tls" 662 | version = "0.2.11" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" 665 | dependencies = [ 666 | "lazy_static", 667 | "libc", 668 | "log", 669 | "openssl", 670 | "openssl-probe", 671 | "openssl-sys", 672 | "schannel", 673 | "security-framework", 674 | "security-framework-sys", 675 | "tempfile", 676 | ] 677 | 678 | [[package]] 679 | name = "num_cpus" 680 | version = "1.16.0" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 683 | dependencies = [ 684 | "hermit-abi", 685 | "libc", 686 | ] 687 | 688 | [[package]] 689 | name = "object" 690 | version = "0.32.2" 691 | source = "registry+https://github.com/rust-lang/crates.io-index" 692 | checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" 693 | dependencies = [ 694 | "memchr", 695 | ] 696 | 697 | [[package]] 698 | name = "once_cell" 699 | version = "1.19.0" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 702 | 703 | [[package]] 704 | name = "openssl" 705 | version = "0.10.64" 706 | source = "registry+https://github.com/rust-lang/crates.io-index" 707 | checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" 708 | dependencies = [ 709 | "bitflags 2.5.0", 710 | "cfg-if", 711 | "foreign-types", 712 | "libc", 713 | "once_cell", 714 | "openssl-macros", 715 | "openssl-sys", 716 | ] 717 | 718 | [[package]] 719 | name = "openssl-macros" 720 | version = "0.1.1" 721 | source = "registry+https://github.com/rust-lang/crates.io-index" 722 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 723 | dependencies = [ 724 | "proc-macro2", 725 | "quote", 726 | "syn", 727 | ] 728 | 729 | [[package]] 730 | name = "openssl-probe" 731 | version = "0.1.5" 732 | source = "registry+https://github.com/rust-lang/crates.io-index" 733 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 734 | 735 | [[package]] 736 | name = "openssl-sys" 737 | version = "0.9.102" 738 | source = "registry+https://github.com/rust-lang/crates.io-index" 739 | checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" 740 | dependencies = [ 741 | "cc", 742 | "libc", 743 | "pkg-config", 744 | "vcpkg", 745 | ] 746 | 747 | [[package]] 748 | name = "parking_lot" 749 | version = "0.12.1" 750 | source = "registry+https://github.com/rust-lang/crates.io-index" 751 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 752 | dependencies = [ 753 | "lock_api", 754 | "parking_lot_core", 755 | ] 756 | 757 | [[package]] 758 | name = "parking_lot_core" 759 | version = "0.9.9" 760 | source = "registry+https://github.com/rust-lang/crates.io-index" 761 | checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" 762 | dependencies = [ 763 | "cfg-if", 764 | "libc", 765 | "redox_syscall", 766 | "smallvec", 767 | "windows-targets 0.48.5", 768 | ] 769 | 770 | [[package]] 771 | name = "percent-encoding" 772 | version = "2.3.1" 773 | source = "registry+https://github.com/rust-lang/crates.io-index" 774 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 775 | 776 | [[package]] 777 | name = "pin-project-lite" 778 | version = "0.2.14" 779 | source = "registry+https://github.com/rust-lang/crates.io-index" 780 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 781 | 782 | [[package]] 783 | name = "pin-utils" 784 | version = "0.1.0" 785 | source = "registry+https://github.com/rust-lang/crates.io-index" 786 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 787 | 788 | [[package]] 789 | name = "pkg-config" 790 | version = "0.3.30" 791 | source = "registry+https://github.com/rust-lang/crates.io-index" 792 | checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" 793 | 794 | [[package]] 795 | name = "ppv-lite86" 796 | version = "0.2.17" 797 | source = "registry+https://github.com/rust-lang/crates.io-index" 798 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 799 | 800 | [[package]] 801 | name = "proc-macro2" 802 | version = "1.0.81" 803 | source = "registry+https://github.com/rust-lang/crates.io-index" 804 | checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" 805 | dependencies = [ 806 | "unicode-ident", 807 | ] 808 | 809 | [[package]] 810 | name = "quinn" 811 | version = "0.10.2" 812 | source = "registry+https://github.com/rust-lang/crates.io-index" 813 | checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" 814 | dependencies = [ 815 | "bytes", 816 | "futures-io", 817 | "pin-project-lite", 818 | "quinn-proto", 819 | "quinn-udp", 820 | "rustc-hash", 821 | "rustls", 822 | "thiserror", 823 | "tokio", 824 | "tracing", 825 | ] 826 | 827 | [[package]] 828 | name = "quinn-proto" 829 | version = "0.10.6" 830 | source = "registry+https://github.com/rust-lang/crates.io-index" 831 | checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" 832 | dependencies = [ 833 | "bytes", 834 | "rand", 835 | "ring 0.16.20", 836 | "rustc-hash", 837 | "rustls", 838 | "slab", 839 | "thiserror", 840 | "tinyvec", 841 | "tracing", 842 | ] 843 | 844 | [[package]] 845 | name = "quinn-udp" 846 | version = "0.4.1" 847 | source = "registry+https://github.com/rust-lang/crates.io-index" 848 | checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" 849 | dependencies = [ 850 | "bytes", 851 | "libc", 852 | "socket2", 853 | "tracing", 854 | "windows-sys 0.48.0", 855 | ] 856 | 857 | [[package]] 858 | name = "quote" 859 | version = "1.0.36" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" 862 | dependencies = [ 863 | "proc-macro2", 864 | ] 865 | 866 | [[package]] 867 | name = "rand" 868 | version = "0.8.5" 869 | source = "registry+https://github.com/rust-lang/crates.io-index" 870 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 871 | dependencies = [ 872 | "libc", 873 | "rand_chacha", 874 | "rand_core", 875 | ] 876 | 877 | [[package]] 878 | name = "rand_chacha" 879 | version = "0.3.1" 880 | source = "registry+https://github.com/rust-lang/crates.io-index" 881 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 882 | dependencies = [ 883 | "ppv-lite86", 884 | "rand_core", 885 | ] 886 | 887 | [[package]] 888 | name = "rand_core" 889 | version = "0.6.4" 890 | source = "registry+https://github.com/rust-lang/crates.io-index" 891 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 892 | dependencies = [ 893 | "getrandom", 894 | ] 895 | 896 | [[package]] 897 | name = "redox_syscall" 898 | version = "0.4.1" 899 | source = "registry+https://github.com/rust-lang/crates.io-index" 900 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 901 | dependencies = [ 902 | "bitflags 1.3.2", 903 | ] 904 | 905 | [[package]] 906 | name = "regex" 907 | version = "1.10.4" 908 | source = "registry+https://github.com/rust-lang/crates.io-index" 909 | checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" 910 | dependencies = [ 911 | "aho-corasick", 912 | "memchr", 913 | "regex-automata", 914 | "regex-syntax", 915 | ] 916 | 917 | [[package]] 918 | name = "regex-automata" 919 | version = "0.4.6" 920 | source = "registry+https://github.com/rust-lang/crates.io-index" 921 | checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" 922 | dependencies = [ 923 | "aho-corasick", 924 | "memchr", 925 | "regex-syntax", 926 | ] 927 | 928 | [[package]] 929 | name = "regex-syntax" 930 | version = "0.8.3" 931 | source = "registry+https://github.com/rust-lang/crates.io-index" 932 | checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" 933 | 934 | [[package]] 935 | name = "reqwest" 936 | version = "0.11.27" 937 | source = "registry+https://github.com/rust-lang/crates.io-index" 938 | checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" 939 | dependencies = [ 940 | "base64", 941 | "bytes", 942 | "encoding_rs", 943 | "futures-core", 944 | "futures-util", 945 | "h2", 946 | "http 0.2.12", 947 | "http-body", 948 | "hyper", 949 | "hyper-rustls", 950 | "hyper-tls", 951 | "ipnet", 952 | "js-sys", 953 | "log", 954 | "mime", 955 | "native-tls", 956 | "once_cell", 957 | "percent-encoding", 958 | "pin-project-lite", 959 | "rustls", 960 | "rustls-pemfile", 961 | "serde", 962 | "serde_json", 963 | "serde_urlencoded", 964 | "sync_wrapper", 965 | "system-configuration", 966 | "tokio", 967 | "tokio-native-tls", 968 | "tokio-rustls", 969 | "tower-service", 970 | "url", 971 | "wasm-bindgen", 972 | "wasm-bindgen-futures", 973 | "web-sys", 974 | "webpki-roots", 975 | "winreg", 976 | ] 977 | 978 | [[package]] 979 | name = "ring" 980 | version = "0.16.20" 981 | source = "registry+https://github.com/rust-lang/crates.io-index" 982 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" 983 | dependencies = [ 984 | "cc", 985 | "libc", 986 | "once_cell", 987 | "spin 0.5.2", 988 | "untrusted 0.7.1", 989 | "web-sys", 990 | "winapi", 991 | ] 992 | 993 | [[package]] 994 | name = "ring" 995 | version = "0.17.8" 996 | source = "registry+https://github.com/rust-lang/crates.io-index" 997 | checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" 998 | dependencies = [ 999 | "cc", 1000 | "cfg-if", 1001 | "getrandom", 1002 | "libc", 1003 | "spin 0.9.8", 1004 | "untrusted 0.9.0", 1005 | "windows-sys 0.52.0", 1006 | ] 1007 | 1008 | [[package]] 1009 | name = "rustc-demangle" 1010 | version = "0.1.23" 1011 | source = "registry+https://github.com/rust-lang/crates.io-index" 1012 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 1013 | 1014 | [[package]] 1015 | name = "rustc-hash" 1016 | version = "1.1.0" 1017 | source = "registry+https://github.com/rust-lang/crates.io-index" 1018 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 1019 | 1020 | [[package]] 1021 | name = "rustix" 1022 | version = "0.38.32" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" 1025 | dependencies = [ 1026 | "bitflags 2.5.0", 1027 | "errno", 1028 | "libc", 1029 | "linux-raw-sys", 1030 | "windows-sys 0.52.0", 1031 | ] 1032 | 1033 | [[package]] 1034 | name = "rustls" 1035 | version = "0.21.10" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" 1038 | dependencies = [ 1039 | "log", 1040 | "ring 0.17.8", 1041 | "rustls-webpki", 1042 | "sct", 1043 | ] 1044 | 1045 | [[package]] 1046 | name = "rustls-native-certs" 1047 | version = "0.6.3" 1048 | source = "registry+https://github.com/rust-lang/crates.io-index" 1049 | checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" 1050 | dependencies = [ 1051 | "openssl-probe", 1052 | "rustls-pemfile", 1053 | "schannel", 1054 | "security-framework", 1055 | ] 1056 | 1057 | [[package]] 1058 | name = "rustls-pemfile" 1059 | version = "1.0.4" 1060 | source = "registry+https://github.com/rust-lang/crates.io-index" 1061 | checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" 1062 | dependencies = [ 1063 | "base64", 1064 | ] 1065 | 1066 | [[package]] 1067 | name = "rustls-webpki" 1068 | version = "0.101.7" 1069 | source = "registry+https://github.com/rust-lang/crates.io-index" 1070 | checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" 1071 | dependencies = [ 1072 | "ring 0.17.8", 1073 | "untrusted 0.9.0", 1074 | ] 1075 | 1076 | [[package]] 1077 | name = "ryu" 1078 | version = "1.0.17" 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" 1080 | checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" 1081 | 1082 | [[package]] 1083 | name = "schannel" 1084 | version = "0.1.23" 1085 | source = "registry+https://github.com/rust-lang/crates.io-index" 1086 | checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" 1087 | dependencies = [ 1088 | "windows-sys 0.52.0", 1089 | ] 1090 | 1091 | [[package]] 1092 | name = "scopeguard" 1093 | version = "1.2.0" 1094 | source = "registry+https://github.com/rust-lang/crates.io-index" 1095 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1096 | 1097 | [[package]] 1098 | name = "sct" 1099 | version = "0.7.1" 1100 | source = "registry+https://github.com/rust-lang/crates.io-index" 1101 | checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" 1102 | dependencies = [ 1103 | "ring 0.17.8", 1104 | "untrusted 0.9.0", 1105 | ] 1106 | 1107 | [[package]] 1108 | name = "security-framework" 1109 | version = "2.10.0" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" 1112 | dependencies = [ 1113 | "bitflags 1.3.2", 1114 | "core-foundation", 1115 | "core-foundation-sys", 1116 | "libc", 1117 | "security-framework-sys", 1118 | ] 1119 | 1120 | [[package]] 1121 | name = "security-framework-sys" 1122 | version = "2.10.0" 1123 | source = "registry+https://github.com/rust-lang/crates.io-index" 1124 | checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" 1125 | dependencies = [ 1126 | "core-foundation-sys", 1127 | "libc", 1128 | ] 1129 | 1130 | [[package]] 1131 | name = "serde" 1132 | version = "1.0.198" 1133 | source = "registry+https://github.com/rust-lang/crates.io-index" 1134 | checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" 1135 | dependencies = [ 1136 | "serde_derive", 1137 | ] 1138 | 1139 | [[package]] 1140 | name = "serde_derive" 1141 | version = "1.0.198" 1142 | source = "registry+https://github.com/rust-lang/crates.io-index" 1143 | checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" 1144 | dependencies = [ 1145 | "proc-macro2", 1146 | "quote", 1147 | "syn", 1148 | ] 1149 | 1150 | [[package]] 1151 | name = "serde_json" 1152 | version = "1.0.116" 1153 | source = "registry+https://github.com/rust-lang/crates.io-index" 1154 | checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" 1155 | dependencies = [ 1156 | "itoa", 1157 | "ryu", 1158 | "serde", 1159 | ] 1160 | 1161 | [[package]] 1162 | name = "serde_urlencoded" 1163 | version = "0.7.1" 1164 | source = "registry+https://github.com/rust-lang/crates.io-index" 1165 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1166 | dependencies = [ 1167 | "form_urlencoded", 1168 | "itoa", 1169 | "ryu", 1170 | "serde", 1171 | ] 1172 | 1173 | [[package]] 1174 | name = "signal-hook-registry" 1175 | version = "1.4.1" 1176 | source = "registry+https://github.com/rust-lang/crates.io-index" 1177 | checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" 1178 | dependencies = [ 1179 | "libc", 1180 | ] 1181 | 1182 | [[package]] 1183 | name = "slab" 1184 | version = "0.4.9" 1185 | source = "registry+https://github.com/rust-lang/crates.io-index" 1186 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1187 | dependencies = [ 1188 | "autocfg", 1189 | ] 1190 | 1191 | [[package]] 1192 | name = "smallvec" 1193 | version = "1.13.2" 1194 | source = "registry+https://github.com/rust-lang/crates.io-index" 1195 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1196 | 1197 | [[package]] 1198 | name = "socket2" 1199 | version = "0.5.6" 1200 | source = "registry+https://github.com/rust-lang/crates.io-index" 1201 | checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" 1202 | dependencies = [ 1203 | "libc", 1204 | "windows-sys 0.52.0", 1205 | ] 1206 | 1207 | [[package]] 1208 | name = "spin" 1209 | version = "0.5.2" 1210 | source = "registry+https://github.com/rust-lang/crates.io-index" 1211 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" 1212 | 1213 | [[package]] 1214 | name = "spin" 1215 | version = "0.9.8" 1216 | source = "registry+https://github.com/rust-lang/crates.io-index" 1217 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1218 | 1219 | [[package]] 1220 | name = "syn" 1221 | version = "2.0.60" 1222 | source = "registry+https://github.com/rust-lang/crates.io-index" 1223 | checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" 1224 | dependencies = [ 1225 | "proc-macro2", 1226 | "quote", 1227 | "unicode-ident", 1228 | ] 1229 | 1230 | [[package]] 1231 | name = "sync_wrapper" 1232 | version = "0.1.2" 1233 | source = "registry+https://github.com/rust-lang/crates.io-index" 1234 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 1235 | 1236 | [[package]] 1237 | name = "system-configuration" 1238 | version = "0.5.1" 1239 | source = "registry+https://github.com/rust-lang/crates.io-index" 1240 | checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" 1241 | dependencies = [ 1242 | "bitflags 1.3.2", 1243 | "core-foundation", 1244 | "system-configuration-sys", 1245 | ] 1246 | 1247 | [[package]] 1248 | name = "system-configuration-sys" 1249 | version = "0.5.0" 1250 | source = "registry+https://github.com/rust-lang/crates.io-index" 1251 | checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" 1252 | dependencies = [ 1253 | "core-foundation-sys", 1254 | "libc", 1255 | ] 1256 | 1257 | [[package]] 1258 | name = "tempfile" 1259 | version = "3.10.1" 1260 | source = "registry+https://github.com/rust-lang/crates.io-index" 1261 | checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" 1262 | dependencies = [ 1263 | "cfg-if", 1264 | "fastrand", 1265 | "rustix", 1266 | "windows-sys 0.52.0", 1267 | ] 1268 | 1269 | [[package]] 1270 | name = "thiserror" 1271 | version = "1.0.58" 1272 | source = "registry+https://github.com/rust-lang/crates.io-index" 1273 | checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" 1274 | dependencies = [ 1275 | "thiserror-impl", 1276 | ] 1277 | 1278 | [[package]] 1279 | name = "thiserror-impl" 1280 | version = "1.0.58" 1281 | source = "registry+https://github.com/rust-lang/crates.io-index" 1282 | checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" 1283 | dependencies = [ 1284 | "proc-macro2", 1285 | "quote", 1286 | "syn", 1287 | ] 1288 | 1289 | [[package]] 1290 | name = "tinyvec" 1291 | version = "1.6.0" 1292 | source = "registry+https://github.com/rust-lang/crates.io-index" 1293 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 1294 | dependencies = [ 1295 | "tinyvec_macros", 1296 | ] 1297 | 1298 | [[package]] 1299 | name = "tinyvec_macros" 1300 | version = "0.1.1" 1301 | source = "registry+https://github.com/rust-lang/crates.io-index" 1302 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 1303 | 1304 | [[package]] 1305 | name = "tokio" 1306 | version = "1.37.0" 1307 | source = "registry+https://github.com/rust-lang/crates.io-index" 1308 | checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" 1309 | dependencies = [ 1310 | "backtrace", 1311 | "bytes", 1312 | "libc", 1313 | "mio", 1314 | "num_cpus", 1315 | "parking_lot", 1316 | "pin-project-lite", 1317 | "signal-hook-registry", 1318 | "socket2", 1319 | "tokio-macros", 1320 | "windows-sys 0.48.0", 1321 | ] 1322 | 1323 | [[package]] 1324 | name = "tokio-macros" 1325 | version = "2.2.0" 1326 | source = "registry+https://github.com/rust-lang/crates.io-index" 1327 | checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" 1328 | dependencies = [ 1329 | "proc-macro2", 1330 | "quote", 1331 | "syn", 1332 | ] 1333 | 1334 | [[package]] 1335 | name = "tokio-native-tls" 1336 | version = "0.3.1" 1337 | source = "registry+https://github.com/rust-lang/crates.io-index" 1338 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 1339 | dependencies = [ 1340 | "native-tls", 1341 | "tokio", 1342 | ] 1343 | 1344 | [[package]] 1345 | name = "tokio-rustls" 1346 | version = "0.24.1" 1347 | source = "registry+https://github.com/rust-lang/crates.io-index" 1348 | checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" 1349 | dependencies = [ 1350 | "rustls", 1351 | "tokio", 1352 | ] 1353 | 1354 | [[package]] 1355 | name = "tokio-util" 1356 | version = "0.7.10" 1357 | source = "registry+https://github.com/rust-lang/crates.io-index" 1358 | checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" 1359 | dependencies = [ 1360 | "bytes", 1361 | "futures-core", 1362 | "futures-sink", 1363 | "pin-project-lite", 1364 | "tokio", 1365 | "tracing", 1366 | ] 1367 | 1368 | [[package]] 1369 | name = "tower-service" 1370 | version = "0.3.2" 1371 | source = "registry+https://github.com/rust-lang/crates.io-index" 1372 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1373 | 1374 | [[package]] 1375 | name = "tracing" 1376 | version = "0.1.40" 1377 | source = "registry+https://github.com/rust-lang/crates.io-index" 1378 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 1379 | dependencies = [ 1380 | "pin-project-lite", 1381 | "tracing-attributes", 1382 | "tracing-core", 1383 | ] 1384 | 1385 | [[package]] 1386 | name = "tracing-attributes" 1387 | version = "0.1.27" 1388 | source = "registry+https://github.com/rust-lang/crates.io-index" 1389 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" 1390 | dependencies = [ 1391 | "proc-macro2", 1392 | "quote", 1393 | "syn", 1394 | ] 1395 | 1396 | [[package]] 1397 | name = "tracing-core" 1398 | version = "0.1.32" 1399 | source = "registry+https://github.com/rust-lang/crates.io-index" 1400 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 1401 | dependencies = [ 1402 | "once_cell", 1403 | ] 1404 | 1405 | [[package]] 1406 | name = "try-lock" 1407 | version = "0.2.5" 1408 | source = "registry+https://github.com/rust-lang/crates.io-index" 1409 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 1410 | 1411 | [[package]] 1412 | name = "unicode-bidi" 1413 | version = "0.3.15" 1414 | source = "registry+https://github.com/rust-lang/crates.io-index" 1415 | checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" 1416 | 1417 | [[package]] 1418 | name = "unicode-ident" 1419 | version = "1.0.12" 1420 | source = "registry+https://github.com/rust-lang/crates.io-index" 1421 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 1422 | 1423 | [[package]] 1424 | name = "unicode-normalization" 1425 | version = "0.1.23" 1426 | source = "registry+https://github.com/rust-lang/crates.io-index" 1427 | checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" 1428 | dependencies = [ 1429 | "tinyvec", 1430 | ] 1431 | 1432 | [[package]] 1433 | name = "untrusted" 1434 | version = "0.7.1" 1435 | source = "registry+https://github.com/rust-lang/crates.io-index" 1436 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" 1437 | 1438 | [[package]] 1439 | name = "untrusted" 1440 | version = "0.9.0" 1441 | source = "registry+https://github.com/rust-lang/crates.io-index" 1442 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 1443 | 1444 | [[package]] 1445 | name = "url" 1446 | version = "2.5.0" 1447 | source = "registry+https://github.com/rust-lang/crates.io-index" 1448 | checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" 1449 | dependencies = [ 1450 | "form_urlencoded", 1451 | "idna", 1452 | "percent-encoding", 1453 | ] 1454 | 1455 | [[package]] 1456 | name = "utf8parse" 1457 | version = "0.2.1" 1458 | source = "registry+https://github.com/rust-lang/crates.io-index" 1459 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 1460 | 1461 | [[package]] 1462 | name = "vcpkg" 1463 | version = "0.2.15" 1464 | source = "registry+https://github.com/rust-lang/crates.io-index" 1465 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1466 | 1467 | [[package]] 1468 | name = "want" 1469 | version = "0.3.1" 1470 | source = "registry+https://github.com/rust-lang/crates.io-index" 1471 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1472 | dependencies = [ 1473 | "try-lock", 1474 | ] 1475 | 1476 | [[package]] 1477 | name = "wasi" 1478 | version = "0.11.0+wasi-snapshot-preview1" 1479 | source = "registry+https://github.com/rust-lang/crates.io-index" 1480 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1481 | 1482 | [[package]] 1483 | name = "wasm-bindgen" 1484 | version = "0.2.92" 1485 | source = "registry+https://github.com/rust-lang/crates.io-index" 1486 | checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" 1487 | dependencies = [ 1488 | "cfg-if", 1489 | "wasm-bindgen-macro", 1490 | ] 1491 | 1492 | [[package]] 1493 | name = "wasm-bindgen-backend" 1494 | version = "0.2.92" 1495 | source = "registry+https://github.com/rust-lang/crates.io-index" 1496 | checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" 1497 | dependencies = [ 1498 | "bumpalo", 1499 | "log", 1500 | "once_cell", 1501 | "proc-macro2", 1502 | "quote", 1503 | "syn", 1504 | "wasm-bindgen-shared", 1505 | ] 1506 | 1507 | [[package]] 1508 | name = "wasm-bindgen-futures" 1509 | version = "0.4.42" 1510 | source = "registry+https://github.com/rust-lang/crates.io-index" 1511 | checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" 1512 | dependencies = [ 1513 | "cfg-if", 1514 | "js-sys", 1515 | "wasm-bindgen", 1516 | "web-sys", 1517 | ] 1518 | 1519 | [[package]] 1520 | name = "wasm-bindgen-macro" 1521 | version = "0.2.92" 1522 | source = "registry+https://github.com/rust-lang/crates.io-index" 1523 | checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" 1524 | dependencies = [ 1525 | "quote", 1526 | "wasm-bindgen-macro-support", 1527 | ] 1528 | 1529 | [[package]] 1530 | name = "wasm-bindgen-macro-support" 1531 | version = "0.2.92" 1532 | source = "registry+https://github.com/rust-lang/crates.io-index" 1533 | checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" 1534 | dependencies = [ 1535 | "proc-macro2", 1536 | "quote", 1537 | "syn", 1538 | "wasm-bindgen-backend", 1539 | "wasm-bindgen-shared", 1540 | ] 1541 | 1542 | [[package]] 1543 | name = "wasm-bindgen-shared" 1544 | version = "0.2.92" 1545 | source = "registry+https://github.com/rust-lang/crates.io-index" 1546 | checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" 1547 | 1548 | [[package]] 1549 | name = "web-sys" 1550 | version = "0.3.69" 1551 | source = "registry+https://github.com/rust-lang/crates.io-index" 1552 | checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" 1553 | dependencies = [ 1554 | "js-sys", 1555 | "wasm-bindgen", 1556 | ] 1557 | 1558 | [[package]] 1559 | name = "webpki-roots" 1560 | version = "0.25.4" 1561 | source = "registry+https://github.com/rust-lang/crates.io-index" 1562 | checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" 1563 | 1564 | [[package]] 1565 | name = "winapi" 1566 | version = "0.3.9" 1567 | source = "registry+https://github.com/rust-lang/crates.io-index" 1568 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1569 | dependencies = [ 1570 | "winapi-i686-pc-windows-gnu", 1571 | "winapi-x86_64-pc-windows-gnu", 1572 | ] 1573 | 1574 | [[package]] 1575 | name = "winapi-i686-pc-windows-gnu" 1576 | version = "0.4.0" 1577 | source = "registry+https://github.com/rust-lang/crates.io-index" 1578 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1579 | 1580 | [[package]] 1581 | name = "winapi-x86_64-pc-windows-gnu" 1582 | version = "0.4.0" 1583 | source = "registry+https://github.com/rust-lang/crates.io-index" 1584 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1585 | 1586 | [[package]] 1587 | name = "windows-sys" 1588 | version = "0.48.0" 1589 | source = "registry+https://github.com/rust-lang/crates.io-index" 1590 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1591 | dependencies = [ 1592 | "windows-targets 0.48.5", 1593 | ] 1594 | 1595 | [[package]] 1596 | name = "windows-sys" 1597 | version = "0.52.0" 1598 | source = "registry+https://github.com/rust-lang/crates.io-index" 1599 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1600 | dependencies = [ 1601 | "windows-targets 0.52.5", 1602 | ] 1603 | 1604 | [[package]] 1605 | name = "windows-targets" 1606 | version = "0.48.5" 1607 | source = "registry+https://github.com/rust-lang/crates.io-index" 1608 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 1609 | dependencies = [ 1610 | "windows_aarch64_gnullvm 0.48.5", 1611 | "windows_aarch64_msvc 0.48.5", 1612 | "windows_i686_gnu 0.48.5", 1613 | "windows_i686_msvc 0.48.5", 1614 | "windows_x86_64_gnu 0.48.5", 1615 | "windows_x86_64_gnullvm 0.48.5", 1616 | "windows_x86_64_msvc 0.48.5", 1617 | ] 1618 | 1619 | [[package]] 1620 | name = "windows-targets" 1621 | version = "0.52.5" 1622 | source = "registry+https://github.com/rust-lang/crates.io-index" 1623 | checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" 1624 | dependencies = [ 1625 | "windows_aarch64_gnullvm 0.52.5", 1626 | "windows_aarch64_msvc 0.52.5", 1627 | "windows_i686_gnu 0.52.5", 1628 | "windows_i686_gnullvm", 1629 | "windows_i686_msvc 0.52.5", 1630 | "windows_x86_64_gnu 0.52.5", 1631 | "windows_x86_64_gnullvm 0.52.5", 1632 | "windows_x86_64_msvc 0.52.5", 1633 | ] 1634 | 1635 | [[package]] 1636 | name = "windows_aarch64_gnullvm" 1637 | version = "0.48.5" 1638 | source = "registry+https://github.com/rust-lang/crates.io-index" 1639 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 1640 | 1641 | [[package]] 1642 | name = "windows_aarch64_gnullvm" 1643 | version = "0.52.5" 1644 | source = "registry+https://github.com/rust-lang/crates.io-index" 1645 | checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" 1646 | 1647 | [[package]] 1648 | name = "windows_aarch64_msvc" 1649 | version = "0.48.5" 1650 | source = "registry+https://github.com/rust-lang/crates.io-index" 1651 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 1652 | 1653 | [[package]] 1654 | name = "windows_aarch64_msvc" 1655 | version = "0.52.5" 1656 | source = "registry+https://github.com/rust-lang/crates.io-index" 1657 | checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" 1658 | 1659 | [[package]] 1660 | name = "windows_i686_gnu" 1661 | version = "0.48.5" 1662 | source = "registry+https://github.com/rust-lang/crates.io-index" 1663 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 1664 | 1665 | [[package]] 1666 | name = "windows_i686_gnu" 1667 | version = "0.52.5" 1668 | source = "registry+https://github.com/rust-lang/crates.io-index" 1669 | checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" 1670 | 1671 | [[package]] 1672 | name = "windows_i686_gnullvm" 1673 | version = "0.52.5" 1674 | source = "registry+https://github.com/rust-lang/crates.io-index" 1675 | checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" 1676 | 1677 | [[package]] 1678 | name = "windows_i686_msvc" 1679 | version = "0.48.5" 1680 | source = "registry+https://github.com/rust-lang/crates.io-index" 1681 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 1682 | 1683 | [[package]] 1684 | name = "windows_i686_msvc" 1685 | version = "0.52.5" 1686 | source = "registry+https://github.com/rust-lang/crates.io-index" 1687 | checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" 1688 | 1689 | [[package]] 1690 | name = "windows_x86_64_gnu" 1691 | version = "0.48.5" 1692 | source = "registry+https://github.com/rust-lang/crates.io-index" 1693 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 1694 | 1695 | [[package]] 1696 | name = "windows_x86_64_gnu" 1697 | version = "0.52.5" 1698 | source = "registry+https://github.com/rust-lang/crates.io-index" 1699 | checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" 1700 | 1701 | [[package]] 1702 | name = "windows_x86_64_gnullvm" 1703 | version = "0.48.5" 1704 | source = "registry+https://github.com/rust-lang/crates.io-index" 1705 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 1706 | 1707 | [[package]] 1708 | name = "windows_x86_64_gnullvm" 1709 | version = "0.52.5" 1710 | source = "registry+https://github.com/rust-lang/crates.io-index" 1711 | checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" 1712 | 1713 | [[package]] 1714 | name = "windows_x86_64_msvc" 1715 | version = "0.48.5" 1716 | source = "registry+https://github.com/rust-lang/crates.io-index" 1717 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 1718 | 1719 | [[package]] 1720 | name = "windows_x86_64_msvc" 1721 | version = "0.52.5" 1722 | source = "registry+https://github.com/rust-lang/crates.io-index" 1723 | checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" 1724 | 1725 | [[package]] 1726 | name = "winreg" 1727 | version = "0.50.0" 1728 | source = "registry+https://github.com/rust-lang/crates.io-index" 1729 | checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" 1730 | dependencies = [ 1731 | "cfg-if", 1732 | "windows-sys 0.48.0", 1733 | ] 1734 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "crypto-http-protcols" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | 9 | [dependencies] 10 | reqwest = { version = "0.11", features = ["blocking", "rustls-tls"] } 11 | tokio = { version = "1", features = ["full"] } 12 | h3 = "0.0.4" 13 | http = "1" 14 | rustls = { version = "0.21", features = ["dangerous_configuration"] } 15 | rustls-native-certs = "0.6" 16 | h3-quinn = "0.0.5" 17 | quinn = { version = "0.10", default-features = false, features = ["runtime-tokio", "tls-rustls", "ring"] } 18 | dashmap = "5.5.3" 19 | futures = "0.3.30" 20 | 21 | dotenv = "0.15.0" 22 | log = "0.4.21" 23 | env_logger = "0.11.3" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Crypto Exchange HTTP Protocol Scanner 2 | 3 | Rust project for determining HTTP protocol support across these exchanges listed below. Most endpoints were order_book related since that's likely to be optimized and the exchange infra is inherently black-boxed. Private endpoints weren't checked, however, based on the results it looks like exchanges tend to keep the same protocol supports respective to the hostname. Hope y'all enjoy :) 4 | 5 | ## Setup 6 | - `rustup default stable` 7 | - `cargo run --release` 8 | - wait 30sec 9 | - `BOOM, results` 10 | 11 | ### Protocols monitored: 12 | - `h1` (HTTP/1.1) 13 | - `h2` (HTTP/2) 14 | - `h3` (HTTP/3 - QUIC) 15 | 16 | ### Exchanges monitored: 17 | - Coinbase 18 | - Binance 19 | - BinanceUS 20 | - OKX 21 | - Bybit 22 | - Kraken 23 | - Bitfinex 24 | - BitMex 25 | - HTX (Huobi) 26 | - KuCoin 27 | - Gemini 28 | - GateIO 29 | - Deribit 30 | - Crypto.com 31 | - Poloniex 32 | - AscendEx 33 | - Whitebit 34 | - WooX 35 | - BingX 36 | - Bitget 37 | - BitMart 38 | - BloFin 39 | - CEX 40 | - CoinEx 41 | - OkCoin 42 | 43 | ### Disclaimer: 44 | - Exchanges listed are *not* endorsements -------------------------------------------------------------------------------- /src/cl.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, Clone)] 2 | pub enum CL { 3 | Pink, 4 | Purple, 5 | Green, 6 | DullGreen, 7 | Blue, 8 | DullRed, 9 | Red, 10 | Orange, 11 | Teal, 12 | DullTeal, 13 | Dull, 14 | End, 15 | } 16 | 17 | impl CL { 18 | pub fn get(&self) -> &str { 19 | match self { 20 | CL::Pink => "\x1b[38;5;201m", 21 | CL::Purple => "\x1b[38;5;135m", 22 | CL::Green => "\x1b[38;5;46m", 23 | CL::DullGreen => "\x1b[38;5;29m", 24 | CL::Blue => "\x1b[38;5;27m", 25 | CL::DullRed => "\x1b[38;5;124m", 26 | CL::Red => "\x1b[38;5;196m", 27 | CL::Orange => "\x1b[38;5;208m", 28 | CL::Teal => "\x1b[38;5;14m", 29 | CL::DullTeal => "\x1b[38;5;153m", 30 | CL::Dull => "\x1b[38;5;8m", 31 | CL::End => "\x1b[37m", 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | // Objective: Iterate through exchanges and their endpoints, ping their servers to see which HTTP protocols are supported 2 | use tokio::sync::Mutex; 3 | use dashmap::DashMap; 4 | use dotenv::dotenv; 5 | use std::sync::Arc; 6 | use log::info; 7 | 8 | mod cl; 9 | use cl::CL; 10 | 11 | mod utils; 12 | use utils::*; 13 | 14 | mod model; 15 | use model::*; 16 | 17 | 18 | fn main() { 19 | dotenv().ok(); 20 | env_logger::init(); 21 | 22 | let rt = tokio::runtime::Builder::new_multi_thread() 23 | .enable_all() 24 | .build() 25 | .unwrap(); 26 | rt.block_on(async move { 27 | let experiments: DashMap>>> = DashMap::new(); 28 | 29 | let mut endpoints = Vec::new(); 30 | endpoints.push(Endpoint::new(MT::SPOT, "https://api.kucoin.com/api/v3/currencies/BTC")); 31 | endpoints.push(Endpoint::new(MT::SWAP, "https://api-futures.kucoin.com/api/v1/level2/snapshot?symbol=XBTUSDM")); 32 | experiments.insert(Exchange::KuCoin, Arc::new(Mutex::new(endpoints))); 33 | 34 | let mut endpoints = Vec::new(); 35 | endpoints.push(Endpoint::new(MT::SPOT, "https://api.gemini.com/v1/book/btcusd")); 36 | experiments.insert(Exchange::Gemini, Arc::new(Mutex::new(endpoints))); 37 | 38 | let mut endpoints = Vec::new(); 39 | endpoints.push(Endpoint::new(MT::SPOT, "https://api.gateio.ws/api/v4/spot/order_book?currency_pair=BTC_USDT")); 40 | endpoints.push(Endpoint::new(MT::DELIVERY, "https://api.gateio.ws/api/v4/delivery/usdt/contracts")); 41 | endpoints.push(Endpoint::new(MT::SWAP, "https://api.gateio.ws/api/v4/futures/usdt/order_book?contract=BTC_USDT")); 42 | endpoints.push(Endpoint::new(MT::OPTIONS, "https://api.gateio.ws/api/v4/options/underlyings")); 43 | experiments.insert(Exchange::GateIO, Arc::new(Mutex::new(endpoints))); 44 | 45 | let mut endpoints = Vec::new(); 46 | endpoints.push(Endpoint::new(MT::INCLUSIVE, "https://www.deribit.com/api/v2/public/get_order_book?depth=5&instrument_name=BTC-PERPETUAL")); 47 | experiments.insert(Exchange::Deribit, Arc::new(Mutex::new(endpoints))); 48 | 49 | let mut endpoints = Vec::new(); 50 | endpoints.push(Endpoint::new(MT::SPOT, "https://api.crypto.com/v2/public/get-book?instrument_name=BTCUSDT&depth=10")); 51 | endpoints.push(Endpoint::new(MT::SWAP, "https://api.crypto.com/v2/public/get-book?instrument_name=BTCUSD-PERP&depth=10")); 52 | experiments.insert(Exchange::CryptoCom, Arc::new(Mutex::new(endpoints))); 53 | 54 | let mut endpoints = Vec::new(); 55 | endpoints.push(Endpoint::new(MT::INCLUSIVE, "https://whitebit.com/api/v1/public/depth/result?market=BTC_USDT")); 56 | endpoints.push(Endpoint::new(MT::INCLUSIVE, "https://whitebit.com/api/v2/public/depth/BTC_USDT")); 57 | endpoints.push(Endpoint::new(MT::INCLUSIVE, "https://whitebit.com/api/v4/public/orderbook/BTC_USDT?limit=100&level=2")); 58 | experiments.insert(Exchange::Whitebit, Arc::new(Mutex::new(endpoints))); 59 | 60 | let mut endpoints = Vec::new(); 61 | endpoints.push(Endpoint::new(MT::SPOT, "https://api.woo.network/v1/public/orderbook/SPOT_BTC_USDT")); 62 | experiments.insert(Exchange::WooX, Arc::new(Mutex::new(endpoints))); 63 | 64 | let mut endpoints = Vec::new(); 65 | endpoints.push(Endpoint::new(MT::SPOT, "https://api.poloniex.com/markets/BTC_USDT/orderBook")); 66 | endpoints.push(Endpoint::new(MT::SWAP, "https://futures-api.poloniex.com/api/v1/level2/snapshot?symbol=BTCUSDTPERP")); 67 | experiments.insert(Exchange::Poloniex, Arc::new(Mutex::new(endpoints))); 68 | 69 | let mut endpoints = Vec::new(); 70 | endpoints.push(Endpoint::new(MT::SPOT, "https://ascendex.com/api/pro/v1/depth?symbol=BTC/USDT")); 71 | endpoints.push(Endpoint::new(MT::SWAP, "https://ascendex.com/api/pro/v2/futures/pricing-data")); 72 | experiments.insert(Exchange::AscendEx, Arc::new(Mutex::new(endpoints))); 73 | 74 | let mut endpoints = Vec::new(); 75 | endpoints.push(Endpoint::new(MT::SPOT, "https://api.binance.com/api/v3/depth?symbol=BTCUSDT")); 76 | endpoints.push(Endpoint::new(MT::SPOT, "https://api-gcp.binance.com/api/v3/depth?symbol=BTCUSDT")); 77 | endpoints.push(Endpoint::new(MT::SPOT, "https://api1.binance.com/api/v3/depth?symbol=BTCUSDT")); 78 | endpoints.push(Endpoint::new(MT::SPOT, "https://api2.binance.com/api/v3/depth?symbol=BTCUSDT")); 79 | endpoints.push(Endpoint::new(MT::SPOT, "https://api3.binance.com/api/v3/depth?symbol=BTCUSDT")); 80 | endpoints.push(Endpoint::new(MT::SPOT, "https://api4.binance.com/api/v3/depth?symbol=BTCUSDT")); 81 | endpoints.push(Endpoint::new(MT::SWAP, "https://fapi.binance.com/fapi/v1/depth?symbol=BTCUSDT")); 82 | endpoints.push(Endpoint::new(MT::COIN, "https://dapi.binance.com/dapi/v1/depth?symbol=BTCUSDT")); 83 | endpoints.push(Endpoint::new(MT::OPTIONS, "https://eapi.binance.com/eapi/v1/depth?symbol=BTCUSDT")); 84 | experiments.insert(Exchange::Binance, Arc::new(Mutex::new(endpoints))); 85 | 86 | let mut endpoints = Vec::new(); 87 | endpoints.push(Endpoint::new(MT::SPOT, "https://api.binance.us/api/v3/depth?symbol=BTCUSD")); 88 | experiments.insert(Exchange::BinanceUS, Arc::new(Mutex::new(endpoints))); 89 | 90 | let mut endpoints = Vec::new(); 91 | endpoints.push(Endpoint::new(MT::SPOT, "https://open-api.bingx.com/openApi/spot/v1/market/depth?symbol=BTC-USDT")); 92 | endpoints.push(Endpoint::new(MT::SWAP, "https://open-api.bingx.com/openApi/swap/v2/quote/depth?symbol=BTC-USDT")); 93 | experiments.insert(Exchange::BingX, Arc::new(Mutex::new(endpoints))); 94 | 95 | let mut endpoints = Vec::new(); 96 | endpoints.push(Endpoint::new(MT::INCLUSIVE, "https://api.bitfinex.com/v1/book/BTCUSD")); 97 | endpoints.push(Endpoint::new(MT::INCLUSIVE, "https://api-pub.bitfinex.com/v2/book/tBTCUSD/P0")); 98 | experiments.insert(Exchange::Bitfinex, Arc::new(Mutex::new(endpoints))); 99 | 100 | let mut endpoints = Vec::new(); 101 | endpoints.push(Endpoint::new(MT::SPOT, "https://api.bitget.com/api/v2/spot/market/orderbook?symbol=BTCUSDT&type=step0&limit=100")); 102 | endpoints.push(Endpoint::new(MT::SWAP, "https://api.bitget.com/api/v2/mix/market/merge-depth?productType=usdt-futures&symbol=BTCUSDT")); 103 | experiments.insert(Exchange::Bitget, Arc::new(Mutex::new(endpoints))); 104 | 105 | let mut endpoints = Vec::new(); 106 | endpoints.push(Endpoint::new(MT::SPOT, "https://api-cloud.bitmart.com/spot/quotation/v3/books?symbol=BTC_USDT&limit=1")); 107 | endpoints.push(Endpoint::new(MT::SWAP, "https://api-cloud.bitmart.com/contract/public/depth")); 108 | experiments.insert(Exchange::BitMart, Arc::new(Mutex::new(endpoints))); 109 | 110 | let mut endpoints = Vec::new(); 111 | endpoints.push(Endpoint::new(MT::INCLUSIVE, "https://www.bitmex.com/api/v1/orderBook/L2?symbol=XBTUSD&depth=1")); 112 | experiments.insert(Exchange::BitMex, Arc::new(Mutex::new(endpoints))); 113 | 114 | let mut endpoints = Vec::new(); 115 | endpoints.push(Endpoint::new(MT::INCLUSIVE, "https://openapi.blofin.com/api/v1/market/books?instId=BTC-USDT")); 116 | experiments.insert(Exchange::BloFin, Arc::new(Mutex::new(endpoints))); 117 | 118 | let mut endpoints = Vec::new(); 119 | endpoints.push(Endpoint::new(MT::INCLUSIVE, "https://api.bybit.com/v5/market/orderbook?category=spot&symbol=BTCUSDT")); 120 | endpoints.push(Endpoint::new(MT::INCLUSIVE, "https://api.bytick.com/v5/market/orderbook?category=spot&symbol=BTCUSDT")); 121 | experiments.insert(Exchange::Bybit, Arc::new(Mutex::new(endpoints))); 122 | 123 | let mut endpoints = Vec::new(); 124 | endpoints.push(Endpoint::new(MT::INCLUSIVE, "https://trade.cex.io/api/spot/rest-public/get_order_book?pair=BTC-USD")); 125 | experiments.insert(Exchange::CEX, Arc::new(Mutex::new(endpoints))); 126 | 127 | let mut endpoints = Vec::new(); 128 | endpoints.push(Endpoint::new(MT::SPOT, "https://api.exchange.coinbase.com/products/BTC-USD/book")); 129 | endpoints.push(Endpoint::new(MT::INCLUSIVE, "https://api.coinbase.com/api/v3/brokerage/time")); 130 | experiments.insert(Exchange::Coinbase, Arc::new(Mutex::new(endpoints))); 131 | 132 | let mut endpoints = Vec::new(); 133 | endpoints.push(Endpoint::new(MT::SPOT, "https://api.coinex.com/v2/spot/depth?market=BTCUSDT&limit=100&interval=0")); 134 | endpoints.push(Endpoint::new(MT::SWAP, "https://api.coinex.com/v2/futures/depth?market=BTCUSDT&limit=100&interval=0")); 135 | experiments.insert(Exchange::CoinEx, Arc::new(Mutex::new(endpoints))); 136 | 137 | let mut endpoints = Vec::new(); 138 | endpoints.push(Endpoint::new(MT::SPOT, "https://api.huobi.pro/market/depth?symbol=btcusdt&type=step0")); 139 | endpoints.push(Endpoint::new(MT::SPOT, "https://api-aws.huobi.pro/market/depth?symbol=btcusdt&type=step0")); 140 | endpoints.push(Endpoint::new(MT::DELIVERY, "https://api.hbdm.com/market/depth?symbol=BTC_CQ&type=step5")); 141 | endpoints.push(Endpoint::new(MT::DELIVERY, "https://api.hbdm.vn/market/depth?symbol=BTC_CQ&type=step5")); 142 | endpoints.push(Endpoint::new(MT::COIN, "https://api.hbdm.com/swap-ex/market/depth?contract_code=BTC-USD&type=step5")); 143 | endpoints.push(Endpoint::new(MT::COIN, "https://api.hbdm.vn/swap-ex/market/depth?contract_code=BTC-USD&type=step5")); 144 | endpoints.push(Endpoint::new(MT::SWAP, "https://api.hbdm.com/linear-swap-ex/market/depth?contract_code=BTC-USDT&type=step5")); 145 | endpoints.push(Endpoint::new(MT::SWAP, "https://api.hbdm.vn/linear-swap-ex/market/depth?contract_code=BTC-USDT&type=step5")); 146 | experiments.insert(Exchange::HTX, Arc::new(Mutex::new(endpoints))); 147 | 148 | let mut endpoints = Vec::new(); 149 | endpoints.push(Endpoint::new(MT::SPOT, "https://api.kraken.com/0/public/Depth?pair=XBTUSD")); 150 | endpoints.push(Endpoint::new(MT::INCLUSIVE, "https://futures.kraken.com/derivatives/api/v3/orderbook?symbol=PI_XBTUSD")); 151 | experiments.insert(Exchange::Kraken, Arc::new(Mutex::new(endpoints))); 152 | 153 | let mut endpoints = Vec::new(); 154 | endpoints.push(Endpoint::new(MT::INCLUSIVE, "https://www.okx.com/api/v5/market/books?instId=BTC-USDT")); 155 | experiments.insert(Exchange::OKX, Arc::new(Mutex::new(endpoints))); 156 | 157 | let mut endpoints = Vec::new(); 158 | endpoints.push(Endpoint::new(MT::INCLUSIVE, "https://www.okcoin.com/api/v5/market/books?instId=BTC-USD")); 159 | experiments.insert(Exchange::OkCoin, Arc::new(Mutex::new(endpoints))); 160 | 161 | 162 | 163 | 164 | info!("{}=-------------------------------------------------------------------={}", CL::Purple.get(), CL::End.get()); 165 | info!("{}[+][+][+][+][+][+][+][+] Starting Experiment [+][+][+][+][+][+][+][+]{}", CL::Purple.get(), CL::End.get()); 166 | info!("{}=-------------------------------------------------------------------={}", CL::Purple.get(), CL::End.get()); 167 | info!("{}[-] Please wait ~30sec while we gather data from exchanges...{}", CL::Dull.get(), CL::End.get()); 168 | info!(""); 169 | info!(""); 170 | 171 | 172 | 173 | 174 | let mut tasks = Vec::new(); 175 | let keys: Vec = experiments.iter().map(|pair| pair.key().clone()).collect(); 176 | for key in keys { 177 | let endpoints = experiments.get_mut(&key).unwrap(); 178 | 179 | let endpoints = Arc::clone(&endpoints); 180 | let task = tokio::spawn(async move { 181 | let roots = get_roots(); 182 | let tls_config: rustls::ClientConfig = get_config(roots).await; 183 | 184 | let h1_client = reqwest::Client::builder() 185 | .http1_only() 186 | .use_rustls_tls() 187 | .timeout(std::time::Duration::from_secs(30)) 188 | .build().expect("[!] Failed to build client"); 189 | 190 | let h2_client = reqwest::Client::builder() 191 | .http2_prior_knowledge() 192 | .use_rustls_tls() 193 | .timeout(std::time::Duration::from_secs(30)) 194 | .build().expect("[!] Failed to build client"); 195 | 196 | for endpoint in endpoints.lock().await.iter_mut() { 197 | let uri = endpoint.uri; 198 | 199 | if let Ok(res) = h1_client.get(uri).send().await { 200 | if res.version() == reqwest::Version::HTTP_11 { 201 | endpoint.h1 = true; 202 | } 203 | } 204 | 205 | if let Ok(res) = h2_client.get(uri).send().await { 206 | if res.version() == reqwest::Version::HTTP_2 { 207 | endpoint.h2 = true; 208 | } 209 | } 210 | 211 | if let Some((version, status_code)) = test_h3(uri, tls_config.clone()).await { 212 | endpoint.h3 = true; 213 | } 214 | 215 | } 216 | }); 217 | tasks.push(task); 218 | 219 | } 220 | 221 | for task in tasks { 222 | task.await.expect("[!] Failed to spawn task"); 223 | } 224 | 225 | 226 | 227 | // now we can iterate through all the experiments and print out the results 228 | 229 | for entry in experiments.iter() { 230 | let (exchange, endpoints) = entry.pair(); 231 | 232 | info!("{}=------------------= Exchange: {:?} =------------------={}", CL::Teal.get(), exchange, CL::End.get()); 233 | for endpoint in endpoints.lock().await.iter() { 234 | info!("{}-> {:?} | Endpoint: {} =-={}", CL::Dull.get(), endpoint.market_type, endpoint.uri, CL::End.get()); 235 | 236 | let (mut h1_color, mut h2_color, mut h3_color) = (CL::Red, CL::Red, CL::Red); 237 | if endpoint.h1 { h1_color = CL::Green } 238 | if endpoint.h2 { h2_color = CL::Green } 239 | if endpoint.h3 { h3_color = CL::Green } 240 | 241 | info!("{}h1{} | {}h2{} | {}h3{}", h1_color.get(), CL::End.get(), h2_color.get(), CL::End.get(), h3_color.get(), CL::End.get()); 242 | } 243 | info!(""); 244 | } 245 | 246 | }); 247 | } -------------------------------------------------------------------------------- /src/model.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | #[derive(Debug)] 4 | pub enum MT { 5 | SPOT, 6 | SWAP, 7 | COIN, 8 | DELIVERY, 9 | OPTIONS, 10 | INCLUSIVE, 11 | } 12 | 13 | #[derive(Debug, Clone, Hash, Eq, PartialEq)] 14 | pub enum Exchange { 15 | KuCoin, 16 | Gemini, 17 | GateIO, 18 | Deribit, 19 | CryptoCom, 20 | Whitebit, 21 | WooX, 22 | Poloniex, 23 | AscendEx, 24 | Binance, 25 | BinanceUS, 26 | BingX, 27 | Bitfinex, 28 | Bitget, 29 | BitMart, 30 | BitMex, 31 | BloFin, 32 | Bybit, 33 | CEX, 34 | Coinbase, 35 | CoinEx, 36 | HTX, 37 | Kraken, 38 | OKX, 39 | OkCoin, 40 | } 41 | 42 | pub struct Endpoint<'a> { 43 | pub market_type: MT, 44 | pub uri: &'a str, 45 | pub h3: bool, 46 | pub h2: bool, 47 | pub h1: bool, 48 | } 49 | 50 | impl<'a> Endpoint<'a> { 51 | pub fn new(market_type: MT, uri: &'a str) -> Self { 52 | Self { 53 | market_type, 54 | uri, 55 | h3: false, 56 | h2: false, 57 | h1: false, 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /src/utils.rs: -------------------------------------------------------------------------------- 1 | use log::{warn, error}; 2 | use std::sync::Arc; 3 | use std::future; 4 | 5 | 6 | static ALPN: &[u8] = b"h3"; 7 | 8 | pub fn get_roots() -> rustls::RootCertStore { 9 | let mut roots = rustls::RootCertStore::empty(); 10 | match rustls_native_certs::load_native_certs() { 11 | Ok(certs) => { 12 | for cert in certs { 13 | if let Err(e) = roots.add(&rustls::Certificate(cert.0)) { 14 | warn!("[!] get_roots |:| Failed to parse trust anchor: {}", e); 15 | } 16 | } 17 | } 18 | Err(e) => { 19 | warn!("[!] get_roots |:| Couldn't load any default trust roots: {}", e); 20 | } 21 | }; 22 | 23 | roots 24 | } 25 | 26 | pub async fn parse_uri(uri: &str) -> Option<(http::Uri, http::uri::Authority, std::net::SocketAddr)> { 27 | let uri = uri.parse::().expect("[!] parse_url |:| Failed to parse URI"); 28 | if uri.scheme() != Some(&http::uri::Scheme::HTTPS) { 29 | return None; 30 | } 31 | 32 | let auth = uri.authority().ok_or("[!] parse_url |:| URI must have a host").expect("[!] parse_url |:| URI must have a host").clone(); 33 | let port = auth.port_u16().unwrap_or(443); 34 | let addr = tokio::net::lookup_host((auth.host(), port)) 35 | .await.expect("[!] parse_url |:| DNS lookup failed") 36 | .next() 37 | .ok_or("[!] parse_url |:| DNS found no addresses").expect("[!] parse_url |:| DNS found no addresses"); 38 | 39 | return Some((uri, auth, addr)); 40 | } 41 | 42 | pub async fn get_config(roots: rustls::RootCertStore) -> rustls::ClientConfig { 43 | let mut tls_config = rustls::ClientConfig::builder() 44 | .with_safe_default_cipher_suites() 45 | .with_safe_default_kx_groups() 46 | .with_protocol_versions(&[&rustls::version::TLS13]).expect("[!] get_config |:| Failed to set protocol versions") 47 | .with_root_certificates(roots) 48 | .with_no_client_auth(); 49 | tls_config.enable_early_data = true; 50 | tls_config.alpn_protocols = vec![ALPN.into()]; 51 | 52 | tls_config 53 | } 54 | 55 | pub fn get_quinn_endpoint(tls_config: rustls::ClientConfig) -> quinn::Endpoint { 56 | let mut client_endpoint = h3_quinn::quinn::Endpoint::client("[::]:0".parse().unwrap()).expect("[!] get_config |:| Failed to create client endpoint"); 57 | let client_config = quinn::ClientConfig::new(Arc::new(tls_config)); 58 | client_endpoint.set_default_client_config(client_config); 59 | 60 | client_endpoint 61 | } 62 | 63 | 64 | 65 | pub async fn test_h3(uri: &str, tls_config: rustls::ClientConfig) -> Option<(http::Version, http::StatusCode)> { 66 | if let Some((uri, auth, addr)) = parse_uri(uri).await { 67 | let client_endpoint = get_quinn_endpoint(tls_config); 68 | let conn = client_endpoint.connect(addr, auth.host()).expect("[!] Failed to connect to client endpoint").await; 69 | if let Ok(conn) = conn { 70 | 71 | let quinn_conn = h3_quinn::Connection::new(conn); 72 | let (mut driver, mut send_request) = h3::client::new(quinn_conn).await.expect("[!] Failed to create h3 client"); 73 | let drive = async move { 74 | let x = future::poll_fn(|cx| driver.poll_close(cx)).await; 75 | match x { 76 | Ok(()) => {} 77 | Err(e) => { 78 | error!("[!] Drive failed: {}", e); 79 | } 80 | } 81 | }; 82 | 83 | let request = async move { 84 | let req = http::Request::builder().uri(uri).body(()); 85 | match req { 86 | Ok(req) => { 87 | let stream = send_request.send_request(req).await; 88 | match stream { 89 | Ok(mut stream) => { 90 | let stream_finish_result = stream.finish().await; 91 | match stream_finish_result { 92 | Ok(()) => { 93 | let resp = stream.recv_response().await; 94 | match resp { 95 | Ok(resp) => { 96 | Some((resp.version(), resp.status())) 97 | } 98 | Err(_) => { 99 | None 100 | } 101 | } 102 | } 103 | Err(_) => { 104 | None 105 | } 106 | } 107 | } 108 | Err(_) => { 109 | return None; 110 | } 111 | } 112 | } 113 | Err(_) => { 114 | return None; 115 | } 116 | } 117 | }; 118 | 119 | let (req_res, _) = tokio::join!(request, drive); 120 | client_endpoint.wait_idle().await; 121 | 122 | if let Some((version, status_code)) = req_res { 123 | Some((version, status_code)) 124 | } else { 125 | None 126 | } 127 | } else { 128 | return None; 129 | } 130 | } else { 131 | None 132 | } 133 | 134 | } --------------------------------------------------------------------------------