chore(deps): 全量升级依赖,适配 gpui-kit 0.7 与 ureq 3

- gpui-kit 0.6→0.7:main.rs 改用 gpui_kit::open_window 自动挂载 Root,
  移除内容视图手动挂载的 dialog/sheet/notification 层
- ureq 2→3:Agent::config_builder 配置超时(global/connect/recv_response),
  响应体改用 read_json / read_to_string / into_body().into_reader()
- hmac 0.13 需显式导入 KeyInit;digest 0.11 的 Output 不再实现 LowerHex,
  sha256 转 hex 改为逐字节格式化,并补已知向量测试
- windows 0.62:SetWindowPos 插入位置参数改为 Option<HWND>
- dirs 6→7、base64 0.22→0.23,其余锁内更新(tokio/sentry/rustls 等)
- TLS 栈不变(rustls + webpki-roots),无 openssl/native-tls 混入

已验证:cargo check 零警告;35 测试通过;运行应用截图核验主界面、
新建连接对话框打开与关闭均正常
This commit is contained in:
2026-09-30 11:43:40 +08:00
parent b22a645588
commit 6f09a5729f
8 changed files with 209 additions and 127 deletions
Generated
+149 -95
View File
@@ -982,6 +982,12 @@ dependencies = [
"cc",
]
[[package]]
name = "cmov"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a"
[[package]]
name = "cocoa"
version = "0.25.0"
@@ -1140,6 +1146,35 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "cookie"
version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a373e3602691c3cdea496d2f0ee5935151e6168fe87739483c463db1b2f2f87"
dependencies = [
"percent-encoding",
"time",
"version_check",
]
[[package]]
name = "cookie_store"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15b2c103cf610ec6cae3da84a766285b42fd16aad564758459e6ecf128c75206"
dependencies = [
"cookie",
"document-features",
"idna",
"indexmap",
"log",
"serde",
"serde_derive",
"serde_json",
"time",
"url",
]
[[package]]
name = "core-foundation"
version = "0.9.4"
@@ -1416,6 +1451,15 @@ dependencies = [
"linktime-proc-macro",
]
[[package]]
name = "ctutils"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e"
dependencies = [
"cmov",
]
[[package]]
name = "data-encoding"
version = "2.11.1"
@@ -1487,6 +1531,7 @@ dependencies = [
"block-buffer 0.12.1",
"const-oid",
"crypto-common 0.2.2",
"ctutils",
]
[[package]]
@@ -1507,6 +1552,15 @@ dependencies = [
"dirs-sys 0.5.0",
]
[[package]]
name = "dirs"
version = "7.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d57d423b3c82e89b9a24ca3091fee61f456a26edbd28d26c65906f4bc1dcd8f"
dependencies = [
"dirs-sys 0.5.0",
]
[[package]]
name = "dirs-sys"
version = "0.4.1"
@@ -2360,9 +2414,9 @@ dependencies = [
[[package]]
name = "gpui-base"
version = "0.6.6"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e904ee0d351f4e85b967e26ae986d3aa195a8d9d35fcd18184a2c40989694e"
checksum = "64bb52b29a8dcdc8d3f595b8b0839c076f237572ab601ba4577d3da8ae085728"
dependencies = [
"aho-corasick",
"anyhow",
@@ -2376,9 +2430,11 @@ dependencies = [
"gpui-pre-sum-tree",
"html5ever",
"instant",
"itertools 0.13.0",
"lsp-types",
"markdown",
"markup5ever_rcdom",
"num-traits",
"objc2 0.6.4",
"objc2-app-kit 0.3.2",
"objc2-foundation 0.3.2",
@@ -2398,9 +2454,9 @@ dependencies = [
[[package]]
name = "gpui-component"
version = "0.6.6"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cf6c72516b44bb2e66a1bd2ccf77a122ecd1b54a75559ac299bb296bfcb5bb7"
checksum = "ac246c9f3d9771e56fbf90bd7d8656d0992d83940b580debf2efab4c44fe91df"
dependencies = [
"anyhow",
"chrono",
@@ -2442,9 +2498,9 @@ dependencies = [
[[package]]
name = "gpui-component-macros"
version = "0.6.6"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3867545508c7cf6a5f6da586f60d894a3f8e7cce94b7fe82df7fad5f868ec20e"
checksum = "830b3574bd6e108b9a09c9d584e60626c9140add6d8fe839bf57627577b7977e"
dependencies = [
"proc-macro-crate",
"proc-macro2",
@@ -2454,9 +2510,9 @@ dependencies = [
[[package]]
name = "gpui-kit"
version = "0.6.6"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42732dc20f50926278b2abf7a99d427a7741ab28bca6bfb49685f9ce3a53a1c7"
checksum = "8edb2a8eafdb6e65ad1a80625347b93f8e54cbf3fac82a584e4924cda674d5c2"
dependencies = [
"gpui-base",
"gpui-component",
@@ -2468,9 +2524,9 @@ dependencies = [
[[package]]
name = "gpui-kit-assets"
version = "0.6.6"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "111d3d03a68454318a193f137419864ccebdc7d3dc0194b0b0b3f818a6bc3d55"
checksum = "885a2abd416e29a76ef1553aea06eb2645a9290cf5e1d3fa02d218ecac6d318f"
dependencies = [
"anyhow",
"gpui-pre",
@@ -2483,9 +2539,9 @@ dependencies = [
[[package]]
name = "gpui-pre"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0437c0b83e636a92bd1a39fa1d05fb632ae671289537497b35871ffbe231b84"
checksum = "0e87a42bb37c7cb4e76dd1ac0ce88851e46e976e0373a47ab3e0757abffee54d"
dependencies = [
"accesskit",
"anyhow",
@@ -2553,12 +2609,12 @@ dependencies = [
[[package]]
name = "gpui-pre-apple"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3af534f0746eb9e014114bcc0ee00dc250c4b8d75df2e437180c403aa65649c1"
checksum = "00053551517815ab169fda28fff78dbebf2712722593c7671c511785cb3f79d5"
dependencies = [
"anyhow",
"block",
"block2 0.6.2",
"cbindgen",
"cocoa 0.26.1",
"core-foundation 0.10.1",
@@ -2577,9 +2633,9 @@ dependencies = [
[[package]]
name = "gpui-pre-collections"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15e7a65204039187d1f4b3d4c2e0233eeac54d4acb0b13f9dc1a3b5adad26c1f"
checksum = "f79760925c31ed06924d28d68981b5b22b2ce25665f58f0a33dfea11170e6e28"
dependencies = [
"gpui-pre-util",
"indexmap",
@@ -2588,9 +2644,9 @@ dependencies = [
[[package]]
name = "gpui-pre-derive-refineable"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79dfb4a05f3cd9893d7768dbf5dba1bbbe99cab7394e89b360ccb3b2bcb6b34e"
checksum = "d1aea3f941581a6a9dd545ecd351ef2d336fe6e2a1a4555cb6414944a4984260"
dependencies = [
"proc-macro2",
"quote",
@@ -2599,9 +2655,9 @@ dependencies = [
[[package]]
name = "gpui-pre-http-client"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfd5a7542c77887a5aff997d78c95884119c8463409569b63fcf060956da1682"
checksum = "ddce27e989e877a3a1a243f97d7ea4f1ade2532abec418d5a0be9cca802702c7"
dependencies = [
"anyhow",
"async-compression",
@@ -2620,9 +2676,9 @@ dependencies = [
[[package]]
name = "gpui-pre-linux"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aab655cda1d6dcd549ac869e8678babc84cf573ab6794a1fe1a39c6c70c60b48"
checksum = "0aac7022e347409454777701082201742710052813964a1e25160f7e22c965ad"
dependencies = [
"accesskit",
"accesskit_unix",
@@ -2667,9 +2723,9 @@ dependencies = [
[[package]]
name = "gpui-pre-macos"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "951d17e41a72067ad2d35c60e08a62e8ad7fa9400b41c802e26cfb459f6c05da"
checksum = "5a43af845b260b09393e923c4f1e1a67a10fcfc847b4815192bbfd02ed9fe725"
dependencies = [
"accesskit",
"accesskit_macos",
@@ -2714,9 +2770,9 @@ dependencies = [
[[package]]
name = "gpui-pre-macros"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6324092b40ea8ec7c327a4a28427e366a489b4d5d23b5d1bd0243fc2f4ca7a9e"
checksum = "e1627c5dd3c3351e39e0621d3f3e31dbbe7c7658df90b1d2ec12bfe95d54cd37"
dependencies = [
"heck 0.5.0",
"proc-macro-crate",
@@ -2727,9 +2783,9 @@ dependencies = [
[[package]]
name = "gpui-pre-perf"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b94bff26ccd8105f6206144f8dab16a2dc02e7a68f39dada02cdf492f0afd940"
checksum = "01954497dd02ba96ab4c252a8668643b0cc3085e7a75dca62e7ba0e3dcd83b02"
dependencies = [
"gpui-pre-collections",
"serde",
@@ -2738,10 +2794,11 @@ dependencies = [
[[package]]
name = "gpui-pre-platform"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8423d1e0a693d2f9f16c0326bb01b5e81ec0531854d596a18476934ac6880478"
checksum = "0112105c2ac6757fbf527c9c92a753be9bcbce9f4cf26959a11eaa1db6565aa5"
dependencies = [
"anyhow",
"console_error_panic_hook",
"gpui-pre",
"gpui-pre-linux",
@@ -2752,9 +2809,9 @@ dependencies = [
[[package]]
name = "gpui-pre-refineable"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93b4b0a8d296a3ee5beb1136bc48f8167a6028eb1e243b56851dcd8c9fc6d7a1"
checksum = "ffd14639e5dfab906bbaeabfe0f94289120dcf2e6ed37217deb13964867e89a5"
dependencies = [
"gpui-pre-derive-refineable",
]
@@ -2811,9 +2868,9 @@ dependencies = [
[[package]]
name = "gpui-pre-scheduler"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff7b10b3d2fc3fda24847a04436eca9531612c8414874a37ddc005f20e521e12"
checksum = "8049963b716df01b67b58f86000597f222d5b31b15b35069b23a3b07f3c68352"
dependencies = [
"async-task",
"backtrace",
@@ -2828,9 +2885,9 @@ dependencies = [
[[package]]
name = "gpui-pre-shared-string"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe17f81bd98a0253140ea79f7f76442d7499bd8d17db302861af8e46c11d38df"
checksum = "8ef6314bdf5ab162c1913712ec4a91b013ce2a9cfb0b557ecdfdd5793c8b61d3"
dependencies = [
"schemars",
"serde",
@@ -2839,9 +2896,9 @@ dependencies = [
[[package]]
name = "gpui-pre-sum-tree"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a6d35e998a51d24248dad731de1f09d386cbbf46a04edde3b67f469b2ce3f16"
checksum = "5cca7e5fad9d53b2d265860fefdffc5f171966cb99c3fd99ecac15c033f19209"
dependencies = [
"gpui-pre-ztracing",
"heapless",
@@ -2852,9 +2909,9 @@ dependencies = [
[[package]]
name = "gpui-pre-util"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a026a30c578930d20974fd8c3d77de36223ac7ba193bd4259e7238929bc8806"
checksum = "d82e06359ae76f8bb07ed713c54adb80cea6a9a2d3dc715f41aec30cd2aadb4d"
dependencies = [
"anyhow",
"log",
@@ -2863,9 +2920,9 @@ dependencies = [
[[package]]
name = "gpui-pre-util-macros"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cbf79627a6afc626d4e887dad9d2d92bb069413e8cc692ba3e90bff219eb7a9"
checksum = "b8a0da4143bb0e7eb926eed7edd3a61c9d17344207543dcc25fb398f0cb96b2f"
dependencies = [
"gpui-pre-perf",
"quote",
@@ -2874,9 +2931,9 @@ dependencies = [
[[package]]
name = "gpui-pre-web"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34be433b9fcb370b1fe9a1c7fe911f0eb6058791ef8167dcf6c5a5deb624975c"
checksum = "ab3870cc909471bb830c3d79496770c754401aad6cfa122147ccb13e8908ad08"
dependencies = [
"anyhow",
"console_error_panic_hook",
@@ -2903,9 +2960,9 @@ dependencies = [
[[package]]
name = "gpui-pre-wgpu"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05515b32799b1767d69300921c1b562cd53104965211a0e8905acdc7aa18e693"
checksum = "f0b02657b56b09140ce542f5e4434fb96d9fdaba0fd0035ba7dba13c171ddb9b"
dependencies = [
"anyhow",
"bytemuck",
@@ -2930,9 +2987,9 @@ dependencies = [
[[package]]
name = "gpui-pre-windows"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27662e65bfcf4445d2cccfad91f1570ec07f4b1b5de98400a9f207fd19c464cf"
checksum = "f05592a6f9e3e6bb7a9f2a0d4779271cf747a948db1c07b02448de777ffff8f3"
dependencies = [
"accesskit",
"accesskit_windows",
@@ -2959,9 +3016,9 @@ dependencies = [
[[package]]
name = "gpui-pre-zlog"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3a5af0b734a391a84872eb770b3ee9830091ec2487b79d06371fe14eefb2b5d"
checksum = "a7506302091e66d7fb5e04a5b3480e90cff0bbe3157458d7df91a41c59238c48"
dependencies = [
"anyhow",
"chrono",
@@ -2971,9 +3028,9 @@ dependencies = [
[[package]]
name = "gpui-pre-ztracing"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a24cb19f78c5bc3aab8ddf1e8e0bd6b402fbcb9c7f112f64ddbedef8f8768a59"
checksum = "4ed1bc6d53b3ca93785a8573d1066d555b67bc475b344fb28871f9811eb6f218"
dependencies = [
"gpui-pre-zlog",
"gpui-pre-ztracing-macro",
@@ -2983,9 +3040,9 @@ dependencies = [
[[package]]
name = "gpui-pre-ztracing-macro"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1bb25850ad31b88bbdef454afb93ec4cdb81f5e200ba5b3f1a0368111780d2c"
checksum = "829258540ea51bb9ea4a71686beffe5c99586901ba9f39944d06e4a180ab63fe"
[[package]]
name = "granit-parser"
@@ -3128,7 +3185,7 @@ version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
dependencies = [
"hmac",
"hmac 0.12.1",
]
[[package]]
@@ -3140,6 +3197,15 @@ dependencies = [
"digest 0.10.7",
]
[[package]]
name = "hmac"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f"
dependencies = [
"digest 0.11.3",
]
[[package]]
name = "hostname"
version = "0.4.2"
@@ -4188,12 +4254,12 @@ name = "mqttx-desktop"
version = "1.0.0"
dependencies = [
"anyhow",
"base64 0.22.1",
"base64 0.23.1",
"chrono",
"dirs 6.0.0",
"dirs 7.0.0",
"embed-resource",
"gpui-kit",
"hmac",
"hmac 0.13.0",
"raw-window-handle",
"rfd",
"rumqttc-v4-next",
@@ -4204,13 +4270,13 @@ dependencies = [
"serde",
"serde_json",
"sevenz-rust",
"sha1",
"sha2 0.10.9",
"sha1 0.11.0",
"sha2 0.11.0",
"smol",
"tokio",
"ureq 2.12.1",
"ureq",
"uuid",
"windows 0.58.0",
"windows 0.62.2",
]
[[package]]
@@ -4937,7 +5003,7 @@ dependencies = [
"futures-util",
"getrandom 0.4.3",
"hkdf",
"hmac",
"hmac 0.12.1",
"md-5",
"num",
"num-bigint-dig",
@@ -5076,7 +5142,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
dependencies = [
"digest 0.10.7",
"hmac",
"hmac 0.12.1",
]
[[package]]
@@ -6425,7 +6491,7 @@ dependencies = [
"sentry-panic",
"sentry-tracing",
"tokio",
"ureq 3.4.2",
"ureq",
]
[[package]]
@@ -6666,6 +6732,17 @@ dependencies = [
"digest 0.10.7",
]
[[package]]
name = "sha1"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214"
dependencies = [
"cfg-if",
"cpufeatures 0.3.1",
"digest 0.11.3",
]
[[package]]
name = "sha1_smol"
version = "1.0.1"
@@ -7675,7 +7752,7 @@ dependencies = [
"rand 0.9.5",
"rustls",
"rustls-pki-types",
"sha1",
"sha1 0.10.7",
"thiserror 2.0.21",
]
@@ -7795,24 +7872,6 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "ureq"
version = "2.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d"
dependencies = [
"base64 0.22.1",
"flate2",
"log",
"once_cell",
"rustls",
"rustls-pki-types",
"serde",
"serde_json",
"url",
"webpki-roots 0.26.11",
]
[[package]]
name = "ureq"
version = "3.4.2"
@@ -7820,13 +7879,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a7ac20be9b7726e0bbdbf974c059676d9acb1cd414961f570a4e8231cacd7fc"
dependencies = [
"base64 0.23.1",
"cookie_store",
"flate2",
"log",
"percent-encoding",
"rustls",
"rustls-pki-types",
"serde",
"serde_json",
"ureq-proto",
"utf8-zero",
"webpki-roots 1.0.9",
"webpki-roots",
]
[[package]]
@@ -8267,15 +8330,6 @@ dependencies = [
"rustls-pki-types",
]
[[package]]
name = "webpki-roots"
version = "0.26.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
dependencies = [
"webpki-roots 1.0.9",
]
[[package]]
name = "webpki-roots"
version = "1.0.9"
+8 -8
View File
@@ -11,7 +11,7 @@ name = "mqttx"
path = "src/main.rs"
[dependencies]
gpui-kit = "0.6"
gpui-kit = "0.7"
anyhow = "1"
serde = { version = "1", features = ["derive"] }
@@ -26,12 +26,12 @@ rumqttc-v4 = { package = "rumqttc-v4-next", version = "0.34", features = ["webso
uuid = { version = "1", features = ["v4"] }
chrono = { version = "0.4", features = ["clock"] }
dirs = "6"
dirs = "7"
# 阿里云 MQTT 签名: HMAC-SHA1 -> Base64
hmac = "0.12"
sha1 = "0.10"
base64 = "0.22"
hmac = "0.13"
sha1 = "0.11"
base64 = "0.23"
# 自定义 TLS(自定义 CA / 双向认证 / 跳过校验),版本与 rumqttc 内部使用的 rustls 一致
rustls = { version = "0.23", default-features = false, features = ["std", "tls12", "aws_lc_rs"] }
@@ -42,8 +42,8 @@ rustls-native-certs = "0.8"
rfd = "0.17"
# OTA 自更新:Gitea Release 检查/下载(ureq 用 rustls,与 rumqttc 依赖同源)
ureq = { version = "2", features = ["json"] }
sha2 = "0.10"
ureq = { version = "3", features = ["json"] }
sha2 = "0.11"
# Release 附件为 7z 压缩包,纯 Rust 解压(客户端免装 7-Zip)
sevenz-rust = "0.6"
@@ -59,7 +59,7 @@ sentry = { version = "0.49", default-features = false, features = [
# 窗口置顶(raw HWND + SetWindowPos)与进程资源采样
raw-window-handle = "0.6"
[target.'cfg(target_os = "windows")'.dependencies]
windows = { version = "0.58", features = [
windows = { version = "0.62", features = [
"Win32_Foundation",
"Win32_System_Threading",
"Win32_System_ProcessStatus",
+1 -1
View File
@@ -13,7 +13,7 @@
//! - password: HMAC-SHA256(DeviceSecret, "clientId{ProductKey}.{DeviceName}deviceName{DeviceName}productKey{ProductKey}timestamp{ts}")
use base64::Engine as _;
use hmac::{Hmac, Mac};
use hmac::{Hmac, KeyInit, Mac};
use serde::{Deserialize, Serialize};
use sha1::Sha1;
use sha2::Sha256;
+4 -4
View File
@@ -1,4 +1,4 @@
use gpui_kit::component::{Root, TitleBar};
use gpui_kit::component::TitleBar;
use gpui_kit::*;
use mqttx_desktop::ui;
@@ -70,9 +70,9 @@ fn main() {
..TitleBar::window_options()
};
cx.open_window(options, |window, cx| {
let view = cx.new(|cx| ui::app::MqttXApp::new(window, cx));
cx.new(|cx| Root::new(view.clone(), window, cx))
// 0.7 起 gpui_kit::open_window 自动挂载 Root(承载 dialog/sheet/notification 层)
gpui_kit::open_window(options, cx, |window, cx| {
cx.new(|cx| ui::app::MqttXApp::new(window, cx))
})
.expect("Failed to open window");
});
+2 -1
View File
@@ -31,7 +31,8 @@ fn set_topmost_windows(window: &gpui_kit::Window, topmost: bool) -> bool {
let hwnd = HWND(w.hwnd.get() as *mut core::ffi::c_void);
let insert = if topmost { HWND_TOPMOST } else { HWND_NOTOPMOST };
let flags = SET_WINDOW_POS_FLAGS(SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
unsafe { SetWindowPos(hwnd, insert, 0, 0, 0, 0, flags).is_ok() }
// windows 0.62 起 SetWindowPos 的插入位置参数改为 Option<HWND>
unsafe { SetWindowPos(hwnd, Some(insert), 0, 0, 0, 0, flags).is_ok() }
}
#[cfg(not(target_os = "windows"))]
+1 -4
View File
@@ -368,7 +368,7 @@ impl MqttXApp {
impl Render for MqttXApp {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
// 0.6.x 的 Root 不自动渲染 dialog/sheet/notification 层,需由内容视图挂载。
// 0.7 起 Root 自动渲染 dialog/sheet/notification 层,内容视图无需再手动挂载。
v_flex()
.size_full()
.bg(cx.theme().background)
@@ -381,8 +381,5 @@ impl Render for MqttXApp {
.child(self.render_sidebar(window, cx))
.child(self.render_main(window, cx)),
)
.children(gpui_kit::component::Root::render_sheet_layer(window, cx))
.children(gpui_kit::component::Root::render_dialog_layer(window, cx))
.children(gpui_kit::component::Root::render_notification_layer(window, cx))
}
}
+12 -9
View File
@@ -3,20 +3,23 @@
use super::*;
pub(super) fn agent() -> ureq::Agent {
ureq::AgentBuilder::new()
// 整体上限:防止慢速滴流的下载无限占用阻塞线程
.timeout(std::time::Duration::from_secs(10 * 60))
.timeout_connect(std::time::Duration::from_secs(HTTP_TIMEOUT_SECS))
.timeout_read(std::time::Duration::from_secs(HTTP_TIMEOUT_SECS))
.build()
ureq::Agent::new_with_config(
ureq::Agent::config_builder()
// 整体上限:防止慢速滴流的下载无限占用阻塞线程
.timeout_global(Some(std::time::Duration::from_secs(10 * 60)))
.timeout_connect(Some(std::time::Duration::from_secs(HTTP_TIMEOUT_SECS)))
.timeout_recv_response(Some(std::time::Duration::from_secs(HTTP_TIMEOUT_SECS)))
.build(),
)
}
pub(super) fn http_get_json(url: &str) -> Result<serde_json::Value, String> {
let resp = agent()
let mut body = agent()
.get(url)
.call()
.map_err(|e| format!("请求失败: {e}"))?;
resp.into_json::<serde_json::Value>()
.map_err(|e| format!("请求失败: {e}"))?
.into_body();
body.read_json::<serde_json::Value>()
.map_err(|e| format!("解析响应失败: {e}"))
}
+32 -5
View File
@@ -115,7 +115,8 @@ fn file_sha256(path: &Path) -> Result<String, String> {
}
hasher.update(&buf[..n]);
}
Ok(format!("{:x}", hasher.finalize()))
// digest 0.11 的 Output 不再实现 LowerHex,手动转 hex
Ok(hasher.finalize().iter().map(|b| format!("{b:02x}")).collect())
}
/// 校验 7z 归档的条目清单(只读归档头,不解压数据)。
@@ -240,7 +241,7 @@ fn download_to(info: &UpdateInfo, tmp: &std::path::Path, on_progress: &dyn Fn(u6
.get(&info.asset_url)
.call()
.map_err(|e| format!("下载失败: {e}"))?;
let mut reader = resp.into_reader();
let mut reader = resp.into_body().into_reader();
let total = info.size;
let mut file = std::fs::File::create(tmp).map_err(|e| format!("创建临时文件失败: {e}"))?;
let mut buf = [0u8; 64 * 1024];
@@ -274,7 +275,7 @@ fn download_to(info: &UpdateInfo, tmp: &std::path::Path, on_progress: &dyn Fn(u6
let expect = fetch_expected_sha256(info)?.ok_or_else(|| {
"Release 未提供 .sha256 校验文件,无法验证完整性,已拒绝安装".to_string()
})?;
let actual = format!("{:x}", hasher.finalize());
let actual: String = hasher.finalize().iter().map(|b| format!("{b:02x}")).collect();
if !actual.eq_ignore_ascii_case(&expect) {
return Err(format!("校验失败:期望 sha256 {expect},实际 {actual}"));
}
@@ -308,11 +309,13 @@ fn fetch_expected_sha256(info: &UpdateInfo) -> Result<Option<String>, String> {
let Some(url) = &info.sha256_url else {
return Ok(None);
};
let text = agent()
let mut body = agent()
.get(url)
.call()
.map_err(|e| format!("获取校验文件失败: {e}"))?
.into_string()
.into_body();
let text = body
.read_to_string()
.map_err(|e| format!("读取校验文件失败: {e}"))?;
// 常见格式:<hex> <filename> 或纯 hex
let hex = text
@@ -517,3 +520,27 @@ pub fn cleanup_old() {
}
// ─── 单元测试 ────────────────────────────────────────────────────────────────
#[cfg(test)]
mod tests {
use super::*;
/// sha256→hex 转换(digest 0.11 起 Output 不再实现 LowerHex)是 OTA
/// 完整性校验的关键路径,用固定向量锁定。
#[test]
fn file_sha256_matches_known_vector() {
let path = std::env::temp_dir().join(format!(
"mqttx-sha-test-{}-{}.txt",
std::process::id(),
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_nanos())
.unwrap_or(0)
));
std::fs::write(&path, b"abc").expect("写入测试文件");
let hex = file_sha256(&path).expect("计算 sha256");
let _ = std::fs::remove_file(&path);
// echo -n abc | sha256sum
assert_eq!(hex, "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad");
}
}