diff --git a/Cargo.lock b/Cargo.lock index 29311fd..13ead53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -159,7 +159,6 @@ dependencies = [ "prometheus 0.14.0", "rand 0.10.2", "rcgen", - "reqwest", "rustls-pemfile", "sd-notify", "serde", @@ -169,7 +168,7 @@ dependencies = [ "subtle", "tokio", "tokio-native-tls", - "tower-http 0.7.0", + "tower-http", "urlencoding", "x509-parser", ] @@ -615,16 +614,6 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation" version = "0.10.1" @@ -1037,15 +1026,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -1255,10 +1235,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", ] [[package]] @@ -1280,11 +1258,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", - "js-sys", "libc", "r-efi 6.0.0", "rand_core 0.10.1", - "wasm-bindgen", ] [[package]] @@ -1520,23 +1496,18 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ - "base64 0.22.1", "bytes", "futures-channel", "futures-util", "http", "http-body", "hyper", - "ipnet", "libc", - "percent-encoding", "pin-project-lite", "socket2", - "system-configuration", "tokio", "tower-service", "tracing", - "windows-registry", ] [[package]] @@ -1563,115 +1534,12 @@ dependencies = [ "cc", ] -[[package]] -name = "icu_collections" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" -dependencies = [ - "displaydoc", - "potential_utf", - "utf8_iter", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" - -[[package]] -name = "icu_properties" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" - -[[package]] -name = "icu_provider" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - [[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - [[package]] name = "indexmap" version = "1.9.3" @@ -1740,12 +1608,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "ipnet" -version = "2.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a756c3fac73139e83f14c2d742155dd2b78d3ee56597b419a0579b7bdd6dd78" - [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -1918,12 +1780,6 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" -[[package]] -name = "litemap" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" - [[package]] name = "local-ip-address" version = "0.6.13" @@ -1998,12 +1854,6 @@ dependencies = [ "hashbrown 0.16.1", ] -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - [[package]] name = "matchit" version = "0.8.4" @@ -2789,15 +2639,6 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" -[[package]] -name = "potential_utf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" -dependencies = [ - "zerovec", -] - [[package]] name = "powerfmt" version = "0.2.0" @@ -2897,63 +2738,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "quinn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" -dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash", - "rustls", - "socket2", - "thiserror 2.0.18", - "tokio", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-proto" -version = "0.11.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560" -dependencies = [ - "aws-lc-rs", - "bytes", - "getrandom 0.4.3", - "lru-slab", - "rand 0.10.2", - "rand_pcg", - "ring", - "rustc-hash", - "rustls", - "rustls-pki-types", - "slab", - "thiserror 2.0.18", - "tinyvec", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-udp" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" -dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.61.2", -] - [[package]] name = "quote" version = "1.0.46" @@ -3051,15 +2835,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" -[[package]] -name = "rand_pcg" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" -dependencies = [ - "rand_core 0.10.1", -] - [[package]] name = "rcgen" version = "0.14.8" @@ -3113,50 +2888,6 @@ version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" -[[package]] -name = "reqwest" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" -dependencies = [ - "base64 0.22.1", - "bytes", - "encoding_rs", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "js-sys", - "log", - "mime", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-pki-types", - "rustls-platform-verifier", - "serde", - "serde_json", - "sync_wrapper", - "tokio", - "tokio-rustls", - "tokio-util", - "tower", - "tower-http 0.6.11", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", -] - [[package]] name = "rfc6979" version = "0.4.0" @@ -3314,7 +3045,6 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" dependencies = [ - "web-time", "zeroize", ] @@ -3324,7 +3054,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" dependencies = [ - "core-foundation 0.10.1", + "core-foundation", "core-foundation-sys", "jni", "log", @@ -3423,7 +3153,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ "bitflags 2.13.0", - "core-foundation 0.10.1", + "core-foundation", "core-foundation-sys", "libc", "security-framework-sys", @@ -3685,12 +3415,6 @@ dependencies = [ "der", ] -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - [[package]] name = "strsim" version = "0.11.1" @@ -3763,9 +3487,6 @@ name = "sync_wrapper" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] [[package]] name = "synstructure" @@ -3778,27 +3499,6 @@ dependencies = [ "syn 2.0.118", ] -[[package]] -name = "system-configuration" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" -dependencies = [ - "bitflags 2.13.0", - "core-foundation 0.9.4", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tagptr" version = "0.2.0" @@ -3917,31 +3617,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tinystr" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tinyvec" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "tokio" version = "1.53.1" @@ -4052,24 +3727,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "tower-http" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" -dependencies = [ - "bitflags 2.13.0", - "bytes", - "futures-util", - "http", - "http-body", - "pin-project-lite", - "tower", - "tower-layer", - "tower-service", - "url", -] - [[package]] name = "tower-http" version = "0.7.0" @@ -4218,30 +3875,12 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" -[[package]] -name = "url" -version = "2.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - [[package]] name = "urlencoding" version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - [[package]] name = "utf8parse" version = "0.2.2" @@ -4318,16 +3957,6 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "wasm-bindgen-macro" version = "0.2.126" @@ -4360,39 +3989,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-streams" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" -dependencies = [ - "futures-util", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "web-sys" -version = "0.3.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "webpki-root-certs" version = "1.0.8" @@ -4474,17 +4070,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" -[[package]] -name = "windows-registry" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" -dependencies = [ - "windows-link", - "windows-result", - "windows-strings", -] - [[package]] name = "windows-result" version = "0.4.1" @@ -4600,12 +4185,6 @@ version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" -[[package]] -name = "writeable" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" - [[package]] name = "x509-parser" version = "0.18.1" @@ -4641,29 +4220,6 @@ dependencies = [ "time", ] -[[package]] -name = "yoke" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", - "synstructure", -] - [[package]] name = "zerocopy" version = "0.8.54" @@ -4684,27 +4240,6 @@ dependencies = [ "syn 2.0.118", ] -[[package]] -name = "zerofrom" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", - "synstructure", -] - [[package]] name = "zeroize" version = "1.9.0" @@ -4725,39 +4260,6 @@ dependencies = [ "syn 2.0.118", ] -[[package]] -name = "zerotrie" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", -] - [[package]] name = "zmij" version = "1.0.21" diff --git a/Cargo.toml b/Cargo.toml index 60c12a7..693ab97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,6 @@ async-trait = "0.1.91" log = "0.4.33" notify = "9.0.0-rc.4" axum = { version = "0.8.9" } -reqwest = { version = "0.13.4", features = ["json", "stream", "blocking"] } serde = { version = "1.0.229", features = ["derive"] } noyalib = { version = "0.0.18", features = ["compat-serde-yaml"] } rand = "0.10.2" diff --git a/src/utils/hcclient.rs b/src/utils/hcclient.rs index 98ccaef..4d5a4d8 100644 --- a/src/utils/hcclient.rs +++ b/src/utils/hcclient.rs @@ -5,6 +5,7 @@ use pingora_core::listeners::ALPN; use pingora_core::prelude::HttpPeer; use pingora_http::RequestHeader; use std::sync::LazyLock; +use std::time::Duration; pub static HC_CONNECTOR: LazyLock = LazyLock::new(|| Connector::new(None)); @@ -24,6 +25,7 @@ pub async fn httpclient(method: &str, tls: bool, host: &str, path: &str, address } let mut is_h2 = false; + peer.options.total_connection_timeout = Option::from(Duration::from_secs(5)); peer.options.alpn = ALPN::H2H1; let (mut http_session, _) = match HC_CONNECTOR.get_http_session(&peer).await { Ok(s) => s, diff --git a/src/utils/httpclient.rs b/src/utils/httpclient.rs index af8c3d8..26f2623 100644 --- a/src/utils/httpclient.rs +++ b/src/utils/httpclient.rs @@ -1,85 +1,166 @@ use crate::utils::kuberconsul::{match_path, ConsulService, KubeEndpoints}; use crate::utils::structs::{GlobalServiceMapping, InnerMap}; -use axum::http::{HeaderMap, HeaderValue}; use dashmap::DashMap; -use reqwest::Client; +use pingora_core::connectors::http::Connector; +use pingora_core::listeners::ALPN; +use pingora_core::prelude::HttpPeer; +use pingora_http::RequestHeader; use std::sync::atomic::AtomicUsize; -use std::sync::Arc; +use std::sync::{Arc, LazyLock}; use std::time::Duration; -pub async fn for_consul(url: String, token: Option, conf: &GlobalServiceMapping) -> Option, (Vec>, AtomicUsize)>> { - let client = Client::builder().timeout(Duration::from_secs(2)).danger_accept_invalid_certs(true).build().ok()?; - let mut headers = HeaderMap::new(); - if let Some(token) = token { - headers.insert("X-Consul-Token", HeaderValue::from_str(&token).unwrap()); - } - let to = Duration::from_secs(1); - let resp = client.get(url).timeout(to).send().await.ok()?; - if !resp.status().is_success() { - eprintln!("Consul API returned status: {}", resp.status()); - return None; - } - let mut inner_vec = Vec::new(); - let upstreams: DashMap, (Vec>, AtomicUsize)> = DashMap::new(); - let endpoints: Vec = resp.json().await.ok()?; - for subsets in endpoints { - let addr = subsets.tagged_addresses.get("lan_ipv4").unwrap().address.clone(); - let prt = subsets.tagged_addresses.get("lan_ipv4").unwrap().port; - let to_add = Arc::from(InnerMap { - address: Arc::from(&*addr), - port: prt, - is_ssl: false, - is_http2: false, - to_https: conf.to_https.unwrap_or(false), - rate_limit: conf.rate_limit, - x4xx_limit: conf.x4xx_limit, - redirect_to: None, - healthcheck: None, - authorization: None, - }); - inner_vec.push(to_add); - } - match_path(conf, &upstreams, inner_vec); - Some(upstreams) +pub static CONNECTOR: LazyLock = LazyLock::new(|| Connector::new(None)); + +pub async fn for_consul(url: &str, token: Option, conf: &GlobalServiceMapping) -> Option, (Vec>, AtomicUsize)>> { + if let Some(data) = getfromapi(url, token, "consul").await { + let endpoints: Vec = serde_json::from_slice(&data).ok()?; + let mut inner_vec = Vec::new(); + let upstreams: DashMap, (Vec>, AtomicUsize)> = DashMap::new(); + for subsets in endpoints { + let addr = subsets.tagged_addresses.get("lan_ipv4").unwrap().address.clone(); + let prt = subsets.tagged_addresses.get("lan_ipv4").unwrap().port; + let to_add = Arc::from(InnerMap { + address: Arc::from(&*addr), + port: prt, + is_ssl: false, + is_http2: false, + to_https: conf.to_https.unwrap_or(false), + rate_limit: conf.rate_limit, + x4xx_limit: conf.x4xx_limit, + redirect_to: None, + healthcheck: None, + authorization: None, + }); + inner_vec.push(to_add); + } + match_path(conf, &upstreams, inner_vec); + return Some(upstreams); + }; + None } pub async fn for_kuber(url: &str, token: &str, conf: &GlobalServiceMapping) -> Option, (Vec>, AtomicUsize)>> { - let to = Duration::from_secs(10); - let client = Client::builder().timeout(Duration::from_secs(10)).danger_accept_invalid_certs(true).build().ok()?; - let resp = client.get(url).timeout(to).bearer_auth(token).send().await.ok()?; - if !resp.status().is_success() { - eprintln!("Kubernetes API returned status: {}", resp.status()); - return None; - } - let endpoints: KubeEndpoints = resp.json().await.ok()?; + if let Some(data) = getfromapi(url, Some(token.to_string()), "kubernetes").await { + let endpoints: KubeEndpoints = serde_json::from_slice(&data).ok()?; + let upstreams: DashMap, (Vec>, AtomicUsize)> = DashMap::new(); + let mut inner_vec = Vec::new(); - let upstreams: DashMap, (Vec>, AtomicUsize)> = DashMap::new(); - - if let Some(subsets) = endpoints.subsets { - for subset in subsets { - if let (Some(addresses), Some(ports)) = (subset.addresses, subset.ports) { - let mut inner_vec = Vec::new(); - for addr in addresses { - for port in &ports { - // let redirect_link = conf.redirect_to.as_ref().map(|www| Arc::from(www.as_str())); - let to_add = Arc::from(InnerMap { - address: Arc::from(addr.ip.clone()), - port: port.port, - is_ssl: false, - is_http2: false, - to_https: conf.to_https.unwrap_or(false), - rate_limit: conf.rate_limit, - x4xx_limit: conf.x4xx_limit, - healthcheck: None, - redirect_to: None, - authorization: None, - }); - inner_vec.push(to_add); + if let Some(subsets) = endpoints.subsets { + for subset in subsets { + if let (Some(addresses), Some(ports)) = (subset.addresses, subset.ports) { + for addr in addresses { + for port in &ports { + let to_add = Arc::from(InnerMap { + address: Arc::from(addr.ip.as_str()), + port: port.port, + is_ssl: false, + is_http2: false, + to_https: conf.to_https.unwrap_or(false), + rate_limit: conf.rate_limit, + x4xx_limit: conf.x4xx_limit, + healthcheck: None, + redirect_to: None, + authorization: None, + }); + inner_vec.push(to_add); + } } } - match_path(conf, &upstreams, inner_vec.clone()); } } + if !inner_vec.is_empty() { + match_path(conf, &upstreams, inner_vec); + return Some(upstreams); + } } - Some(upstreams) + None +} +pub async fn getfromapi(url: &str, token: Option, provider: &str) -> Option> { + let (host, port, path, is_tls) = parse_url(&url).ok()?; + + let mut peer = HttpPeer::new((host, port), is_tls, host.to_string()); + peer.options.total_connection_timeout = Some(Duration::from_secs(5)); + peer.options.read_timeout = Some(Duration::from_secs(5)); + + if is_tls { + peer.options.verify_cert = false; + peer.options.verify_hostname = false; + peer.options.alpn = ALPN::H2H1; + } + + let mut http_session = CONNECTOR.get_http_session(&peer).await.ok()?; + let mut req = RequestHeader::build("GET", path.as_bytes(), None).ok()?; + + let host_header = if (is_tls && port == 443) || (!is_tls && port == 80) { + host.to_string() + } else { + format!("{}:{}", host, port) + }; + req.insert_header("Host", host_header).ok()?; + req.insert_header("Accept", "application/json").ok()?; + + match provider { + "consul" => { + if let Some(token) = token { + req.insert_header("X-Consul-Token", token).ok()?; + } + } + "kubernetes" => { + if let Some(token) = token { + req.insert_header("Authorization", format!("Bearer {}", token)).ok()?; + } + } + _ => {} + } + + if http_session.0.write_request_header(Box::new(req)).await.is_err() { + CONNECTOR.release_http_session(http_session.0, &peer, None).await; + return None; + } + + let status = match http_session.0.read_response_header().await { + Ok(_) => http_session.0.response_header().map(|r| r.status.as_u16()).unwrap_or(500), + Err(e) => { + log::warn!("API call failed to read response header for {}: {}", url, e); + 500 + } + }; + + let mut body_bytes = Vec::new(); + if status == 200 { + while let Ok(Some(chunk)) = http_session.0.read_response_body().await { + body_bytes.extend_from_slice(&chunk); + } + } + + CONNECTOR.release_http_session(http_session.0, &peer, None).await; + + if status == 200 && !body_bytes.is_empty() { + Some(body_bytes) + } else { + None + } +} + +fn parse_url(url: &str) -> Result<(&str, u16, &str, bool), &'static str> { + let is_https = url.starts_with("https://"); + let default_port = if is_https { 443 } else { 80 }; + + let no_scheme = url.split_once("://").map_or(url, |(_, rest)| rest); + + let (authority, uri) = no_scheme.find('/').map_or((no_scheme, "/"), |i| (&no_scheme[..i], &no_scheme[i..])); + + let (host, port) = match authority.split_once(':') { + Some((h, p)) => { + let port_num = p.parse::().map_err(|_| "Invalid port number")?; + (h, port_num) + } + None => (authority, default_port), + }; + + if host.is_empty() { + return Err("Empty host in URL"); + } + + Ok((host, port, uri, is_https)) } diff --git a/src/utils/kuberconsul.rs b/src/utils/kuberconsul.rs index c1821ba..e523ca3 100644 --- a/src/utils/kuberconsul.rs +++ b/src/utils/kuberconsul.rs @@ -196,7 +196,7 @@ impl ServiceDiscovery for ConsulDiscovery { } let pref = ss.clone() + &i.upstream; - let list = httpclient::for_consul(pref, consul.token.clone(), &i).await; + let list = httpclient::for_consul(pref.as_str(), consul.token.clone(), &i).await; list_to_upstreams(list, &upstreams, &i); } }