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