mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-21 08:59:22 +01:00
Add proxy setting for HTTP requests (#127)
This commit is contained in:
@@ -1 +1,7 @@
|
||||
edition = "2018"
|
||||
|
||||
# Widths
|
||||
chain_width = 100
|
||||
max_width = 100
|
||||
single_line_if_else_max_width = 100
|
||||
fn_call_width = 100
|
||||
|
||||
391
src-tauri/Cargo.lock
generated
391
src-tauri/Cargo.lock
generated
@@ -403,31 +403,30 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.6.20"
|
||||
name = "aws-lc-rs"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
|
||||
checksum = "cdd82dba44d209fddb11c190e0a94b78651f95299598e472215667417a03ff1d"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core 0.3.4",
|
||||
"bitflags 1.3.2",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 0.2.12",
|
||||
"http-body 0.4.6",
|
||||
"hyper 0.14.30",
|
||||
"itoa 1.0.11",
|
||||
"matchit",
|
||||
"memchr",
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"serde",
|
||||
"sync_wrapper 0.1.2",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"aws-lc-sys",
|
||||
"mirai-annotations",
|
||||
"paste",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-sys"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df7a4168111d7eb622a31b214057b8509c0a7e1794f44c546d742330dc793972"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"cc",
|
||||
"cmake",
|
||||
"dunce",
|
||||
"fs_extra",
|
||||
"libc",
|
||||
"paste",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -437,7 +436,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core 0.4.3",
|
||||
"axum-core",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 1.1.0",
|
||||
@@ -457,23 +456,6 @@ dependencies = [
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 0.2.12",
|
||||
"http-body 0.4.6",
|
||||
"mime",
|
||||
"rustversion",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.4.3"
|
||||
@@ -527,6 +509,29 @@ version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.69.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools 0.12.1",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash 1.1.0",
|
||||
"shlex",
|
||||
"syn 2.0.72",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit_field"
|
||||
version = "0.10.2"
|
||||
@@ -803,6 +808,15 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom 7.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfb"
|
||||
version = "0.7.3"
|
||||
@@ -857,6 +871,17 @@ dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clipboard-win"
|
||||
version = "5.4.0"
|
||||
@@ -866,6 +891,15 @@ dependencies = [
|
||||
"error-code",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cocoa"
|
||||
version = "0.25.0"
|
||||
@@ -1410,7 +1444,7 @@ version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
||||
dependencies = [
|
||||
"libloading",
|
||||
"libloading 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1806,6 +1840,12 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
@@ -2335,6 +2375,30 @@ dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "headers"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bytes",
|
||||
"headers-core",
|
||||
"http 1.1.0",
|
||||
"httpdate",
|
||||
"mime",
|
||||
"sha1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "headers-core"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4"
|
||||
dependencies = [
|
||||
"http 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
@@ -2534,6 +2598,26 @@ dependencies = [
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-proxy2"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9043b7b23fb0bc4a1c7014c27b50a4fc42cc76206f71d34fc0dfe5b28ddc3faf"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"headers",
|
||||
"http 1.1.0",
|
||||
"hyper 1.4.1",
|
||||
"hyper-tls",
|
||||
"hyper-util",
|
||||
"native-tls",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-rustls"
|
||||
version = "0.24.2"
|
||||
@@ -2545,22 +2629,24 @@ dependencies = [
|
||||
"hyper 0.14.30",
|
||||
"log",
|
||||
"rustls 0.21.12",
|
||||
"rustls-native-certs",
|
||||
"rustls-native-certs 0.6.3",
|
||||
"tokio",
|
||||
"tokio-rustls 0.24.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-rustls"
|
||||
version = "0.27.2"
|
||||
version = "0.27.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155"
|
||||
checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"http 1.1.0",
|
||||
"hyper 1.4.1",
|
||||
"hyper-util",
|
||||
"log",
|
||||
"rustls 0.23.12",
|
||||
"rustls-native-certs 0.8.0",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
"tokio-rustls 0.26.0",
|
||||
@@ -2611,9 +2697,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.7"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9"
|
||||
checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
@@ -2624,7 +2710,6 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tower",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
@@ -2989,6 +3074,12 @@ dependencies = [
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "lebe"
|
||||
version = "0.5.2"
|
||||
@@ -3015,7 +3106,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf"
|
||||
dependencies = [
|
||||
"gtk-sys",
|
||||
"libloading",
|
||||
"libloading 0.7.4",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
@@ -3046,6 +3137,16 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.2.8"
|
||||
@@ -3248,6 +3349,12 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mirai-annotations"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1"
|
||||
|
||||
[[package]]
|
||||
name = "muda"
|
||||
version = "0.15.1"
|
||||
@@ -4202,22 +4309,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.12.6"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29"
|
||||
checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive 0.12.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e13db3d3fde688c61e2446b4d843bc27a7e8af269a69440c0308021dc92333cc"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive 0.13.1",
|
||||
"prost-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4234,8 +4331,8 @@ dependencies = [
|
||||
"once_cell",
|
||||
"petgraph",
|
||||
"prettyplease",
|
||||
"prost 0.13.1",
|
||||
"prost-types 0.13.1",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"regex",
|
||||
"syn 2.0.72",
|
||||
"tempfile",
|
||||
@@ -4243,22 +4340,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.12.6"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.12.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18bec9b0adc4eba778b33684b7ba3e7137789434769ee3ce3930463ef904cfca"
|
||||
checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.13.0",
|
||||
@@ -4269,24 +4353,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "prost-reflect"
|
||||
version = "0.12.0"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "057237efdb71cf4b3f9396302a3d6599a92fa94063ba537b66130980ea9909f3"
|
||||
checksum = "4b7535b02f0e5efe3e1dbfcb428be152226ed0c66cad9541f2274c8ba8d4cd40"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"base64 0.22.1",
|
||||
"once_cell",
|
||||
"prost 0.12.6",
|
||||
"prost",
|
||||
"prost-reflect-derive",
|
||||
"prost-types 0.12.6",
|
||||
"prost-types",
|
||||
"serde",
|
||||
"serde-value",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-reflect-derive"
|
||||
version = "0.12.0"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "172da1212c02be2c94901440cb27183cd92bff00ebacca5c323bf7520b8f9c04"
|
||||
checksum = "f4fce6b22f15cc8d8d400a2b98ad29202b33bd56c7d9ddd815bc803a807ecb65"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -4295,20 +4379,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.12.6"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0"
|
||||
checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670"
|
||||
dependencies = [
|
||||
"prost 0.12.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cee5168b05f49d4b0ca581206eb14a7b22fafd963efe729ac48eb03266e25cc2"
|
||||
dependencies = [
|
||||
"prost 0.13.1",
|
||||
"prost",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4390,7 +4465,7 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rustc-hash",
|
||||
"rustc-hash 2.0.0",
|
||||
"rustls 0.23.12",
|
||||
"socket2",
|
||||
"thiserror",
|
||||
@@ -4407,7 +4482,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"rand 0.8.5",
|
||||
"ring",
|
||||
"rustc-hash",
|
||||
"rustc-hash 2.0.0",
|
||||
"rustls 0.23.12",
|
||||
"slab",
|
||||
"thiserror",
|
||||
@@ -4713,7 +4788,7 @@ dependencies = [
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"hyper 1.4.1",
|
||||
"hyper-rustls 0.27.2",
|
||||
"hyper-rustls 0.27.3",
|
||||
"hyper-tls",
|
||||
"hyper-util",
|
||||
"ipnet",
|
||||
@@ -4893,6 +4968,12 @@ version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.0.0"
|
||||
@@ -4939,6 +5020,8 @@ version = "0.23.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"log",
|
||||
"once_cell",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
@@ -4959,6 +5042,19 @@ dependencies = [
|
||||
"security-framework",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-native-certs"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a"
|
||||
dependencies = [
|
||||
"openssl-probe",
|
||||
"rustls-pemfile 2.1.3",
|
||||
"rustls-pki-types",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "1.0.4"
|
||||
@@ -5000,6 +5096,7 @@ version = "0.102.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"untrusted",
|
||||
@@ -5200,9 +5297,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.208"
|
||||
version = "1.0.210"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2"
|
||||
checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
@@ -5230,9 +5327,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.208"
|
||||
version = "1.0.210"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf"
|
||||
checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -5401,6 +5498,12 @@ dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.2"
|
||||
@@ -6557,9 +6660,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.15"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af"
|
||||
checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
@@ -6640,40 +6743,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tonic"
|
||||
version = "0.10.2"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e"
|
||||
checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
"axum 0.6.20",
|
||||
"base64 0.21.7",
|
||||
"bytes",
|
||||
"h2 0.3.26",
|
||||
"http 0.2.12",
|
||||
"http-body 0.4.6",
|
||||
"hyper 0.14.30",
|
||||
"hyper-timeout 0.4.1",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"prost 0.12.6",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tonic"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38659f4a91aba8598d27821589f5db7dddd94601e7a01b1e485a50e5484c7401"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
"axum 0.7.5",
|
||||
"axum",
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"h2 0.4.5",
|
||||
@@ -6685,7 +6761,7 @@ dependencies = [
|
||||
"hyper-util",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"prost 0.13.1",
|
||||
"prost",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
@@ -6710,15 +6786,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tonic-reflection"
|
||||
version = "0.10.2"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fa37c513df1339d197f4ba21d28c918b9ef1ac1768265f11ecb6b7f1cba1b76"
|
||||
checksum = "878d81f52e7fcfd80026b7fdb6a9b578b3c3653ba987f87f0dce4b64043cba27"
|
||||
dependencies = [
|
||||
"prost 0.12.6",
|
||||
"prost-types 0.12.6",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tonic 0.10.2",
|
||||
"tonic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7368,6 +7444,18 @@ version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
|
||||
dependencies = [
|
||||
"either",
|
||||
"home",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "whoami"
|
||||
version = "1.5.1"
|
||||
@@ -7896,20 +7984,23 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"dunce",
|
||||
"hyper 0.14.30",
|
||||
"hyper-rustls 0.24.2",
|
||||
"hyper 1.4.1",
|
||||
"hyper-proxy2",
|
||||
"hyper-rustls 0.27.3",
|
||||
"hyper-util",
|
||||
"log",
|
||||
"md5",
|
||||
"prost 0.12.6",
|
||||
"prost",
|
||||
"prost-reflect",
|
||||
"prost-types 0.12.6",
|
||||
"prost-types",
|
||||
"rustls 0.23.12",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-plugin-shell",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tonic 0.10.2",
|
||||
"tonic",
|
||||
"tonic-reflection",
|
||||
"uuid",
|
||||
]
|
||||
@@ -7943,7 +8034,7 @@ dependencies = [
|
||||
"dunce",
|
||||
"log",
|
||||
"path-slash",
|
||||
"prost 0.13.1",
|
||||
"prost",
|
||||
"rand 0.8.5",
|
||||
"regex",
|
||||
"reqwest",
|
||||
@@ -7953,7 +8044,7 @@ dependencies = [
|
||||
"tauri-plugin-shell",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tonic 0.12.1",
|
||||
"tonic",
|
||||
"tonic-build",
|
||||
"ts-rs",
|
||||
"yaak_models",
|
||||
|
||||
1
src-tauri/migrations/20241012181547_proxy-setting.sql
Normal file
1
src-tauri/migrations/20241012181547_proxy-setting.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE settings ADD COLUMN proxy TEXT;
|
||||
@@ -14,7 +14,7 @@ use http::{HeaderMap, HeaderName, HeaderValue};
|
||||
use log::{debug, error, warn};
|
||||
use mime_guess::Mime;
|
||||
use reqwest::redirect::Policy;
|
||||
use reqwest::{multipart, Url};
|
||||
use reqwest::{multipart, Proxy, Url};
|
||||
use reqwest::{Method, Response};
|
||||
use serde_json::Value;
|
||||
use tauri::{Manager, Runtime, WebviewWindow};
|
||||
@@ -25,10 +25,11 @@ use tokio::sync::watch::Receiver;
|
||||
use tokio::sync::{oneshot, Mutex};
|
||||
use yaak_models::models::{
|
||||
Cookie, CookieJar, Environment, HttpRequest, HttpResponse, HttpResponseHeader,
|
||||
HttpResponseState,
|
||||
HttpResponseState, ProxySetting, ProxySettingAuth,
|
||||
};
|
||||
use yaak_models::queries::{
|
||||
get_http_response, get_workspace, update_response_if_id, upsert_cookie_jar,
|
||||
get_http_response, get_or_create_settings, get_workspace, update_response_if_id,
|
||||
upsert_cookie_jar,
|
||||
};
|
||||
use yaak_plugin_runtime::events::{RenderPurpose, WindowContext};
|
||||
|
||||
@@ -40,9 +41,9 @@ pub async fn send_http_request<R: Runtime>(
|
||||
cookie_jar: Option<CookieJar>,
|
||||
cancelled_rx: &mut Receiver<bool>,
|
||||
) -> Result<HttpResponse, String> {
|
||||
let workspace = get_workspace(window, &request.workspace_id)
|
||||
.await
|
||||
.expect("Failed to get Workspace");
|
||||
let workspace =
|
||||
get_workspace(window, &request.workspace_id).await.expect("Failed to get Workspace");
|
||||
let settings = get_or_create_settings(window).await;
|
||||
let cb = PluginTemplateCallback::new(
|
||||
window.app_handle(),
|
||||
&WindowContext::from_window(window),
|
||||
@@ -61,6 +62,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
if !url_string.starts_with("http://") && !url_string.starts_with("https://") {
|
||||
url_string = format!("http://{}", url_string);
|
||||
}
|
||||
debug!("Sending request to {url_string}");
|
||||
|
||||
let mut client_builder = reqwest::Client::builder()
|
||||
.redirect(match workspace.setting_follow_redirects {
|
||||
@@ -75,6 +77,31 @@ pub async fn send_http_request<R: Runtime>(
|
||||
.danger_accept_invalid_certs(!workspace.setting_validate_certificates)
|
||||
.tls_info(true);
|
||||
|
||||
match settings.proxy {
|
||||
Some(ProxySetting::Disabled) => client_builder = client_builder.no_proxy(),
|
||||
Some(ProxySetting::Enabled { http, https, auth }) => {
|
||||
debug!("Using proxy http={http} https={https}");
|
||||
let mut proxy = Proxy::custom(move |url| {
|
||||
let http = if http.is_empty() { None } else { Some(http.to_owned()) };
|
||||
let https = if https.is_empty() { None } else { Some(https.to_owned()) };
|
||||
let proxy_url = match (url.scheme(), http, https) {
|
||||
("http", Some(proxy_url), _) => Some(proxy_url),
|
||||
("https", _, Some(proxy_url)) => Some(proxy_url),
|
||||
_ => None,
|
||||
};
|
||||
proxy_url
|
||||
});
|
||||
|
||||
if let Some(ProxySettingAuth { user, password }) = auth {
|
||||
debug!("Using proxy auth");
|
||||
proxy = proxy.basic_auth(user.as_str(), password.as_str());
|
||||
}
|
||||
|
||||
client_builder = client_builder.proxy(proxy);
|
||||
}
|
||||
None => {} // Nothing to do for this one, as it is the default
|
||||
}
|
||||
|
||||
// Add cookie store if specified
|
||||
let maybe_cookie_manager = match cookie_jar.clone() {
|
||||
Some(cj) => {
|
||||
@@ -196,16 +223,8 @@ pub async fn send_http_request<R: Runtime>(
|
||||
let a = rendered_request.authentication;
|
||||
|
||||
if b == "basic" {
|
||||
let username = a
|
||||
.get("username")
|
||||
.unwrap_or(empty_value)
|
||||
.as_str()
|
||||
.unwrap_or_default();
|
||||
let password = a
|
||||
.get("password")
|
||||
.unwrap_or(empty_value)
|
||||
.as_str()
|
||||
.unwrap_or_default();
|
||||
let username = a.get("username").unwrap_or(empty_value).as_str().unwrap_or_default();
|
||||
let password = a.get("password").unwrap_or(empty_value).as_str().unwrap_or_default();
|
||||
|
||||
let auth = format!("{username}:{password}");
|
||||
let encoded = BASE64_STANDARD.encode(auth);
|
||||
@@ -214,11 +233,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
HeaderValue::from_str(&format!("Basic {}", encoded)).unwrap(),
|
||||
);
|
||||
} else if b == "bearer" {
|
||||
let token = a
|
||||
.get("token")
|
||||
.unwrap_or(empty_value)
|
||||
.as_str()
|
||||
.unwrap_or_default();
|
||||
let token = a.get("token").unwrap_or(empty_value).as_str().unwrap_or_default();
|
||||
headers.insert(
|
||||
"Authorization",
|
||||
HeaderValue::from_str(&format!("Bearer {token}")).unwrap(),
|
||||
@@ -232,10 +247,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
let query = get_str_h(&request_body, "query");
|
||||
let variables = get_str_h(&request_body, "variables");
|
||||
let body = if variables.trim().is_empty() {
|
||||
format!(
|
||||
r#"{{"query":{}}}"#,
|
||||
serde_json::to_string(query).unwrap_or_default()
|
||||
)
|
||||
format!(r#"{{"query":{}}}"#, serde_json::to_string(query).unwrap_or_default())
|
||||
} else {
|
||||
format!(
|
||||
r#"{{"query":{},"variables":{variables}}}"#,
|
||||
@@ -326,9 +338,8 @@ pub async fn send_http_request<R: Runtime>(
|
||||
Mime::from_str("application/octet-stream").unwrap();
|
||||
let mime =
|
||||
mime_guess::from_path(file_path.clone()).first_or(default_mime);
|
||||
part = part
|
||||
.mime_str(mime.essence_str())
|
||||
.map_err(|e| e.to_string())?;
|
||||
part =
|
||||
part.mime_str(mime.essence_str()).map_err(|e| e.to_string())?;
|
||||
}
|
||||
|
||||
// Set file path if not empty
|
||||
@@ -359,6 +370,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
let sendable_req = match request_builder.build() {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
warn!("Failed to build request builder {e:?}");
|
||||
return Ok(response_err(&*response.lock().await, e.to_string(), window).await);
|
||||
}
|
||||
};
|
||||
@@ -392,9 +404,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
let response_headers = v.headers().clone();
|
||||
let dir = window.app_handle().path().app_data_dir().unwrap();
|
||||
let base_dir = dir.join("responses");
|
||||
create_dir_all(base_dir.clone())
|
||||
.await
|
||||
.expect("Failed to create responses dir");
|
||||
create_dir_all(base_dir.clone()).await.expect("Failed to create responses dir");
|
||||
let body_path = if response_id.is_empty() {
|
||||
base_dir.join(response_id.clone())
|
||||
} else {
|
||||
@@ -509,7 +519,8 @@ pub async fn send_http_request<R: Runtime>(
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
response_err(&*response.lock().await, e.to_string(), &window).await;
|
||||
warn!("Failed to execute request {e}");
|
||||
response_err(&*response.lock().await, format!("{e} → {e:?}"), &window).await;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -596,6 +596,7 @@ async fn cmd_grpc_go<R: Runtime>(
|
||||
stream.into_inner()
|
||||
}
|
||||
Some(Err(e)) => {
|
||||
warn!("GRPC stream error {e:?}");
|
||||
upsert_grpc_event(
|
||||
&w,
|
||||
&(match e.status {
|
||||
@@ -648,7 +649,7 @@ async fn cmd_grpc_go<R: Runtime>(
|
||||
&w,
|
||||
&GrpcEvent {
|
||||
content: "Connection complete".to_string(),
|
||||
status: Some(Code::Unavailable as i32),
|
||||
status: Some(Code::Ok as i32),
|
||||
metadata: metadata_to_map(trailers),
|
||||
event_type: GrpcEventType::ConnectionEnd,
|
||||
..base_event.clone()
|
||||
@@ -1164,7 +1165,7 @@ async fn response_err<R: Runtime>(
|
||||
error: String,
|
||||
w: &WebviewWindow<R>,
|
||||
) -> HttpResponse {
|
||||
warn!("Failed to send request: {}", error);
|
||||
warn!("Failed to send request: {error:?}");
|
||||
let mut response = response.clone();
|
||||
response.state = HttpResponseState::Closed;
|
||||
response.error = Some(error.clone());
|
||||
|
||||
@@ -4,21 +4,24 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
tonic = "0.10.2"
|
||||
prost = "0.12"
|
||||
tokio = { version = "1.0", features = ["macros", "rt-multi-thread", "fs"] }
|
||||
tonic-reflection = "0.10.2"
|
||||
tokio-stream = "0.1.14"
|
||||
prost-types = "0.12.3"
|
||||
serde = { version = "1.0.196", features = ["derive"] }
|
||||
serde_json = "1.0.113"
|
||||
prost-reflect = { version = "0.12.0", features = ["serde", "derive"] }
|
||||
log = "0.4.20"
|
||||
anyhow = "1.0.79"
|
||||
hyper = { version = "0.14" }
|
||||
hyper-rustls = { version = "0.24.0", features = ["http2"] }
|
||||
uuid = { version = "1.7.0", features = ["v4"] }
|
||||
dunce = "1.0.4"
|
||||
hyper = { version = "1.4.1" }
|
||||
hyper-proxy2 = { version = "0.1.0" }
|
||||
hyper-rustls = { version = "0.27.3", features = ["http2", "rustls-native-certs"] }
|
||||
hyper-util = { version = "0.1.9" }
|
||||
log = "0.4.20"
|
||||
md5 = "0.7.0"
|
||||
prost = "0.13.3"
|
||||
prost-reflect = { version = "0.14.2", features = ["serde", "derive"] }
|
||||
prost-types = "0.13.3"
|
||||
rustls = { version = "0.23.12" , features = ["ring"]}
|
||||
serde = { version = "1.0.210", features = ["derive"] }
|
||||
serde_json = "1.0.113"
|
||||
tauri = { workspace = true }
|
||||
tauri-plugin-shell = { workspace = true }
|
||||
md5 = "0.7.0"
|
||||
dunce = "1.0.4"
|
||||
tokio = { version = "1.0", features = ["macros", "rt-multi-thread", "fs"] }
|
||||
tokio-stream = "0.1.14"
|
||||
tonic = "0.12.3"
|
||||
tonic-reflection = "0.12.3"
|
||||
uuid = { version = "1.7.0", features = ["v4"] }
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
use hyper::client::HttpConnector;
|
||||
use hyper::Client;
|
||||
use hyper_rustls::HttpsConnector;
|
||||
use hyper_util::client::legacy::Client;
|
||||
use hyper_util::client::legacy::connect::HttpConnector;
|
||||
pub use prost_reflect::DynamicMessage;
|
||||
use prost_reflect::{DescriptorPool, MethodDescriptor, ServiceDescriptor};
|
||||
use serde_json::Deserializer;
|
||||
@@ -28,7 +27,7 @@ pub struct GrpcConnection {
|
||||
pub uri: Uri,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Default, Debug)]
|
||||
pub struct StreamError {
|
||||
pub message: String,
|
||||
pub status: Option<Status>,
|
||||
@@ -54,19 +53,14 @@ impl From<Status> for StreamError {
|
||||
|
||||
impl GrpcConnection {
|
||||
pub fn service(&self, service: &str) -> Result<ServiceDescriptor, String> {
|
||||
let service = self
|
||||
.pool
|
||||
.get_service_by_name(service)
|
||||
.ok_or("Failed to find service")?;
|
||||
let service = self.pool.get_service_by_name(service).ok_or("Failed to find service")?;
|
||||
Ok(service)
|
||||
}
|
||||
|
||||
pub fn method(&self, service: &str, method: &str) -> Result<MethodDescriptor, String> {
|
||||
let service = self.service(service)?;
|
||||
let method = service
|
||||
.methods()
|
||||
.find(|m| m.name() == method)
|
||||
.ok_or("Failed to find method")?;
|
||||
let method =
|
||||
service.methods().find(|m| m.name() == method).ok_or("Failed to find method")?;
|
||||
Ok(method)
|
||||
}
|
||||
|
||||
@@ -132,13 +126,10 @@ impl GrpcConnection {
|
||||
let path = method_desc_to_path(method);
|
||||
let codec = DynamicCodec::new(method.clone());
|
||||
client.ready().await.unwrap();
|
||||
client
|
||||
.client_streaming(req, path, codec)
|
||||
.await
|
||||
.map_err(|e| StreamError {
|
||||
message: e.message().to_string(),
|
||||
status: Some(e),
|
||||
})
|
||||
client.client_streaming(req, path, codec).await.map_err(|e| StreamError {
|
||||
message: e.message().to_string(),
|
||||
status: Some(e),
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn server_streaming(
|
||||
@@ -197,8 +188,7 @@ impl GrpcHandle {
|
||||
fill_pool_from_files(&self.app_handle, proto_files).await
|
||||
}?;
|
||||
|
||||
self.pools
|
||||
.insert(make_pool_key(id, uri, proto_files), pool.clone());
|
||||
self.pools.insert(make_pool_key(id, uri, proto_files), pool.clone());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -211,9 +201,7 @@ impl GrpcHandle {
|
||||
// Ensure reflection is up-to-date
|
||||
self.reflect(id, uri, proto_files).await?;
|
||||
|
||||
let pool = self
|
||||
.get_pool(id, uri, proto_files)
|
||||
.ok_or("Failed to get pool".to_string())?;
|
||||
let pool = self.get_pool(id, uri, proto_files).ok_or("Failed to get pool".to_string())?;
|
||||
Ok(self.services_from_pool(&pool))
|
||||
}
|
||||
|
||||
@@ -249,9 +237,7 @@ impl GrpcHandle {
|
||||
proto_files: &Vec<PathBuf>,
|
||||
) -> Result<GrpcConnection, String> {
|
||||
self.reflect(id, uri, proto_files).await?;
|
||||
let pool = self
|
||||
.get_pool(id, uri, proto_files)
|
||||
.ok_or("Failed to get pool")?;
|
||||
let pool = self.get_pool(id, uri, proto_files).ok_or("Failed to get pool")?;
|
||||
|
||||
let uri = uri_from_str(uri)?;
|
||||
let conn = get_transport();
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
use std::env::temp_dir;
|
||||
use std::ops::Deref;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use hyper::client::HttpConnector;
|
||||
use hyper::Client;
|
||||
use hyper_rustls::{HttpsConnector, HttpsConnectorBuilder};
|
||||
use hyper_util::client::legacy::connect::HttpConnector;
|
||||
use hyper_util::client::legacy::Client;
|
||||
use hyper_util::rt::TokioExecutor;
|
||||
use log::{debug, warn};
|
||||
use prost::Message;
|
||||
use prost_reflect::{DescriptorPool, MethodDescriptor};
|
||||
use prost_types::{FileDescriptorProto, FileDescriptorSet};
|
||||
use std::env::temp_dir;
|
||||
use std::ops::Deref;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use tauri::path::BaseDirectory;
|
||||
use tauri::{AppHandle, Manager};
|
||||
use tauri_plugin_shell::ShellExt;
|
||||
@@ -20,10 +20,10 @@ use tonic::body::BoxBody;
|
||||
use tonic::codegen::http::uri::PathAndQuery;
|
||||
use tonic::transport::Uri;
|
||||
use tonic::Request;
|
||||
use tonic_reflection::pb::server_reflection_client::ServerReflectionClient;
|
||||
use tonic_reflection::pb::server_reflection_request::MessageRequest;
|
||||
use tonic_reflection::pb::server_reflection_response::MessageResponse;
|
||||
use tonic_reflection::pb::ServerReflectionRequest;
|
||||
use tonic_reflection::pb::v1::server_reflection_client::ServerReflectionClient;
|
||||
use tonic_reflection::pb::v1::server_reflection_request::MessageRequest;
|
||||
use tonic_reflection::pb::v1::server_reflection_response::MessageResponse;
|
||||
use tonic_reflection::pb::v1::ServerReflectionRequest;
|
||||
|
||||
pub async fn fill_pool_from_files(
|
||||
app_handle: &AppHandle,
|
||||
@@ -38,9 +38,8 @@ pub async fn fill_pool_from_files(
|
||||
.expect("failed to resolve protoc include directory");
|
||||
|
||||
// HACK: Remove UNC prefix for Windows paths
|
||||
let global_import_dir = dunce::simplified(global_import_dir.as_path())
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
let global_import_dir =
|
||||
dunce::simplified(global_import_dir.as_path()).to_string_lossy().to_string();
|
||||
let desc_path = dunce::simplified(desc_path.as_path());
|
||||
|
||||
let mut args = vec![
|
||||
@@ -89,12 +88,9 @@ pub async fn fill_pool_from_files(
|
||||
|
||||
let bytes = fs::read(desc_path).await.map_err(|e| e.to_string())?;
|
||||
let fdp = FileDescriptorSet::decode(bytes.deref()).map_err(|e| e.to_string())?;
|
||||
pool.add_file_descriptor_set(fdp)
|
||||
.map_err(|e| e.to_string())?;
|
||||
pool.add_file_descriptor_set(fdp).map_err(|e| e.to_string())?;
|
||||
|
||||
fs::remove_file(desc_path)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
fs::remove_file(desc_path).await.map_err(|e| e.to_string())?;
|
||||
|
||||
Ok(pool)
|
||||
}
|
||||
@@ -114,16 +110,34 @@ pub async fn fill_pool_from_reflection(uri: &Uri) -> Result<DescriptorPool, Stri
|
||||
}
|
||||
|
||||
pub fn get_transport() -> Client<HttpsConnector<HttpConnector>, BoxBody> {
|
||||
let connector = HttpsConnectorBuilder::new().with_native_roots();
|
||||
let connector = connector.https_or_http().enable_http2().wrap_connector({
|
||||
let mut http_connector = HttpConnector::new();
|
||||
http_connector.enforce_http(false);
|
||||
http_connector
|
||||
});
|
||||
Client::builder()
|
||||
.pool_max_idle_per_host(0)
|
||||
.http2_only(true)
|
||||
.build(connector)
|
||||
if let Err(_) = rustls::crypto::ring::default_provider().install_default() {
|
||||
warn!("Default certs already installed");
|
||||
}
|
||||
|
||||
let connector = HttpsConnectorBuilder::new()
|
||||
.with_native_roots()
|
||||
.unwrap()
|
||||
.https_or_http()
|
||||
.enable_http2()
|
||||
.wrap_connector({
|
||||
let mut http_connector = HttpConnector::new();
|
||||
http_connector.enforce_http(false);
|
||||
http_connector
|
||||
|
||||
// TODO: Figure out how to make proxy work. We'll need to run the following on every request:
|
||||
// if let Some(headers) = proxy.http_headers(&uri) {
|
||||
// req.headers_mut().extend(headers.clone().into_iter());
|
||||
// }
|
||||
// This means we need to move this connection logic next to where the req is built
|
||||
|
||||
// let proxy_uri = "http://localhost:9090".parse().unwrap();
|
||||
// let proxy = Proxy::new(Intercept::All, proxy_uri);
|
||||
// let mut proxy_connector = ProxyConnector::unsecured(http_connector);
|
||||
// proxy_connector.add_proxy(proxy);
|
||||
// proxy_connector
|
||||
});
|
||||
|
||||
Client::builder(TokioExecutor::new()).http2_only(true).build(connector)
|
||||
}
|
||||
|
||||
async fn list_services(
|
||||
@@ -137,11 +151,7 @@ async fn list_services(
|
||||
_ => panic!("Expected a ListServicesResponse variant"),
|
||||
};
|
||||
|
||||
Ok(list_services_response
|
||||
.service
|
||||
.iter()
|
||||
.map(|s| s.name.clone())
|
||||
.collect::<Vec<_>>())
|
||||
Ok(list_services_response.service.iter().map(|s| s.name.clone()).collect::<Vec<_>>())
|
||||
}
|
||||
|
||||
async fn file_descriptor_set_from_service_name(
|
||||
@@ -157,10 +167,7 @@ async fn file_descriptor_set_from_service_name(
|
||||
{
|
||||
Ok(resp) => resp,
|
||||
Err(e) => {
|
||||
warn!(
|
||||
"Error fetching file descriptor for service {}: {}",
|
||||
service_name, e
|
||||
);
|
||||
warn!("Error fetching file descriptor for service {}: {}", service_name, e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -178,8 +185,7 @@ async fn file_descriptor_set_from_service_name(
|
||||
file_descriptor_set_by_filename(&dep_name, pool, client).await;
|
||||
}
|
||||
|
||||
pool.add_file_descriptor_proto(fdp)
|
||||
.expect("add file descriptor proto");
|
||||
pool.add_file_descriptor_proto(fdp).expect("add file descriptor proto");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,8 +214,7 @@ async fn file_descriptor_set_by_filename(
|
||||
|
||||
for fd in file_descriptor_response.file_descriptor_proto {
|
||||
let fdp = FileDescriptorProto::decode(fd.deref()).unwrap();
|
||||
pool.add_file_descriptor_proto(fdp)
|
||||
.expect("add file descriptor proto");
|
||||
pool.add_file_descriptor_proto(fdp).expect("add file descriptor proto");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,10 @@ export type KeyValue = { model: "key_value", createdAt: string, updatedAt: strin
|
||||
|
||||
export type Plugin = { model: "plugin", id: string, createdAt: string, updatedAt: string, checkedAt: string | null, directory: string, enabled: boolean, url: string | null, };
|
||||
|
||||
export type Settings = { model: "settings", id: string, createdAt: string, updatedAt: string, appearance: string, editorFontSize: number, editorSoftWrap: boolean, interfaceFontSize: number, interfaceScale: number, openWorkspaceNewWindow: boolean | null, telemetry: boolean, theme: string, themeDark: string, themeLight: string, updateChannel: string, };
|
||||
export type ProxySetting = { "type": "enabled", http: string, https: string, auth: ProxySettingAuth | null, } | { "type": "disabled" };
|
||||
|
||||
export type ProxySettingAuth = { user: string, password: string, };
|
||||
|
||||
export type Settings = { model: "settings", id: string, createdAt: string, updatedAt: string, appearance: string, editorFontSize: number, editorSoftWrap: boolean, interfaceFontSize: number, interfaceScale: number, openWorkspaceNewWindow: boolean | null, telemetry: boolean, theme: string, themeDark: string, themeLight: string, updateChannel: string, proxy: ProxySetting | null, };
|
||||
|
||||
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, variables: Array<EnvironmentVariable>, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, };
|
||||
|
||||
@@ -6,6 +6,26 @@ use serde_json::Value;
|
||||
use std::collections::BTreeMap;
|
||||
use ts_rs::TS;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "camelCase", tag = "type")]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
pub enum ProxySetting {
|
||||
Enabled {
|
||||
http: String,
|
||||
https: String,
|
||||
auth: Option<ProxySettingAuth>,
|
||||
},
|
||||
Disabled,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
pub struct ProxySettingAuth {
|
||||
pub user: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
@@ -27,6 +47,7 @@ pub struct Settings {
|
||||
pub theme_dark: String,
|
||||
pub theme_light: String,
|
||||
pub update_channel: String,
|
||||
pub proxy: Option<ProxySetting>,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
@@ -44,6 +65,7 @@ pub enum SettingsIden {
|
||||
InterfaceFontSize,
|
||||
InterfaceScale,
|
||||
OpenWorkspaceNewWindow,
|
||||
Proxy,
|
||||
Telemetry,
|
||||
Theme,
|
||||
ThemeDark,
|
||||
@@ -55,22 +77,24 @@ impl<'s> TryFrom<&Row<'s>> for Settings {
|
||||
type Error = rusqlite::Error;
|
||||
|
||||
fn try_from(r: &Row<'s>) -> Result<Self, Self::Error> {
|
||||
let proxy: Option<String> = r.get("proxy")?;
|
||||
Ok(Settings {
|
||||
id: r.get("id")?,
|
||||
model: r.get("model")?,
|
||||
created_at: r.get("created_at")?,
|
||||
updated_at: r.get("updated_at")?,
|
||||
theme: r.get("theme")?,
|
||||
appearance: r.get("appearance")?,
|
||||
editor_font_size: r.get("editor_font_size")?,
|
||||
editor_soft_wrap: r.get("editor_soft_wrap")?,
|
||||
interface_font_size: r.get("interface_font_size")?,
|
||||
interface_scale: r.get("interface_scale")?,
|
||||
open_workspace_new_window: r.get("open_workspace_new_window")?,
|
||||
proxy: proxy.map(|p| -> ProxySetting { serde_json::from_str(p.as_str()).unwrap() }),
|
||||
telemetry: r.get("telemetry")?,
|
||||
theme: r.get("theme")?,
|
||||
theme_dark: r.get("theme_dark")?,
|
||||
theme_light: r.get("theme_light")?,
|
||||
update_channel: r.get("update_channel")?,
|
||||
interface_font_size: r.get("interface_font_size")?,
|
||||
interface_scale: r.get("interface_scale")?,
|
||||
editor_font_size: r.get("editor_font_size")?,
|
||||
editor_soft_wrap: r.get("editor_soft_wrap")?,
|
||||
telemetry: r.get("telemetry")?,
|
||||
open_workspace_new_window: r.get("open_workspace_new_window")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -431,7 +455,7 @@ pub struct HttpResponseHeader {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde( rename_all = "snake_case")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
pub enum HttpResponseState {
|
||||
Initialized,
|
||||
@@ -618,7 +642,7 @@ impl<'s> TryFrom<&Row<'s>> for GrpcRequest {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde( rename_all = "snake_case")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
pub enum GrpcConnectionState {
|
||||
Initialized,
|
||||
@@ -626,7 +650,7 @@ pub enum GrpcConnectionState {
|
||||
Closed,
|
||||
}
|
||||
|
||||
impl Default for GrpcConnectionState{
|
||||
impl Default for GrpcConnectionState {
|
||||
fn default() -> Self {
|
||||
Self::Initialized
|
||||
}
|
||||
@@ -911,7 +935,7 @@ impl ModelType {
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "camelCase", untagged)]
|
||||
#[ts(export, export_to="models.ts")]
|
||||
#[ts(export, export_to = "models.ts")]
|
||||
pub enum AnyModel {
|
||||
CookieJar(CookieJar),
|
||||
Environment(Environment),
|
||||
|
||||
@@ -11,6 +11,7 @@ use crate::models::{
|
||||
use crate::plugin::SqliteConnection;
|
||||
use log::{debug, error};
|
||||
use rand::distributions::{Alphanumeric, DistString};
|
||||
use rusqlite::OptionalExtension;
|
||||
use sea_query::ColumnRef::Asterisk;
|
||||
use sea_query::Keyword::CurrentTimestamp;
|
||||
use sea_query::{Cond, Expr, OnConflict, Order, Query, SqliteQueryBuilder};
|
||||
@@ -117,9 +118,7 @@ pub async fn set_key_value_raw<R: Runtime>(
|
||||
.returning_all()
|
||||
.build_rusqlite(SqliteQueryBuilder);
|
||||
|
||||
let mut stmt = db
|
||||
.prepare(sql.as_str())
|
||||
.expect("Failed to prepare KeyValue upsert");
|
||||
let mut stmt = db.prepare(sql.as_str()).expect("Failed to prepare KeyValue upsert");
|
||||
let kv = stmt
|
||||
.query_row(&*params.as_params(), |row| row.try_into())
|
||||
.expect("Failed to upsert KeyValue");
|
||||
@@ -143,8 +142,7 @@ pub async fn get_key_value_raw<R: Runtime>(
|
||||
)
|
||||
.build_rusqlite(SqliteQueryBuilder);
|
||||
|
||||
db.query_row(sql.as_str(), &*params.as_params(), |row| row.try_into())
|
||||
.ok()
|
||||
db.query_row(sql.as_str(), &*params.as_params(), |row| row.try_into()).ok()
|
||||
}
|
||||
|
||||
pub async fn list_workspaces<R: Runtime>(mgr: &impl Manager<R>) -> Result<Vec<Workspace>> {
|
||||
@@ -365,11 +363,7 @@ pub async fn upsert_grpc_request<R: Runtime>(
|
||||
request.service.as_ref().map(|s| s.as_str()).into(),
|
||||
request.method.as_ref().map(|s| s.as_str()).into(),
|
||||
request.message.as_str().into(),
|
||||
request
|
||||
.authentication_type
|
||||
.as_ref()
|
||||
.map(|s| s.as_str())
|
||||
.into(),
|
||||
request.authentication_type.as_ref().map(|s| s.as_str()).into(),
|
||||
serde_json::to_string(&request.authentication)?.into(),
|
||||
serde_json::to_string(&request.metadata)?.into(),
|
||||
])
|
||||
@@ -434,10 +428,7 @@ pub async fn upsert_grpc_connection<R: Runtime>(
|
||||
) -> Result<GrpcConnection> {
|
||||
let connections =
|
||||
list_http_responses_for_request(window, connection.request_id.as_str(), None).await?;
|
||||
for c in connections
|
||||
.iter()
|
||||
.skip(MAX_GRPC_CONNECTIONS_PER_REQUEST - 1)
|
||||
{
|
||||
for c in connections.iter().skip(MAX_GRPC_CONNECTIONS_PER_REQUEST - 1) {
|
||||
debug!("Deleting old grpc connection {}", c.id);
|
||||
delete_grpc_connection(window, c.id.as_str()).await?;
|
||||
}
|
||||
@@ -664,7 +655,7 @@ pub async fn list_grpc_events<R: Runtime>(
|
||||
.from(GrpcEventIden::Table)
|
||||
.cond_where(Expr::col(GrpcEventIden::ConnectionId).eq(connection_id))
|
||||
.column(Asterisk)
|
||||
.order_by(GrpcEventIden::CreatedAt, Order::Desc)
|
||||
.order_by(GrpcEventIden::CreatedAt, Order::Asc)
|
||||
.build_rusqlite(SqliteQueryBuilder);
|
||||
let mut stmt = db.prepare(sql.as_str())?;
|
||||
let items = stmt.query_map(&*params.as_params(), |row| row.try_into())?;
|
||||
@@ -757,7 +748,7 @@ pub async fn delete_environment<R: Runtime>(
|
||||
|
||||
const SETTINGS_ID: &str = "default";
|
||||
|
||||
async fn get_settings<R: Runtime>(mgr: &impl Manager<R>) -> Result<Settings> {
|
||||
async fn get_settings<R: Runtime>(mgr: &impl Manager<R>) -> Result<Option<Settings>> {
|
||||
let dbm = &*mgr.state::<SqliteConnection>();
|
||||
let db = dbm.0.lock().await.get().unwrap();
|
||||
|
||||
@@ -767,13 +758,15 @@ async fn get_settings<R: Runtime>(mgr: &impl Manager<R>) -> Result<Settings> {
|
||||
.cond_where(Expr::col(SettingsIden::Id).eq(SETTINGS_ID))
|
||||
.build_rusqlite(SqliteQueryBuilder);
|
||||
let mut stmt = db.prepare(sql.as_str())?;
|
||||
Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?)
|
||||
Ok(stmt.query_row(&*params.as_params(), |row| row.try_into()).optional()?)
|
||||
}
|
||||
|
||||
pub async fn get_or_create_settings<R: Runtime>(mgr: &impl Manager<R>) -> Settings {
|
||||
if let Ok(settings) = get_settings(mgr).await {
|
||||
return settings;
|
||||
}
|
||||
match get_settings(mgr).await {
|
||||
Ok(Some(settings)) => return settings,
|
||||
Ok(None) => (),
|
||||
Err(e) => panic!("Failed to get settings {e:?}"),
|
||||
};
|
||||
|
||||
let dbm = &*mgr.state::<SqliteConnection>();
|
||||
let db = dbm.0.lock().await.get().unwrap();
|
||||
@@ -785,11 +778,8 @@ pub async fn get_or_create_settings<R: Runtime>(mgr: &impl Manager<R>) -> Settin
|
||||
.returning_all()
|
||||
.build_rusqlite(SqliteQueryBuilder);
|
||||
|
||||
let mut stmt = db
|
||||
.prepare(sql.as_str())
|
||||
.expect("Failed to prepare Settings insert");
|
||||
stmt.query_row(&*params.as_params(), |row| row.try_into())
|
||||
.expect("Failed to insert Settings")
|
||||
let mut stmt = db.prepare(sql.as_str()).expect("Failed to prepare Settings insert");
|
||||
stmt.query_row(&*params.as_params(), |row| row.try_into()).expect("Failed to insert Settings")
|
||||
}
|
||||
|
||||
pub async fn update_settings<R: Runtime>(
|
||||
@@ -805,39 +795,23 @@ pub async fn update_settings<R: Runtime>(
|
||||
.values([
|
||||
(SettingsIden::Id, "default".into()),
|
||||
(SettingsIden::CreatedAt, CurrentTimestamp.into()),
|
||||
(
|
||||
SettingsIden::Appearance,
|
||||
settings.appearance.as_str().into(),
|
||||
),
|
||||
(SettingsIden::Appearance, settings.appearance.as_str().into()),
|
||||
(SettingsIden::ThemeDark, settings.theme_dark.as_str().into()),
|
||||
(
|
||||
SettingsIden::ThemeLight,
|
||||
settings.theme_light.as_str().into(),
|
||||
),
|
||||
(
|
||||
SettingsIden::UpdateChannel,
|
||||
settings.update_channel.as_str().into(),
|
||||
),
|
||||
(
|
||||
SettingsIden::InterfaceFontSize,
|
||||
settings.interface_font_size.into(),
|
||||
),
|
||||
(
|
||||
SettingsIden::InterfaceScale,
|
||||
settings.interface_scale.into(),
|
||||
),
|
||||
(
|
||||
SettingsIden::EditorFontSize,
|
||||
settings.editor_font_size.into(),
|
||||
),
|
||||
(
|
||||
SettingsIden::EditorSoftWrap,
|
||||
settings.editor_soft_wrap.into(),
|
||||
),
|
||||
(SettingsIden::ThemeLight, settings.theme_light.as_str().into()),
|
||||
(SettingsIden::UpdateChannel, settings.update_channel.into()),
|
||||
(SettingsIden::InterfaceFontSize, settings.interface_font_size.into()),
|
||||
(SettingsIden::InterfaceScale, settings.interface_scale.into()),
|
||||
(SettingsIden::EditorFontSize, settings.editor_font_size.into()),
|
||||
(SettingsIden::EditorSoftWrap, settings.editor_soft_wrap.into()),
|
||||
(SettingsIden::Telemetry, settings.telemetry.into()),
|
||||
(SettingsIden::OpenWorkspaceNewWindow, settings.open_workspace_new_window.into()),
|
||||
(
|
||||
SettingsIden::OpenWorkspaceNewWindow,
|
||||
settings.open_workspace_new_window.into(),
|
||||
SettingsIden::Proxy,
|
||||
(match settings.proxy {
|
||||
None => None,
|
||||
Some(p) => Some(serde_json::to_string(&p)?),
|
||||
})
|
||||
.into(),
|
||||
),
|
||||
])
|
||||
.returning_all()
|
||||
@@ -1308,10 +1282,7 @@ pub async fn create_http_response<R: Runtime>(
|
||||
elapsed.into(),
|
||||
elapsed_headers.into(),
|
||||
url.into(),
|
||||
serde_json::to_value(state)?
|
||||
.as_str()
|
||||
.unwrap_or_default()
|
||||
.into(),
|
||||
serde_json::to_value(state)?.as_str().unwrap_or_default().into(),
|
||||
status.into(),
|
||||
status_reason.into(),
|
||||
content_length.into(),
|
||||
@@ -1391,32 +1362,15 @@ pub async fn update_http_response<R: Runtime>(
|
||||
HttpResponseIden::StatusReason,
|
||||
response.status_reason.as_ref().map(|s| s.as_str()).into(),
|
||||
),
|
||||
(
|
||||
HttpResponseIden::ContentLength,
|
||||
response.content_length.into(),
|
||||
),
|
||||
(
|
||||
HttpResponseIden::BodyPath,
|
||||
response.body_path.as_ref().map(|s| s.as_str()).into(),
|
||||
),
|
||||
(
|
||||
HttpResponseIden::Error,
|
||||
response.error.as_ref().map(|s| s.as_str()).into(),
|
||||
),
|
||||
(HttpResponseIden::ContentLength, response.content_length.into()),
|
||||
(HttpResponseIden::BodyPath, response.body_path.as_ref().map(|s| s.as_str()).into()),
|
||||
(HttpResponseIden::Error, response.error.as_ref().map(|s| s.as_str()).into()),
|
||||
(
|
||||
HttpResponseIden::Headers,
|
||||
serde_json::to_string(&response.headers)
|
||||
.unwrap_or_default()
|
||||
.into(),
|
||||
),
|
||||
(
|
||||
HttpResponseIden::Version,
|
||||
response.version.as_ref().map(|s| s.as_str()).into(),
|
||||
),
|
||||
(
|
||||
HttpResponseIden::State,
|
||||
serde_json::to_value(&response.state)?.as_str().into(),
|
||||
serde_json::to_string(&response.headers).unwrap_or_default().into(),
|
||||
),
|
||||
(HttpResponseIden::Version, response.version.as_ref().map(|s| s.as_str()).into()),
|
||||
(HttpResponseIden::State, serde_json::to_value(&response.state)?.as_str().into()),
|
||||
(
|
||||
HttpResponseIden::RemoteAddr,
|
||||
response.remote_addr.as_ref().map(|s| s.as_str()).into(),
|
||||
|
||||
@@ -10,6 +10,7 @@ import { HeaderSize } from '../HeaderSize';
|
||||
import { SettingsAppearance } from './SettingsAppearance';
|
||||
import { SettingsGeneral } from './SettingsGeneral';
|
||||
import { SettingsPlugins } from './SettingsPlugins';
|
||||
import {SettingsProxy} from "./SettingsProxy";
|
||||
|
||||
interface Props {
|
||||
hide?: () => void;
|
||||
@@ -17,11 +18,12 @@ interface Props {
|
||||
|
||||
enum Tab {
|
||||
General = 'general',
|
||||
Proxy = 'proxy',
|
||||
Appearance = 'appearance',
|
||||
Plugins = 'plugins',
|
||||
}
|
||||
|
||||
const tabs = [Tab.General, Tab.Appearance, Tab.Plugins];
|
||||
const tabs = [Tab.General, Tab.Appearance, Tab.Proxy, Tab.Plugins];
|
||||
|
||||
export default function Settings({ hide }: Props) {
|
||||
const osInfo = useOsInfo();
|
||||
@@ -78,6 +80,9 @@ export default function Settings({ hide }: Props) {
|
||||
<TabContent value={Tab.Plugins} className="pt-3 overflow-y-auto h-full px-4">
|
||||
<SettingsPlugins />
|
||||
</TabContent>
|
||||
<TabContent value={Tab.Proxy} className="pt-3 overflow-y-auto h-full px-4">
|
||||
<SettingsProxy />
|
||||
</TabContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -27,12 +27,13 @@ export function SettingsGeneral() {
|
||||
}
|
||||
|
||||
return (
|
||||
<VStack space={2} className="mb-4">
|
||||
<VStack space={1.5} className="mb-4">
|
||||
<div className="grid grid-cols-[minmax(0,1fr)_auto] gap-1">
|
||||
<Select
|
||||
name="updateChannel"
|
||||
label="Update Channel"
|
||||
labelPosition="left"
|
||||
labelClassName="w-[12rem]"
|
||||
size="sm"
|
||||
value={settings.updateChannel}
|
||||
onChange={(updateChannel) => updateSettings.mutate({ updateChannel })}
|
||||
@@ -54,22 +55,19 @@ export function SettingsGeneral() {
|
||||
name="openWorkspace"
|
||||
label="Open Workspace"
|
||||
labelPosition="left"
|
||||
labelClassName="w-[12rem]"
|
||||
size="sm"
|
||||
value={
|
||||
settings.openWorkspaceNewWindow === true
|
||||
? 'new'
|
||||
: settings.openWorkspaceNewWindow === false
|
||||
? 'current'
|
||||
: 'ask'
|
||||
? 'current'
|
||||
: 'ask'
|
||||
}
|
||||
onChange={(v) => {
|
||||
if (v === 'current') {
|
||||
updateSettings.mutate({ openWorkspaceNewWindow: false });
|
||||
} else if (v === 'new') {
|
||||
updateSettings.mutate({ openWorkspaceNewWindow: true });
|
||||
} else {
|
||||
updateSettings.mutate({ openWorkspaceNewWindow: null });
|
||||
}
|
||||
if (v === 'current') updateSettings.mutate({ openWorkspaceNewWindow: false });
|
||||
else if (v === 'new') updateSettings.mutate({ openWorkspaceNewWindow: true });
|
||||
else updateSettings.mutate({ openWorkspaceNewWindow: null });
|
||||
}}
|
||||
options={[
|
||||
{ label: 'Always Ask', value: 'ask' },
|
||||
@@ -77,7 +75,9 @@ export function SettingsGeneral() {
|
||||
{ label: 'New Window', value: 'new' },
|
||||
]}
|
||||
/>
|
||||
|
||||
<Checkbox
|
||||
className="mt-3"
|
||||
checked={settings.telemetry}
|
||||
title="Send Usage Statistics"
|
||||
onChange={(telemetry) => updateSettings.mutate({ telemetry })}
|
||||
|
||||
119
src-web/components/Settings/SettingsProxy.tsx
Normal file
119
src-web/components/Settings/SettingsProxy.tsx
Normal file
@@ -0,0 +1,119 @@
|
||||
import React from 'react';
|
||||
import { useSettings } from '../../hooks/useSettings';
|
||||
import { useUpdateSettings } from '../../hooks/useUpdateSettings';
|
||||
import { Checkbox } from '../core/Checkbox';
|
||||
import { PlainInput } from '../core/PlainInput';
|
||||
import { Select } from '../core/Select';
|
||||
import { Separator } from '../core/Separator';
|
||||
import { HStack, VStack } from '../core/Stacks';
|
||||
|
||||
export function SettingsProxy() {
|
||||
const settings = useSettings();
|
||||
const updateSettings = useUpdateSettings();
|
||||
|
||||
return (
|
||||
<VStack space={1.5} className="mb-4">
|
||||
<Select
|
||||
name="proxy"
|
||||
label="Proxy"
|
||||
hideLabel
|
||||
size="sm"
|
||||
value={settings.proxy?.type ?? 'automatic'}
|
||||
onChange={(v) => {
|
||||
if (v === 'automatic') {
|
||||
updateSettings.mutate({ proxy: undefined });
|
||||
} else if (v === 'enabled') {
|
||||
updateSettings.mutate({
|
||||
proxy: {
|
||||
type: 'enabled',
|
||||
http: '',
|
||||
https: '',
|
||||
auth: { user: '', password: '' },
|
||||
},
|
||||
});
|
||||
} else {
|
||||
updateSettings.mutate({ proxy: { type: 'disabled' } });
|
||||
}
|
||||
}}
|
||||
options={[
|
||||
{ label: 'Automatic Proxy Detection', value: 'automatic' },
|
||||
{ label: 'Custom Proxy Configuration', value: 'enabled' },
|
||||
{ label: 'No Proxy', value: 'disabled' },
|
||||
]}
|
||||
/>
|
||||
{settings.proxy?.type === 'enabled' && (
|
||||
<VStack space={1.5}>
|
||||
<HStack space={1.5} className="mt-3">
|
||||
<PlainInput
|
||||
size="sm"
|
||||
label="HTTP"
|
||||
placeholder="localhost:9090"
|
||||
defaultValue={settings.proxy?.http}
|
||||
onChange={(http) => {
|
||||
const https = settings.proxy?.type === 'enabled' ? settings.proxy.https : '';
|
||||
const auth = settings.proxy?.type === 'enabled' ? settings.proxy.auth : null;
|
||||
updateSettings.mutate({ proxy: { type: 'enabled', http, https, auth } });
|
||||
}}
|
||||
/>
|
||||
<PlainInput
|
||||
size="sm"
|
||||
label="HTTPS"
|
||||
placeholder="localhost:9090"
|
||||
defaultValue={settings.proxy?.https}
|
||||
onChange={(https) => {
|
||||
const http = settings.proxy?.type === 'enabled' ? settings.proxy.http : '';
|
||||
const auth = settings.proxy?.type === 'enabled' ? settings.proxy.auth : null;
|
||||
updateSettings.mutate({ proxy: { type: 'enabled', http, https, auth } });
|
||||
}}
|
||||
/>
|
||||
</HStack>
|
||||
<Separator className="my-6"/>
|
||||
<Checkbox
|
||||
checked={settings.proxy.auth != null}
|
||||
title="Enable authentication"
|
||||
onChange={(enabled) => {
|
||||
const http = settings.proxy?.type === 'enabled' ? settings.proxy.http : '';
|
||||
const https = settings.proxy?.type === 'enabled' ? settings.proxy.https : '';
|
||||
const auth = enabled ? { user: '', password: '' } : null;
|
||||
updateSettings.mutate({ proxy: { type: 'enabled', http, https, auth } });
|
||||
}}
|
||||
/>
|
||||
|
||||
{settings.proxy.auth != null && (
|
||||
<HStack space={1.5}>
|
||||
<PlainInput
|
||||
size="sm"
|
||||
label="User"
|
||||
placeholder="myUser"
|
||||
defaultValue={settings.proxy.auth.user}
|
||||
onChange={(user) => {
|
||||
const https = settings.proxy?.type === 'enabled' ? settings.proxy.https : '';
|
||||
const http = settings.proxy?.type === 'enabled' ? settings.proxy.http : '';
|
||||
const password =
|
||||
settings.proxy?.type === 'enabled' ? (settings.proxy.auth?.password ?? '') : '';
|
||||
const auth = { user, password };
|
||||
updateSettings.mutate({ proxy: { type: 'enabled', http, https, auth } });
|
||||
}}
|
||||
/>
|
||||
<PlainInput
|
||||
size="sm"
|
||||
label="Password"
|
||||
type="password"
|
||||
placeholder="s3cretPassw0rd"
|
||||
defaultValue={settings.proxy.auth.password}
|
||||
onChange={(password) => {
|
||||
const https = settings.proxy?.type === 'enabled' ? settings.proxy.https : '';
|
||||
const http = settings.proxy?.type === 'enabled' ? settings.proxy.http : '';
|
||||
const user =
|
||||
settings.proxy?.type === 'enabled' ? (settings.proxy.auth?.user ?? '') : '';
|
||||
const auth = { user, password };
|
||||
updateSettings.mutate({ proxy: { type: 'enabled', http, https, auth } });
|
||||
}}
|
||||
/>
|
||||
</HStack>
|
||||
)}
|
||||
</VStack>
|
||||
)}
|
||||
</VStack>
|
||||
);
|
||||
}
|
||||
@@ -14,6 +14,7 @@ export function Banner({ children, className, color = 'secondary' }: Props) {
|
||||
className={classNames(
|
||||
className,
|
||||
`x-theme-banner--${color}`,
|
||||
'whitespace-pre-wrap',
|
||||
'border border-dashed border-border-subtle bg-surface',
|
||||
'italic px-3 py-2 rounded select-auto cursor-text',
|
||||
'overflow-x-auto text-text',
|
||||
|
||||
@@ -93,7 +93,7 @@ export const PlainInput = forwardRef<HTMLInputElement, PlainInputProps>(function
|
||||
htmlFor={id}
|
||||
className={classNames(
|
||||
labelClassName,
|
||||
'text-text-subtle whitespace-nowrap',
|
||||
'text-text-subtle whitespace-nowrap flex-shrink-0',
|
||||
hideLabel && 'sr-only',
|
||||
)}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user