diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml new file mode 100644 index 0000000000..fb9a1fe149 --- /dev/null +++ b/.pre-commit-hooks.yaml @@ -0,0 +1,18 @@ +- id: lychee + name: lychee + description: "Run 'lychee' for fast, async, stream-based link checking" + entry: lychee + language: system + args: ["--no-progress"] + types: [text] + pass_filenames: true + require_serial: true +- id: lychee-docker + name: lychee + description: "Run 'lychee' docker image for fast, async, stream-based link checking" + entry: lycheeverse/lychee:0.14 + language: docker_image + args: ["--no-progress"] + types: [text] + pass_filenames: true + require_serial: true diff --git a/Cargo.lock b/Cargo.lock index 4b3a458a06..fd93bd9065 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", @@ -31,18 +31,18 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "android-tzdata" @@ -67,9 +67,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.5" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", @@ -81,9 +81,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" @@ -115,15 +115,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" [[package]] name = "arc-swap" -version = "1.6.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" [[package]] name = "ascii_utils" @@ -143,9 +143,9 @@ dependencies = [ [[package]] name = "assert_cmd" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88903cb14723e4d4003335bb7f8a14f27691649105346a0f0957466c096adfe6" +checksum = "ed72493ac66d5804837f480ab3766c72bdfab91a65e565fc54fa9e42db0073a8" dependencies = [ "anstyle", "bstr", @@ -169,22 +169,22 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.1.1" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" +checksum = "136d4d23bcc79e27423727b36823d86233aad06dfea531837b038394d11e9928" dependencies = [ "concurrent-queue", - "event-listener 4.0.2", - "event-listener-strategy", + "event-listener 5.3.0", + "event-listener-strategy 0.5.1", "futures-core", "pin-project-lite", ] [[package]] name = "async-compression" -version = "0.4.5" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc2d0cfb2a7388d34f590e76686704c494ed7aaceed62ee1ba35cbf363abc2a5" +checksum = "07dbbf24db18d609b1462965249abdf49129ccad073ec257da372adc83259c60" dependencies = [ "flate2", "futures-core", @@ -195,15 +195,14 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.8.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +checksum = "b10202063978b3351199d68f8b22c4e47e4b1b822f8d43fd862d5ea8c006b29a" dependencies = [ - "async-lock 3.2.0", "async-task", "concurrent-queue", - "fastrand 2.0.1", - "futures-lite 2.1.0", + "fastrand 2.0.2", + "futures-lite 2.3.0", "slab", ] @@ -213,12 +212,12 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel 2.1.1", + "async-channel 2.2.1", "async-executor", - "async-io 2.2.2", - "async-lock 3.2.0", + "async-io 2.3.2", + "async-lock 3.3.0", "blocking", - "futures-lite 2.1.0", + "futures-lite 2.3.0", "once_cell", ] @@ -244,18 +243,18 @@ dependencies = [ [[package]] name = "async-io" -version = "2.2.2" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" +checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" dependencies = [ - "async-lock 3.2.0", + "async-lock 3.3.0", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.1.0", + "futures-lite 2.3.0", "parking", - "polling 3.3.1", - "rustix 0.38.28", + "polling 3.7.0", + "rustix 0.38.34", "slab", "tracing", "windows-sys 0.52.0", @@ -272,12 +271,12 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7125e42787d53db9dd54261812ef17e937c95a51e4d291373b670342fa44310c" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" dependencies = [ - "event-listener 4.0.2", - "event-listener-strategy", + "event-listener 4.0.3", + "event-listener-strategy 0.4.0", "pin-project-lite", ] @@ -306,37 +305,37 @@ dependencies = [ "cfg-if", "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.38.28", + "rustix 0.38.34", "windows-sys 0.48.0", ] [[package]] name = "async-recursion" -version = "1.0.5" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" +checksum = "30c5ef0ede93efbf733c1a727f3b6b5a1060bbedd5600183e66f6e4be4af0ec5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] name = "async-signal" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +checksum = "afe66191c335039c7bb78f99dc7520b0cbb166b3a1cb33a03f53d8a1c6f2afda" dependencies = [ - "async-io 2.2.2", - "async-lock 2.8.0", + "async-io 2.3.2", + "async-lock 3.3.0", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.28", + "rustix 0.38.34", "signal-hook-registry", "slab", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -402,7 +401,7 @@ dependencies = [ "futures-util", "pin-utils", "socket2 0.4.10", - "trust-dns-resolver 0.21.2", + "trust-dns-resolver", ] [[package]] @@ -424,7 +423,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -435,13 +434,13 @@ checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -452,15 +451,15 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -479,9 +478,15 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" [[package]] name = "benches" @@ -499,9 +504,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "block-buffer" @@ -518,24 +523,24 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" dependencies = [ - "async-channel 2.1.1", - "async-lock 3.2.0", + "async-channel 2.2.1", + "async-lock 3.3.0", "async-task", - "fastrand 2.0.1", + "fastrand 2.0.2", "futures-io", - "futures-lite 2.1.0", + "futures-lite 2.3.0", "piper", "tracing", ] [[package]] name = "bstr" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" dependencies = [ "memchr", - "regex-automata 0.4.3", + "regex-automata 0.4.6", "serde", ] @@ -549,42 +554,42 @@ checksum = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8" name = "builder" version = "0.1.0" dependencies = [ - "http 0.2.11", + "http 1.1.0", "lychee-lib", "regex", - "reqwest", + "reqwest 0.12.4", "tokio", ] [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "by_address" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf8dba2868114ed769a1f2590fc9ae5eb331175b44313b6c9b922f8f7ca813d0" +checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" [[package]] name = "bytecount" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cached" -version = "0.46.1" +version = "0.49.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c8c50262271cdf5abc979a5f76515c234e764fa025d1ba4862c0f0bcda0e95" +checksum = "8e8e463fceca5674287f32d252fb1d94083758b8709c160efae66d263e5f4eba" dependencies = [ "ahash", "cached_proc_macro", @@ -597,9 +602,9 @@ dependencies = [ [[package]] name = "cached_proc_macro" -version = "0.18.1" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c878c71c2821aa2058722038a59a67583a4240524687c6028571c9b395ded61f" +checksum = "ad9f16c0d84de31a2ab7fdf5f7783c14631f7075cf464eb3bb43119f61c9cb2a" dependencies = [ "darling 0.14.4", "proc-macro2", @@ -609,9 +614,9 @@ dependencies = [ [[package]] name = "cached_proc_macro_types" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" +checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" [[package]] name = "cast" @@ -621,12 +626,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.83" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b" [[package]] name = "cfg-if" @@ -634,6 +636,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chain" +version = "0.1.0" +dependencies = [ + "async-trait", + "lychee-lib", + "reqwest 0.12.4", + "tokio", +] + [[package]] name = "check-if-email-exists" version = "0.9.1" @@ -645,38 +657,38 @@ dependencies = [ "async-smtp", "async-std", "async-std-resolver", - "fast-socks5 0.9.2", + "fast-socks5 0.9.6", "levenshtein", "log", "mailchecker", "md5", "pwned", - "rand 0.8.5", + "rand", "regex", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", - "trust-dns-proto 0.21.2", + "trust-dns-proto", ] [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "serde", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] name = "ciborium" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" dependencies = [ "ciborium-io", "ciborium-ll", @@ -685,15 +697,15 @@ dependencies = [ [[package]] name = "ciborium-io" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" [[package]] name = "ciborium-ll" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", "half", @@ -701,9 +713,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.13" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52bdc885e4cacc7f7c9eedc1ef6da641603180c783c41a15c264944deeaab642" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", "clap_derive", @@ -711,33 +723,33 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.12" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb7fb5e4e979aec3be7791562fcba452f94ad85e954da024396433e0e25a79e9" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.10.0", + "strsim 0.11.1", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "client_pool" @@ -753,10 +765,10 @@ dependencies = [ name = "collect_links" version = "0.1.0" dependencies = [ - "http 0.2.11", + "http 1.1.0", "lychee-lib", "regex", - "reqwest", + "reqwest 0.12.4", "tokio", "tokio-stream", ] @@ -778,15 +790,15 @@ dependencies = [ [[package]] name = "console" -version = "0.15.7" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" dependencies = [ "encode_unicode", "lazy_static", "libc", "unicode-width", - "windows-sys 0.45.0", + "windows-sys 0.52.0", ] [[package]] @@ -809,17 +821,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "cookie" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - [[package]] name = "cookie" version = "0.17.0" @@ -831,30 +832,13 @@ dependencies = [ "version_check", ] -[[package]] -name = "cookie_store" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d606d0fba62e13cf04db20536c05cb7f13673c161cb47a47a82b9b9e7d3f1daa" -dependencies = [ - "cookie 0.16.2", - "idna 0.2.3", - "log", - "publicsuffix", - "serde", - "serde_derive", - "serde_json", - "time", - "url", -] - [[package]] name = "cookie_store" version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "387461abbc748185c3a6e1673d826918b450b87ff22639429c694619a83b6cf6" dependencies = [ - "cookie 0.17.0", + "cookie", "idna 0.3.0", "log", "publicsuffix", @@ -892,9 +876,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] @@ -911,7 +895,7 @@ dependencies = [ "clap", "criterion-plot", "is-terminal", - "itertools 0.10.5", + "itertools", "num-traits", "once_cell", "oorandom", @@ -932,16 +916,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools 0.10.5", + "itertools", ] [[package]] name = "crossbeam" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eb9105919ca8e40d437fc9cbb8f1975d916f1bd28afe795a48aae32a2cc8920" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" dependencies = [ - "cfg-if", "crossbeam-channel", "crossbeam-deque", "crossbeam-epoch", @@ -951,54 +934,52 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.10" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a9b73a36529d9c47029b9fb3a6f0ea3cc916a261195352ba19e770fc1748b2" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.17" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-queue" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc6598521bb5a83d491e8c1fe51db7296019d2ca3cb93cc6c2a20369a4d78a2" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.18" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-common" @@ -1053,12 +1034,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.3" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", + "darling_core 0.20.8", + "darling_macro 0.20.8", ] [[package]] @@ -1091,16 +1072,16 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.3" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -1127,13 +1108,13 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ - "darling_core 0.20.3", + "darling_core 0.20.8", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -1158,14 +1139,13 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "deadpool" -version = "0.9.5" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "421fe0f90f2ab22016f32a9881be5134fdd71c65298917084b0c7477cbc3856e" +checksum = "fb84100978c1c7b37f09ed3ce3e5f843af02c2a2c431bae5b19230dad2c1b490" dependencies = [ "async-trait", "deadpool-runtime", "num_cpus", - "retain_mut", "tokio", ] @@ -1272,9 +1252,9 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "either" -version = "1.9.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "email_address" @@ -1293,9 +1273,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -1306,35 +1286,33 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "syn 1.0.109", ] [[package]] -name = "enum-as-inner" -version = "0.6.0" +name = "env_filter" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.48", + "log", + "regex", ] [[package]] name = "env_logger" -version = "0.10.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" dependencies = [ + "anstream", + "anstyle", + "env_filter", "humantime", - "is-terminal", "log", - "regex", - "termcolor", ] [[package]] @@ -1372,9 +1350,20 @@ dependencies = [ [[package]] name = "event-listener" -version = "4.0.2" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "218a870470cce1469024e9fb66b901aa983929d81304a1cdb299f28118e550d5" +checksum = "6d9944b8ca13534cdfb2800775f8dd4902ff3fc75a50101466decadfdf322a24" dependencies = [ "concurrent-queue", "parking", @@ -1387,7 +1376,17 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" dependencies = [ - "event-listener 4.0.2", + "event-listener 4.0.3", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332f51cb23d20b0de8458b86580878211da09bcd4503cb579c225b3d124cabb3" +dependencies = [ + "event-listener 5.3.0", "pin-project-lite", ] @@ -1414,9 +1413,9 @@ dependencies = [ [[package]] name = "fast-socks5" -version = "0.9.2" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d449e348301d5fb9b0e5781510d8235ffe3bbac3286bd305462736a9e7043039" +checksum = "f89f36d4ee12370d30d57b16c7e190950a1a916e7dbbb5fd5a412f5ef913fe84" dependencies = [ "anyhow", "async-trait", @@ -1446,9 +1445,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] name = "flate2" @@ -1587,11 +1586,11 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeee267a1883f7ebef3700f262d2d54de95dfaf38189015a74fdc4e0c7ad8143" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand 2.0.1", + "fastrand 2.0.2", "futures-core", "futures-io", "parking", @@ -1606,7 +1605,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -1623,9 +1622,9 @@ checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-timer" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" @@ -1666,25 +1665,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.11" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] @@ -1714,17 +1702,36 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.22" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http 0.2.11", - "indexmap 2.1.0", + "http 1.1.0", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", @@ -1733,9 +1740,13 @@ dependencies = [ [[package]] name = "half" -version = "1.8.2" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] [[package]] name = "hashbrown" @@ -1755,14 +1766,14 @@ dependencies = [ [[package]] name = "headers" -version = "0.3.9" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "bytes", "headers-core", - "http 0.2.11", + "http 1.1.0", "httpdate", "mime", "sha1 0.10.6", @@ -1770,11 +1781,11 @@ dependencies = [ [[package]] name = "headers-core" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" dependencies = [ - "http 0.2.11", + "http 1.1.0", ] [[package]] @@ -1783,11 +1794,17 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -1808,16 +1825,16 @@ dependencies = [ [[package]] name = "html5ever" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" +checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4" dependencies = [ "log", "mac", "markup5ever", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.60", ] [[package]] @@ -1831,9 +1848,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -1842,9 +1859,9 @@ dependencies = [ [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1858,7 +1875,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http 0.2.11", + "http 0.2.12", "pin-project-lite", ] @@ -1869,34 +1886,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "http 1.0.0", + "http 1.1.0", ] [[package]] -name = "http-range-header" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" - -[[package]] -name = "http-types" -version = "2.12.0" +name = "http-body-util" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e9b187a72d63adbfba487f48095306ac823049cb504ee195541e91c7775f5ad" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" dependencies = [ - "anyhow", - "async-channel 1.9.0", - "base64 0.13.1", - "futures-lite 1.13.0", - "http 0.2.11", - "infer", + "bytes", + "futures-core", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", - "rand 0.7.3", - "serde", - "serde_json", - "serde_qs", - "serde_urlencoded", - "url", ] [[package]] @@ -1937,14 +1940,14 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http 0.2.11", + "h2 0.3.26", + "http 0.2.12", "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.5", + "socket2 0.5.6", "tokio", "tower-service", "tracing", @@ -1953,43 +1956,55 @@ dependencies = [ [[package]] name = "hyper" -version = "1.1.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" dependencies = [ "bytes", - "http 1.0.0", + "futures-channel", + "futures-util", + "h2 0.4.4", + "http 1.1.0", "http-body 1.0.0", + "httparse", + "httpdate", + "itoa", "pin-project-lite", + "smallvec", "tokio", + "want", ] [[package]] name = "hyper-rustls" -version = "0.24.2" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", - "http 0.2.11", - "hyper 0.14.28", + "http 1.1.0", + "hyper 1.3.1", + "hyper-util", "log", "rustls", "rustls-native-certs", + "rustls-pki-types", "tokio", "tokio-rustls", + "tower-service", ] [[package]] name = "hyper-timeout" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" dependencies = [ - "hyper 0.14.28", + "hyper 1.3.1", + "hyper-util", "pin-project-lite", "tokio", - "tokio-io-timeout", + "tower-service", ] [[package]] @@ -2005,11 +2020,47 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.3.1", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.3.1", + "pin-project-lite", + "socket2 0.5.6", + "tokio", + "tower", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" -version = "0.1.59" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2055,16 +2106,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "idna" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "idna" version = "0.5.0" @@ -2088,9 +2129,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -2099,9 +2140,9 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" dependencies = [ "console", "instant", @@ -2110,12 +2151,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "infer" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e9829a50b42bb782c1df523f78d332fe371b10c661e78b7a3c34b0198e9fac" - [[package]] name = "instant" version = "0.1.12" @@ -2148,10 +2183,10 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.5", + "socket2 0.5.6", "widestring", "windows-sys 0.48.0", - "winreg", + "winreg 0.50.0", ] [[package]] @@ -2162,9 +2197,9 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "iri-string" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21859b667d66a4c1dacd9df0863b3efb65785474255face87f5bca39dd8407c0" +checksum = "7f5f6c2df22c009ac44f6f1499308e7a3ac7ba42cd2378475cc691510e1eef1b" dependencies = [ "memchr", "serde", @@ -2172,20 +2207,20 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ "hermit-abi", - "rustix 0.38.28", + "libc", "windows-sys 0.52.0", ] [[package]] name = "is_ci" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb" +checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" [[package]] name = "itertools" @@ -2196,20 +2231,11 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jetscii" @@ -2219,20 +2245,20 @@ checksum = "47f142fe24a9c9944451e8349de0a56af5f3e7226dc46f3ed4d4ecc0b85af75e" [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] [[package]] name = "jsonwebtoken" -version = "9.2.0" +version = "9.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ea04a7c5c055c175f189b6dc6ba036fd62306b58c66c9f6389036c503a3f4" +checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "js-sys", "pem", "ring", @@ -2274,19 +2300,18 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.5.0", "libc", - "redox_syscall", ] [[package]] @@ -2312,9 +2337,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" @@ -2328,9 +2353,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" dependencies = [ "value-bag", ] @@ -2346,7 +2371,7 @@ dependencies = [ [[package]] name = "lychee" -version = "0.14.3" +version = "0.15.1" dependencies = [ "anyhow", "assert-json-diff", @@ -2359,7 +2384,7 @@ dependencies = [ "env_logger", "futures", "headers", - "http 0.2.11", + "http 1.1.0", "humantime", "humantime-serde", "indicatif", @@ -2371,7 +2396,7 @@ dependencies = [ "predicates", "pretty_assertions", "regex", - "reqwest", + "reqwest 0.12.4", "reqwest_cookie_store", "ring", "secrecy", @@ -2391,9 +2416,10 @@ dependencies = [ [[package]] name = "lychee-lib" -version = "0.14.3" +version = "0.15.1" dependencies = [ "async-stream", + "async-trait", "cached", "check-if-email-exists", "doc-comment", @@ -2403,8 +2429,8 @@ dependencies = [ "headers", "html5ever", "html5gum", - "http 0.2.11", - "hyper 1.1.0", + "http 1.1.0", + "hyper 1.3.1", "ip_network", "jwalk", "linkify", @@ -2417,7 +2443,7 @@ dependencies = [ "percent-encoding", "pulldown-cmark", "regex", - "reqwest", + "reqwest 0.12.4", "reqwest_cookie_store", "ring", "rstest", @@ -2453,9 +2479,9 @@ dependencies = [ [[package]] name = "markup5ever" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" +checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45" dependencies = [ "log", "phf", @@ -2494,9 +2520,9 @@ checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "mime" @@ -2512,21 +2538,21 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.48.0", ] @@ -2536,7 +2562,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "getrandom 0.2.11", + "getrandom", ] [[package]] @@ -2559,9 +2585,9 @@ dependencies = [ [[package]] name = "new_debug_unreachable" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nom" @@ -2590,21 +2616,26 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", ] @@ -2636,24 +2667,26 @@ dependencies = [ [[package]] name = "octocrab" -version = "0.32.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abfeeafb5fa0da7046229ec3c7b3bd2981aae05c549871192c408d59fc0fffd5" +checksum = "68a8a3df00728324ad654ecd1ed449a60157c55b7ff8c109af3a35989687c367" dependencies = [ "arc-swap", "async-trait", - "base64 0.21.5", + "base64 0.22.0", "bytes", "cfg-if", "chrono", "either", "futures", "futures-util", - "http 0.2.11", - "http-body 0.4.6", - "hyper 0.14.28", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.3.1", "hyper-rustls", "hyper-timeout", + "hyper-util", "jsonwebtoken", "once_cell", "percent-encoding", @@ -2685,11 +2718,11 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "openssl" -version = "0.10.62" +version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.5.0", "cfg-if", "foreign-types", "libc", @@ -2706,7 +2739,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -2717,18 +2750,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.2.1+3.2.0" +version = "300.2.3+3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe476c29791a5ca0d1273c697e96085bbabbbea2ef7afd5617e78a4b40332d3" +checksum = "5cff92b6f71555b61bb9315f7c64da3ca43d87531622120fea0195fc761b4843" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.98" +version = "0.9.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" dependencies = [ "cc", "libc", @@ -2819,11 +2852,11 @@ checksum = "17359afc20d7ab31fdb42bb844c8b3bb1dabd7dcf7e68428492da7f16966fcef" [[package]] name = "pem" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" dependencies = [ - "base64 0.21.5", + "base64 0.22.0", "serde", ] @@ -2835,21 +2868,21 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "phf" -version = "0.10.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_shared", + "phf_shared 0.11.2", ] [[package]] name = "phf_codegen" -version = "0.10.0" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.11.2", + "phf_shared 0.11.2", ] [[package]] @@ -2858,8 +2891,18 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" dependencies = [ - "phf_shared", - "rand 0.8.5", + "phf_shared 0.10.0", + "rand", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", + "rand", ] [[package]] @@ -2871,31 +2914,40 @@ dependencies = [ "siphasher", ] +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -2910,15 +2962,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" dependencies = [ "atomic-waker", - "fastrand 2.0.1", + "fastrand 2.0.2", "futures-io", ] [[package]] name = "pkg-config" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "plotters" @@ -2966,14 +3018,15 @@ dependencies = [ [[package]] name = "polling" -version = "3.3.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" +checksum = "645493cf344456ef24219d02a768cf1fb92ddf8c92161679ae3d91b91a637be3" dependencies = [ "cfg-if", "concurrent-queue", + "hermit-abi", "pin-project-lite", - "rustix 0.38.28", + "rustix 0.38.34", "tracing", "windows-sys 0.52.0", ] @@ -3004,14 +3057,13 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "predicates" -version = "3.0.4" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dfc28575c2e3f19cb3c73b93af36460ae898d426eba6fc15b9bd2a5220758a0" +checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" dependencies = [ "anstyle", "difflib", "float-cmp", - "itertools 0.11.0", "normalize-line-endings", "predicates-core", "regex", @@ -3069,9 +3121,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] @@ -3094,11 +3146,11 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.9.3" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" +checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "getopts", "memchr", "unicase", @@ -3111,7 +3163,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f75258f75c681eb691607acdb325d0150907bc68826365b07476834df2664974" dependencies = [ "derive_builder", - "reqwest", + "reqwest 0.11.27", "serde", "serde_derive", "serde_json", @@ -3127,26 +3179,13 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] - [[package]] name = "rand" version = "0.8.5" @@ -3154,18 +3193,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "rand_chacha", + "rand_core", ] [[package]] @@ -3175,16 +3204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", + "rand_core", ] [[package]] @@ -3193,23 +3213,14 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.11", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", + "getrandom", ] [[package]] name = "rayon" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -3217,9 +3228,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3236,25 +3247,25 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom 0.2.11", + "getrandom", "libredox", "thiserror", ] [[package]] name = "regex" -version = "1.10.2" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", - "regex-syntax 0.8.2", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", ] [[package]] @@ -3268,13 +3279,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -3285,9 +3296,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "relative-path" @@ -3297,24 +3308,67 @@ checksum = "e898588f33fdd5b9420719948f9f2a32c922a246964576f71ba7f24f80610fbc" [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "async-compression", - "base64 0.21.5", + "base64 0.21.7", "bytes", - "cookie 0.16.2", - "cookie_store 0.16.2", "encoding_rs", "futures-core", "futures-util", - "h2", - "http 0.2.11", + "h2 0.3.26", + "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", + "hyper-tls 0.5.0", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-socks", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.50.0", +] + +[[package]] +name = "reqwest" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" +dependencies = [ + "async-compression", + "base64 0.22.0", + "bytes", + "cookie", + "cookie_store", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.4.4", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.3.1", "hyper-rustls", - "hyper-tls", + "hyper-tls 0.6.0", + "hyper-util", "ipnet", "js-sys", "log", @@ -3325,34 +3379,34 @@ dependencies = [ "pin-project-lite", "rustls", "rustls-native-certs", - "rustls-pemfile", + "rustls-pemfile 2.1.2", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-native-tls", "tokio-rustls", - "tokio-socks", "tokio-util", "tower-service", - "trust-dns-resolver 0.23.2", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg", + "winreg 0.52.0", ] [[package]] name = "reqwest_cookie_store" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba529055ea150e42e4eb9c11dcd380a41025ad4d594b0cb4904ef28b037e1061" +checksum = "93ea5c6f30c19d766efe8d823c88f9abd1c56516648a0d4264ab2dc04cc19472" dependencies = [ "bytes", - "cookie_store 0.20.0", - "reqwest", + "cookie_store", + "reqwest 0.12.4", "url", ] @@ -3366,31 +3420,26 @@ dependencies = [ "quick-error", ] -[[package]] -name = "retain_mut" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" - [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", - "getrandom 0.2.11", + "cfg-if", + "getrandom", "libc", "spin", "untrusted", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "rstest" -version = "0.18.2" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97eeab2f3c0a199bc4be135c36c924b6590b88c377d416494288c14f2db30199" +checksum = "9d5316d2a1479eeef1ea21e7f9ddc67c191d497abc8fc3ba2467857abbb68330" dependencies = [ "futures", "futures-timer", @@ -3400,9 +3449,9 @@ dependencies = [ [[package]] name = "rstest_macros" -version = "0.18.2" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d428f8247852f894ee1be110b375111b586d4fa431f6c46e64ba5a0dcccbe605" +checksum = "04a9df72cc1f67020b0d63ad9bfe4a323e459ea7eb68e03bd9824db49f9a4c25" dependencies = [ "cfg-if", "glob", @@ -3411,7 +3460,7 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.48", + "syn 2.0.60", "unicode-ident", ] @@ -3446,37 +3495,40 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.28" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.5.0", "errno", "libc", - "linux-raw-sys 0.4.12", + "linux-raw-sys 0.4.13", "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.21.10" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", "ring", + "rustls-pki-types", "rustls-webpki", - "sct", + "subtle", + "zeroize", ] [[package]] name = "rustls-native-certs" -version = "0.6.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 2.1.2", + "rustls-pki-types", "schannel", "security-framework", ] @@ -3487,30 +3539,47 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.0", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beb461507cee2c2ff151784c52762cf4d9ff6a61f3e80968600ed24fa837fa54" + [[package]] name = "rustls-webpki" -version = "0.101.7" +version = "0.102.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +checksum = "f3bce581c0dd41bce533ce695a1437fa16a7ab5ac3ccfa99fe1a620a7885eabf" dependencies = [ "ring", + "rustls-pki-types", "untrusted", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "same-file" @@ -3536,16 +3605,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "secrecy" version = "0.8.0" @@ -3558,9 +3617,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -3571,9 +3630,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" dependencies = [ "core-foundation-sys", "libc", @@ -3581,35 +3640,35 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "itoa", "ryu", @@ -3618,25 +3677,14 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" dependencies = [ "itoa", "serde", ] -[[package]] -name = "serde_qs" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7715380eec75f029a4ef7de39a9200e0a63823176b759d055b613f5a87df6a6" -dependencies = [ - "percent-encoding", - "serde", - "thiserror", -] - [[package]] name = "serde_spanned" version = "0.6.5" @@ -3660,16 +3708,17 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.4.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +checksum = "2c85f8e96d1d6857f13768fcbd895fcb06225510022a2774ed8b5150581847b0" dependencies = [ - "base64 0.21.5", + "base64 0.22.0", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.1.0", + "indexmap 2.2.6", "serde", + "serde_derive", "serde_json", "serde_with_macros", "time", @@ -3677,14 +3726,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.4.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +checksum = "c8b3a576c4eb2924262d5951a3b737ccaf16c931e39a2810c36f9a7e25575557" dependencies = [ - "darling 0.20.3", + "darling 0.20.8", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -3733,9 +3782,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -3777,31 +3826,29 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "snafu" -version = "0.7.5" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4de37ad025c587a29e8f3f5605c00f70b98715ef90b9061a815b9e59e9042d6" +checksum = "75976f4748ab44f6e5332102be424e7c2dc18daeaf7e725f2040c3ebb133512e" dependencies = [ - "backtrace", - "doc-comment", "snafu-derive", ] [[package]] name = "snafu-derive" -version = "0.7.5" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990079665f075b699031e9c08fd3ab99be5029b96f3b78dc0709e8f77e4efebf" +checksum = "b4b19911debfb8c2fb1107bc6cb2d61868aaf53a988449213959bb1b5b1ed95f" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.60", ] [[package]] @@ -3816,12 +3863,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3842,7 +3889,7 @@ dependencies = [ "new_debug_unreachable", "once_cell", "parking_lot", - "phf_shared", + "phf_shared 0.10.0", "precomputed-hash", "serde", ] @@ -3853,8 +3900,8 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.10.0", + "phf_shared 0.10.0", "proc-macro2", "quote", ] @@ -3871,35 +3918,46 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "strum" -version = "0.25.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.25.3" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", - "syn 2.0.48", + "syn 2.0.60", ] +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + [[package]] name = "supports-color" -version = "2.1.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6398cde53adc3c4557306a96ce67b302968513830a77a95b2b17305d9719a89" +checksum = "9829b314621dfc575df4e409e79f9d6a66a3bd707ab73f23cb4aa3a854ac854f" dependencies = [ - "is-terminal", "is_ci", ] @@ -3916,15 +3974,21 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "system-configuration" version = "0.5.1" @@ -3963,7 +4027,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c138f99377e5d653a371cdad263615634cfc8467685dfe8e73e2b8e98f44b17" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro-error", "proc-macro2", "quote", @@ -3972,14 +4036,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.9.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand 2.0.1", - "redox_syscall", - "rustix 0.38.28", + "fastrand 2.0.2", + "rustix 0.38.34", "windows-sys 0.52.0", ] @@ -3994,15 +4057,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "termcolor" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" -dependencies = [ - "winapi-util", -] - [[package]] name = "termtree" version = "0.4.1" @@ -4011,29 +4065,29 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -4041,12 +4095,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -4061,10 +4116,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -4095,9 +4151,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", @@ -4107,21 +4163,11 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2 0.5.6", "tokio-macros", "windows-sys 0.48.0", ] -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - [[package]] name = "tokio-macros" version = "2.2.0" @@ -4130,7 +4176,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -4145,11 +4191,12 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ "rustls", + "rustls-pki-types", "tokio", ] @@ -4167,9 +4214,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", "pin-project-lite", @@ -4192,9 +4239,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.8" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" dependencies = [ "serde", "serde_spanned", @@ -4213,11 +4260,11 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.21.0" +version = "0.22.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", @@ -4243,17 +4290,16 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" +checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.5.0", "bytes", - "futures-core", "futures-util", - "http 0.2.11", - "http-body 0.4.6", - "http-range-header", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", "iri-string", "pin-project-lite", "tower", @@ -4294,7 +4340,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -4330,7 +4376,7 @@ dependencies = [ "async-trait", "cfg-if", "data-encoding", - "enum-as-inner 0.4.0", + "enum-as-inner", "futures-channel", "futures-io", "futures-util", @@ -4338,7 +4384,7 @@ dependencies = [ "ipnet", "lazy_static", "log", - "rand 0.8.5", + "rand", "smallvec", "thiserror", "tinyvec", @@ -4346,31 +4392,6 @@ dependencies = [ "url", ] -[[package]] -name = "trust-dns-proto" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3119112651c157f4488931a01e586aa459736e9d6046d3bd9105ffb69352d374" -dependencies = [ - "async-trait", - "cfg-if", - "data-encoding", - "enum-as-inner 0.6.0", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.4.0", - "ipnet", - "once_cell", - "rand 0.8.5", - "smallvec", - "thiserror", - "tinyvec", - "tokio", - "tracing", - "url", -] - [[package]] name = "trust-dns-resolver" version = "0.21.2" @@ -4387,28 +4408,7 @@ dependencies = [ "resolv-conf", "smallvec", "thiserror", - "trust-dns-proto 0.21.2", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a3e6c3aff1718b3c73e395d1f35202ba2ffa847c6a62eea0db8fb4cfe30be6" -dependencies = [ - "cfg-if", - "futures-util", - "ipconfig", - "lru-cache", - "once_cell", - "parking_lot", - "rand 0.8.5", - "resolv-conf", - "smallvec", - "thiserror", - "tokio", - "tracing", - "trust-dns-proto 0.23.2", + "trust-dns-proto", ] [[package]] @@ -4419,22 +4419,22 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typed-builder" -version = "0.18.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e47c0496149861b7c95198088cbf36645016b1a0734cf350c50e2a38e070f38a" +checksum = "77739c880e00693faef3d65ea3aad725f196da38b22fdc7ea6ded6e1ce4d3add" dependencies = [ "typed-builder-macro", ] [[package]] name = "typed-builder-macro" -version = "0.18.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982ee4197351b5c9782847ef5ec1fdcaf50503fb19d68f9771adae314e72b492" +checksum = "1f718dfaf347dcb5b983bfc87608144b0bad87970aebcbea5ce44d2a30c08e63" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -4454,9 +4454,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -4466,9 +4466,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] @@ -4517,18 +4517,18 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ - "getrandom 0.2.11", + "getrandom", ] [[package]] name = "value-bag" -version = "1.4.3" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ce5bb364b23e66b528d03168df78b38c0f7b6fe17386928f29d5ab2e7cb2f7" +checksum = "74797339c3b98616c009c7c3eb53a0ce41e85c8ec66bd3db96ed132d20cfdee8" [[package]] name = "vcpkg" @@ -4559,9 +4559,9 @@ checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -4576,12 +4576,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -4590,9 +4584,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4600,24 +4594,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.39" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -4627,9 +4621,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4637,28 +4631,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -4666,9 +4660,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" [[package]] name = "winapi" @@ -4688,11 +4682,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -4707,16 +4701,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", + "windows-targets 0.52.5", ] [[package]] @@ -4734,22 +4719,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets 0.52.5", ] [[package]] @@ -4769,25 +4739,20 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -4796,15 +4761,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -4814,15 +4773,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -4832,15 +4785,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" [[package]] -name = "windows_i686_msvc" -version = "0.42.2" +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -4850,15 +4803,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -4868,15 +4815,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -4886,15 +4827,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -4904,15 +4839,15 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" -version = "0.5.32" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8434aeec7b290e8da5c3f0d628cb0eac6cabcb31d14bb74f779a08109a5914d6" +checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352" dependencies = [ "memchr", ] @@ -4927,26 +4862,38 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "wiremock" -version = "0.5.22" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13a3a53eaf34f390dd30d7b1b078287dd05df2aa2e21a589ccb80f5c7253c2e9" +checksum = "ec874e1eef0df2dcac546057fe5e29186f09c378181cd7b635b4b7bcc98e9d81" dependencies = [ "assert-json-diff", "async-trait", - "base64 0.21.5", + "base64 0.21.7", "deadpool", "futures", - "futures-timer", - "http-types", - "hyper 0.14.28", + "http 1.1.0", + "http-body-util", + "hyper 1.3.1", + "hyper-util", "log", "once_cell", "regex", "serde", "serde_json", "tokio", + "url", ] [[package]] @@ -4972,11 +4919,11 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "63381fa6624bf92130a6b87c0d07380116f80b565c42cf0d754136f0238359ef" diff --git a/Cargo.toml b/Cargo.toml index 7e299a5cc8..3e34e95f73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["lychee-bin", "lychee-lib", "examples/*", "benches"] resolver = "2" [workspace.package] -version = "0.14.3" +version = "0.15.1" [profile.release] debug = true diff --git a/README.md b/README.md index 661c8e54e1..69fa3fc29b 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Available as a command-line utility, a library and a [GitHub Action](https://git - [Commandline usage](#commandline-usage) - [Library usage](#library-usage) - [GitHub Action Usage](#github-action-usage) +- [Pre-commit Usage](#pre-commit-usage) - [Contributing to lychee](#contributing-to-lychee) - [Debugging and improving async code](#debugging-and-improving-async-code) - [Troubleshooting and Workarounds](#troubleshooting-and-workarounds) @@ -78,6 +79,13 @@ scoop install lychee pkg install lychee ``` +### Alpine Linux + +```sh + # available for Alpine Edge in testing repositories +apk add lychee +``` + ### Pre-built binaries We provide binaries for Linux, macOS, and Windows for every release. \ @@ -437,7 +445,7 @@ Options: [default: get] -b, --base - Base URL or website root directory to check relative URLs e.g. https://example.com or `/path/to/public` + Base URL or website root directory to check relative URLs e.g. or `/path/to/public` --basic-auth Basic authentication support. E.g. `http://example.com username:password` @@ -567,6 +575,27 @@ folder. A GitHub Action that uses lychee is available as a separate repository: [lycheeverse/lychee-action](https://github.com/lycheeverse/lychee-action) which includes usage instructions. +## Pre-commit Usage + +Lychee can also be used as a [pre-commit](https://pre-commit.com/) hook. +```yaml +# .pre-commit-config.yaml +repos: + - repo: https://github.com/lycheeverse/lychee.git + rev: v0.15.1 + hooks: + - id: lychee + # Optionally include additional CLI arguments + args: ["--no-progress", "--exclude", "file://"] +``` + +Rather than running on staged-files only, Lychee can be run against an entire repository. +```yaml +- id: lychee + args: ["--no-progress", "."] + pass_filenames: false +``` + ## Contributing to lychee We'd be thankful for any contribution. \ diff --git a/examples/builder/Cargo.toml b/examples/builder/Cargo.toml index d2eba27bc2..a10a1b6367 100644 --- a/examples/builder/Cargo.toml +++ b/examples/builder/Cargo.toml @@ -9,10 +9,10 @@ path = "builder.rs" [dependencies] lychee-lib = { path = "../../lychee-lib", default-features = false } -tokio = { version = "1.35.1", features = ["full"] } -regex = "1.10.2" -http = "0.2.10" -reqwest = { version = "0.11.23", default-features = false, features = ["gzip"] } +tokio = { version = "1.37.0", features = ["full"] } +regex = "1.10.4" +http = "1.0.0" +reqwest = { version = "0.12.4", default-features = false, features = ["gzip"] } [features] email-check = ["lychee-lib/email-check"] diff --git a/examples/chain/Cargo.toml b/examples/chain/Cargo.toml new file mode 100644 index 0000000000..48d403ed8b --- /dev/null +++ b/examples/chain/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "chain" +version = "0.1.0" +edition = "2021" + +[[example]] +name = "chain" +path = "chain.rs" + +[dependencies] +async-trait = "0.1.80" +lychee-lib = { path = "../../lychee-lib", default-features = false } +reqwest = "0.12.4" +tokio = { version = "1.37.0", features = ["full"] } + +[features] +email-check = ["lychee-lib/email-check"] +native-tls = ["lychee-lib/native-tls"] +rustls-tls = ["lychee-lib/rustls-tls"] +default = ["native-tls", "email-check"] diff --git a/examples/chain/LICENSE-APACHE b/examples/chain/LICENSE-APACHE new file mode 100644 index 0000000000..f51e79e400 --- /dev/null +++ b/examples/chain/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2020 The lychee maintainers + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/examples/chain/LICENSE-MIT b/examples/chain/LICENSE-MIT new file mode 100644 index 0000000000..f702c7bc16 --- /dev/null +++ b/examples/chain/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 The lychee maintainers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/examples/chain/chain.rs b/examples/chain/chain.rs new file mode 100644 index 0000000000..57aa70961e --- /dev/null +++ b/examples/chain/chain.rs @@ -0,0 +1,34 @@ +use async_trait::async_trait; +use lychee_lib::{chain::RequestChain, ChainResult, ClientBuilder, Handler, Result, Status}; +use reqwest::{Method, Request}; + +#[derive(Debug)] +struct MyHandler {} + +#[async_trait] +impl Handler for MyHandler { + async fn handle(&mut self, mut request: Request) -> ChainResult { + // Handle special case of some website (fictional example) + if request.url().domain() == Some("wikipedia.org") && request.url().path() == "/home" { + request.url_mut().set_path("/foo-bar"); + *request.method_mut() = Method::PUT; + } + + ChainResult::Next(request) + } +} + +#[tokio::main] +async fn main() -> Result<()> { + let chain = RequestChain::new(vec![Box::new(MyHandler {})]); + + let client = ClientBuilder::builder() + .plugin_request_chain(chain) + .build() + .client()?; + + let result = client.check("https://wikipedia.org/home").await; + println!("{:?}", result); + + Ok(()) +} diff --git a/examples/client_pool/Cargo.toml b/examples/client_pool/Cargo.toml index 9acf75cff2..47d73c4e5d 100644 --- a/examples/client_pool/Cargo.toml +++ b/examples/client_pool/Cargo.toml @@ -9,9 +9,9 @@ path = "client_pool.rs" [dependencies] futures = "0.3.30" -tokio-stream = "0.1.14" +tokio-stream = "0.1.15" lychee-lib = { path = "../../lychee-lib", default-features = false } -tokio = { version = "1.35.1", features = ["full"] } +tokio = { version = "1.37.0", features = ["full"] } [features] email-check = ["lychee-lib/email-check"] diff --git a/examples/collect_links/Cargo.toml b/examples/collect_links/Cargo.toml index 9be0888971..74aa700f22 100644 --- a/examples/collect_links/Cargo.toml +++ b/examples/collect_links/Cargo.toml @@ -9,11 +9,11 @@ path = "collect_links.rs" [dependencies] lychee-lib = { path = "../../lychee-lib", default-features = false } -tokio = { version = "1.35.1", features = ["full"] } -regex = "1.10.2" -http = "0.2.10" -tokio-stream = "0.1.14" -reqwest = { version = "0.11.23", default-features = false, features = ["gzip"] } +tokio = { version = "1.37.0", features = ["full"] } +regex = "1.10.4" +http = "1.0.0" +tokio-stream = "0.1.15" +reqwest = { version = "0.12.4", default-features = false, features = ["gzip"] } [features] email-check = ["lychee-lib/email-check"] diff --git a/examples/extract/Cargo.toml b/examples/extract/Cargo.toml index 3b404df6a6..160a86726c 100644 --- a/examples/extract/Cargo.toml +++ b/examples/extract/Cargo.toml @@ -9,7 +9,7 @@ path = "extract.rs" [dependencies] lychee-lib = { path = "../../lychee-lib", default-features = false } -tokio = { version = "1.35.1", features = ["full"] } +tokio = { version = "1.37.0", features = ["full"] } [features] email-check = ["lychee-lib/email-check"] diff --git a/examples/simple/Cargo.toml b/examples/simple/Cargo.toml index 8915c213f4..80dc93015f 100644 --- a/examples/simple/Cargo.toml +++ b/examples/simple/Cargo.toml @@ -9,7 +9,7 @@ path = "simple.rs" [dependencies] lychee-lib = { path = "../../lychee-lib", default-features = false } -tokio = { version = "1.35.1", features = ["full"] } +tokio = { version = "1.37.0", features = ["full"] } [features] email-check = ["lychee-lib/email-check"] diff --git a/fixtures/bench/arch.html b/fixtures/bench/arch.html index a4b53101c9..dc6736caa3 100644 --- a/fixtures/bench/arch.html +++ b/fixtures/bench/arch.html @@ -72,28 +72,28 @@

- + Search - + @@ -129,48 +129,48 @@

Navigation menu

- +
- @@ -235,9 +235,9 @@

More collapsed

- +
    - +
    @@ -259,7 +259,7 @@

    List of applications

    From ArchWiki
    - +

    This article is a general list of applications sorted by category, as a reference for those looking for packages. Many sections are split between console and graphical applications.

    -
    Tip: +
    Tip:
    • This page exists primarily to make it easier to search for alternatives to an application that you do not know under which section has been added. Use the links in the template at the top to view the main sections as separate pages.
    • Please consider installing the pkgstats package, which provides a timer that sends a list of the packages installed on your system, along with the architecture and the mirrors you use, to the Arch Linux developers in order to help them prioritize their efforts and make the distribution even better. The information is sent anonymously and cannot be used to identify you. You can view the collected data at the Statistics page. More information is available in this forum thread.
    • Daemon packages usually include the relevant systemd unit file to start; some packages even include different ones. After installation pacman -Qql package | grep -Fe .service -e .socket can be used to check and find the relevant one.
    @@ -1234,7 +1234,7 @@
    Browsers based o
    • wyeb — A vim-like web browser inspired by dwb and luakit with Adblock.
    https://github.com/jun7/wyeb || wyeb-gitAUR
    Browsers based on qt5-webkit
    -
    • OSPKit — Webkit based html browser for printing.
    +
    • OSPKit — Webkit based HTML browser for printing.
    http://osp.kitchen/tools/ospkit/ || ospkit-gitAUR
    • Otter Browser — Browser aiming to recreate classic Opera (12.x) UI using Qt5.
    https://otter-browser.org/ || otter-browser
    @@ -1436,7 +1436,7 @@

    Cloud storage servers
  • Seafile — An online file storage and collaboration tool with advanced support for file syncing, privacy protection and teamwork.
  • https://www.seafile.com/ || seafile-serverAUR

    Cloud synchronization clients

    -
    Tip: +
    Tip: @@ -7029,7 +7029,7 @@

    See also

  • Arch Linux Forums / LnF Awards 2012 - The best Light & Fast apps of 2012
  • Arch Linux Forums / most popular apps of 2013-2014
  • Arch Linux Forums / most popular apps of 2017+ (requires login)
  • - - \ No newline at end of file + diff --git a/fixtures/fragments/file1.md b/fixtures/fragments/file1.md index 9b90727db9..7f63b15890 100644 --- a/fixtures/fragments/file1.md +++ b/fixtures/fragments/file1.md @@ -28,7 +28,7 @@ Therefore we put the test into a code block for now to prevent false positives. [Link to explicit fragment](#explicit-fragment) -[To the html doc](file.html#a-word) +[To the HTML doc](file.html#a-word) ## Custom Fragments diff --git a/lychee-bin/Cargo.toml b/lychee-bin/Cargo.toml index f32048acfc..800a297ecf 100644 --- a/lychee-bin/Cargo.toml +++ b/lychee-bin/Cargo.toml @@ -14,59 +14,59 @@ version.workspace = true [dependencies] # NOTE: We need to specify the version of lychee-lib here because crates.io # requires all dependencies to have a version number. -lychee-lib = { path = "../lychee-lib", version = "0.14.3", default-features = false } +lychee-lib = { path = "../lychee-lib", version = "0.15.1", default-features = false } -anyhow = "1.0.78" +anyhow = "1.0.82" assert-json-diff = "2.0.2" -clap = { version = "4.4.12", features = ["env", "derive"] } -console = "0.15.7" +clap = { version = "4.5.4", features = ["env", "derive"] } +console = "0.15.8" const_format = "0.2.32" csv = "1.3.0" dashmap = { version = "5.5.3", features = ["serde"] } -env_logger = "0.10.1" +env_logger = "0.11.1" futures = "0.3.30" -headers = "0.3.8" -http = "0.2.10" +headers = "0.4.0" +http = "1.0.0" humantime = "2.1.0" humantime-serde = "1.1.1" -indicatif = "0.17.7" -log = "0.4.20" +indicatif = "0.17.8" +log = "0.4.21" once_cell = "1.19.0" -openssl-sys = { version = "0.9.98", optional = true } +openssl-sys = { version = "0.9.102", optional = true } pad = "0.1.6" -regex = "1.10.2" -reqwest = { version = "0.11.23", default-features = false, features = [ +regex = "1.10.4" +reqwest = { version = "0.12.4", default-features = false, features = [ "gzip", "json", ] } -reqwest_cookie_store = "0.6.0" +reqwest_cookie_store = "0.7.0" # Make build work on Apple Silicon. # See https://github.com/briansmith/ring/issues/1163 # This is necessary for the homebrew build # https://github.com/Homebrew/homebrew-core/pull/70216 -ring = "0.17.7" +ring = "0.17.8" secrecy = { version = "0.8.0", features = ["serde"] } -serde = { version = "1.0.193", features = ["derive"] } -serde_json = "1.0.109" -strum = { version = "0.25.0", features = ["derive"] } -supports-color = "2.1.0" +serde = { version = "1.0.198", features = ["derive"] } +serde_json = "1.0.116" +strum = { version = "0.26.2", features = ["derive"] } +supports-color = "3.0.0" tabled = "0.15.0" -tokio = { version = "1.35.1", features = ["full"] } -tokio-stream = "0.1.14" -toml = "0.8.8" +tokio = { version = "1.37.0", features = ["full"] } +tokio-stream = "0.1.15" +toml = "0.8.12" [dev-dependencies] -assert_cmd = "2.0.12" -predicates = "3.0.4" +assert_cmd = "2.0.14" +predicates = "3.1.0" pretty_assertions = "1.4.0" -tempfile = "3.9.0" +tempfile = "3.10.1" tracing-subscriber = { version = "0.3.18", default-features = false, features = [ "fmt", "registry", "env-filter", ] } -uuid = { version = "1.6.1", features = ["v4"] } -wiremock = "0.5.22" +uuid = { version = "1.8.0", features = ["v4"] } +wiremock = "0.6.0" # console-subscriber is not yet published to crates.io # Users have to uncomment this section and the feature below and build lychee diff --git a/lychee-bin/src/archive/mod.rs b/lychee-bin/src/archive/mod.rs index 7246f8a82d..767b232530 100644 --- a/lychee-bin/src/archive/mod.rs +++ b/lychee-bin/src/archive/mod.rs @@ -1,7 +1,7 @@ use reqwest::{Error, Url}; use serde::{Deserialize, Serialize}; use std::fmt::Display; -use strum::{Display, EnumIter, EnumString, EnumVariantNames}; +use strum::{Display, EnumIter, EnumString, VariantNames}; use crate::color::{color, GREEN, PINK}; @@ -23,7 +23,7 @@ impl Display for Suggestion { } #[non_exhaustive] -#[derive(Debug, Deserialize, Default, Clone, Display, EnumIter, EnumString, EnumVariantNames)] +#[derive(Debug, Deserialize, Default, Clone, Display, EnumIter, EnumString, VariantNames)] pub(crate) enum Archive { #[serde(rename = "wayback")] #[strum(serialize = "wayback", ascii_case_insensitive)] diff --git a/lychee-bin/src/commands/check.rs b/lychee-bin/src/commands/check.rs index 5ad2d49df2..6b22f6e362 100644 --- a/lychee-bin/src/commands/check.rs +++ b/lychee-bin/src/commands/check.rs @@ -10,7 +10,7 @@ use reqwest::Url; use tokio::sync::mpsc; use tokio_stream::wrappers::ReceiverStream; -use lychee_lib::{Client, Request, Response, Uri}; +use lychee_lib::{Client, ErrorKind, Request, Response, Uri}; use lychee_lib::{InputSource, Result}; use lychee_lib::{ResponseBody, Status}; @@ -235,6 +235,25 @@ async fn request_channel_task( .await; } +/// Check a URL and return a response. +/// +/// # Errors +/// +/// This can fail when the URL could not be parsed to a URI. +async fn check_url(client: &Client, request: Request) -> Response { + // Request was not cached; run a normal check + let uri = request.uri.clone(); + let source = request.source.clone(); + client.check(request).await.unwrap_or_else(|e| { + log::error!("Error checking URL {}: Cannot parse URL to URI: {}", uri, e); + Response::new( + uri.clone(), + Status::Error(ErrorKind::InvalidURI(uri.clone())), + source, + ) + }) +} + /// Handle a single request async fn handle( client: &Client, @@ -261,12 +280,7 @@ async fn handle( } // Request was not cached; run a normal check - // - // This can panic when the Url could not be parsed to a Uri. - // See https://github.com/servo/rust-url/issues/554 - // See https://github.com/seanmonstar/reqwest/issues/668 - // TODO: Handle error as soon as https://github.com/seanmonstar/reqwest/pull/1399 got merged - let response = client.check(request).await.expect("cannot check URI"); + let response = check_url(client, request).await; // - Never cache filesystem access as it is fast already so caching has no // benefit. @@ -343,7 +357,7 @@ mod tests { use http::StatusCode; use log::info; - use lychee_lib::{CacheStatus, ErrorKind, InputSource, ResponseBody, Uri}; + use lychee_lib::{CacheStatus, ErrorKind, ClientBuilder, InputSource, ResponseBody, Uri}; use crate::formatters; @@ -431,6 +445,19 @@ mod tests { &Uri::try_from("https://[::1]").unwrap(), &Status::Ok(StatusCode::OK), &exclude + )); + } + + #[tokio::test] + async fn test_invalid_url() { + // Run a normal request with an invalid Url + let client = ClientBuilder::builder().build().client().unwrap(); + let request = Request::try_from("http://\"").unwrap(); + let response = check_url(&client, request).await; + assert!(response.status().is_error()); + assert!(matches!( + response.status(), + Status::Error(ErrorKind::InvalidURI(_)) )); } } diff --git a/lychee-bin/src/main.rs b/lychee-bin/src/main.rs index 3535fea9d5..2715d178a8 100644 --- a/lychee-bin/src/main.rs +++ b/lychee-bin/src/main.rs @@ -383,7 +383,7 @@ async fn run(opts: &LycheeOptions) -> Result { if github_issues && opts.config.github_token.is_none() { let mut handle = io::stderr(); - color!(handle, YELLOW, "\u{1f4a1} There were issues with Github URLs. You could try setting a Github token and running lychee again.",)?; + color!(handle, YELLOW, "\u{1f4a1} There were issues with GitHub URLs. You could try setting a GitHub token and running lychee again.",)?; } if opts.config.cache { diff --git a/lychee-bin/src/options.rs b/lychee-bin/src/options.rs index 893f92711c..de8c4f9e05 100644 --- a/lychee-bin/src/options.rs +++ b/lychee-bin/src/options.rs @@ -370,7 +370,7 @@ separated list of accepted status codes. This example will accept 200, 201, pub(crate) method: String, /// Base URL or website root directory to check relative URLs - /// e.g. https://example.com or `/path/to/public` + /// e.g. or `/path/to/public` #[arg(short, long, value_parser= parse_base)] #[serde(default)] pub(crate) base: Option, diff --git a/lychee-bin/src/stats.rs b/lychee-bin/src/stats.rs index d412cdd930..01c91a29b5 100644 --- a/lychee-bin/src/stats.rs +++ b/lychee-bin/src/stats.rs @@ -1,3 +1,6 @@ +// Disable lint, clippy thinks that InputSource has inner mutability, but this seems like a false positive +#![allow(clippy::mutable_key_type)] + use std::collections::{HashMap, HashSet}; use crate::archive::Suggestion; @@ -60,7 +63,7 @@ impl ResponseStats { self.increment_status_counters(status); match status { - _ if status.is_failure() => { + _ if status.is_error() => { let fail = self.fail_map.entry(source).or_default(); fail.insert(response.1); } diff --git a/lychee-bin/tests/cli.rs b/lychee-bin/tests/cli.rs index 6db4e288bb..166a2234ce 100644 --- a/lychee-bin/tests/cli.rs +++ b/lychee-bin/tests/cli.rs @@ -416,7 +416,7 @@ mod cli { "✗ [404] https://github.com/mre/idiomatic-rust-doesnt-exist-man | Failed: Network error: Not Found" )) .stderr(contains( - "There were issues with Github URLs. You could try setting a Github token and running lychee again.", + "There were issues with GitHub URLs. You could try setting a GitHub token and running lychee again.", )); } diff --git a/lychee-lib/Cargo.toml b/lychee-lib/Cargo.toml index 917266c5d7..00ec685baa 100644 --- a/lychee-lib/Cargo.toml +++ b/lychee-lib/Cargo.toml @@ -13,48 +13,49 @@ version.workspace = true [dependencies] async-stream = "0.3.5" -cached = "0.46.1" +async-trait = "0.1.80" +cached = "0.49.3" check-if-email-exists = { version = "0.9.1", optional = true } email_address = "0.2.4" futures = "0.3.30" glob = "0.3.1" -headers = "0.3.8" -html5ever = "0.26.0" +headers = "0.4.0" +html5ever = "0.27.0" html5gum = "0.5.7" -http = "0.2.10" -hyper = "1.1.0" +http = "1.0.0" +hyper = "1.3.1" ip_network = "0.4.1" jwalk = "0.8.1" linkify = "0.10.0" -log = "0.4.20" -octocrab = "0.32.0" +log = "0.4.21" +octocrab = "0.38.0" once_cell = "1.19.0" -openssl-sys = { version = "0.9.98", optional = true } +openssl-sys = { version = "0.9.102", optional = true } path-clean = "1.0.1" percent-encoding = "2.3.1" -pulldown-cmark = "0.9.3" -regex = "1.10.2" +pulldown-cmark = "0.9.6" +regex = "1.10.4" # Use trust-dns to avoid lookup failures on high concurrency # https://github.com/seanmonstar/reqwest/issues/296 -reqwest = { version = "0.11.23", default-features = false, features = [ +reqwest = { version = "0.12.4", default-features = false, features = [ "gzip", "trust-dns", "cookies", ] } -reqwest_cookie_store = "0.6.0" +reqwest_cookie_store = "0.7.0" # Make build work on Apple Silicon. # See https://github.com/briansmith/ring/issues/1163 # This is necessary for the homebrew build # https://github.com/Homebrew/homebrew-core/pull/70216 -ring = "0.17.7" +ring = "0.17.8" secrecy = "0.8.0" -serde = { version = "1.0.193", features = ["derive"] } -serde_with = "3.4.0" +serde = { version = "1.0.198", features = ["derive"] } +serde_with = "3.7.0" shellexpand = "3.1.0" -thiserror = "1.0.53" -tokio = { version = "1.35.1", features = ["full"] } -toml = "0.8.8" -typed-builder = "0.18.0" +thiserror = "1.0.59" +tokio = { version = "1.37.0", features = ["full"] } +toml = "0.8.12" +typed-builder = "0.18.2" url = { version = "2.5.0", features = ["serde"] } [dependencies.par-stream] @@ -63,11 +64,11 @@ features = ["runtime-tokio"] [dev-dependencies] doc-comment = "0.3.3" -tempfile = "3.9.0" -wiremock = "0.5.22" -serde_json = "1.0.109" -rstest = "0.18.2" -toml = "0.8.8" +tempfile = "3.10.1" +wiremock = "0.6.0" +serde_json = "1.0.116" +rstest = "0.19.0" +toml = "0.8.12" [features] diff --git a/lychee-lib/src/chain/mod.rs b/lychee-lib/src/chain/mod.rs new file mode 100644 index 0000000000..c6fbc08af0 --- /dev/null +++ b/lychee-lib/src/chain/mod.rs @@ -0,0 +1,226 @@ +//! [Chain of responsibility pattern][pattern] implementation. +//! +//! lychee is based on a chain of responsibility, where each handler can modify +//! a request and decide if it should be passed to the next element or not. +//! +//! The chain is implemented as a vector of [`Handler`] handlers. It is +//! traversed by calling [`Chain::traverse`], which will call +//! [`Handler::chain`] on each handler in the chain consecutively. +//! +//! To add external handlers, you can implement the [`Handler`] trait and add +//! the handler to the chain. +//! +//! [pattern]: https://github.com/lpxxn/rust-design-pattern/blob/master/behavioral/chain_of_responsibility.rs +use crate::Status; +use async_trait::async_trait; +use core::fmt::Debug; +use std::sync::Arc; +use tokio::sync::Mutex; + +/// Result of a handler. +/// +/// This is used to decide if the chain should continue to the next handler or +/// stop and return the result: +/// +/// - If the chain should continue, the handler should return +/// [`ChainResult::Next`]. This will traverse the next handler in the chain. +/// - If the chain should stop, the handler should return [`ChainResult::Done`]. +/// All subsequent chain elements are skipped and the result is returned. +#[derive(Debug, PartialEq)] +pub enum ChainResult { + /// Continue to the next handler in the chain. + Next(T), + /// Stop the chain and return the result. + Done(R), +} + +/// Request chain type +/// +/// This takes a request and returns a status. +pub type RequestChain = Chain; + +/// Inner chain type. +/// +/// This holds all handlers, which were chained together. +/// Handlers are traversed in order. +/// +/// Each handler needs to implement the `Handler` trait and be `Send`, because +/// the chain is traversed concurrently and the handlers can be sent between +/// threads. +pub(crate) type InnerChain = Vec + Send>>; + +/// The outer chain type. +/// +/// This is a wrapper around the inner chain type and allows for +/// concurrent access to the chain. +#[derive(Debug)] +pub struct Chain(Arc>>); + +impl Default for Chain { + fn default() -> Self { + Self(Arc::new(Mutex::new(InnerChain::default()))) + } +} + +impl Clone for Chain { + fn clone(&self) -> Self { + // Cloning the chain is a cheap operation, because the inner chain is + // wrapped in an `Arc` and `Mutex`. + Self(self.0.clone()) + } +} + +impl Chain { + /// Create a new chain from a vector of chainable handlers + #[must_use] + pub fn new(values: InnerChain) -> Self { + Self(Arc::new(Mutex::new(values))) + } + + /// Traverse the chain with the given input. + /// + /// This will call `chain` on each handler in the chain and return + /// the result. If a handler returns `ChainResult::Done`, the chain + /// will stop and return. + /// + /// If no handler returns `ChainResult::Done`, the chain will return + /// `ChainResult::Next` with the input. + pub(crate) async fn traverse(&self, mut input: T) -> ChainResult { + use ChainResult::{Done, Next}; + for e in self.0.lock().await.iter_mut() { + match e.handle(input).await { + Next(r) => input = r, + Done(r) => { + return Done(r); + } + } + } + + Next(input) + } +} + +/// Handler trait for implementing request handlers +/// +/// This trait needs to be implemented by all chainable handlers. +/// It is the only requirement to handle requests in lychee. +/// +/// It takes an input request and returns a [`ChainResult`], which can be either +/// [`ChainResult::Next`] to continue to the next handler or +/// [`ChainResult::Done`] to stop the chain. +/// +/// The request can be modified by the handler before it is passed to the next +/// handler. This allows for modifying the request, such as adding headers or +/// changing the URL (e.g. for remapping or filtering). +#[async_trait] +pub trait Handler: Debug { + /// Given an input request, return a [`ChainResult`] to continue or stop the + /// chain. + /// + /// The input request can be modified by the handler before it is passed to + /// the next handler. + /// + /// # Example + /// + /// ``` + /// use lychee_lib::{Handler, ChainResult, Status}; + /// use reqwest::Request; + /// use async_trait::async_trait; + /// + /// #[derive(Debug)] + /// struct AddHeader; + /// + /// #[async_trait] + /// impl Handler for AddHeader { + /// async fn handle(&mut self, mut request: Request) -> ChainResult { + /// // You can modify the request however you like here + /// request.headers_mut().append("X-Header", "value".parse().unwrap()); + /// + /// // Pass the request to the next handler + /// ChainResult::Next(request) + /// } + /// } + /// ``` + async fn handle(&mut self, input: T) -> ChainResult; +} + +/// Client request chains +/// +/// This struct holds all request chains. +/// +/// Usually, this is used to hold the default request chain and the external +/// plugin request chain. +#[derive(Debug)] +pub(crate) struct ClientRequestChains<'a> { + chains: Vec<&'a RequestChain>, +} + +impl<'a> ClientRequestChains<'a> { + /// Create a new chain of request chains. + pub(crate) fn new(chains: Vec<&'a RequestChain>) -> Self { + Self { chains } + } + + /// Traverse all request chains and resolve to a status. + pub(crate) async fn traverse(&self, mut input: reqwest::Request) -> Status { + use ChainResult::{Done, Next}; + + for e in &self.chains { + match e.traverse(input).await { + Next(r) => input = r, + Done(r) => { + return r; + } + } + } + + // Consider the request to be excluded if no chain element has converted + // it to a `ChainResult::Done` + Status::Excluded + } +} + +mod test { + use super::{ + ChainResult, + ChainResult::{Done, Next}, + Handler, + }; + use async_trait::async_trait; + + #[allow(dead_code)] // work-around + #[derive(Debug)] + struct Add(usize); + + #[derive(Debug, PartialEq, Eq)] + struct Result(usize); + + #[async_trait] + impl Handler for Add { + async fn handle(&mut self, req: Result) -> ChainResult { + let added = req.0 + self.0; + if added > 100 { + Done(Result(req.0)) + } else { + Next(Result(added)) + } + } + } + + #[tokio::test] + async fn simple_chain() { + use super::Chain; + let chain: Chain = Chain::new(vec![Box::new(Add(7)), Box::new(Add(3))]); + let result = chain.traverse(Result(0)).await; + assert_eq!(result, Next(Result(10))); + } + + #[tokio::test] + async fn early_exit_chain() { + use super::Chain; + let chain: Chain = + Chain::new(vec![Box::new(Add(80)), Box::new(Add(30)), Box::new(Add(1))]); + let result = chain.traverse(Result(0)).await; + assert_eq!(result, Done(Result(80))); + } +} diff --git a/lychee-lib/src/checker.rs b/lychee-lib/src/checker.rs new file mode 100644 index 0000000000..428551ad2b --- /dev/null +++ b/lychee-lib/src/checker.rs @@ -0,0 +1,80 @@ +use crate::{ + chain::{ChainResult, Handler}, + retry::RetryExt, + Status, +}; +use async_trait::async_trait; +use http::StatusCode; +use reqwest::Request; +use std::{collections::HashSet, time::Duration}; + +#[derive(Debug, Clone)] +pub(crate) struct Checker { + retry_wait_time: Duration, + max_retries: u64, + reqwest_client: reqwest::Client, + accepted: Option>, +} + +impl Checker { + pub(crate) const fn new( + retry_wait_time: Duration, + max_retries: u64, + reqwest_client: reqwest::Client, + accepted: Option>, + ) -> Self { + Self { + retry_wait_time, + max_retries, + reqwest_client, + accepted, + } + } + + /// Retry requests up to `max_retries` times + /// with an exponential backoff. + pub(crate) async fn retry_request(&self, request: Request) -> Status { + let mut retries: u64 = 0; + let mut wait_time = self.retry_wait_time; + + let mut status = self.check_default(clone_unwrap(&request)).await; + while retries < self.max_retries { + if status.is_success() || !status.should_retry() { + return status; + } + retries += 1; + tokio::time::sleep(wait_time).await; + wait_time = wait_time.saturating_mul(2); + status = self.check_default(clone_unwrap(&request)).await; + } + status + } + + /// Check a URI using [reqwest](https://github.com/seanmonstar/reqwest). + async fn check_default(&self, request: Request) -> Status { + match self.reqwest_client.execute(request).await { + Ok(ref response) => Status::new(response, self.accepted.clone()), + Err(e) => e.into(), + } + } +} + +/// Clones a `reqwest::Request`. +/// +/// # Safety +/// +/// This panics if the request cannot be cloned. This should only happen if the +/// request body is a `reqwest` stream. We disable the `stream` feature, so the +/// body should never be a stream. +/// +/// See +fn clone_unwrap(request: &Request) -> Request { + request.try_clone().expect("Failed to clone request: body was a stream, which should be impossible with `stream` feature disabled") +} + +#[async_trait] +impl Handler for Checker { + async fn handle(&mut self, input: Request) -> ChainResult { + ChainResult::Done(self.retry_request(input).await) + } +} diff --git a/lychee-lib/src/client.rs b/lychee-lib/src/client.rs index 801d4e9891..3369abf0b5 100644 --- a/lychee-lib/src/client.rs +++ b/lychee-lib/src/client.rs @@ -17,9 +17,8 @@ use std::{collections::HashSet, path::Path, sync::Arc, time::Duration}; #[cfg(all(feature = "email-check", feature = "native-tls"))] use check_if_email_exists::{check_email, CheckEmailInput, Reachable}; -use headers::authorization::Credentials; use http::{ - header::{HeaderMap, HeaderValue, AUTHORIZATION}, + header::{HeaderMap, HeaderValue}, StatusCode, }; use log::{debug, warn}; @@ -31,13 +30,14 @@ use secrecy::{ExposeSecret, SecretString}; use typed_builder::TypedBuilder; use crate::{ + chain::{Chain, ClientRequestChains, RequestChain}, + checker::Checker, filter::{Excludes, Filter, Includes}, quirks::Quirks, remap::Remaps, - retry::RetryExt, types::uri::github::GithubUri, utils::fragment_checker::FragmentChecker, - BasicAuthCredentials, ErrorKind, Request, Response, Result, Status, Uri, + ErrorKind, Request, Response, Result, Status, Uri, }; #[cfg(all(feature = "email-check", feature = "native-tls"))] @@ -269,11 +269,17 @@ pub struct ClientBuilder { /// Cookie store used for requests. /// - /// See https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html#method.cookie_store + /// See cookie_jar: Option>, /// Enable the checking of fragments in links. include_fragments: bool, + + /// Requests run through this chain where each item in the chain + /// can modify the request. A chained item can also decide to exit + /// early and return a status, so that subsequent chain items are + /// skipped and the lychee-internal request chain is not activated. + plugin_request_chain: RequestChain, } impl Default for ClientBuilder { @@ -294,7 +300,7 @@ impl ClientBuilder { /// - The reqwest client cannot be instantiated. This occurs if a TLS /// backend cannot be initialized or the resolver fails to load the system /// configuration. See [here]. - /// - The Github client cannot be created. Since the implementation also + /// - The GitHub client cannot be created. Since the implementation also /// uses reqwest under the hood, this errors in the same circumstances as /// the last one. /// @@ -374,8 +380,6 @@ impl ClientBuilder { include_mail: self.include_mail, }; - let quirks = Quirks::default(); - Ok(Client { reqwest_client, github_client, @@ -386,9 +390,9 @@ impl ClientBuilder { method: self.method, accepted: self.accepted, require_https: self.require_https, - quirks, include_fragments: self.include_fragments, fragment_checker: FragmentChecker::new(), + plugin_request_chain: self.plugin_request_chain, }) } } @@ -433,14 +437,13 @@ pub struct Client { /// This would treat unencrypted links as errors when HTTPS is available. require_https: bool, - /// Override behaviors for certain known issues with special URIs. - quirks: Quirks, - /// Enable the checking of fragments in links. include_fragments: bool, /// Caches Fragments fragment_checker: FragmentChecker, + + plugin_request_chain: RequestChain, } impl Client { @@ -463,7 +466,7 @@ impl Client { { let Request { ref mut uri, - ref credentials, + credentials, source, .. } = request.try_into()?; @@ -483,10 +486,22 @@ impl Client { return Ok(Response::new(uri.clone(), Status::Excluded, source)); } + let default_chain: RequestChain = Chain::new(vec![ + Box::::default(), + Box::new(credentials), + Box::new(Checker::new( + self.retry_wait_time, + self.max_retries, + self.reqwest_client.clone(), + self.accepted.clone(), + )), + ]); + let status = match uri.scheme() { _ if uri.is_file() => self.check_file(uri).await, _ if uri.is_mail() => self.check_mail(uri).await, - _ => self.check_website(uri, credentials).await?, + _ if uri.is_tel() => self.check_tel(uri).await, + _ => self.check_website(uri, default_chain).await?, }; Ok(Response::new(uri.clone(), status, source)) @@ -519,15 +534,11 @@ impl Client { /// - The request failed. /// - The response status code is not accepted. /// - The URI cannot be converted to HTTPS. - pub async fn check_website( - &self, - uri: &Uri, - credentials: &Option, - ) -> Result { - match self.check_website_inner(uri, credentials).await { + pub async fn check_website(&self, uri: &Uri, default_chain: RequestChain) -> Result { + match self.check_website_inner(uri, &default_chain).await { Status::Ok(code) if self.require_https && uri.scheme() == "http" => { if self - .check_website_inner(&uri.to_https()?, credentials) + .check_website_inner(&uri.to_https()?, &default_chain) .await .is_success() { @@ -552,11 +563,7 @@ impl Client { /// - The URI is invalid. /// - The request failed. /// - The response status code is not accepted. - pub async fn check_website_inner( - &self, - uri: &Uri, - credentials: &Option, - ) -> Status { + pub async fn check_website_inner(&self, uri: &Uri, default_chain: &RequestChain) -> Status { // Workaround for upstream reqwest panic if validate_url(&uri.url) { if matches!(uri.scheme(), "http" | "https") { @@ -571,17 +578,34 @@ impl Client { return Status::Unsupported(ErrorKind::InvalidURI(uri.clone())); } - let status = self.retry_request(uri, credentials).await; + let request = self + .reqwest_client + .request(self.method.clone(), uri.as_str()) + .build(); + + let request = match request { + Ok(r) => r, + Err(e) => return e.into(), + }; + + let status = ClientRequestChains::new(vec![&self.plugin_request_chain, default_chain]) + .traverse(request) + .await; + + self.handle_github(status, uri).await + } + + // Pull out the heavy machinery in case of a failed normal request. + // This could be a GitHub URL and we ran into the rate limiter. + // TODO: We should first try to parse the URI as GitHub URI first (Lucius, Jan 2023) + async fn handle_github(&self, status: Status, uri: &Uri) -> Status { if status.is_success() { return status; } - // Pull out the heavy machinery in case of a failed normal request. - // This could be a GitHub URL and we ran into the rate limiter. - // TODO: We should first try to parse the URI as GitHub URI first (Lucius, Jan 2023) if let Ok(github_uri) = GithubUri::try_from(uri) { let status = self.check_github(github_uri).await; - // Only return Github status in case of success + // Only return GitHub status in case of success // Otherwise return the original error, which has more information if status.is_success() { return status; @@ -591,25 +615,6 @@ impl Client { status } - /// Retry requests up to `max_retries` times - /// with an exponential backoff. - async fn retry_request(&self, uri: &Uri, credentials: &Option) -> Status { - let mut retries: u64 = 0; - let mut wait_time = self.retry_wait_time; - - let mut status = self.check_default(uri, credentials).await; - while retries < self.max_retries { - if status.is_success() || !status.should_retry() { - return status; - } - retries += 1; - tokio::time::sleep(wait_time).await; - wait_time = wait_time.saturating_mul(2); - status = self.check_default(uri, credentials).await; - } - status - } - /// Check a `uri` hosted on `GitHub` via the GitHub API. /// /// # Caveats @@ -645,33 +650,6 @@ impl Client { Status::Ok(StatusCode::OK) } - /// Check a URI using [reqwest](https://github.com/seanmonstar/reqwest). - async fn check_default(&self, uri: &Uri, credentials: &Option) -> Status { - let request = match credentials { - Some(credentials) => self - .reqwest_client - .request(self.method.clone(), uri.as_str()) - .header(AUTHORIZATION, credentials.to_authorization().0.encode()) - .build(), - None => self - .reqwest_client - .request(self.method.clone(), uri.as_str()) - .build(), - }; - - let request = match request { - Ok(r) => r, - Err(e) => return e.into(), - }; - - let request = self.quirks.apply(request); - - match self.reqwest_client.execute(request).await { - Ok(ref response) => Status::new(response, self.accepted.clone()), - Err(e) => e.into(), - } - } - /// Check a `file` URI. pub async fn check_file(&self, uri: &Uri) -> Status { let Ok(path) = uri.url.to_file_path() else { @@ -725,6 +703,14 @@ impl Client { pub async fn check_mail(&self, _uri: &Uri) -> Status { Status::Excluded } + + /// Check a tel + /// + /// This implementation simply excludes all tel. + #[allow(clippy::unused_async)] + pub async fn check_tel(&self, _uri: &Uri) -> Status { + Status::Excluded + } } // Check if the given `Url` would cause `reqwest` to panic. @@ -765,26 +751,32 @@ mod tests { time::{Duration, Instant}, }; + use async_trait::async_trait; use http::{header::HeaderMap, StatusCode}; use reqwest::header; use tempfile::tempdir; use wiremock::matchers::path; use super::ClientBuilder; - use crate::{mock_server, test_utils::get_mock_client_response, Uri}; + use crate::{ + chain::{ChainResult, Handler, RequestChain}, + mock_server, + test_utils::get_mock_client_response, + Request, Status, Uri, + }; #[tokio::test] async fn test_nonexistent() { let mock_server = mock_server!(StatusCode::NOT_FOUND); let res = get_mock_client_response(mock_server.uri()).await; - assert!(res.status().is_failure()); + assert!(res.status().is_error()); } #[tokio::test] async fn test_nonexistent_with_path() { let res = get_mock_client_response("http://127.0.0.1/invalid").await; - assert!(res.status().is_failure()); + assert!(res.status().is_error()); } #[tokio::test] @@ -796,7 +788,7 @@ mod tests { #[tokio::test] async fn test_github_nonexistent_repo() { let res = get_mock_client_response("https://github.com/lycheeverse/not-lychee").await; - assert!(res.status().is_failure()); + assert!(res.status().is_error()); } #[tokio::test] @@ -805,7 +797,7 @@ mod tests { "https://github.com/lycheeverse/lychee/blob/master/NON_EXISTENT_FILE.md", ) .await; - assert!(res.status().is_failure()); + assert!(res.status().is_error()); } #[tokio::test] @@ -815,7 +807,25 @@ mod tests { assert!(res.status().is_success()); let res = get_mock_client_response("https://www.youtube.com/watch?v=invalidNlKuICiT470&list=PLbWDhxwM_45mPVToqaIZNbZeIzFchsKKQ&index=7").await; - assert!(res.status().is_failure()); + assert!(res.status().is_error()); + } + + #[tokio::test] + async fn test_basic_auth() { + let mut r: Request = "https://authenticationtest.com/HTTPAuth/" + .try_into() + .unwrap(); + + let res = get_mock_client_response(r.clone()).await; + assert_eq!(res.status().code(), Some(401.try_into().unwrap())); + + r.credentials = Some(crate::BasicAuthCredentials { + username: "user".into(), + password: "pass".into(), + }); + + let res = get_mock_client_response(r).await; + assert!(res.status().is_success()); } #[tokio::test] @@ -830,7 +840,7 @@ mod tests { async fn test_invalid_ssl() { let res = get_mock_client_response("https://expired.badssl.com/").await; - assert!(res.status().is_failure()); + assert!(res.status().is_error()); // Same, but ignore certificate error let res = ClientBuilder::builder() @@ -906,6 +916,14 @@ mod tests { })); } + #[tokio::test] + async fn test_include_tel() { + let client = ClientBuilder::builder().build().client().unwrap(); + assert!(client.is_excluded(&Uri { + url: "tel:1234567890".try_into().unwrap() + })); + } + #[tokio::test] async fn test_require_https() { let client = ClientBuilder::builder().build().client().unwrap(); @@ -919,7 +937,7 @@ mod tests { .client() .unwrap(); let res = client.check("http://example.com").await.unwrap(); - assert!(res.status().is_failure()); + assert!(res.status().is_error()); } #[tokio::test] @@ -983,7 +1001,7 @@ mod tests { let res = client.check(mock_server.uri()).await.unwrap(); let end = start.elapsed(); - assert!(res.status().is_failure()); + assert!(res.status().is_error()); // on slow connections, this might take a bit longer than nominal // backed-off timeout (7 secs) @@ -995,7 +1013,7 @@ mod tests { let client = ClientBuilder::builder().build().client().unwrap(); // This request will fail, but it won't panic let res = client.check("http://\"").await.unwrap(); - assert!(res.status().is_failure()); + assert!(res.status().is_error()); } #[tokio::test] @@ -1028,7 +1046,7 @@ mod tests { .unwrap(); let res = client.check(redirect_uri.clone()).await.unwrap(); - assert!(res.status().is_failure()); + assert!(res.status().is_error()); let client = ClientBuilder::builder() .max_redirects(1_usize) @@ -1059,7 +1077,7 @@ mod tests { .unwrap(); let res = client.check(mock_server.uri()).await.unwrap(); - assert!(res.status().is_failure()); + assert!(res.status().is_error()); } #[tokio::test] @@ -1076,4 +1094,31 @@ mod tests { assert!(res.status().is_unsupported()); } } + + #[tokio::test] + async fn test_chain() { + use reqwest::Request; + + #[derive(Debug)] + struct ExampleHandler(); + + #[async_trait] + impl Handler for ExampleHandler { + async fn handle(&mut self, _: Request) -> ChainResult { + ChainResult::Done(Status::Excluded) + } + } + + let chain = RequestChain::new(vec![Box::new(ExampleHandler {})]); + + let client = ClientBuilder::builder() + .plugin_request_chain(chain) + .build() + .client() + .unwrap(); + + let result = client.check("http://example.com"); + let res = result.await.unwrap(); + assert_eq!(res.status(), &Status::Excluded); + } } diff --git a/lychee-lib/src/collector.rs b/lychee-lib/src/collector.rs index 821b3593d7..ed048abc9e 100644 --- a/lychee-lib/src/collector.rs +++ b/lychee-lib/src/collector.rs @@ -351,7 +351,7 @@ mod tests { async fn test_relative_url_with_base_extracted_from_input() { let contents = r#" "#; diff --git a/lychee-lib/src/extract/html/html5ever.rs b/lychee-lib/src/extract/html/html5ever.rs index 25ed226aa2..1ee03b836f 100644 --- a/lychee-lib/src/extract/html/html5ever.rs +++ b/lychee-lib/src/extract/html/html5ever.rs @@ -89,9 +89,10 @@ impl TokenSink for LinkExtractor { // This ignores links like `` let is_email = is_email_link(url); let is_mailto = url.starts_with("mailto:"); + let is_phone = url.starts_with("tel:"); let is_href = attr.name.local.as_ref() == "href"; - !is_email || (is_mailto && is_href) + !is_email || (is_mailto && is_href) || (is_phone && is_href) }) .map(|url| RawUri { text: url.to_string(), @@ -124,7 +125,7 @@ impl LinkExtractor { } } - /// Extract all semantically known links from a given html attribute. + /// Extract all semantically known links from a given HTML attribute. #[allow(clippy::unnested_or_patterns)] pub(crate) fn extract_urls_from_elem_attr<'a>( attr_name: &str, @@ -166,7 +167,7 @@ impl LinkExtractor { /// Extract unparsed URL strings from an HTML string. pub(crate) fn extract_html(buf: &str, include_verbatim: bool) -> Vec { - let mut input = BufferQueue::new(); + let mut input = BufferQueue::default(); input.push_back(StrTendril::from(buf)); let mut tokenizer = Tokenizer::new( @@ -267,9 +268,9 @@ mod tests { #[test] fn test_include_nofollow() { let input = r#" - do not follow me - do not follow me - do not follow me + do not follow me + do not follow me + do not follow me "#; let expected = vec![RawUri { text: "https://example.org".to_string(), @@ -286,7 +287,7 @@ mod tests { - i'm fine + i'm fine "#; let expected = vec![RawUri { text: "https://example.org".to_string(), @@ -318,6 +319,29 @@ mod tests { let uris = extract_html(input, false); assert_eq!(uris, expected); } + + #[test] + fn test_valid_tel() { + let input = r#" + + + + Test + + + + + "#; + + let expected = vec![RawUri { + text: "tel:1234567890".to_string(), + element: Some("a".to_string()), + attribute: Some("href".to_string()), + }]; + let uris = extract_html(input, false); + assert_eq!(uris, expected); + } + #[test] fn test_exclude_email_without_mailto() { let input = r#" diff --git a/lychee-lib/src/extract/html/html5gum.rs b/lychee-lib/src/extract/html/html5gum.rs index 9555beeb54..cf9d88f489 100644 --- a/lychee-lib/src/extract/html/html5gum.rs +++ b/lychee-lib/src/extract/html/html5gum.rs @@ -45,7 +45,7 @@ impl LinkExtractor { } } - /// Extract all semantically known links from a given html attribute. + /// Extract all semantically known links from a given HTML attribute. #[allow(clippy::unnested_or_patterns)] pub(crate) fn extract_urls_from_elem_attr<'a>( attr_name: &str, @@ -172,9 +172,10 @@ impl LinkExtractor { // This ignores links like `` let is_email = is_email_link(url); let is_mailto = url.starts_with("mailto:"); + let is_phone = url.starts_with("tel:"); let is_href = attr == "href"; - !is_email || (is_mailto && is_href) + !is_email || (is_mailto && is_href) || (is_phone && is_href) }) .map(|url| RawUri { text: url.to_string(), @@ -453,6 +454,28 @@ mod tests { assert_eq!(uris, expected); } + #[test] + fn test_valid_tel() { + let input = r#" + + + + Test + + + + + "#; + + let expected = vec![RawUri { + text: "tel:1234567890".to_string(), + element: Some("a".to_string()), + attribute: Some("href".to_string()), + }]; + let uris = extract_html(input, false); + assert_eq!(uris, expected); + } + #[test] fn test_valid_email() { let input = r#" diff --git a/lychee-lib/src/extract/html/mod.rs b/lychee-lib/src/extract/html/mod.rs index ef02c06fc4..b990acfda4 100644 --- a/lychee-lib/src/extract/html/mod.rs +++ b/lychee-lib/src/extract/html/mod.rs @@ -1,4 +1,4 @@ -//! Extract links and fragments from html documents +//! Extract links and fragments from HTML documents pub(crate) mod html5ever; pub(crate) mod html5gum; mod srcset; diff --git a/lychee-lib/src/extract/mod.rs b/lychee-lib/src/extract/mod.rs index 39d15cf8db..e0c0ee44bb 100644 --- a/lychee-lib/src/extract/mod.rs +++ b/lychee-lib/src/extract/mod.rs @@ -190,7 +190,7 @@ mod tests { let contents = r#" "#; diff --git a/lychee-lib/src/filter/mod.rs b/lychee-lib/src/filter/mod.rs index f970cf299f..a6cda08656 100644 --- a/lychee-lib/src/filter/mod.rs +++ b/lychee-lib/src/filter/mod.rs @@ -124,7 +124,7 @@ pub struct Filter { /// Example: 169.254.0.0 pub exclude_link_local_ips: bool, /// For IPv4: 127.0.0.1/8 - /// For IPv6: ::1/128 + /// For IPv6: `::1/128` pub exclude_loopback_ips: bool, /// Example: octocat@github.com pub include_mail: bool, @@ -214,6 +214,7 @@ impl Filter { || self.is_host_excluded(uri) || self.is_ip_excluded(uri) || self.is_mail_excluded(uri) + || uri.is_tel() || is_example_domain(uri) || is_unsupported_domain(uri) { diff --git a/lychee-lib/src/lib.rs b/lychee-lib/src/lib.rs index ef8415e179..bc970c7f9a 100644 --- a/lychee-lib/src/lib.rs +++ b/lychee-lib/src/lib.rs @@ -51,6 +51,8 @@ doc_comment::doctest!("../../README.md"); mod basic_auth; +pub mod chain; +mod checker; mod client; /// A pool of clients, to handle concurrent checks pub mod collector; @@ -83,6 +85,8 @@ use openssl_sys as _; // required for vendored-openssl feature #[doc(inline)] pub use crate::{ basic_auth::BasicAuthExtractor, + // Expose the `Handler` trait to allow defining external handlers (plugins) + chain::{ChainResult, Handler}, // Constants get exposed so that the CLI can use the same defaults as the library client::{ check, Client, ClientBuilder, DEFAULT_MAX_REDIRECTS, DEFAULT_MAX_RETRIES, diff --git a/lychee-lib/src/quirks/mod.rs b/lychee-lib/src/quirks/mod.rs index 7f30cba854..39af65173c 100644 --- a/lychee-lib/src/quirks/mod.rs +++ b/lychee-lib/src/quirks/mod.rs @@ -1,3 +1,8 @@ +use crate::{ + chain::{ChainResult, Handler}, + Status, +}; +use async_trait::async_trait; use header::HeaderValue; use http::header; use once_cell::sync::Lazy; @@ -86,6 +91,13 @@ impl Quirks { } } +#[async_trait] +impl Handler for Quirks { + async fn handle(&mut self, input: Request) -> ChainResult { + ChainResult::Next(self.apply(input)) + } +} + #[cfg(test)] mod tests { use header::HeaderValue; diff --git a/lychee-lib/src/retry.rs b/lychee-lib/src/retry.rs index 0eed204f20..cff2eaa487 100644 --- a/lychee-lib/src/retry.rs +++ b/lychee-lib/src/retry.rs @@ -95,7 +95,7 @@ impl RetryExt for ErrorKind { // If the error is a `reqwest::Error`, delegate to that if let Some(r) = self.reqwest_error() { r.should_retry() - // Github errors sometimes wrap `reqwest` errors. + // GitHub errors sometimes wrap `reqwest` errors. // In that case, delegate to the underlying error. } else if let Some(octocrab::Error::Http { source, diff --git a/lychee-lib/src/types/basic_auth/credentials.rs b/lychee-lib/src/types/basic_auth/credentials.rs index 2452fb973b..1af0144c02 100644 --- a/lychee-lib/src/types/basic_auth/credentials.rs +++ b/lychee-lib/src/types/basic_auth/credentials.rs @@ -1,9 +1,16 @@ +use async_trait::async_trait; use std::str::FromStr; +use headers::authorization::Credentials; use headers::{authorization::Basic, Authorization}; +use http::header::AUTHORIZATION; +use reqwest::Request; use serde::Deserialize; use thiserror::Error; +use crate::chain::{ChainResult, Handler}; +use crate::Status; + #[derive(Copy, Clone, Debug, Error, PartialEq)] pub enum BasicAuthCredentialsParseError { #[error("Invalid basic auth credentials syntax")] @@ -66,3 +73,16 @@ impl BasicAuthCredentials { Authorization::basic(&self.username, &self.password) } } + +#[async_trait] +impl Handler for Option { + async fn handle(&mut self, mut request: Request) -> ChainResult { + if let Some(credentials) = self { + request + .headers_mut() + .append(AUTHORIZATION, credentials.to_authorization().0.encode()); + } + + ChainResult::Next(request) + } +} diff --git a/lychee-lib/src/types/error.rs b/lychee-lib/src/types/error.rs index 19bb50c96a..e8f9b426c5 100644 --- a/lychee-lib/src/types/error.rs +++ b/lychee-lib/src/types/error.rs @@ -24,7 +24,7 @@ pub enum ErrorKind { #[error("Error creating request client: {0}")] BuildRequestClient(#[source] reqwest::Error), - /// Network error while using Github API + /// Network error while using GitHub API #[error("Network error (GitHub client)")] GithubRequest(#[from] octocrab::Error), @@ -44,12 +44,12 @@ pub enum ErrorKind { #[error("Attempted to interpret an invalid sequence of bytes as a string")] Utf8(#[from] std::str::Utf8Error), - /// The Github client required for making requests cannot be created - #[error("Error creating Github client")] + /// The GitHub client required for making requests cannot be created + #[error("Error creating GitHub client")] BuildGithubClient(#[source] octocrab::Error), - /// Invalid Github URL - #[error("Github URL is invalid: {0}")] + /// Invalid GitHub URL + #[error("GitHub URL is invalid: {0}")] InvalidGithubUrl(String), /// The input is empty and not accepted as a valid URL @@ -102,7 +102,7 @@ pub enum ErrorKind { #[error("UNIX glob pattern is invalid")] InvalidGlobPattern(#[from] glob::PatternError), - /// The Github API could not be called because of a missing Github token. + /// The GitHub API could not be called because of a missing GitHub token. #[error("GitHub token not specified. To check GitHub links reliably, use `--github-token` flag / `GITHUB_TOKEN` env var.")] MissingGitHubToken, diff --git a/lychee-lib/src/types/status.rs b/lychee-lib/src/types/status.rs index a4a9a01fb5..b2ee128c77 100644 --- a/lychee-lib/src/types/status.rs +++ b/lychee-lib/src/types/status.rs @@ -36,7 +36,7 @@ pub enum Status { Excluded, /// The request type is currently not supported, /// for example when the URL scheme is `slack://`. - /// See https://github.com/lycheeverse/lychee/issues/199 + /// See Unsupported(ErrorKind), /// Cached request status from previous run Cached(CacheStatus), @@ -160,7 +160,7 @@ impl Status { #[inline] #[must_use] /// Returns `true` if the check was not successful - pub const fn is_failure(&self) -> bool { + pub const fn is_error(&self) -> bool { matches!( self, Status::Error(_) | Status::Cached(CacheStatus::Error(_)) | Status::Timeout(_) diff --git a/lychee-lib/src/types/uri/github.rs b/lychee-lib/src/types/uri/github.rs index 68ba3d97b3..514f2e0e76 100644 --- a/lychee-lib/src/types/uri/github.rs +++ b/lychee-lib/src/types/uri/github.rs @@ -23,7 +23,7 @@ static GITHUB_API_EXCLUDED_ENDPOINTS: Lazy> = Lazy::new(|| ]) }); -/// Uri path segments extracted from a Github URL +/// Uri path segments extracted from a GitHub URL #[derive(PartialEq, Eq, PartialOrd, Ord, Debug)] pub struct GithubUri { /// Organization name @@ -35,7 +35,7 @@ pub struct GithubUri { } impl GithubUri { - /// Create a new Github URI without an endpoint + /// Create a new GitHub URI without an endpoint #[cfg(test)] fn new>(owner: T, repo: T) -> Self { GithubUri { @@ -83,7 +83,7 @@ impl GithubUri { if parts.len() < 2 { // Not a valid org/repo pair. - // Note: We don't check for exactly 2 here, because the Github + // Note: We don't check for exactly 2 here, because the GitHub // API doesn't handle checking individual files inside repos or // paths like , so we are more // permissive and only check for repo existence. This is the diff --git a/lychee-lib/src/types/uri/valid.rs b/lychee-lib/src/types/uri/valid.rs index 87954b4e7a..9e9bb72a72 100644 --- a/lychee-lib/src/types/uri/valid.rs +++ b/lychee-lib/src/types/uri/valid.rs @@ -96,6 +96,13 @@ impl Uri { self.scheme() == "mailto" } + #[inline] + #[must_use] + /// Check if the URI is a tel + pub fn is_tel(&self) -> bool { + self.scheme() == "tel" + } + #[inline] #[must_use] /// Check if the URI is a file @@ -325,6 +332,14 @@ mod tests { ); } + #[test] + fn test_uri_tel() { + assert_eq!( + Uri::try_from("tel:1234567890"), + Ok(Uri::try_from("tel:1234567890").unwrap()) + ); + } + #[test] fn test_uri_host_ip_v4() { assert_eq!(