├── .deepsource.toml ├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ ├── publish-crate.yml │ ├── publish-docker-image.yml │ ├── rust-clippy.yml │ └── upload-release-artifacts.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── Dockerfile ├── LICENSE ├── README.md └── src ├── main.rs └── proxy_utilities └── mod.rs /.deepsource.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | 3 | [[analyzers]] 4 | name = "docker" 5 | 6 | [[analyzers]] 7 | name = "rust" 8 | 9 | [analyzers.meta] 10 | msrv = "stable" 11 | 12 | [[transformers]] 13 | name = "rustfmt" -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | - package-ecosystem: "cargo" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" 8 | time: "03:00" 9 | timezone: "America/Chicago" 10 | -------------------------------------------------------------------------------- /.github/workflows/publish-crate.yml: -------------------------------------------------------------------------------- 1 | name: Publish Crate to crates.io 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | publish-crate: 9 | name: Publish Crate to crates.io 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | 14 | - name: Set up Rust toolchain 15 | uses: actions-rs/toolchain@v1 16 | with: 17 | profile: minimal 18 | toolchain: stable 19 | override: true 20 | 21 | - name: Publish crate to crates.io 22 | run: cargo publish 23 | env: 24 | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} 25 | -------------------------------------------------------------------------------- /.github/workflows/publish-docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Publish Docker Image 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | publish-docker-image: 9 | name: Publish Docker Image 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | 14 | - name: Set up QEMU 15 | uses: docker/setup-qemu-action@v3 16 | 17 | - name: Set up Docker Buildx 18 | uses: docker/setup-buildx-action@v3 19 | 20 | - name: Login to GitHub Container Registry 21 | uses: docker/login-action@v3 22 | with: 23 | registry: ghcr.io 24 | username: ${{ github.repository_owner }} 25 | password: ${{ secrets.GITHUB_TOKEN }} 26 | 27 | - name: Get repository owner 28 | uses: ASzc/change-string-case-action@v6 29 | id: repo-owner 30 | with: 31 | string: ${{ github.repository_owner }} 32 | 33 | - name: Get crate version 34 | uses: colathro/crate-version@1.0.0 35 | id: crate-version 36 | with: 37 | file: ./Cargo.toml 38 | 39 | - name: Build and push 40 | uses: docker/build-push-action@v5 41 | with: 42 | context: . 43 | platforms: linux/amd64,linux/arm64,linux/arm/v7 44 | push: true 45 | tags: | 46 | ghcr.io/${{ steps.repo-owner.outputs.lowercase }}/proxy-scraper-checker:${{ steps.crate-version.outputs.version }} 47 | ghcr.io/${{ steps.repo-owner.outputs.lowercase }}/proxy-scraper-checker:latest 48 | -------------------------------------------------------------------------------- /.github/workflows/rust-clippy.yml: -------------------------------------------------------------------------------- 1 | name: Analyze With Clippy 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - src/** 9 | pull_request: 10 | paths: 11 | - src/** 12 | 13 | permissions: 14 | contents: read 15 | security-events: write 16 | actions: read 17 | 18 | jobs: 19 | analyze-with-clippy: 20 | name: Analyze With Clippy 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v4 24 | 25 | - name: Install Rust toolchain 26 | uses: actions-rs/toolchain@v1 27 | with: 28 | profile: minimal 29 | toolchain: stable 30 | components: clippy 31 | override: true 32 | 33 | - name: Install clippy-sarif and sarif-fmt 34 | run: cargo install clippy-sarif sarif-fmt 35 | 36 | - name: Run rust-clippy 37 | run: cargo clippy 38 | --all-features 39 | --message-format=json | clippy-sarif | tee rust-clippy-results.sarif | sarif-fmt 40 | continue-on-error: true 41 | 42 | - name: Upload analysis results to GitHub 43 | uses: github/codeql-action/upload-sarif@v2 44 | with: 45 | sarif_file: rust-clippy-results.sarif 46 | wait-for-processing: true 47 | -------------------------------------------------------------------------------- /.github/workflows/upload-release-artifacts.yml: -------------------------------------------------------------------------------- 1 | name: Upload Release Artifacts to GitHub Releases 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | upload-release-artifacts: 9 | name: Release ${{ matrix.target }} 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | include: 14 | - target: x86_64-pc-windows-gnu 15 | archive: zip 16 | - target: x86_64-unknown-linux-musl 17 | archive: tar.gz 18 | - target: x86_64-apple-darwin 19 | archive: zip 20 | steps: 21 | - uses: actions/checkout@v4 22 | 23 | - name: Compile and upload artifacts 24 | uses: rust-build/rust-build.action@latest 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 27 | with: 28 | RUSTTARGET: ${{ matrix.target }} 29 | ARCHIVE_TYPES: ${{ matrix.archive }} 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Project specific 2 | proxies/ 3 | 4 | # Generated by Cargo 5 | # will have compiled files and executables 6 | target/ 7 | 8 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 9 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 10 | # Cargo.lock 11 | 12 | # These are backup files generated by rustfmt 13 | **/*.rs.bk 14 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 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 = "anstream" 22 | version = "0.6.18" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" 25 | dependencies = [ 26 | "anstyle", 27 | "anstyle-parse", 28 | "anstyle-query", 29 | "anstyle-wincon", 30 | "colorchoice", 31 | "is_terminal_polyfill", 32 | "utf8parse", 33 | ] 34 | 35 | [[package]] 36 | name = "anstyle" 37 | version = "1.0.10" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" 40 | 41 | [[package]] 42 | name = "anstyle-parse" 43 | version = "0.2.6" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" 46 | dependencies = [ 47 | "utf8parse", 48 | ] 49 | 50 | [[package]] 51 | name = "anstyle-query" 52 | version = "1.1.2" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" 55 | dependencies = [ 56 | "windows-sys 0.59.0", 57 | ] 58 | 59 | [[package]] 60 | name = "anstyle-wincon" 61 | version = "3.0.6" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" 64 | dependencies = [ 65 | "anstyle", 66 | "windows-sys 0.59.0", 67 | ] 68 | 69 | [[package]] 70 | name = "anyhow" 71 | version = "1.0.98" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" 74 | 75 | [[package]] 76 | name = "atomic-waker" 77 | version = "1.1.2" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 80 | 81 | [[package]] 82 | name = "autocfg" 83 | version = "1.4.0" 84 | source = "registry+https://github.com/rust-lang/crates.io-index" 85 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 86 | 87 | [[package]] 88 | name = "backtrace" 89 | version = "0.3.74" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 92 | dependencies = [ 93 | "addr2line", 94 | "cfg-if", 95 | "libc", 96 | "miniz_oxide", 97 | "object", 98 | "rustc-demangle", 99 | "windows-targets 0.52.6", 100 | ] 101 | 102 | [[package]] 103 | name = "base64" 104 | version = "0.22.1" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 107 | 108 | [[package]] 109 | name = "bitflags" 110 | version = "2.6.0" 111 | source = "registry+https://github.com/rust-lang/crates.io-index" 112 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 113 | 114 | [[package]] 115 | name = "bumpalo" 116 | version = "3.16.0" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 119 | 120 | [[package]] 121 | name = "bytecount" 122 | version = "0.6.8" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" 125 | 126 | [[package]] 127 | name = "byteorder" 128 | version = "1.5.0" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 131 | 132 | [[package]] 133 | name = "bytes" 134 | version = "1.9.0" 135 | source = "registry+https://github.com/rust-lang/crates.io-index" 136 | checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" 137 | 138 | [[package]] 139 | name = "cc" 140 | version = "1.2.16" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" 143 | dependencies = [ 144 | "shlex", 145 | ] 146 | 147 | [[package]] 148 | name = "cfg-if" 149 | version = "1.0.0" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 152 | 153 | [[package]] 154 | name = "clap" 155 | version = "4.5.40" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" 158 | dependencies = [ 159 | "clap_builder", 160 | "clap_derive", 161 | ] 162 | 163 | [[package]] 164 | name = "clap_builder" 165 | version = "4.5.40" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" 168 | dependencies = [ 169 | "anstream", 170 | "anstyle", 171 | "clap_lex", 172 | "strsim", 173 | ] 174 | 175 | [[package]] 176 | name = "clap_derive" 177 | version = "4.5.40" 178 | source = "registry+https://github.com/rust-lang/crates.io-index" 179 | checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" 180 | dependencies = [ 181 | "heck", 182 | "proc-macro2", 183 | "quote", 184 | "syn", 185 | ] 186 | 187 | [[package]] 188 | name = "clap_lex" 189 | version = "0.7.4" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" 192 | 193 | [[package]] 194 | name = "colorchoice" 195 | version = "1.0.3" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" 198 | 199 | [[package]] 200 | name = "console" 201 | version = "0.15.10" 202 | source = "registry+https://github.com/rust-lang/crates.io-index" 203 | checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" 204 | dependencies = [ 205 | "encode_unicode", 206 | "libc", 207 | "once_cell", 208 | "unicode-width 0.2.0", 209 | "windows-sys 0.59.0", 210 | ] 211 | 212 | [[package]] 213 | name = "core-foundation" 214 | version = "0.9.4" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 217 | dependencies = [ 218 | "core-foundation-sys", 219 | "libc", 220 | ] 221 | 222 | [[package]] 223 | name = "core-foundation-sys" 224 | version = "0.8.7" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 227 | 228 | [[package]] 229 | name = "cssparser" 230 | version = "0.34.0" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | checksum = "b7c66d1cd8ed61bf80b38432613a7a2f09401ab8d0501110655f8b341484a3e3" 233 | dependencies = [ 234 | "cssparser-macros", 235 | "dtoa-short", 236 | "itoa", 237 | "phf", 238 | "smallvec", 239 | ] 240 | 241 | [[package]] 242 | name = "cssparser-macros" 243 | version = "0.6.1" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" 246 | dependencies = [ 247 | "quote", 248 | "syn", 249 | ] 250 | 251 | [[package]] 252 | name = "derive_more" 253 | version = "0.99.18" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" 256 | dependencies = [ 257 | "proc-macro2", 258 | "quote", 259 | "syn", 260 | ] 261 | 262 | [[package]] 263 | name = "displaydoc" 264 | version = "0.2.5" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 267 | dependencies = [ 268 | "proc-macro2", 269 | "quote", 270 | "syn", 271 | ] 272 | 273 | [[package]] 274 | name = "dtoa" 275 | version = "1.0.9" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" 278 | 279 | [[package]] 280 | name = "dtoa-short" 281 | version = "0.3.5" 282 | source = "registry+https://github.com/rust-lang/crates.io-index" 283 | checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" 284 | dependencies = [ 285 | "dtoa", 286 | ] 287 | 288 | [[package]] 289 | name = "ego-tree" 290 | version = "0.10.0" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "b2972feb8dffe7bc8c5463b1dacda1b0dfbed3710e50f977d965429692d74cd8" 293 | 294 | [[package]] 295 | name = "encode_unicode" 296 | version = "1.0.0" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" 299 | 300 | [[package]] 301 | name = "encoding_rs" 302 | version = "0.8.35" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" 305 | dependencies = [ 306 | "cfg-if", 307 | ] 308 | 309 | [[package]] 310 | name = "equivalent" 311 | version = "1.0.1" 312 | source = "registry+https://github.com/rust-lang/crates.io-index" 313 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 314 | 315 | [[package]] 316 | name = "errno" 317 | version = "0.3.10" 318 | source = "registry+https://github.com/rust-lang/crates.io-index" 319 | checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" 320 | dependencies = [ 321 | "libc", 322 | "windows-sys 0.59.0", 323 | ] 324 | 325 | [[package]] 326 | name = "fastrand" 327 | version = "2.3.0" 328 | source = "registry+https://github.com/rust-lang/crates.io-index" 329 | checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 330 | 331 | [[package]] 332 | name = "fnv" 333 | version = "1.0.7" 334 | source = "registry+https://github.com/rust-lang/crates.io-index" 335 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 336 | 337 | [[package]] 338 | name = "foreign-types" 339 | version = "0.3.2" 340 | source = "registry+https://github.com/rust-lang/crates.io-index" 341 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 342 | dependencies = [ 343 | "foreign-types-shared", 344 | ] 345 | 346 | [[package]] 347 | name = "foreign-types-shared" 348 | version = "0.1.1" 349 | source = "registry+https://github.com/rust-lang/crates.io-index" 350 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 351 | 352 | [[package]] 353 | name = "form_urlencoded" 354 | version = "1.2.1" 355 | source = "registry+https://github.com/rust-lang/crates.io-index" 356 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 357 | dependencies = [ 358 | "percent-encoding", 359 | ] 360 | 361 | [[package]] 362 | name = "futf" 363 | version = "0.1.5" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" 366 | dependencies = [ 367 | "mac", 368 | "new_debug_unreachable", 369 | ] 370 | 371 | [[package]] 372 | name = "futures" 373 | version = "0.3.31" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 376 | dependencies = [ 377 | "futures-channel", 378 | "futures-core", 379 | "futures-executor", 380 | "futures-io", 381 | "futures-sink", 382 | "futures-task", 383 | "futures-util", 384 | ] 385 | 386 | [[package]] 387 | name = "futures-channel" 388 | version = "0.3.31" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 391 | dependencies = [ 392 | "futures-core", 393 | "futures-sink", 394 | ] 395 | 396 | [[package]] 397 | name = "futures-core" 398 | version = "0.3.31" 399 | source = "registry+https://github.com/rust-lang/crates.io-index" 400 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 401 | 402 | [[package]] 403 | name = "futures-executor" 404 | version = "0.3.31" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" 407 | dependencies = [ 408 | "futures-core", 409 | "futures-task", 410 | "futures-util", 411 | ] 412 | 413 | [[package]] 414 | name = "futures-io" 415 | version = "0.3.31" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 418 | 419 | [[package]] 420 | name = "futures-macro" 421 | version = "0.3.31" 422 | source = "registry+https://github.com/rust-lang/crates.io-index" 423 | checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 424 | dependencies = [ 425 | "proc-macro2", 426 | "quote", 427 | "syn", 428 | ] 429 | 430 | [[package]] 431 | name = "futures-sink" 432 | version = "0.3.31" 433 | source = "registry+https://github.com/rust-lang/crates.io-index" 434 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 435 | 436 | [[package]] 437 | name = "futures-task" 438 | version = "0.3.31" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 441 | 442 | [[package]] 443 | name = "futures-util" 444 | version = "0.3.31" 445 | source = "registry+https://github.com/rust-lang/crates.io-index" 446 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 447 | dependencies = [ 448 | "futures-channel", 449 | "futures-core", 450 | "futures-io", 451 | "futures-macro", 452 | "futures-sink", 453 | "futures-task", 454 | "memchr", 455 | "pin-project-lite", 456 | "pin-utils", 457 | "slab", 458 | ] 459 | 460 | [[package]] 461 | name = "fxhash" 462 | version = "0.2.1" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" 465 | dependencies = [ 466 | "byteorder", 467 | ] 468 | 469 | [[package]] 470 | name = "getopts" 471 | version = "0.2.21" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" 474 | dependencies = [ 475 | "unicode-width 0.1.14", 476 | ] 477 | 478 | [[package]] 479 | name = "getrandom" 480 | version = "0.2.15" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 483 | dependencies = [ 484 | "cfg-if", 485 | "libc", 486 | "wasi", 487 | ] 488 | 489 | [[package]] 490 | name = "gimli" 491 | version = "0.31.1" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 494 | 495 | [[package]] 496 | name = "h2" 497 | version = "0.4.7" 498 | source = "registry+https://github.com/rust-lang/crates.io-index" 499 | checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" 500 | dependencies = [ 501 | "atomic-waker", 502 | "bytes", 503 | "fnv", 504 | "futures-core", 505 | "futures-sink", 506 | "http", 507 | "indexmap", 508 | "slab", 509 | "tokio", 510 | "tokio-util", 511 | "tracing", 512 | ] 513 | 514 | [[package]] 515 | name = "hashbrown" 516 | version = "0.15.2" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 519 | 520 | [[package]] 521 | name = "heck" 522 | version = "0.5.0" 523 | source = "registry+https://github.com/rust-lang/crates.io-index" 524 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 525 | 526 | [[package]] 527 | name = "html5ever" 528 | version = "0.29.0" 529 | source = "registry+https://github.com/rust-lang/crates.io-index" 530 | checksum = "2e15626aaf9c351bc696217cbe29cb9b5e86c43f8a46b5e2f5c6c5cf7cb904ce" 531 | dependencies = [ 532 | "log", 533 | "mac", 534 | "markup5ever", 535 | "proc-macro2", 536 | "quote", 537 | "syn", 538 | ] 539 | 540 | [[package]] 541 | name = "http" 542 | version = "1.2.0" 543 | source = "registry+https://github.com/rust-lang/crates.io-index" 544 | checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" 545 | dependencies = [ 546 | "bytes", 547 | "fnv", 548 | "itoa", 549 | ] 550 | 551 | [[package]] 552 | name = "http-body" 553 | version = "1.0.1" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 556 | dependencies = [ 557 | "bytes", 558 | "http", 559 | ] 560 | 561 | [[package]] 562 | name = "http-body-util" 563 | version = "0.1.2" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" 566 | dependencies = [ 567 | "bytes", 568 | "futures-util", 569 | "http", 570 | "http-body", 571 | "pin-project-lite", 572 | ] 573 | 574 | [[package]] 575 | name = "httparse" 576 | version = "1.9.5" 577 | source = "registry+https://github.com/rust-lang/crates.io-index" 578 | checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" 579 | 580 | [[package]] 581 | name = "humantime" 582 | version = "2.2.0" 583 | source = "registry+https://github.com/rust-lang/crates.io-index" 584 | checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" 585 | 586 | [[package]] 587 | name = "hyper" 588 | version = "1.6.0" 589 | source = "registry+https://github.com/rust-lang/crates.io-index" 590 | checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" 591 | dependencies = [ 592 | "bytes", 593 | "futures-channel", 594 | "futures-util", 595 | "h2", 596 | "http", 597 | "http-body", 598 | "httparse", 599 | "itoa", 600 | "pin-project-lite", 601 | "smallvec", 602 | "tokio", 603 | "want", 604 | ] 605 | 606 | [[package]] 607 | name = "hyper-rustls" 608 | version = "0.27.5" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" 611 | dependencies = [ 612 | "futures-util", 613 | "http", 614 | "hyper", 615 | "hyper-util", 616 | "rustls", 617 | "rustls-pki-types", 618 | "tokio", 619 | "tokio-rustls", 620 | "tower-service", 621 | ] 622 | 623 | [[package]] 624 | name = "hyper-tls" 625 | version = "0.6.0" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" 628 | dependencies = [ 629 | "bytes", 630 | "http-body-util", 631 | "hyper", 632 | "hyper-util", 633 | "native-tls", 634 | "tokio", 635 | "tokio-native-tls", 636 | "tower-service", 637 | ] 638 | 639 | [[package]] 640 | name = "hyper-util" 641 | version = "0.1.13" 642 | source = "registry+https://github.com/rust-lang/crates.io-index" 643 | checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8" 644 | dependencies = [ 645 | "base64", 646 | "bytes", 647 | "futures-channel", 648 | "futures-core", 649 | "futures-util", 650 | "http", 651 | "http-body", 652 | "hyper", 653 | "ipnet", 654 | "libc", 655 | "percent-encoding", 656 | "pin-project-lite", 657 | "socket2", 658 | "system-configuration", 659 | "tokio", 660 | "tower-service", 661 | "tracing", 662 | "windows-registry", 663 | ] 664 | 665 | [[package]] 666 | name = "icu_collections" 667 | version = "1.5.0" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" 670 | dependencies = [ 671 | "displaydoc", 672 | "yoke", 673 | "zerofrom", 674 | "zerovec", 675 | ] 676 | 677 | [[package]] 678 | name = "icu_locid" 679 | version = "1.5.0" 680 | source = "registry+https://github.com/rust-lang/crates.io-index" 681 | checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" 682 | dependencies = [ 683 | "displaydoc", 684 | "litemap", 685 | "tinystr", 686 | "writeable", 687 | "zerovec", 688 | ] 689 | 690 | [[package]] 691 | name = "icu_locid_transform" 692 | version = "1.5.0" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" 695 | dependencies = [ 696 | "displaydoc", 697 | "icu_locid", 698 | "icu_locid_transform_data", 699 | "icu_provider", 700 | "tinystr", 701 | "zerovec", 702 | ] 703 | 704 | [[package]] 705 | name = "icu_locid_transform_data" 706 | version = "1.5.0" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" 709 | 710 | [[package]] 711 | name = "icu_normalizer" 712 | version = "1.5.0" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" 715 | dependencies = [ 716 | "displaydoc", 717 | "icu_collections", 718 | "icu_normalizer_data", 719 | "icu_properties", 720 | "icu_provider", 721 | "smallvec", 722 | "utf16_iter", 723 | "utf8_iter", 724 | "write16", 725 | "zerovec", 726 | ] 727 | 728 | [[package]] 729 | name = "icu_normalizer_data" 730 | version = "1.5.0" 731 | source = "registry+https://github.com/rust-lang/crates.io-index" 732 | checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" 733 | 734 | [[package]] 735 | name = "icu_properties" 736 | version = "1.5.1" 737 | source = "registry+https://github.com/rust-lang/crates.io-index" 738 | checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" 739 | dependencies = [ 740 | "displaydoc", 741 | "icu_collections", 742 | "icu_locid_transform", 743 | "icu_properties_data", 744 | "icu_provider", 745 | "tinystr", 746 | "zerovec", 747 | ] 748 | 749 | [[package]] 750 | name = "icu_properties_data" 751 | version = "1.5.0" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" 754 | 755 | [[package]] 756 | name = "icu_provider" 757 | version = "1.5.0" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" 760 | dependencies = [ 761 | "displaydoc", 762 | "icu_locid", 763 | "icu_provider_macros", 764 | "stable_deref_trait", 765 | "tinystr", 766 | "writeable", 767 | "yoke", 768 | "zerofrom", 769 | "zerovec", 770 | ] 771 | 772 | [[package]] 773 | name = "icu_provider_macros" 774 | version = "1.5.0" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" 777 | dependencies = [ 778 | "proc-macro2", 779 | "quote", 780 | "syn", 781 | ] 782 | 783 | [[package]] 784 | name = "idna" 785 | version = "1.0.3" 786 | source = "registry+https://github.com/rust-lang/crates.io-index" 787 | checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 788 | dependencies = [ 789 | "idna_adapter", 790 | "smallvec", 791 | "utf8_iter", 792 | ] 793 | 794 | [[package]] 795 | name = "idna_adapter" 796 | version = "1.2.0" 797 | source = "registry+https://github.com/rust-lang/crates.io-index" 798 | checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" 799 | dependencies = [ 800 | "icu_normalizer", 801 | "icu_properties", 802 | ] 803 | 804 | [[package]] 805 | name = "indexmap" 806 | version = "2.7.0" 807 | source = "registry+https://github.com/rust-lang/crates.io-index" 808 | checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" 809 | dependencies = [ 810 | "equivalent", 811 | "hashbrown", 812 | ] 813 | 814 | [[package]] 815 | name = "indicatif" 816 | version = "0.17.11" 817 | source = "registry+https://github.com/rust-lang/crates.io-index" 818 | checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" 819 | dependencies = [ 820 | "console", 821 | "number_prefix", 822 | "portable-atomic", 823 | "unicode-width 0.2.0", 824 | "web-time", 825 | ] 826 | 827 | [[package]] 828 | name = "ipnet" 829 | version = "2.10.1" 830 | source = "registry+https://github.com/rust-lang/crates.io-index" 831 | checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" 832 | 833 | [[package]] 834 | name = "iri-string" 835 | version = "0.7.8" 836 | source = "registry+https://github.com/rust-lang/crates.io-index" 837 | checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" 838 | dependencies = [ 839 | "memchr", 840 | "serde", 841 | ] 842 | 843 | [[package]] 844 | name = "is_terminal_polyfill" 845 | version = "1.70.1" 846 | source = "registry+https://github.com/rust-lang/crates.io-index" 847 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 848 | 849 | [[package]] 850 | name = "itoa" 851 | version = "1.0.14" 852 | source = "registry+https://github.com/rust-lang/crates.io-index" 853 | checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" 854 | 855 | [[package]] 856 | name = "js-sys" 857 | version = "0.3.77" 858 | source = "registry+https://github.com/rust-lang/crates.io-index" 859 | checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" 860 | dependencies = [ 861 | "once_cell", 862 | "wasm-bindgen", 863 | ] 864 | 865 | [[package]] 866 | name = "libc" 867 | version = "0.2.172" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" 870 | 871 | [[package]] 872 | name = "linux-raw-sys" 873 | version = "0.4.14" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 876 | 877 | [[package]] 878 | name = "litemap" 879 | version = "0.7.4" 880 | source = "registry+https://github.com/rust-lang/crates.io-index" 881 | checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" 882 | 883 | [[package]] 884 | name = "lock_api" 885 | version = "0.4.12" 886 | source = "registry+https://github.com/rust-lang/crates.io-index" 887 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 888 | dependencies = [ 889 | "autocfg", 890 | "scopeguard", 891 | ] 892 | 893 | [[package]] 894 | name = "log" 895 | version = "0.4.22" 896 | source = "registry+https://github.com/rust-lang/crates.io-index" 897 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 898 | 899 | [[package]] 900 | name = "mac" 901 | version = "0.1.1" 902 | source = "registry+https://github.com/rust-lang/crates.io-index" 903 | checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" 904 | 905 | [[package]] 906 | name = "markup5ever" 907 | version = "0.14.0" 908 | source = "registry+https://github.com/rust-lang/crates.io-index" 909 | checksum = "82c88c6129bd24319e62a0359cb6b958fa7e8be6e19bb1663bc396b90883aca5" 910 | dependencies = [ 911 | "log", 912 | "phf", 913 | "phf_codegen", 914 | "string_cache", 915 | "string_cache_codegen", 916 | "tendril", 917 | ] 918 | 919 | [[package]] 920 | name = "memchr" 921 | version = "2.7.4" 922 | source = "registry+https://github.com/rust-lang/crates.io-index" 923 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 924 | 925 | [[package]] 926 | name = "mime" 927 | version = "0.3.17" 928 | source = "registry+https://github.com/rust-lang/crates.io-index" 929 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 930 | 931 | [[package]] 932 | name = "miniz_oxide" 933 | version = "0.8.2" 934 | source = "registry+https://github.com/rust-lang/crates.io-index" 935 | checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" 936 | dependencies = [ 937 | "adler2", 938 | ] 939 | 940 | [[package]] 941 | name = "mio" 942 | version = "1.0.3" 943 | source = "registry+https://github.com/rust-lang/crates.io-index" 944 | checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" 945 | dependencies = [ 946 | "libc", 947 | "wasi", 948 | "windows-sys 0.52.0", 949 | ] 950 | 951 | [[package]] 952 | name = "native-tls" 953 | version = "0.2.12" 954 | source = "registry+https://github.com/rust-lang/crates.io-index" 955 | checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" 956 | dependencies = [ 957 | "libc", 958 | "log", 959 | "openssl", 960 | "openssl-probe", 961 | "openssl-sys", 962 | "schannel", 963 | "security-framework", 964 | "security-framework-sys", 965 | "tempfile", 966 | ] 967 | 968 | [[package]] 969 | name = "new_debug_unreachable" 970 | version = "1.0.6" 971 | source = "registry+https://github.com/rust-lang/crates.io-index" 972 | checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" 973 | 974 | [[package]] 975 | name = "number_prefix" 976 | version = "0.4.0" 977 | source = "registry+https://github.com/rust-lang/crates.io-index" 978 | checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" 979 | 980 | [[package]] 981 | name = "object" 982 | version = "0.36.7" 983 | source = "registry+https://github.com/rust-lang/crates.io-index" 984 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 985 | dependencies = [ 986 | "memchr", 987 | ] 988 | 989 | [[package]] 990 | name = "once_cell" 991 | version = "1.20.2" 992 | source = "registry+https://github.com/rust-lang/crates.io-index" 993 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 994 | 995 | [[package]] 996 | name = "openssl" 997 | version = "0.10.72" 998 | source = "registry+https://github.com/rust-lang/crates.io-index" 999 | checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" 1000 | dependencies = [ 1001 | "bitflags", 1002 | "cfg-if", 1003 | "foreign-types", 1004 | "libc", 1005 | "once_cell", 1006 | "openssl-macros", 1007 | "openssl-sys", 1008 | ] 1009 | 1010 | [[package]] 1011 | name = "openssl-macros" 1012 | version = "0.1.1" 1013 | source = "registry+https://github.com/rust-lang/crates.io-index" 1014 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 1015 | dependencies = [ 1016 | "proc-macro2", 1017 | "quote", 1018 | "syn", 1019 | ] 1020 | 1021 | [[package]] 1022 | name = "openssl-probe" 1023 | version = "0.1.5" 1024 | source = "registry+https://github.com/rust-lang/crates.io-index" 1025 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 1026 | 1027 | [[package]] 1028 | name = "openssl-sys" 1029 | version = "0.9.107" 1030 | source = "registry+https://github.com/rust-lang/crates.io-index" 1031 | checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" 1032 | dependencies = [ 1033 | "cc", 1034 | "libc", 1035 | "pkg-config", 1036 | "vcpkg", 1037 | ] 1038 | 1039 | [[package]] 1040 | name = "papergrid" 1041 | version = "0.17.0" 1042 | source = "registry+https://github.com/rust-lang/crates.io-index" 1043 | checksum = "6978128c8b51d8f4080631ceb2302ab51e32cc6e8615f735ee2f83fd269ae3f1" 1044 | dependencies = [ 1045 | "bytecount", 1046 | "fnv", 1047 | "unicode-width 0.2.0", 1048 | ] 1049 | 1050 | [[package]] 1051 | name = "parking_lot" 1052 | version = "0.12.3" 1053 | source = "registry+https://github.com/rust-lang/crates.io-index" 1054 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 1055 | dependencies = [ 1056 | "lock_api", 1057 | "parking_lot_core", 1058 | ] 1059 | 1060 | [[package]] 1061 | name = "parking_lot_core" 1062 | version = "0.9.10" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 1065 | dependencies = [ 1066 | "cfg-if", 1067 | "libc", 1068 | "redox_syscall", 1069 | "smallvec", 1070 | "windows-targets 0.52.6", 1071 | ] 1072 | 1073 | [[package]] 1074 | name = "percent-encoding" 1075 | version = "2.3.1" 1076 | source = "registry+https://github.com/rust-lang/crates.io-index" 1077 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1078 | 1079 | [[package]] 1080 | name = "phf" 1081 | version = "0.11.2" 1082 | source = "registry+https://github.com/rust-lang/crates.io-index" 1083 | checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" 1084 | dependencies = [ 1085 | "phf_macros", 1086 | "phf_shared 0.11.2", 1087 | ] 1088 | 1089 | [[package]] 1090 | name = "phf_codegen" 1091 | version = "0.11.2" 1092 | source = "registry+https://github.com/rust-lang/crates.io-index" 1093 | checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" 1094 | dependencies = [ 1095 | "phf_generator 0.11.2", 1096 | "phf_shared 0.11.2", 1097 | ] 1098 | 1099 | [[package]] 1100 | name = "phf_generator" 1101 | version = "0.10.0" 1102 | source = "registry+https://github.com/rust-lang/crates.io-index" 1103 | checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" 1104 | dependencies = [ 1105 | "phf_shared 0.10.0", 1106 | "rand", 1107 | ] 1108 | 1109 | [[package]] 1110 | name = "phf_generator" 1111 | version = "0.11.2" 1112 | source = "registry+https://github.com/rust-lang/crates.io-index" 1113 | checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" 1114 | dependencies = [ 1115 | "phf_shared 0.11.2", 1116 | "rand", 1117 | ] 1118 | 1119 | [[package]] 1120 | name = "phf_macros" 1121 | version = "0.11.2" 1122 | source = "registry+https://github.com/rust-lang/crates.io-index" 1123 | checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" 1124 | dependencies = [ 1125 | "phf_generator 0.11.2", 1126 | "phf_shared 0.11.2", 1127 | "proc-macro2", 1128 | "quote", 1129 | "syn", 1130 | ] 1131 | 1132 | [[package]] 1133 | name = "phf_shared" 1134 | version = "0.10.0" 1135 | source = "registry+https://github.com/rust-lang/crates.io-index" 1136 | checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" 1137 | dependencies = [ 1138 | "siphasher", 1139 | ] 1140 | 1141 | [[package]] 1142 | name = "phf_shared" 1143 | version = "0.11.2" 1144 | source = "registry+https://github.com/rust-lang/crates.io-index" 1145 | checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" 1146 | dependencies = [ 1147 | "siphasher", 1148 | ] 1149 | 1150 | [[package]] 1151 | name = "pin-project-lite" 1152 | version = "0.2.15" 1153 | source = "registry+https://github.com/rust-lang/crates.io-index" 1154 | checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" 1155 | 1156 | [[package]] 1157 | name = "pin-utils" 1158 | version = "0.1.0" 1159 | source = "registry+https://github.com/rust-lang/crates.io-index" 1160 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1161 | 1162 | [[package]] 1163 | name = "pkg-config" 1164 | version = "0.3.31" 1165 | source = "registry+https://github.com/rust-lang/crates.io-index" 1166 | checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" 1167 | 1168 | [[package]] 1169 | name = "portable-atomic" 1170 | version = "1.10.0" 1171 | source = "registry+https://github.com/rust-lang/crates.io-index" 1172 | checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" 1173 | 1174 | [[package]] 1175 | name = "ppv-lite86" 1176 | version = "0.2.20" 1177 | source = "registry+https://github.com/rust-lang/crates.io-index" 1178 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 1179 | dependencies = [ 1180 | "zerocopy", 1181 | ] 1182 | 1183 | [[package]] 1184 | name = "precomputed-hash" 1185 | version = "0.1.1" 1186 | source = "registry+https://github.com/rust-lang/crates.io-index" 1187 | checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" 1188 | 1189 | [[package]] 1190 | name = "proc-macro-error-attr2" 1191 | version = "2.0.0" 1192 | source = "registry+https://github.com/rust-lang/crates.io-index" 1193 | checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" 1194 | dependencies = [ 1195 | "proc-macro2", 1196 | "quote", 1197 | ] 1198 | 1199 | [[package]] 1200 | name = "proc-macro-error2" 1201 | version = "2.0.1" 1202 | source = "registry+https://github.com/rust-lang/crates.io-index" 1203 | checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" 1204 | dependencies = [ 1205 | "proc-macro-error-attr2", 1206 | "proc-macro2", 1207 | "quote", 1208 | "syn", 1209 | ] 1210 | 1211 | [[package]] 1212 | name = "proc-macro2" 1213 | version = "1.0.92" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" 1216 | dependencies = [ 1217 | "unicode-ident", 1218 | ] 1219 | 1220 | [[package]] 1221 | name = "proxy-scraper-checker" 1222 | version = "0.1.3" 1223 | dependencies = [ 1224 | "anyhow", 1225 | "clap", 1226 | "futures", 1227 | "humantime", 1228 | "indicatif", 1229 | "reqwest", 1230 | "rlimit", 1231 | "scraper", 1232 | "serde_json", 1233 | "tabled", 1234 | "tokio", 1235 | ] 1236 | 1237 | [[package]] 1238 | name = "quote" 1239 | version = "1.0.38" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" 1242 | dependencies = [ 1243 | "proc-macro2", 1244 | ] 1245 | 1246 | [[package]] 1247 | name = "rand" 1248 | version = "0.8.5" 1249 | source = "registry+https://github.com/rust-lang/crates.io-index" 1250 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1251 | dependencies = [ 1252 | "libc", 1253 | "rand_chacha", 1254 | "rand_core", 1255 | ] 1256 | 1257 | [[package]] 1258 | name = "rand_chacha" 1259 | version = "0.3.1" 1260 | source = "registry+https://github.com/rust-lang/crates.io-index" 1261 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1262 | dependencies = [ 1263 | "ppv-lite86", 1264 | "rand_core", 1265 | ] 1266 | 1267 | [[package]] 1268 | name = "rand_core" 1269 | version = "0.6.4" 1270 | source = "registry+https://github.com/rust-lang/crates.io-index" 1271 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1272 | dependencies = [ 1273 | "getrandom", 1274 | ] 1275 | 1276 | [[package]] 1277 | name = "redox_syscall" 1278 | version = "0.5.8" 1279 | source = "registry+https://github.com/rust-lang/crates.io-index" 1280 | checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" 1281 | dependencies = [ 1282 | "bitflags", 1283 | ] 1284 | 1285 | [[package]] 1286 | name = "reqwest" 1287 | version = "0.12.20" 1288 | source = "registry+https://github.com/rust-lang/crates.io-index" 1289 | checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813" 1290 | dependencies = [ 1291 | "base64", 1292 | "bytes", 1293 | "encoding_rs", 1294 | "futures-core", 1295 | "h2", 1296 | "http", 1297 | "http-body", 1298 | "http-body-util", 1299 | "hyper", 1300 | "hyper-rustls", 1301 | "hyper-tls", 1302 | "hyper-util", 1303 | "js-sys", 1304 | "log", 1305 | "mime", 1306 | "native-tls", 1307 | "percent-encoding", 1308 | "pin-project-lite", 1309 | "rustls-pki-types", 1310 | "serde", 1311 | "serde_json", 1312 | "serde_urlencoded", 1313 | "sync_wrapper", 1314 | "tokio", 1315 | "tokio-native-tls", 1316 | "tower", 1317 | "tower-http", 1318 | "tower-service", 1319 | "url", 1320 | "wasm-bindgen", 1321 | "wasm-bindgen-futures", 1322 | "web-sys", 1323 | ] 1324 | 1325 | [[package]] 1326 | name = "ring" 1327 | version = "0.17.13" 1328 | source = "registry+https://github.com/rust-lang/crates.io-index" 1329 | checksum = "70ac5d832aa16abd7d1def883a8545280c20a60f523a370aa3a9617c2b8550ee" 1330 | dependencies = [ 1331 | "cc", 1332 | "cfg-if", 1333 | "getrandom", 1334 | "libc", 1335 | "untrusted", 1336 | "windows-sys 0.52.0", 1337 | ] 1338 | 1339 | [[package]] 1340 | name = "rlimit" 1341 | version = "0.10.2" 1342 | source = "registry+https://github.com/rust-lang/crates.io-index" 1343 | checksum = "7043b63bd0cd1aaa628e476b80e6d4023a3b50eb32789f2728908107bd0c793a" 1344 | dependencies = [ 1345 | "libc", 1346 | ] 1347 | 1348 | [[package]] 1349 | name = "rustc-demangle" 1350 | version = "0.1.24" 1351 | source = "registry+https://github.com/rust-lang/crates.io-index" 1352 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1353 | 1354 | [[package]] 1355 | name = "rustix" 1356 | version = "0.38.42" 1357 | source = "registry+https://github.com/rust-lang/crates.io-index" 1358 | checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" 1359 | dependencies = [ 1360 | "bitflags", 1361 | "errno", 1362 | "libc", 1363 | "linux-raw-sys", 1364 | "windows-sys 0.59.0", 1365 | ] 1366 | 1367 | [[package]] 1368 | name = "rustls" 1369 | version = "0.23.20" 1370 | source = "registry+https://github.com/rust-lang/crates.io-index" 1371 | checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" 1372 | dependencies = [ 1373 | "once_cell", 1374 | "rustls-pki-types", 1375 | "rustls-webpki", 1376 | "subtle", 1377 | "zeroize", 1378 | ] 1379 | 1380 | [[package]] 1381 | name = "rustls-pki-types" 1382 | version = "1.10.1" 1383 | source = "registry+https://github.com/rust-lang/crates.io-index" 1384 | checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" 1385 | 1386 | [[package]] 1387 | name = "rustls-webpki" 1388 | version = "0.102.8" 1389 | source = "registry+https://github.com/rust-lang/crates.io-index" 1390 | checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" 1391 | dependencies = [ 1392 | "ring", 1393 | "rustls-pki-types", 1394 | "untrusted", 1395 | ] 1396 | 1397 | [[package]] 1398 | name = "rustversion" 1399 | version = "1.0.20" 1400 | source = "registry+https://github.com/rust-lang/crates.io-index" 1401 | checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" 1402 | 1403 | [[package]] 1404 | name = "ryu" 1405 | version = "1.0.18" 1406 | source = "registry+https://github.com/rust-lang/crates.io-index" 1407 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 1408 | 1409 | [[package]] 1410 | name = "schannel" 1411 | version = "0.1.27" 1412 | source = "registry+https://github.com/rust-lang/crates.io-index" 1413 | checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" 1414 | dependencies = [ 1415 | "windows-sys 0.59.0", 1416 | ] 1417 | 1418 | [[package]] 1419 | name = "scopeguard" 1420 | version = "1.2.0" 1421 | source = "registry+https://github.com/rust-lang/crates.io-index" 1422 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1423 | 1424 | [[package]] 1425 | name = "scraper" 1426 | version = "0.23.1" 1427 | source = "registry+https://github.com/rust-lang/crates.io-index" 1428 | checksum = "527e65d9d888567588db4c12da1087598d0f6f8b346cc2c5abc91f05fc2dffe2" 1429 | dependencies = [ 1430 | "cssparser", 1431 | "ego-tree", 1432 | "getopts", 1433 | "html5ever", 1434 | "precomputed-hash", 1435 | "selectors", 1436 | "tendril", 1437 | ] 1438 | 1439 | [[package]] 1440 | name = "security-framework" 1441 | version = "2.11.1" 1442 | source = "registry+https://github.com/rust-lang/crates.io-index" 1443 | checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 1444 | dependencies = [ 1445 | "bitflags", 1446 | "core-foundation", 1447 | "core-foundation-sys", 1448 | "libc", 1449 | "security-framework-sys", 1450 | ] 1451 | 1452 | [[package]] 1453 | name = "security-framework-sys" 1454 | version = "2.13.0" 1455 | source = "registry+https://github.com/rust-lang/crates.io-index" 1456 | checksum = "1863fd3768cd83c56a7f60faa4dc0d403f1b6df0a38c3c25f44b7894e45370d5" 1457 | dependencies = [ 1458 | "core-foundation-sys", 1459 | "libc", 1460 | ] 1461 | 1462 | [[package]] 1463 | name = "selectors" 1464 | version = "0.26.0" 1465 | source = "registry+https://github.com/rust-lang/crates.io-index" 1466 | checksum = "fd568a4c9bb598e291a08244a5c1f5a8a6650bee243b5b0f8dbb3d9cc1d87fe8" 1467 | dependencies = [ 1468 | "bitflags", 1469 | "cssparser", 1470 | "derive_more", 1471 | "fxhash", 1472 | "log", 1473 | "new_debug_unreachable", 1474 | "phf", 1475 | "phf_codegen", 1476 | "precomputed-hash", 1477 | "servo_arc", 1478 | "smallvec", 1479 | ] 1480 | 1481 | [[package]] 1482 | name = "serde" 1483 | version = "1.0.217" 1484 | source = "registry+https://github.com/rust-lang/crates.io-index" 1485 | checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" 1486 | dependencies = [ 1487 | "serde_derive", 1488 | ] 1489 | 1490 | [[package]] 1491 | name = "serde_derive" 1492 | version = "1.0.217" 1493 | source = "registry+https://github.com/rust-lang/crates.io-index" 1494 | checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" 1495 | dependencies = [ 1496 | "proc-macro2", 1497 | "quote", 1498 | "syn", 1499 | ] 1500 | 1501 | [[package]] 1502 | name = "serde_json" 1503 | version = "1.0.140" 1504 | source = "registry+https://github.com/rust-lang/crates.io-index" 1505 | checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" 1506 | dependencies = [ 1507 | "itoa", 1508 | "memchr", 1509 | "ryu", 1510 | "serde", 1511 | ] 1512 | 1513 | [[package]] 1514 | name = "serde_urlencoded" 1515 | version = "0.7.1" 1516 | source = "registry+https://github.com/rust-lang/crates.io-index" 1517 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1518 | dependencies = [ 1519 | "form_urlencoded", 1520 | "itoa", 1521 | "ryu", 1522 | "serde", 1523 | ] 1524 | 1525 | [[package]] 1526 | name = "servo_arc" 1527 | version = "0.4.0" 1528 | source = "registry+https://github.com/rust-lang/crates.io-index" 1529 | checksum = "ae65c4249478a2647db249fb43e23cec56a2c8974a427e7bd8cb5a1d0964921a" 1530 | dependencies = [ 1531 | "stable_deref_trait", 1532 | ] 1533 | 1534 | [[package]] 1535 | name = "shlex" 1536 | version = "1.3.0" 1537 | source = "registry+https://github.com/rust-lang/crates.io-index" 1538 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1539 | 1540 | [[package]] 1541 | name = "signal-hook-registry" 1542 | version = "1.4.2" 1543 | source = "registry+https://github.com/rust-lang/crates.io-index" 1544 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 1545 | dependencies = [ 1546 | "libc", 1547 | ] 1548 | 1549 | [[package]] 1550 | name = "siphasher" 1551 | version = "0.3.11" 1552 | source = "registry+https://github.com/rust-lang/crates.io-index" 1553 | checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" 1554 | 1555 | [[package]] 1556 | name = "slab" 1557 | version = "0.4.9" 1558 | source = "registry+https://github.com/rust-lang/crates.io-index" 1559 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1560 | dependencies = [ 1561 | "autocfg", 1562 | ] 1563 | 1564 | [[package]] 1565 | name = "smallvec" 1566 | version = "1.13.2" 1567 | source = "registry+https://github.com/rust-lang/crates.io-index" 1568 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1569 | 1570 | [[package]] 1571 | name = "socket2" 1572 | version = "0.5.10" 1573 | source = "registry+https://github.com/rust-lang/crates.io-index" 1574 | checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" 1575 | dependencies = [ 1576 | "libc", 1577 | "windows-sys 0.52.0", 1578 | ] 1579 | 1580 | [[package]] 1581 | name = "stable_deref_trait" 1582 | version = "1.2.0" 1583 | source = "registry+https://github.com/rust-lang/crates.io-index" 1584 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 1585 | 1586 | [[package]] 1587 | name = "string_cache" 1588 | version = "0.8.7" 1589 | source = "registry+https://github.com/rust-lang/crates.io-index" 1590 | checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" 1591 | dependencies = [ 1592 | "new_debug_unreachable", 1593 | "once_cell", 1594 | "parking_lot", 1595 | "phf_shared 0.10.0", 1596 | "precomputed-hash", 1597 | "serde", 1598 | ] 1599 | 1600 | [[package]] 1601 | name = "string_cache_codegen" 1602 | version = "0.5.2" 1603 | source = "registry+https://github.com/rust-lang/crates.io-index" 1604 | checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" 1605 | dependencies = [ 1606 | "phf_generator 0.10.0", 1607 | "phf_shared 0.10.0", 1608 | "proc-macro2", 1609 | "quote", 1610 | ] 1611 | 1612 | [[package]] 1613 | name = "strsim" 1614 | version = "0.11.1" 1615 | source = "registry+https://github.com/rust-lang/crates.io-index" 1616 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1617 | 1618 | [[package]] 1619 | name = "subtle" 1620 | version = "2.6.1" 1621 | source = "registry+https://github.com/rust-lang/crates.io-index" 1622 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 1623 | 1624 | [[package]] 1625 | name = "syn" 1626 | version = "2.0.94" 1627 | source = "registry+https://github.com/rust-lang/crates.io-index" 1628 | checksum = "987bc0be1cdea8b10216bd06e2ca407d40b9543468fafd3ddfb02f36e77f71f3" 1629 | dependencies = [ 1630 | "proc-macro2", 1631 | "quote", 1632 | "unicode-ident", 1633 | ] 1634 | 1635 | [[package]] 1636 | name = "sync_wrapper" 1637 | version = "1.0.2" 1638 | source = "registry+https://github.com/rust-lang/crates.io-index" 1639 | checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 1640 | dependencies = [ 1641 | "futures-core", 1642 | ] 1643 | 1644 | [[package]] 1645 | name = "synstructure" 1646 | version = "0.13.1" 1647 | source = "registry+https://github.com/rust-lang/crates.io-index" 1648 | checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" 1649 | dependencies = [ 1650 | "proc-macro2", 1651 | "quote", 1652 | "syn", 1653 | ] 1654 | 1655 | [[package]] 1656 | name = "system-configuration" 1657 | version = "0.6.1" 1658 | source = "registry+https://github.com/rust-lang/crates.io-index" 1659 | checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" 1660 | dependencies = [ 1661 | "bitflags", 1662 | "core-foundation", 1663 | "system-configuration-sys", 1664 | ] 1665 | 1666 | [[package]] 1667 | name = "system-configuration-sys" 1668 | version = "0.6.0" 1669 | source = "registry+https://github.com/rust-lang/crates.io-index" 1670 | checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" 1671 | dependencies = [ 1672 | "core-foundation-sys", 1673 | "libc", 1674 | ] 1675 | 1676 | [[package]] 1677 | name = "tabled" 1678 | version = "0.20.0" 1679 | source = "registry+https://github.com/rust-lang/crates.io-index" 1680 | checksum = "e39a2ee1fbcd360805a771e1b300f78cc88fec7b8d3e2f71cd37bbf23e725c7d" 1681 | dependencies = [ 1682 | "papergrid", 1683 | "tabled_derive", 1684 | "testing_table", 1685 | ] 1686 | 1687 | [[package]] 1688 | name = "tabled_derive" 1689 | version = "0.11.0" 1690 | source = "registry+https://github.com/rust-lang/crates.io-index" 1691 | checksum = "0ea5d1b13ca6cff1f9231ffd62f15eefd72543dab5e468735f1a456728a02846" 1692 | dependencies = [ 1693 | "heck", 1694 | "proc-macro-error2", 1695 | "proc-macro2", 1696 | "quote", 1697 | "syn", 1698 | ] 1699 | 1700 | [[package]] 1701 | name = "tempfile" 1702 | version = "3.15.0" 1703 | source = "registry+https://github.com/rust-lang/crates.io-index" 1704 | checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" 1705 | dependencies = [ 1706 | "cfg-if", 1707 | "fastrand", 1708 | "getrandom", 1709 | "once_cell", 1710 | "rustix", 1711 | "windows-sys 0.59.0", 1712 | ] 1713 | 1714 | [[package]] 1715 | name = "tendril" 1716 | version = "0.4.3" 1717 | source = "registry+https://github.com/rust-lang/crates.io-index" 1718 | checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" 1719 | dependencies = [ 1720 | "futf", 1721 | "mac", 1722 | "utf-8", 1723 | ] 1724 | 1725 | [[package]] 1726 | name = "testing_table" 1727 | version = "0.3.0" 1728 | source = "registry+https://github.com/rust-lang/crates.io-index" 1729 | checksum = "0f8daae29995a24f65619e19d8d31dea5b389f3d853d8bf297bbf607cd0014cc" 1730 | dependencies = [ 1731 | "unicode-width 0.2.0", 1732 | ] 1733 | 1734 | [[package]] 1735 | name = "tinystr" 1736 | version = "0.7.6" 1737 | source = "registry+https://github.com/rust-lang/crates.io-index" 1738 | checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" 1739 | dependencies = [ 1740 | "displaydoc", 1741 | "zerovec", 1742 | ] 1743 | 1744 | [[package]] 1745 | name = "tokio" 1746 | version = "1.45.1" 1747 | source = "registry+https://github.com/rust-lang/crates.io-index" 1748 | checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" 1749 | dependencies = [ 1750 | "backtrace", 1751 | "bytes", 1752 | "libc", 1753 | "mio", 1754 | "parking_lot", 1755 | "pin-project-lite", 1756 | "signal-hook-registry", 1757 | "socket2", 1758 | "tokio-macros", 1759 | "windows-sys 0.52.0", 1760 | ] 1761 | 1762 | [[package]] 1763 | name = "tokio-macros" 1764 | version = "2.5.0" 1765 | source = "registry+https://github.com/rust-lang/crates.io-index" 1766 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 1767 | dependencies = [ 1768 | "proc-macro2", 1769 | "quote", 1770 | "syn", 1771 | ] 1772 | 1773 | [[package]] 1774 | name = "tokio-native-tls" 1775 | version = "0.3.1" 1776 | source = "registry+https://github.com/rust-lang/crates.io-index" 1777 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 1778 | dependencies = [ 1779 | "native-tls", 1780 | "tokio", 1781 | ] 1782 | 1783 | [[package]] 1784 | name = "tokio-rustls" 1785 | version = "0.26.1" 1786 | source = "registry+https://github.com/rust-lang/crates.io-index" 1787 | checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" 1788 | dependencies = [ 1789 | "rustls", 1790 | "tokio", 1791 | ] 1792 | 1793 | [[package]] 1794 | name = "tokio-util" 1795 | version = "0.7.13" 1796 | source = "registry+https://github.com/rust-lang/crates.io-index" 1797 | checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" 1798 | dependencies = [ 1799 | "bytes", 1800 | "futures-core", 1801 | "futures-sink", 1802 | "pin-project-lite", 1803 | "tokio", 1804 | ] 1805 | 1806 | [[package]] 1807 | name = "tower" 1808 | version = "0.5.2" 1809 | source = "registry+https://github.com/rust-lang/crates.io-index" 1810 | checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" 1811 | dependencies = [ 1812 | "futures-core", 1813 | "futures-util", 1814 | "pin-project-lite", 1815 | "sync_wrapper", 1816 | "tokio", 1817 | "tower-layer", 1818 | "tower-service", 1819 | ] 1820 | 1821 | [[package]] 1822 | name = "tower-http" 1823 | version = "0.6.5" 1824 | source = "registry+https://github.com/rust-lang/crates.io-index" 1825 | checksum = "5cc2d9e086a412a451384326f521c8123a99a466b329941a9403696bff9b0da2" 1826 | dependencies = [ 1827 | "bitflags", 1828 | "bytes", 1829 | "futures-util", 1830 | "http", 1831 | "http-body", 1832 | "iri-string", 1833 | "pin-project-lite", 1834 | "tower", 1835 | "tower-layer", 1836 | "tower-service", 1837 | ] 1838 | 1839 | [[package]] 1840 | name = "tower-layer" 1841 | version = "0.3.3" 1842 | source = "registry+https://github.com/rust-lang/crates.io-index" 1843 | checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 1844 | 1845 | [[package]] 1846 | name = "tower-service" 1847 | version = "0.3.3" 1848 | source = "registry+https://github.com/rust-lang/crates.io-index" 1849 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 1850 | 1851 | [[package]] 1852 | name = "tracing" 1853 | version = "0.1.41" 1854 | source = "registry+https://github.com/rust-lang/crates.io-index" 1855 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 1856 | dependencies = [ 1857 | "pin-project-lite", 1858 | "tracing-core", 1859 | ] 1860 | 1861 | [[package]] 1862 | name = "tracing-core" 1863 | version = "0.1.33" 1864 | source = "registry+https://github.com/rust-lang/crates.io-index" 1865 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 1866 | dependencies = [ 1867 | "once_cell", 1868 | ] 1869 | 1870 | [[package]] 1871 | name = "try-lock" 1872 | version = "0.2.5" 1873 | source = "registry+https://github.com/rust-lang/crates.io-index" 1874 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 1875 | 1876 | [[package]] 1877 | name = "unicode-ident" 1878 | version = "1.0.14" 1879 | source = "registry+https://github.com/rust-lang/crates.io-index" 1880 | checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" 1881 | 1882 | [[package]] 1883 | name = "unicode-width" 1884 | version = "0.1.14" 1885 | source = "registry+https://github.com/rust-lang/crates.io-index" 1886 | checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" 1887 | 1888 | [[package]] 1889 | name = "unicode-width" 1890 | version = "0.2.0" 1891 | source = "registry+https://github.com/rust-lang/crates.io-index" 1892 | checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" 1893 | 1894 | [[package]] 1895 | name = "untrusted" 1896 | version = "0.9.0" 1897 | source = "registry+https://github.com/rust-lang/crates.io-index" 1898 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 1899 | 1900 | [[package]] 1901 | name = "url" 1902 | version = "2.5.4" 1903 | source = "registry+https://github.com/rust-lang/crates.io-index" 1904 | checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" 1905 | dependencies = [ 1906 | "form_urlencoded", 1907 | "idna", 1908 | "percent-encoding", 1909 | ] 1910 | 1911 | [[package]] 1912 | name = "utf-8" 1913 | version = "0.7.6" 1914 | source = "registry+https://github.com/rust-lang/crates.io-index" 1915 | checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 1916 | 1917 | [[package]] 1918 | name = "utf16_iter" 1919 | version = "1.0.5" 1920 | source = "registry+https://github.com/rust-lang/crates.io-index" 1921 | checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" 1922 | 1923 | [[package]] 1924 | name = "utf8_iter" 1925 | version = "1.0.4" 1926 | source = "registry+https://github.com/rust-lang/crates.io-index" 1927 | checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 1928 | 1929 | [[package]] 1930 | name = "utf8parse" 1931 | version = "0.2.2" 1932 | source = "registry+https://github.com/rust-lang/crates.io-index" 1933 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 1934 | 1935 | [[package]] 1936 | name = "vcpkg" 1937 | version = "0.2.15" 1938 | source = "registry+https://github.com/rust-lang/crates.io-index" 1939 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1940 | 1941 | [[package]] 1942 | name = "want" 1943 | version = "0.3.1" 1944 | source = "registry+https://github.com/rust-lang/crates.io-index" 1945 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1946 | dependencies = [ 1947 | "try-lock", 1948 | ] 1949 | 1950 | [[package]] 1951 | name = "wasi" 1952 | version = "0.11.0+wasi-snapshot-preview1" 1953 | source = "registry+https://github.com/rust-lang/crates.io-index" 1954 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1955 | 1956 | [[package]] 1957 | name = "wasm-bindgen" 1958 | version = "0.2.100" 1959 | source = "registry+https://github.com/rust-lang/crates.io-index" 1960 | checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" 1961 | dependencies = [ 1962 | "cfg-if", 1963 | "once_cell", 1964 | "rustversion", 1965 | "wasm-bindgen-macro", 1966 | ] 1967 | 1968 | [[package]] 1969 | name = "wasm-bindgen-backend" 1970 | version = "0.2.100" 1971 | source = "registry+https://github.com/rust-lang/crates.io-index" 1972 | checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" 1973 | dependencies = [ 1974 | "bumpalo", 1975 | "log", 1976 | "proc-macro2", 1977 | "quote", 1978 | "syn", 1979 | "wasm-bindgen-shared", 1980 | ] 1981 | 1982 | [[package]] 1983 | name = "wasm-bindgen-futures" 1984 | version = "0.4.50" 1985 | source = "registry+https://github.com/rust-lang/crates.io-index" 1986 | checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" 1987 | dependencies = [ 1988 | "cfg-if", 1989 | "js-sys", 1990 | "once_cell", 1991 | "wasm-bindgen", 1992 | "web-sys", 1993 | ] 1994 | 1995 | [[package]] 1996 | name = "wasm-bindgen-macro" 1997 | version = "0.2.100" 1998 | source = "registry+https://github.com/rust-lang/crates.io-index" 1999 | checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" 2000 | dependencies = [ 2001 | "quote", 2002 | "wasm-bindgen-macro-support", 2003 | ] 2004 | 2005 | [[package]] 2006 | name = "wasm-bindgen-macro-support" 2007 | version = "0.2.100" 2008 | source = "registry+https://github.com/rust-lang/crates.io-index" 2009 | checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" 2010 | dependencies = [ 2011 | "proc-macro2", 2012 | "quote", 2013 | "syn", 2014 | "wasm-bindgen-backend", 2015 | "wasm-bindgen-shared", 2016 | ] 2017 | 2018 | [[package]] 2019 | name = "wasm-bindgen-shared" 2020 | version = "0.2.100" 2021 | source = "registry+https://github.com/rust-lang/crates.io-index" 2022 | checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" 2023 | dependencies = [ 2024 | "unicode-ident", 2025 | ] 2026 | 2027 | [[package]] 2028 | name = "web-sys" 2029 | version = "0.3.77" 2030 | source = "registry+https://github.com/rust-lang/crates.io-index" 2031 | checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" 2032 | dependencies = [ 2033 | "js-sys", 2034 | "wasm-bindgen", 2035 | ] 2036 | 2037 | [[package]] 2038 | name = "web-time" 2039 | version = "1.1.0" 2040 | source = "registry+https://github.com/rust-lang/crates.io-index" 2041 | checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" 2042 | dependencies = [ 2043 | "js-sys", 2044 | "wasm-bindgen", 2045 | ] 2046 | 2047 | [[package]] 2048 | name = "windows-link" 2049 | version = "0.1.0" 2050 | source = "registry+https://github.com/rust-lang/crates.io-index" 2051 | checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" 2052 | 2053 | [[package]] 2054 | name = "windows-registry" 2055 | version = "0.4.0" 2056 | source = "registry+https://github.com/rust-lang/crates.io-index" 2057 | checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" 2058 | dependencies = [ 2059 | "windows-result", 2060 | "windows-strings", 2061 | "windows-targets 0.53.0", 2062 | ] 2063 | 2064 | [[package]] 2065 | name = "windows-result" 2066 | version = "0.3.1" 2067 | source = "registry+https://github.com/rust-lang/crates.io-index" 2068 | checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189" 2069 | dependencies = [ 2070 | "windows-link", 2071 | ] 2072 | 2073 | [[package]] 2074 | name = "windows-strings" 2075 | version = "0.3.1" 2076 | source = "registry+https://github.com/rust-lang/crates.io-index" 2077 | checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" 2078 | dependencies = [ 2079 | "windows-link", 2080 | ] 2081 | 2082 | [[package]] 2083 | name = "windows-sys" 2084 | version = "0.52.0" 2085 | source = "registry+https://github.com/rust-lang/crates.io-index" 2086 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2087 | dependencies = [ 2088 | "windows-targets 0.52.6", 2089 | ] 2090 | 2091 | [[package]] 2092 | name = "windows-sys" 2093 | version = "0.59.0" 2094 | source = "registry+https://github.com/rust-lang/crates.io-index" 2095 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2096 | dependencies = [ 2097 | "windows-targets 0.52.6", 2098 | ] 2099 | 2100 | [[package]] 2101 | name = "windows-targets" 2102 | version = "0.52.6" 2103 | source = "registry+https://github.com/rust-lang/crates.io-index" 2104 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2105 | dependencies = [ 2106 | "windows_aarch64_gnullvm 0.52.6", 2107 | "windows_aarch64_msvc 0.52.6", 2108 | "windows_i686_gnu 0.52.6", 2109 | "windows_i686_gnullvm 0.52.6", 2110 | "windows_i686_msvc 0.52.6", 2111 | "windows_x86_64_gnu 0.52.6", 2112 | "windows_x86_64_gnullvm 0.52.6", 2113 | "windows_x86_64_msvc 0.52.6", 2114 | ] 2115 | 2116 | [[package]] 2117 | name = "windows-targets" 2118 | version = "0.53.0" 2119 | source = "registry+https://github.com/rust-lang/crates.io-index" 2120 | checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" 2121 | dependencies = [ 2122 | "windows_aarch64_gnullvm 0.53.0", 2123 | "windows_aarch64_msvc 0.53.0", 2124 | "windows_i686_gnu 0.53.0", 2125 | "windows_i686_gnullvm 0.53.0", 2126 | "windows_i686_msvc 0.53.0", 2127 | "windows_x86_64_gnu 0.53.0", 2128 | "windows_x86_64_gnullvm 0.53.0", 2129 | "windows_x86_64_msvc 0.53.0", 2130 | ] 2131 | 2132 | [[package]] 2133 | name = "windows_aarch64_gnullvm" 2134 | version = "0.52.6" 2135 | source = "registry+https://github.com/rust-lang/crates.io-index" 2136 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2137 | 2138 | [[package]] 2139 | name = "windows_aarch64_gnullvm" 2140 | version = "0.53.0" 2141 | source = "registry+https://github.com/rust-lang/crates.io-index" 2142 | checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" 2143 | 2144 | [[package]] 2145 | name = "windows_aarch64_msvc" 2146 | version = "0.52.6" 2147 | source = "registry+https://github.com/rust-lang/crates.io-index" 2148 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2149 | 2150 | [[package]] 2151 | name = "windows_aarch64_msvc" 2152 | version = "0.53.0" 2153 | source = "registry+https://github.com/rust-lang/crates.io-index" 2154 | checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" 2155 | 2156 | [[package]] 2157 | name = "windows_i686_gnu" 2158 | version = "0.52.6" 2159 | source = "registry+https://github.com/rust-lang/crates.io-index" 2160 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2161 | 2162 | [[package]] 2163 | name = "windows_i686_gnu" 2164 | version = "0.53.0" 2165 | source = "registry+https://github.com/rust-lang/crates.io-index" 2166 | checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" 2167 | 2168 | [[package]] 2169 | name = "windows_i686_gnullvm" 2170 | version = "0.52.6" 2171 | source = "registry+https://github.com/rust-lang/crates.io-index" 2172 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2173 | 2174 | [[package]] 2175 | name = "windows_i686_gnullvm" 2176 | version = "0.53.0" 2177 | source = "registry+https://github.com/rust-lang/crates.io-index" 2178 | checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" 2179 | 2180 | [[package]] 2181 | name = "windows_i686_msvc" 2182 | version = "0.52.6" 2183 | source = "registry+https://github.com/rust-lang/crates.io-index" 2184 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2185 | 2186 | [[package]] 2187 | name = "windows_i686_msvc" 2188 | version = "0.53.0" 2189 | source = "registry+https://github.com/rust-lang/crates.io-index" 2190 | checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" 2191 | 2192 | [[package]] 2193 | name = "windows_x86_64_gnu" 2194 | version = "0.52.6" 2195 | source = "registry+https://github.com/rust-lang/crates.io-index" 2196 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2197 | 2198 | [[package]] 2199 | name = "windows_x86_64_gnu" 2200 | version = "0.53.0" 2201 | source = "registry+https://github.com/rust-lang/crates.io-index" 2202 | checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" 2203 | 2204 | [[package]] 2205 | name = "windows_x86_64_gnullvm" 2206 | version = "0.52.6" 2207 | source = "registry+https://github.com/rust-lang/crates.io-index" 2208 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2209 | 2210 | [[package]] 2211 | name = "windows_x86_64_gnullvm" 2212 | version = "0.53.0" 2213 | source = "registry+https://github.com/rust-lang/crates.io-index" 2214 | checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" 2215 | 2216 | [[package]] 2217 | name = "windows_x86_64_msvc" 2218 | version = "0.52.6" 2219 | source = "registry+https://github.com/rust-lang/crates.io-index" 2220 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2221 | 2222 | [[package]] 2223 | name = "windows_x86_64_msvc" 2224 | version = "0.53.0" 2225 | source = "registry+https://github.com/rust-lang/crates.io-index" 2226 | checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" 2227 | 2228 | [[package]] 2229 | name = "write16" 2230 | version = "1.0.0" 2231 | source = "registry+https://github.com/rust-lang/crates.io-index" 2232 | checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" 2233 | 2234 | [[package]] 2235 | name = "writeable" 2236 | version = "0.5.5" 2237 | source = "registry+https://github.com/rust-lang/crates.io-index" 2238 | checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" 2239 | 2240 | [[package]] 2241 | name = "yoke" 2242 | version = "0.7.5" 2243 | source = "registry+https://github.com/rust-lang/crates.io-index" 2244 | checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" 2245 | dependencies = [ 2246 | "serde", 2247 | "stable_deref_trait", 2248 | "yoke-derive", 2249 | "zerofrom", 2250 | ] 2251 | 2252 | [[package]] 2253 | name = "yoke-derive" 2254 | version = "0.7.5" 2255 | source = "registry+https://github.com/rust-lang/crates.io-index" 2256 | checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" 2257 | dependencies = [ 2258 | "proc-macro2", 2259 | "quote", 2260 | "syn", 2261 | "synstructure", 2262 | ] 2263 | 2264 | [[package]] 2265 | name = "zerocopy" 2266 | version = "0.7.35" 2267 | source = "registry+https://github.com/rust-lang/crates.io-index" 2268 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 2269 | dependencies = [ 2270 | "byteorder", 2271 | "zerocopy-derive", 2272 | ] 2273 | 2274 | [[package]] 2275 | name = "zerocopy-derive" 2276 | version = "0.7.35" 2277 | source = "registry+https://github.com/rust-lang/crates.io-index" 2278 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 2279 | dependencies = [ 2280 | "proc-macro2", 2281 | "quote", 2282 | "syn", 2283 | ] 2284 | 2285 | [[package]] 2286 | name = "zerofrom" 2287 | version = "0.1.5" 2288 | source = "registry+https://github.com/rust-lang/crates.io-index" 2289 | checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" 2290 | dependencies = [ 2291 | "zerofrom-derive", 2292 | ] 2293 | 2294 | [[package]] 2295 | name = "zerofrom-derive" 2296 | version = "0.1.5" 2297 | source = "registry+https://github.com/rust-lang/crates.io-index" 2298 | checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" 2299 | dependencies = [ 2300 | "proc-macro2", 2301 | "quote", 2302 | "syn", 2303 | "synstructure", 2304 | ] 2305 | 2306 | [[package]] 2307 | name = "zeroize" 2308 | version = "1.8.1" 2309 | source = "registry+https://github.com/rust-lang/crates.io-index" 2310 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 2311 | 2312 | [[package]] 2313 | name = "zerovec" 2314 | version = "0.10.4" 2315 | source = "registry+https://github.com/rust-lang/crates.io-index" 2316 | checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" 2317 | dependencies = [ 2318 | "yoke", 2319 | "zerofrom", 2320 | "zerovec-derive", 2321 | ] 2322 | 2323 | [[package]] 2324 | name = "zerovec-derive" 2325 | version = "0.10.3" 2326 | source = "registry+https://github.com/rust-lang/crates.io-index" 2327 | checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" 2328 | dependencies = [ 2329 | "proc-macro2", 2330 | "quote", 2331 | "syn", 2332 | ] 2333 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "proxy-scraper-checker" 3 | version = "0.1.3" 4 | edition = "2021" 5 | authors = ["Xewdy444 "] 6 | license = "MIT" 7 | description = "A command-line tool for scraping and checking HTTP and SOCKS5 proxies from the checkerproxy.net proxies archive" 8 | readme = "README.md" 9 | homepage = "https://github.com/Xewdy444/Proxy-Scraper-Checker" 10 | repository = "https://github.com/Xewdy444/Proxy-Scraper-Checker" 11 | keywords = ["proxy", "scraper", "checker", "http", "socks5"] 12 | categories = ["command-line-utilities"] 13 | 14 | [profile.release] 15 | codegen-units = 1 16 | strip = true 17 | lto = "fat" 18 | 19 | [dependencies] 20 | anyhow = "1.0.98" 21 | clap = { version = "4.5.40", features = ["derive"] } 22 | futures = "0.3.31" 23 | humantime = "2.2.0" 24 | indicatif = "0.17.11" 25 | reqwest = { version = "0.12.20", features = ["socks"] } 26 | rlimit = "0.10.2" 27 | scraper = "0.23.1" 28 | serde_json = "1.0.140" 29 | tabled = "0.20.0" 30 | tokio = { version = "1.45.1", features = ["full"] } 31 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:slim as builder 2 | 3 | WORKDIR /app 4 | 5 | COPY . . 6 | 7 | RUN apt-get update -y \ 8 | && apt-get install -y --no-install-recommends \ 9 | pkg-config \ 10 | libssl-dev \ 11 | && cargo build --release 12 | 13 | FROM debian:stable-slim 14 | 15 | RUN apt-get update -y \ 16 | && apt-get install -y --no-install-recommends \ 17 | libssl-dev \ 18 | ca-certificates \ 19 | && apt-get clean \ 20 | && rm -rf /var/lib/apt/lists/* 21 | 22 | COPY --from=builder /app/target/release/proxy-scraper-checker /usr/local/bin/proxy-scraper-checker 23 | 24 | ENTRYPOINT [ "/usr/local/bin/proxy-scraper-checker" ] 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Xewdy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Proxy-Scraper-Checker 2 | A command-line tool for scraping and checking HTTP and SOCKS5 proxies from the [checkerproxy.net proxies archive](https://checkerproxy.net/getAllProxy). By default, the working proxies are written to `proxies/http.txt` and `proxies/socks5.txt` according to the respective proxy type. 3 | 4 | ![image](https://github.com/Xewdy444/Proxy-Scraper-Checker/assets/95155966/91b55084-f82c-43d6-be29-6eaee1c8b23f) 5 | 6 | ## Docker 7 | 8 | ### Local 9 | $ docker build -t proxy-scraper-checker:latest . 10 | $ docker run -it -v ./proxies:/proxies --rm proxy-scraper-checker:latest 11 | 12 | ### GitHub Container Registry 13 | $ docker run -it -v ./proxies:/proxies --rm ghcr.io/xewdy444/proxy-scraper-checker:latest 14 | 15 | ## Installation 16 | 17 | ### Local 18 | $ cargo install --path . 19 | 20 | ### Rust Package Registry 21 | $ cargo install proxy-scraper-checker 22 | 23 | ## Usage 24 | ``` 25 | A command-line tool for scraping and checking HTTP and SOCKS5 proxies from the checkerproxy.net proxies archive 26 | 27 | Usage: proxy-scraper-checker.exe [OPTIONS] 28 | 29 | Options: 30 | -u, --url The URL to check the proxies against [default: https://httpbin.org/ip] 31 | --tasks The number of tasks to run concurrently for checking proxies [default: 512] 32 | --timeout The proxy request timeout in seconds [default: 30] 33 | -f, --folder The folder to save the working proxies to [default: proxies] 34 | -a, --anonymous Only save anonymous proxies 35 | --http Only save HTTP proxies 36 | --socks5 Only save SOCKS5 proxies 37 | -n, --no-set-limit Do not set the open file limit (tasks * 2) 38 | -h, --help Print help 39 | ``` 40 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | mod proxy_utilities; 2 | 3 | #[cfg(windows)] 4 | use anyhow::bail; 5 | use anyhow::{Context, Result}; 6 | use clap::{command, Parser}; 7 | use futures::future; 8 | use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; 9 | use proxy_utilities::{Proxies, Proxy, ProxyChecker, ProxyScraper, ProxyType}; 10 | #[cfg(not(windows))] 11 | use rlimit::Resource; 12 | use std::fs::{self, File}; 13 | use std::io::{BufWriter, Write}; 14 | use std::path::Path; 15 | use std::sync::Arc; 16 | use std::time::Duration; 17 | use tabled::builder::Builder; 18 | use tabled::settings::{Alignment, Style}; 19 | use tokio::sync::Semaphore; 20 | 21 | /// Represents the result of a check task. 22 | #[derive(Debug)] 23 | struct CheckTaskResult { 24 | proxy_type: ProxyType, 25 | working_proxies: Vec, 26 | proxies_checked: u64, 27 | check_duration: Duration, 28 | } 29 | 30 | impl CheckTaskResult { 31 | /// Returns a new [`CheckTaskResult`] instance. 32 | /// 33 | /// # Parameters 34 | /// 35 | /// * `proxy_type` - The type of proxies that were checked. 36 | /// * `working_proxies` - The working proxies. 37 | /// * `proxies_checked` - The number of proxies that were checked. 38 | /// * `check_duration` - The duration of the check task. 39 | fn new( 40 | proxy_type: ProxyType, 41 | working_proxies: Vec, 42 | proxies_checked: u64, 43 | check_duration: Duration, 44 | ) -> Self { 45 | Self { 46 | proxy_type, 47 | working_proxies, 48 | proxies_checked, 49 | check_duration, 50 | } 51 | } 52 | } 53 | 54 | /// Increases the open file limit if necessary on Windows. 55 | /// 56 | /// # Parameters 57 | /// 58 | /// * `limit` - The limit to set. 59 | /// 60 | /// # Returns 61 | /// 62 | /// A [`Result`] containing the result of the operation. 63 | /// 64 | /// # Errors 65 | /// 66 | /// Returns an error if the open file limit is greater than 8192 67 | /// or if the limit could not be set. 68 | #[cfg(windows)] 69 | fn set_open_file_limit(limit: u64) -> Result<()> { 70 | let open_file_limit = rlimit::getmaxstdio() as u64; 71 | 72 | if limit <= open_file_limit { 73 | return Ok(()); 74 | } 75 | 76 | if limit > 8192 { 77 | bail!("Windows does not support open file limits greater than 8192"); 78 | } 79 | 80 | rlimit::setmaxstdio(limit as u32).context("Failed to set open file limit")?; 81 | Ok(()) 82 | } 83 | 84 | /// Increases the open file limit if necessary on non-Windows platforms. 85 | /// 86 | /// # Parameters 87 | /// 88 | /// * `limit` - The limit to set. 89 | /// 90 | /// # Returns 91 | /// 92 | /// A [`Result`] containing the result of the operation. 93 | /// 94 | /// # Errors 95 | /// 96 | /// Returns an error if the limit could not be retrieved or set. 97 | #[cfg(not(windows))] 98 | fn set_open_file_limit(limit: u64) -> Result<()> { 99 | let open_file_limit = 100 | rlimit::getrlimit(Resource::NOFILE).context("Failed to get open file limit")?; 101 | 102 | if limit <= open_file_limit.0 { 103 | return Ok(()); 104 | } 105 | 106 | rlimit::setrlimit(Resource::NOFILE, limit, open_file_limit.1) 107 | .context("Failed to set open file limit")?; 108 | 109 | Ok(()) 110 | } 111 | 112 | /// Writes the proxies to a file. 113 | /// 114 | /// # Parameters 115 | /// 116 | /// * `proxy_type` - The type of proxies. 117 | /// * `proxies` - The proxies to write to a file. 118 | /// * `proxies_folder` - The folder to save the proxies to. 119 | /// 120 | /// # Returns 121 | /// 122 | /// A [`Result`] containing the result of the operation. 123 | /// 124 | /// # Errors 125 | /// 126 | /// Returns an error if the proxies folder could not be created, 127 | /// if the file could not be created, or if the proxies could not be written to the file. 128 | fn write_proxies_to_file( 129 | proxy_type: ProxyType, 130 | proxies: &[Proxy], 131 | proxies_folder: &Path, 132 | ) -> Result<()> { 133 | if !proxies_folder.exists() { 134 | fs::create_dir_all(proxies_folder).context("Failed to create proxies folder")?; 135 | } 136 | 137 | let file_name = match proxy_type { 138 | ProxyType::Http => "http.txt", 139 | ProxyType::Socks5 => "socks5.txt", 140 | }; 141 | 142 | let file = File::create(proxies_folder.join(file_name)).context("Failed to create file")?; 143 | let mut writer = BufWriter::new(file); 144 | 145 | for proxy in proxies { 146 | writeln!(writer, "{proxy}").context("Failed to write proxy")?; 147 | } 148 | 149 | writer.flush().context("Failed to flush writer")?; 150 | Ok(()) 151 | } 152 | 153 | #[derive(Debug, Parser)] 154 | #[command( 155 | about = "A command-line tool for scraping and checking HTTP and SOCKS5 proxies from the checkerproxy.net proxies archive" 156 | )] 157 | struct Args { 158 | /// The URL to check the proxies against 159 | #[arg(short, long, default_value_t = String::from("https://httpbin.org/ip"))] 160 | url: String, 161 | 162 | /// The number of tasks to run concurrently for checking proxies 163 | #[arg(long, default_value_t = 512)] 164 | tasks: u64, 165 | 166 | /// The proxy request timeout in seconds 167 | #[arg(long, default_value_t = 30)] 168 | timeout: u64, 169 | 170 | /// The folder to save the working proxies to 171 | #[arg(short, long, default_value_t = String::from("proxies"))] 172 | folder: String, 173 | 174 | /// Only save anonymous proxies 175 | #[arg(short, long, default_value_t = false)] 176 | anonymous: bool, 177 | 178 | /// Only save HTTP proxies 179 | #[arg(long, default_value_t = false, conflicts_with = "socks5")] 180 | http: bool, 181 | 182 | /// Only save SOCKS5 proxies 183 | #[arg(long, default_value_t = false, conflicts_with = "http")] 184 | socks5: bool, 185 | 186 | /// Do not set the open file limit (tasks * 2) 187 | #[arg(short, long, default_value_t = false)] 188 | no_set_limit: bool, 189 | } 190 | 191 | #[tokio::main] 192 | async fn main() { 193 | let args = Args::parse(); 194 | let proxy_scraper = ProxyScraper::default(); 195 | 196 | if !args.no_set_limit { 197 | set_open_file_limit(args.tasks * 2) 198 | .context("You can pass the --no-set-limit flag at your own risk") 199 | .unwrap(); 200 | } 201 | 202 | let archive_urls = proxy_scraper.scrape_archive_urls().await.unwrap(); 203 | 204 | let scrape_progress_bar = ProgressBar::new(archive_urls.len() as u64).with_style( 205 | ProgressStyle::default_bar() 206 | .template( 207 | "[{msg}] {spinner:.red} {percent}% [{wide_bar:.red}] {pos}/{len} [{elapsed_precise}<{eta_precise}, {per_sec}]", 208 | ) 209 | .unwrap(), 210 | ); 211 | 212 | scrape_progress_bar.set_message("Scraping proxies archive"); 213 | let mut scrape_tasks = Vec::new(); 214 | 215 | for url in archive_urls { 216 | let proxy_scraper = proxy_scraper.clone(); 217 | let progress_bar = scrape_progress_bar.clone(); 218 | 219 | let task = tokio::spawn(async move { 220 | let result = proxy_scraper.scrape_proxies(url, args.anonymous).await; 221 | progress_bar.inc(1); 222 | result 223 | }); 224 | 225 | scrape_tasks.push(task); 226 | } 227 | 228 | let proxies: Proxies = future::try_join_all(scrape_tasks) 229 | .await 230 | .unwrap() 231 | .into_iter() 232 | .filter_map(|proxies| proxies.ok()) 233 | .flatten() 234 | .collect(); 235 | 236 | scrape_progress_bar.finish_with_message("Finished scraping proxies archive"); 237 | 238 | let multiprogress_bar = MultiProgress::new(); 239 | let semaphore = Arc::new(Semaphore::new(args.tasks as usize)); 240 | let mut check_tasks = Vec::new(); 241 | 242 | if !args.socks5 { 243 | let proxy_count = proxies.http.len() as u64; 244 | 245 | let http_progress_bar = multiprogress_bar.add( 246 | ProgressBar::new(proxy_count).with_style( 247 | ProgressStyle::default_bar() 248 | .template( 249 | "[{msg}] {spinner:.green} {percent}% [{wide_bar:.green}] {pos}/{len} [{elapsed_precise}<{eta_precise}, {per_sec}]", 250 | ) 251 | .unwrap(), 252 | ), 253 | ); 254 | 255 | let http_semaphore = semaphore.clone(); 256 | let url = args.url.clone(); 257 | 258 | let http_task = tokio::spawn(async move { 259 | let proxy_checker = ProxyChecker::new(http_semaphore, http_progress_bar.clone()); 260 | http_progress_bar.set_message("Checking HTTP proxies"); 261 | 262 | let mut working_proxies = proxy_checker 263 | .check_proxies(proxies.http, url, args.timeout) 264 | .await 265 | .unwrap(); 266 | 267 | http_progress_bar.finish_with_message("Finished checking HTTP proxies"); 268 | let check_duration = Duration::from_secs(http_progress_bar.elapsed().as_secs()); 269 | working_proxies.sort_unstable(); 270 | 271 | CheckTaskResult::new( 272 | ProxyType::Http, 273 | working_proxies, 274 | proxy_count, 275 | check_duration, 276 | ) 277 | }); 278 | 279 | check_tasks.push(http_task); 280 | } 281 | 282 | if !args.http { 283 | let proxy_count = proxies.socks5.len() as u64; 284 | 285 | let socks5_progress_bar = multiprogress_bar.add( 286 | ProgressBar::new(proxy_count).with_style( 287 | ProgressStyle::default_bar() 288 | .template( 289 | "[{msg}] {spinner:.blue} {percent}% [{wide_bar:.blue}] {pos}/{len} [{elapsed_precise}<{eta_precise}, {per_sec}]", 290 | ) 291 | .unwrap(), 292 | ), 293 | ); 294 | 295 | let socks5_semaphore = semaphore.clone(); 296 | let url = args.url.clone(); 297 | 298 | let socks5_task = tokio::spawn(async move { 299 | let proxy_checker = ProxyChecker::new(socks5_semaphore, socks5_progress_bar.clone()); 300 | socks5_progress_bar.set_message("Checking SOCKS5 proxies"); 301 | 302 | let mut working_proxies = proxy_checker 303 | .check_proxies(proxies.socks5, url, args.timeout) 304 | .await 305 | .unwrap(); 306 | 307 | socks5_progress_bar.finish_with_message("Finished checking SOCKS5 proxies"); 308 | let check_duration = Duration::from_secs(socks5_progress_bar.elapsed().as_secs()); 309 | working_proxies.sort_unstable(); 310 | 311 | CheckTaskResult::new( 312 | ProxyType::Socks5, 313 | working_proxies, 314 | proxy_count, 315 | check_duration, 316 | ) 317 | }); 318 | 319 | check_tasks.push(socks5_task); 320 | } 321 | 322 | let check_task_results: Vec = future::try_join_all(check_tasks) 323 | .await 324 | .unwrap() 325 | .into_iter() 326 | .collect(); 327 | 328 | let proxies_folder = Path::new(&args.folder); 329 | let mut table_builder = Builder::default(); 330 | 331 | table_builder.push_record([ 332 | "Proxy Type", 333 | "Working Proxies", 334 | "Proxies Checked", 335 | "Check Duration", 336 | ]); 337 | 338 | if !args.socks5 { 339 | let result = check_task_results 340 | .iter() 341 | .find(|result| result.proxy_type == ProxyType::Http) 342 | .unwrap(); 343 | 344 | table_builder.push_record([ 345 | "HTTP", 346 | &result.working_proxies.len().to_string(), 347 | &result.proxies_checked.to_string(), 348 | &humantime::format_duration(result.check_duration).to_string(), 349 | ]); 350 | 351 | if !result.working_proxies.is_empty() { 352 | write_proxies_to_file(ProxyType::Http, &result.working_proxies, proxies_folder) 353 | .unwrap(); 354 | } 355 | } 356 | 357 | if !args.http { 358 | let result = check_task_results 359 | .iter() 360 | .find(|result| result.proxy_type == ProxyType::Socks5) 361 | .unwrap(); 362 | 363 | table_builder.push_record([ 364 | "SOCKS5", 365 | &result.working_proxies.len().to_string(), 366 | &result.proxies_checked.to_string(), 367 | &humantime::format_duration(result.check_duration).to_string(), 368 | ]); 369 | 370 | if !result.working_proxies.is_empty() { 371 | write_proxies_to_file(ProxyType::Socks5, &result.working_proxies, proxies_folder) 372 | .unwrap(); 373 | } 374 | } 375 | 376 | let mut table = table_builder.build(); 377 | println!("{}", table.with(Style::modern()).with(Alignment::center())); 378 | } 379 | -------------------------------------------------------------------------------- /src/proxy_utilities/mod.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{bail, Context, Result}; 2 | use futures::future; 3 | use indicatif::ProgressBar; 4 | use scraper::{Html, Selector}; 5 | use serde_json::Value; 6 | use std::cmp::Ordering; 7 | use std::collections::HashSet; 8 | use std::fmt; 9 | use std::hash::Hash; 10 | use std::net::IpAddr; 11 | use std::str::FromStr; 12 | use std::sync::Arc; 13 | use std::time::Duration; 14 | use tokio::sync::{AcquireError, Semaphore}; 15 | 16 | /// Represents the type of proxy. 17 | #[derive(Debug, PartialEq)] 18 | pub enum ProxyType { 19 | Http, 20 | Socks5, 21 | } 22 | 23 | /// Represents a proxy, which can be either an HTTP or SOCKS5 proxy. 24 | #[derive(Clone, Debug, Eq, Hash, PartialEq)] 25 | pub enum Proxy { 26 | Http(String), 27 | Socks5(String), 28 | } 29 | 30 | impl fmt::Display for Proxy { 31 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 32 | match self { 33 | Proxy::Http(host) | Proxy::Socks5(host) => write!(f, "{host}"), 34 | } 35 | } 36 | } 37 | 38 | impl PartialOrd for Proxy { 39 | fn partial_cmp(&self, other: &Self) -> Option { 40 | Some(self.cmp(other)) 41 | } 42 | } 43 | 44 | impl Ord for Proxy { 45 | fn cmp(&self, other: &Self) -> Ordering { 46 | let (addr, port) = self 47 | .parse_host() 48 | .unwrap_or_else(|_| (IpAddr::from([0, 0, 0, 0]), 0)); 49 | 50 | let (other_addr, other_port) = other 51 | .parse_host() 52 | .unwrap_or_else(|_| (IpAddr::from([0, 0, 0, 0]), 0)); 53 | 54 | if addr < other_addr { 55 | Ordering::Less 56 | } else if addr > other_addr { 57 | Ordering::Greater 58 | } else if port < other_port { 59 | Ordering::Less 60 | } else if port > other_port { 61 | Ordering::Greater 62 | } else { 63 | Ordering::Equal 64 | } 65 | } 66 | } 67 | 68 | impl Proxy { 69 | /// Returns the URL of the proxy. 70 | fn url(&self) -> String { 71 | match self { 72 | Proxy::Http(host) => format!("http://{host}"), 73 | Proxy::Socks5(host) => format!("socks5://{host}"), 74 | } 75 | } 76 | 77 | /// Returns a tuple containing the IP address and port of the proxy. 78 | /// 79 | /// ## Errors 80 | /// 81 | /// Returns an error if the proxy is invalid. 82 | fn parse_host(&self) -> Result<(IpAddr, u16)> { 83 | let host = self.to_string(); 84 | let parts: Vec<&str> = host.split(':').collect(); 85 | 86 | if parts.len() != 2 { 87 | bail!("Invalid proxy: {host}"); 88 | } 89 | 90 | let addr = IpAddr::from_str(parts[0]).context("Invalid IP address")?; 91 | let port: u16 = parts[1].parse().context("Invalid port")?; 92 | Ok((addr, port)) 93 | } 94 | } 95 | 96 | /// A collection of unique HTTP and SOCKS5 proxies. 97 | /// 98 | /// ## Fields 99 | /// 100 | /// * `http` - A [`HashSet`] of unique HTTP proxies. 101 | /// * `socks5` - A [`HashSet`] of unique SOCKS5 proxies. 102 | #[derive(Debug)] 103 | pub struct Proxies { 104 | pub http: HashSet, 105 | pub socks5: HashSet, 106 | } 107 | 108 | impl Proxies { 109 | /// Returns a new [`Proxies`] instance. 110 | pub fn new() -> Self { 111 | Self { 112 | http: HashSet::new(), 113 | socks5: HashSet::new(), 114 | } 115 | } 116 | 117 | /// Adds a proxy to the respective proxy list. 118 | /// 119 | /// ## Parameters 120 | /// 121 | /// * `proxy` - The proxy to add. 122 | /// 123 | /// ## Returns 124 | /// 125 | /// `true` if the proxy was added, `false` if it was already present. 126 | pub fn add(&mut self, proxy: Proxy) -> bool { 127 | match proxy { 128 | Proxy::Http(_) => self.http.insert(proxy), 129 | Proxy::Socks5(_) => self.socks5.insert(proxy), 130 | } 131 | } 132 | } 133 | 134 | impl FromIterator for Proxies { 135 | fn from_iter>(iter: T) -> Self { 136 | let mut proxy_lists = Self::new(); 137 | 138 | for proxy in iter { 139 | proxy_lists.add(proxy); 140 | } 141 | 142 | proxy_lists 143 | } 144 | } 145 | 146 | /// Used to scrape proxies from the checkerproxy.net proxies archive. 147 | /// 148 | /// ## Fields 149 | /// 150 | /// * `client` - The [`reqwest::Client`] to use for making requests. 151 | #[derive(Clone, Debug)] 152 | pub struct ProxyScraper { 153 | client: reqwest::Client, 154 | } 155 | 156 | impl ProxyScraper { 157 | /// Returns a new [`ProxyScraper`] instance. 158 | /// 159 | /// ## Parameters 160 | /// 161 | /// * `client` - The [`reqwest::Client`] to use for making requests. 162 | pub fn new(client: reqwest::Client) -> Self { 163 | Self { client } 164 | } 165 | 166 | /// Scrapes the archive URLs from the page 167 | /// and converts them into the API URLs. 168 | /// 169 | /// ## Returns 170 | /// 171 | /// A [`Vec`] of the API URLs. 172 | /// 173 | /// ## Errors 174 | /// 175 | /// Returns an error if the request to the page fails. 176 | pub async fn scrape_archive_urls(&self) -> Result> { 177 | let response = self 178 | .client 179 | .get("https://checkerproxy.net/getAllProxy") 180 | .send() 181 | .await 182 | .context("Failed to get archive URLs")?; 183 | 184 | let html = response.text().await?; 185 | let parser = Html::parse_document(&html); 186 | let selector = Selector::parse("li > a").unwrap(); 187 | 188 | let mut archive_urls = Vec::new(); 189 | 190 | for element in parser.select(&selector) { 191 | let uri_path = match element.value().attr("href") { 192 | Some(path) => path, 193 | None => continue, 194 | }; 195 | 196 | if !uri_path.contains("/archive/") { 197 | continue; 198 | } 199 | 200 | let url = format!("https://checkerproxy.net/api{uri_path}"); 201 | archive_urls.push(url); 202 | } 203 | 204 | Ok(archive_urls) 205 | } 206 | 207 | /// Scrapes the proxies from the given checkerproxy.net archive API URL. 208 | /// 209 | /// ## Parameters 210 | /// 211 | /// * `archive_url` - The archive API URL to scrape the proxies from. 212 | /// * `anonymous_only` - Whether to only scrape anonymous proxies. 213 | /// 214 | /// ## Returns 215 | /// 216 | /// A [`Vec`] of the scraped proxies. 217 | /// 218 | /// ## Errors 219 | /// 220 | /// Returns an error if the request to the archive API URL fails or 221 | /// if the JSON received is invalid. 222 | pub async fn scrape_proxies( 223 | &self, 224 | archive_url: String, 225 | anonymous_only: bool, 226 | ) -> Result> { 227 | let response = self 228 | .client 229 | .get(archive_url) 230 | .send() 231 | .await 232 | .context("Request failed")? 233 | .error_for_status() 234 | .context("Request returned an error status code")?; 235 | 236 | let json: Value = serde_json::from_str(&response.text().await?)?; 237 | let mut proxies = Vec::new(); 238 | 239 | for proxy_dict in json.as_array().context("Invalid JSON received")? { 240 | if anonymous_only { 241 | let kind = match proxy_dict.get("kind") { 242 | Some(value) => match value.as_u64() { 243 | Some(value) => value, 244 | None => continue, 245 | }, 246 | None => continue, 247 | }; 248 | 249 | if kind != 2 { 250 | continue; 251 | } 252 | } 253 | 254 | let host = match proxy_dict.get("addr") { 255 | Some(value) => match value.as_str() { 256 | Some(str_value) => str_value.to_string(), 257 | None => continue, 258 | }, 259 | None => continue, 260 | }; 261 | 262 | let proxy = match proxy_dict.get("type") { 263 | Some(value) => match value.as_u64() { 264 | Some(1) => Proxy::Http(host), 265 | Some(2) => Proxy::Http(host), 266 | Some(4) => Proxy::Socks5(host), 267 | _ => continue, 268 | }, 269 | None => continue, 270 | }; 271 | 272 | proxies.push(proxy); 273 | } 274 | 275 | Ok(proxies) 276 | } 277 | } 278 | 279 | impl Default for ProxyScraper { 280 | /// Returns a new [`ProxyScraper`] instance with a 30 second timeout. 281 | fn default() -> Self { 282 | Self::new( 283 | reqwest::Client::builder() 284 | .timeout(Duration::from_secs(30)) 285 | .build() 286 | .unwrap(), 287 | ) 288 | } 289 | } 290 | 291 | /// Used to check a collection of proxies. 292 | /// 293 | /// ## Fields 294 | /// 295 | /// * `semaphore` - The semaphore used to limit the number of concurrent requests. 296 | /// * `progress_bar` - The progress bar used to display the progress of the proxy checks. 297 | #[derive(Debug)] 298 | pub struct ProxyChecker { 299 | semaphore: Arc, 300 | progress_bar: ProgressBar, 301 | } 302 | 303 | impl ProxyChecker { 304 | /// Returns a new [`ProxyChecker`] instance. 305 | /// 306 | /// ## Parameters 307 | /// 308 | /// * `semaphore` - The semaphore used to limit the number of concurrent requests. 309 | /// * `progress_bar` - The progress bar used to display the progress of the proxy checks. 310 | pub fn new(semaphore: Arc, progress_bar: ProgressBar) -> Self { 311 | Self { 312 | semaphore, 313 | progress_bar, 314 | } 315 | } 316 | 317 | /// Checks if the given proxy is working by making an HTTP request to the given URL. 318 | /// 319 | /// ## Parameters 320 | /// 321 | /// * `proxy` - The proxy to check. 322 | /// * `url` - The URL that the proxy will be checked against. 323 | /// * `timeout` - The request timeout in seconds. 324 | /// 325 | /// ## Returns 326 | /// 327 | /// The proxy if the check succeeds. 328 | /// 329 | /// ## Errors 330 | /// 331 | /// An error is returned if the [`reqwest::Client`] cannot be built, if the request fails, 332 | /// or if the HTTP response is an error status code. 333 | async fn check_proxy(proxy: Proxy, url: String, timeout: u64) -> Result { 334 | let client = reqwest::Client::builder() 335 | .proxy(reqwest::Proxy::all(proxy.url())?) 336 | .timeout(Duration::from_secs(timeout)) 337 | .build()?; 338 | 339 | client 340 | .get(url) 341 | .send() 342 | .await 343 | .context("Request failed")? 344 | .error_for_status() 345 | .context("Request returned an error status code")?; 346 | 347 | Ok(proxy) 348 | } 349 | 350 | /// Checks if the given proxies are working by making an HTTP request to the given URL. 351 | /// 352 | /// ## Parameters 353 | /// 354 | /// * `proxies` - A set of proxies to check. 355 | /// * `url` - The URL that the proxies will be checked against. 356 | /// * `timeout` - The request timeout in seconds. 357 | /// 358 | /// ## Returns 359 | /// 360 | /// A [`Vec`] of the working proxies. 361 | /// 362 | /// ## Errors 363 | /// 364 | /// An error is returned if the semaphore has been closed. 365 | pub async fn check_proxies( 366 | &self, 367 | proxies: HashSet, 368 | url: String, 369 | timeout: u64, 370 | ) -> Result> { 371 | let mut tasks = Vec::new(); 372 | 373 | for proxy in proxies { 374 | let semaphore = self.semaphore.clone(); 375 | let progress_bar = self.progress_bar.clone(); 376 | let url = url.clone(); 377 | 378 | let task = tokio::spawn(async move { 379 | let _permit = semaphore.acquire().await?; 380 | let result = Self::check_proxy(proxy, url, timeout).await; 381 | progress_bar.inc(1); 382 | result 383 | }); 384 | 385 | tasks.push(task); 386 | } 387 | 388 | let results = future::try_join_all(tasks).await?; 389 | let mut working_proxies = Vec::new(); 390 | 391 | for result in results { 392 | match result { 393 | Ok(proxy) => working_proxies.push(proxy), 394 | Err(err) => match err.downcast_ref::() { 395 | Some(_) => bail!("Semaphore has been closed"), 396 | None => continue, 397 | }, 398 | } 399 | } 400 | 401 | Ok(working_proxies) 402 | } 403 | } 404 | --------------------------------------------------------------------------------