mirror of
https://github.com/zellij-org/zellij.git
synced 2026-10-12 02:27:24 +00:00
Move from native-tls to rustls in the remote client (mirrors the web server) (#4972)
* native-tls -> rustls * add/update tests * rustfmt * add pr
This commit is contained in:
@@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
* feat: add --layout-string to allow for in-line layouts, add --tab-id to all new-pane CLI commands (https://github.com/zellij-org/zellij/pull/4956)
|
||||
* fix: proper error on socket paths that are too long (https://github.com/zellij-org/zellij/pull/4957)
|
||||
* fix: scrollback with partial scroll region (eg. Codex bug) (https://github.com/zellij-org/zellij/pull/4941)
|
||||
* fix: remote attach issues on macOS (https://github.com/zellij-org/zellij/pull/4972)
|
||||
|
||||
## [0.44.0] - 2026-03-23
|
||||
* fix: meta key handling in web client (https://github.com/zellij-org/zellij/pull/4376)
|
||||
|
||||
Generated
+84
-98
@@ -331,9 +331,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.5.0"
|
||||
version = "2.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
@@ -623,9 +623,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.3"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
|
||||
checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
@@ -720,7 +720,7 @@ version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
"crossterm_winapi",
|
||||
"mio 1.0.3",
|
||||
"parking_lot 0.12.1",
|
||||
@@ -767,7 +767,7 @@ checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22"
|
||||
dependencies = [
|
||||
"curl-sys",
|
||||
"libc",
|
||||
"openssl-probe",
|
||||
"openssl-probe 0.1.5",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"socket2 0.4.9",
|
||||
@@ -1084,21 +1084,6 @@ version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.1"
|
||||
@@ -1974,7 +1959,7 @@ version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
"libc",
|
||||
"redox_syscall 0.5.13",
|
||||
]
|
||||
@@ -2223,23 +2208,6 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.23.1"
|
||||
@@ -2269,7 +2237,7 @@ version = "6.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
"crossbeam-channel",
|
||||
"filetime",
|
||||
"fsevent-sys",
|
||||
@@ -2344,38 +2312,18 @@ version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.96",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-src"
|
||||
version = "300.5.4+3.5.4"
|
||||
@@ -2470,6 +2418,16 @@ dependencies = [
|
||||
"windows-targets 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pem"
|
||||
version = "3.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
@@ -2743,6 +2701,19 @@ dependencies = [
|
||||
"zerocopy 0.8.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rcgen"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2"
|
||||
dependencies = [
|
||||
"pem",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"time",
|
||||
"yasna",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "recvmsg"
|
||||
version = "1.0.0"
|
||||
@@ -2773,7 +2744,7 @@ version = "0.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2824,7 +2795,7 @@ version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a78046161564f5e7cd9008aff3b2990b3850dc8e0349119b98e8f251e099f24d"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
"fallible-iterator",
|
||||
"fallible-streaming-iterator",
|
||||
"hashlink",
|
||||
@@ -2867,7 +2838,7 @@ version = "0.38.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.4.15",
|
||||
@@ -2880,7 +2851,7 @@ version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.11.0",
|
||||
@@ -2904,6 +2875,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"log",
|
||||
"once_cell",
|
||||
"rustls-pki-types",
|
||||
"rustls-webpki",
|
||||
@@ -2911,6 +2883,18 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-native-certs"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
|
||||
dependencies = [
|
||||
"openssl-probe 0.2.1",
|
||||
"rustls-pki-types",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "2.2.0"
|
||||
@@ -2994,11 +2978,11 @@ checksum = "584e070911c7017da6cb2eb0788d09f43d789029b5877d3e5ecc8acf86ceee21"
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.10.0"
|
||||
version = "3.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6"
|
||||
checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags 2.11.0",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
@@ -3007,9 +2991,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.11.0"
|
||||
version = "2.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7"
|
||||
checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
@@ -3529,7 +3513,7 @@ version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b858526d22750088a9b3cf2e3c2aacebd5377f13adeec02860c30d09113010a6"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
"cap-fs-ext",
|
||||
"cap-std",
|
||||
"fd-lock",
|
||||
@@ -3722,16 +3706,6 @@ dependencies = [
|
||||
"syn 2.0.96",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.26.2"
|
||||
@@ -3761,9 +3735,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tungstenite 0.20.1",
|
||||
]
|
||||
|
||||
@@ -3863,7 +3835,7 @@ version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fdb0c213ca27a9f57ab69ddb290fd80d970922355b83ae380b395d3986b8a2e"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
"bytes",
|
||||
"http 1.3.1",
|
||||
"pin-project-lite",
|
||||
@@ -3937,7 +3909,6 @@ dependencies = [
|
||||
"http 0.2.9",
|
||||
"httparse",
|
||||
"log",
|
||||
"native-tls",
|
||||
"rand 0.8.5",
|
||||
"sha1",
|
||||
"thiserror 1.0.61",
|
||||
@@ -4187,7 +4158,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82735a180c58e86727965ca39c0390d21c86a354f03cf7a3fc73f1de4c01ae1c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
"cap-fs-ext",
|
||||
"cap-rand",
|
||||
"cap-std",
|
||||
@@ -4326,7 +4297,7 @@ version = "0.228.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4abf1132c1fdf747d56bbc1bb52152400c70f336870f968b85e89ea422198ae3"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
"indexmap 2.7.1",
|
||||
]
|
||||
|
||||
@@ -4336,7 +4307,7 @@ version = "0.239.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c9d90bb93e764f6beabf1d02028c70a2156a6583e63ac4218dd07ef733368b0"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
"indexmap 2.7.1",
|
||||
]
|
||||
|
||||
@@ -4405,7 +4376,7 @@ checksum = "b61d3bcb6a981233e8b774738f4495ad2c724a0d73ac626f373944e9ba1e3101"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
"thiserror 2.0.12",
|
||||
"tracing",
|
||||
"wiggle-macro",
|
||||
@@ -4700,7 +4671,7 @@ version = "0.36.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9643b83820c0cd246ecabe5fa454dd04ba4fa67996369466d0747472d337346"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
@@ -4710,7 +4681,7 @@ version = "0.33.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4783,6 +4754,15 @@ dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yasna"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd"
|
||||
dependencies = [
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.8.1"
|
||||
@@ -4853,18 +4833,24 @@ dependencies = [
|
||||
"isahc",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"native-tls",
|
||||
"nix",
|
||||
"notify",
|
||||
"num_cpus",
|
||||
"rcgen",
|
||||
"regex",
|
||||
"rustls",
|
||||
"rustls-native-certs",
|
||||
"rustls-pemfile",
|
||||
"rustls-pki-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"serial_test",
|
||||
"signal-hook",
|
||||
"tempfile",
|
||||
"time",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tokio-tungstenite 0.20.1",
|
||||
"tokio-util",
|
||||
"tower-http",
|
||||
@@ -4951,7 +4937,7 @@ version = "0.44.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"backtrace",
|
||||
"bitflags 2.5.0",
|
||||
"bitflags 2.11.0",
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"colored",
|
||||
|
||||
@@ -39,8 +39,12 @@ zellij-utils = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
tokio-util = { workspace = true }
|
||||
isahc = { workspace = true }
|
||||
tokio-tungstenite = { version = "0.20", features = ["native-tls"] } #TODO: see about this native-tls...
|
||||
native-tls = "0.2"
|
||||
tokio-tungstenite = "0.20"
|
||||
rustls = { version = "0.23", default-features = false, features = ["std"] }
|
||||
tokio-rustls = "0.26"
|
||||
rustls-pemfile = "2"
|
||||
rustls-native-certs = "0.8"
|
||||
rustls-pki-types = "1"
|
||||
futures-util = "0.3"
|
||||
urlencoding = "2.1"
|
||||
|
||||
@@ -61,8 +65,10 @@ windows-sys = { workspace = true, features = [
|
||||
|
||||
[dev-dependencies]
|
||||
insta = "1.6.0"
|
||||
rcgen = "0.13"
|
||||
serde_json = "1.0"
|
||||
serial_test = "3.0"
|
||||
tempfile = "3"
|
||||
|
||||
[features]
|
||||
unstable = []
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
mod auth;
|
||||
mod config;
|
||||
mod http_client;
|
||||
mod websockets;
|
||||
pub mod http_client;
|
||||
pub mod websockets;
|
||||
|
||||
#[cfg(test)]
|
||||
mod unit;
|
||||
|
||||
@@ -59,11 +59,11 @@ mod mock_server {
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct LoginRequest {
|
||||
auth_token: String,
|
||||
pub struct LoginRequest {
|
||||
pub auth_token: String,
|
||||
}
|
||||
|
||||
async fn handle_login(
|
||||
pub async fn handle_login(
|
||||
State(state): State<MockRemoteServerState>,
|
||||
jar: CookieJar,
|
||||
Json(payload): Json<LoginRequest>,
|
||||
@@ -101,7 +101,7 @@ mod mock_server {
|
||||
))
|
||||
}
|
||||
|
||||
async fn handle_session(
|
||||
pub async fn handle_session(
|
||||
State(state): State<MockRemoteServerState>,
|
||||
jar: CookieJar,
|
||||
) -> Result<Json<serde_json::Value>, StatusCode> {
|
||||
@@ -124,7 +124,7 @@ mod mock_server {
|
||||
})))
|
||||
}
|
||||
|
||||
async fn handle_ws_terminal(
|
||||
pub async fn handle_ws_terminal(
|
||||
ws: axum::extract::ws::WebSocketUpgrade,
|
||||
State(state): State<MockRemoteServerState>,
|
||||
jar: CookieJar,
|
||||
@@ -157,7 +157,7 @@ mod mock_server {
|
||||
}))
|
||||
}
|
||||
|
||||
async fn handle_ws_control(
|
||||
pub async fn handle_ws_control(
|
||||
ws: axum::extract::ws::WebSocketUpgrade,
|
||||
State(state): State<MockRemoteServerState>,
|
||||
jar: CookieJar,
|
||||
@@ -215,6 +215,112 @@ mod mock_server {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "web_server_capability")]
|
||||
mod tls_mock_server {
|
||||
use super::mock_server::MockRemoteServerState;
|
||||
use axum::routing::{get, post};
|
||||
use axum::Router;
|
||||
use axum_server::tls_rustls::RustlsConfig;
|
||||
use axum_server::Handle;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
|
||||
pub struct TlsTestCerts {
|
||||
pub ca_cert_path: PathBuf,
|
||||
_ca_cert_file: tempfile::NamedTempFile,
|
||||
_server_cert_file: tempfile::NamedTempFile,
|
||||
_server_key_file: tempfile::NamedTempFile,
|
||||
server_cert_path: PathBuf,
|
||||
server_key_path: PathBuf,
|
||||
}
|
||||
|
||||
pub fn generate_test_certs() -> TlsTestCerts {
|
||||
// Create a CA with proper key usage
|
||||
let ca_key = rcgen::KeyPair::generate().unwrap();
|
||||
let mut ca_params = rcgen::CertificateParams::new(Vec::<String>::new()).unwrap();
|
||||
ca_params.is_ca = rcgen::IsCa::Ca(rcgen::BasicConstraints::Unconstrained);
|
||||
ca_params.key_usages = vec![
|
||||
rcgen::KeyUsagePurpose::KeyCertSign,
|
||||
rcgen::KeyUsagePurpose::CrlSign,
|
||||
];
|
||||
let ca = ca_params.self_signed(&ca_key).unwrap();
|
||||
|
||||
// Create server cert with IP SAN only (no DNS name for IP addresses)
|
||||
let mut server_params = rcgen::CertificateParams::new(Vec::<String>::new()).unwrap();
|
||||
server_params.subject_alt_names = vec![rcgen::SanType::IpAddress(std::net::IpAddr::V4(
|
||||
std::net::Ipv4Addr::LOCALHOST,
|
||||
))];
|
||||
server_params.extended_key_usages = vec![rcgen::ExtendedKeyUsagePurpose::ServerAuth];
|
||||
let server_key = rcgen::KeyPair::generate().unwrap();
|
||||
let server_cert = server_params.signed_by(&server_key, &ca, &ca_key).unwrap();
|
||||
|
||||
// Write to temp files
|
||||
let ca_cert_file = tempfile::NamedTempFile::new().unwrap();
|
||||
std::fs::write(ca_cert_file.path(), ca.pem()).unwrap();
|
||||
|
||||
let server_cert_file = tempfile::NamedTempFile::new().unwrap();
|
||||
std::fs::write(server_cert_file.path(), server_cert.pem()).unwrap();
|
||||
|
||||
let server_key_file = tempfile::NamedTempFile::new().unwrap();
|
||||
std::fs::write(server_key_file.path(), server_key.serialize_pem()).unwrap();
|
||||
|
||||
TlsTestCerts {
|
||||
ca_cert_path: ca_cert_file.path().to_path_buf(),
|
||||
server_cert_path: server_cert_file.path().to_path_buf(),
|
||||
server_key_path: server_key_file.path().to_path_buf(),
|
||||
_ca_cert_file: ca_cert_file,
|
||||
_server_cert_file: server_cert_file,
|
||||
_server_key_file: server_key_file,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn start_tls_mock_server(
|
||||
state: MockRemoteServerState,
|
||||
certs: &TlsTestCerts,
|
||||
) -> (u16, Handle, tokio::task::JoinHandle<()>) {
|
||||
let app = Router::new()
|
||||
.route("/command/login", post(super::mock_server::handle_login))
|
||||
.route("/session", post(super::mock_server::handle_session))
|
||||
.route("/ws/terminal", get(super::mock_server::handle_ws_terminal))
|
||||
.route(
|
||||
"/ws/terminal/{session_name}",
|
||||
get(super::mock_server::handle_ws_terminal),
|
||||
)
|
||||
.route("/ws/control", get(super::mock_server::handle_ws_control))
|
||||
.with_state(state);
|
||||
|
||||
let rustls_config =
|
||||
RustlsConfig::from_pem_file(&certs.server_cert_path, &certs.server_key_path)
|
||||
.await
|
||||
.expect("Failed to load test TLS config");
|
||||
|
||||
let listener =
|
||||
std::net::TcpListener::bind("127.0.0.1:0").expect("Failed to bind test TLS server");
|
||||
let port = listener.local_addr().unwrap().port();
|
||||
|
||||
let handle = Handle::new();
|
||||
let server_handle = handle.clone();
|
||||
|
||||
let server_task = tokio::spawn(async move {
|
||||
axum_server::from_tcp_rustls(listener, rustls_config)
|
||||
.handle(server_handle)
|
||||
.serve(app.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
// Wait for the server to be listening (deterministic, no sleep)
|
||||
handle.listening().await;
|
||||
|
||||
(port, handle, server_task)
|
||||
}
|
||||
|
||||
pub async fn shutdown_server(handle: Handle, server_task: tokio::task::JoinHandle<()>) {
|
||||
handle.graceful_shutdown(Some(Duration::from_secs(1)));
|
||||
let _ = server_task.await;
|
||||
}
|
||||
}
|
||||
|
||||
// Database test helpers
|
||||
fn setup_test_db(server_url: &str) {
|
||||
let _ = remote_session_tokens::delete_session_token(server_url);
|
||||
@@ -658,6 +764,172 @@ mod tests {
|
||||
RemoteClientError::UrlParseError(_)
|
||||
));
|
||||
}
|
||||
|
||||
// -- TLS tests ------------------------------------------------------------
|
||||
//
|
||||
// These tests exercise the rustls WebSocket TLS code paths added by the
|
||||
// native-tls → rustls migration. They call establish_websocket_connections
|
||||
// directly rather than going through attach_to_remote_session, because:
|
||||
//
|
||||
// 1. The HTTP auth step (isahc/curl) uses a separate TLS stack that was
|
||||
// not changed by this migration — it is tested by the non-TLS tests above.
|
||||
// 2. attach_to_remote_session opens the SQLite session-token database,
|
||||
// which can cause I/O contention with web_client tests that use a
|
||||
// different SQLite database in the same directory.
|
||||
//
|
||||
// Each test seeds a session directly in the mock server state and
|
||||
// pre-populates the HTTP client cookie, then connects over wss://.
|
||||
|
||||
/// Helper: create an HTTP client with a pre-seeded session cookie and
|
||||
/// register the session in the mock server state. Returns (web_client_id,
|
||||
/// http_client).
|
||||
fn seed_mock_session(
|
||||
server_state: &MockRemoteServerState,
|
||||
) -> (
|
||||
String,
|
||||
crate::remote_attach::http_client::HttpClientWithCookies,
|
||||
) {
|
||||
let session_token = uuid::Uuid::new_v4().to_string();
|
||||
let web_client_id = uuid::Uuid::new_v4().to_string();
|
||||
server_state
|
||||
.session_tokens
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(session_token.clone(), web_client_id.clone());
|
||||
|
||||
// The HTTP client is only used for its cookie jar (WebSocket upgrade
|
||||
// sends the session cookie). TLS for this client is irrelevant since
|
||||
// it never makes HTTP requests in these tests.
|
||||
let http_client =
|
||||
crate::remote_attach::http_client::HttpClientWithCookies::new(None, true).unwrap();
|
||||
http_client.set_cookie("session_token".to_string(), session_token);
|
||||
|
||||
(web_client_id, http_client)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn test_tls_insecure_mode() {
|
||||
use crate::remote_attach::websockets;
|
||||
|
||||
let certs = tls_mock_server::generate_test_certs();
|
||||
let server_state = MockRemoteServerState::new();
|
||||
|
||||
let (port, handle, server_task) =
|
||||
tls_mock_server::start_tls_mock_server(server_state.clone(), &certs).await;
|
||||
|
||||
let (web_client_id, http_client) = seed_mock_session(&server_state);
|
||||
let server_base_url = format!("https://127.0.0.1:{}", port);
|
||||
|
||||
let result = tokio::time::timeout(
|
||||
Duration::from_secs(10),
|
||||
websockets::establish_websocket_connections(
|
||||
&web_client_id,
|
||||
&http_client,
|
||||
&server_base_url,
|
||||
"test-session",
|
||||
None,
|
||||
true, // insecure — exercises NoVerifier
|
||||
),
|
||||
)
|
||||
.await
|
||||
.expect("Test timed out");
|
||||
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"TLS insecure mode should connect successfully: {:?}",
|
||||
result.err()
|
||||
);
|
||||
|
||||
let connections = result.unwrap();
|
||||
assert!(!connections.web_client_id.is_empty());
|
||||
|
||||
let endpoints = server_state.get_endpoints_called();
|
||||
assert!(endpoints.contains(&"/ws/terminal".to_string()));
|
||||
assert!(endpoints.contains(&"/ws/control".to_string()));
|
||||
|
||||
tls_mock_server::shutdown_server(handle, server_task).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn test_tls_ca_cert_mode() {
|
||||
use crate::remote_attach::websockets;
|
||||
|
||||
let certs = tls_mock_server::generate_test_certs();
|
||||
let server_state = MockRemoteServerState::new();
|
||||
|
||||
let (port, handle, server_task) =
|
||||
tls_mock_server::start_tls_mock_server(server_state.clone(), &certs).await;
|
||||
|
||||
let (web_client_id, http_client) = seed_mock_session(&server_state);
|
||||
let server_base_url = format!("https://127.0.0.1:{}", port);
|
||||
|
||||
let result = tokio::time::timeout(
|
||||
Duration::from_secs(10),
|
||||
websockets::establish_websocket_connections(
|
||||
&web_client_id,
|
||||
&http_client,
|
||||
&server_base_url,
|
||||
"test-session",
|
||||
Some(certs.ca_cert_path.as_path()),
|
||||
false, // not insecure — verify against CA cert
|
||||
),
|
||||
)
|
||||
.await
|
||||
.expect("Test timed out");
|
||||
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"WebSocket TLS with CA cert should connect successfully: {:?}",
|
||||
result.err()
|
||||
);
|
||||
|
||||
let connections = result.unwrap();
|
||||
assert!(!connections.web_client_id.is_empty());
|
||||
|
||||
let endpoints = server_state.get_endpoints_called();
|
||||
assert!(endpoints.contains(&"/ws/terminal".to_string()));
|
||||
assert!(endpoints.contains(&"/ws/control".to_string()));
|
||||
|
||||
tls_mock_server::shutdown_server(handle, server_task).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn test_tls_rejects_untrusted_cert() {
|
||||
use crate::remote_attach::websockets;
|
||||
|
||||
let certs = tls_mock_server::generate_test_certs();
|
||||
let server_state = MockRemoteServerState::new();
|
||||
|
||||
let (port, handle, server_task) =
|
||||
tls_mock_server::start_tls_mock_server(server_state.clone(), &certs).await;
|
||||
|
||||
let (web_client_id, http_client) = seed_mock_session(&server_state);
|
||||
let server_base_url = format!("https://127.0.0.1:{}", port);
|
||||
|
||||
let result = tokio::time::timeout(
|
||||
Duration::from_secs(10),
|
||||
websockets::establish_websocket_connections(
|
||||
&web_client_id,
|
||||
&http_client,
|
||||
&server_base_url,
|
||||
"test-session",
|
||||
None, // no CA cert
|
||||
false, // not insecure — should reject self-signed
|
||||
),
|
||||
)
|
||||
.await
|
||||
.expect("Test timed out");
|
||||
|
||||
assert!(
|
||||
result.is_err(),
|
||||
"TLS without CA cert should reject self-signed server"
|
||||
);
|
||||
|
||||
tls_mock_server::shutdown_server(handle, server_task).await;
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that don't require the web_server_capability feature
|
||||
|
||||
@@ -1,14 +1,178 @@
|
||||
use super::config::{WS_CONTROL_ENDPOINT, WS_TERMINAL_ENDPOINT};
|
||||
use super::http_client::HttpClientWithCookies;
|
||||
use std::path::Path;
|
||||
use std::pin::Pin;
|
||||
use std::sync::Arc;
|
||||
use std::task::{Context, Poll};
|
||||
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
|
||||
use tokio::net::TcpStream;
|
||||
use tokio_tungstenite::{
|
||||
connect_async_tls_with_config, Connector, MaybeTlsStream, WebSocketStream,
|
||||
};
|
||||
use tokio_tungstenite::WebSocketStream;
|
||||
|
||||
// -- MaybeTls stream enum -------------------------------------------------
|
||||
|
||||
/// A TCP stream that may or may not be wrapped in TLS.
|
||||
pub enum MaybeTls {
|
||||
Plain(TcpStream),
|
||||
Tls(tokio_rustls::client::TlsStream<TcpStream>),
|
||||
}
|
||||
|
||||
impl AsyncRead for MaybeTls {
|
||||
fn poll_read(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &mut ReadBuf<'_>,
|
||||
) -> Poll<std::io::Result<()>> {
|
||||
match self.get_mut() {
|
||||
MaybeTls::Plain(s) => Pin::new(s).poll_read(cx, buf),
|
||||
MaybeTls::Tls(s) => Pin::new(s).poll_read(cx, buf),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncWrite for MaybeTls {
|
||||
fn poll_write(
|
||||
self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &[u8],
|
||||
) -> Poll<std::io::Result<usize>> {
|
||||
match self.get_mut() {
|
||||
MaybeTls::Plain(s) => Pin::new(s).poll_write(cx, buf),
|
||||
MaybeTls::Tls(s) => Pin::new(s).poll_write(cx, buf),
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
|
||||
match self.get_mut() {
|
||||
MaybeTls::Plain(s) => Pin::new(s).poll_flush(cx),
|
||||
MaybeTls::Tls(s) => Pin::new(s).poll_flush(cx),
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
|
||||
match self.get_mut() {
|
||||
MaybeTls::Plain(s) => Pin::new(s).poll_shutdown(cx),
|
||||
MaybeTls::Tls(s) => Pin::new(s).poll_shutdown(cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- NoVerifier (for --insecure mode) --------------------------------------
|
||||
|
||||
#[derive(Debug)]
|
||||
struct NoVerifier;
|
||||
|
||||
impl rustls::client::danger::ServerCertVerifier for NoVerifier {
|
||||
fn verify_server_cert(
|
||||
&self,
|
||||
_end_entity: &rustls_pki_types::CertificateDer<'_>,
|
||||
_intermediates: &[rustls_pki_types::CertificateDer<'_>],
|
||||
_server_name: &rustls_pki_types::ServerName<'_>,
|
||||
_ocsp_response: &[u8],
|
||||
_now: rustls_pki_types::UnixTime,
|
||||
) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
|
||||
Ok(rustls::client::danger::ServerCertVerified::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
_message: &[u8],
|
||||
_cert: &rustls_pki_types::CertificateDer<'_>,
|
||||
_dss: &rustls::DigitallySignedStruct,
|
||||
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
|
||||
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
_message: &[u8],
|
||||
_cert: &rustls_pki_types::CertificateDer<'_>,
|
||||
_dss: &rustls::DigitallySignedStruct,
|
||||
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
|
||||
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
|
||||
rustls::crypto::aws_lc_rs::default_provider()
|
||||
.signature_verification_algorithms
|
||||
.supported_schemes()
|
||||
}
|
||||
}
|
||||
|
||||
// -- TLS config builder ----------------------------------------------------
|
||||
|
||||
fn build_tls_config(
|
||||
ca_cert: Option<&Path>,
|
||||
insecure: bool,
|
||||
) -> Result<Arc<rustls::ClientConfig>, Box<dyn std::error::Error>> {
|
||||
let provider = Arc::new(rustls::crypto::aws_lc_rs::default_provider());
|
||||
|
||||
if insecure {
|
||||
let config = rustls::ClientConfig::builder_with_provider(provider)
|
||||
.with_safe_default_protocol_versions()?
|
||||
.dangerous()
|
||||
.with_custom_certificate_verifier(Arc::new(NoVerifier))
|
||||
.with_no_client_auth();
|
||||
Ok(Arc::new(config))
|
||||
} else if let Some(ca_path) = ca_cert {
|
||||
let ca_pem = std::fs::read(ca_path)?;
|
||||
let mut cursor = std::io::Cursor::new(ca_pem);
|
||||
let certs: Vec<rustls_pki_types::CertificateDer<'static>> =
|
||||
rustls_pemfile::certs(&mut cursor)
|
||||
.filter_map(|r| r.ok())
|
||||
.collect();
|
||||
let mut root_store = rustls::RootCertStore::empty();
|
||||
for cert in certs {
|
||||
root_store.add(cert)?;
|
||||
}
|
||||
let config = rustls::ClientConfig::builder_with_provider(provider)
|
||||
.with_safe_default_protocol_versions()?
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth();
|
||||
Ok(Arc::new(config))
|
||||
} else {
|
||||
let native_certs = rustls_native_certs::load_native_certs();
|
||||
for err in &native_certs.errors {
|
||||
log::warn!("Error loading native certificate: {}", err);
|
||||
}
|
||||
let mut root_store = rustls::RootCertStore::empty();
|
||||
root_store.add_parsable_certificates(native_certs.certs);
|
||||
let config = rustls::ClientConfig::builder_with_provider(provider)
|
||||
.with_safe_default_protocol_versions()?
|
||||
.with_root_certificates(root_store)
|
||||
.with_no_client_auth();
|
||||
Ok(Arc::new(config))
|
||||
}
|
||||
}
|
||||
|
||||
// -- WebSocket connection helpers ------------------------------------------
|
||||
|
||||
async fn connect_ws(
|
||||
request: tokio_tungstenite::tungstenite::http::Request<()>,
|
||||
host: &str,
|
||||
port: u16,
|
||||
tls_config: Option<Arc<rustls::ClientConfig>>,
|
||||
) -> Result<WebSocketStream<MaybeTls>, Box<dyn std::error::Error>> {
|
||||
let tcp_stream = TcpStream::connect((host, port)).await?;
|
||||
|
||||
let stream = if let Some(config) = tls_config {
|
||||
let connector = tokio_rustls::TlsConnector::from(config);
|
||||
let server_name = rustls_pki_types::ServerName::try_from(host.to_string())?;
|
||||
let tls_stream = connector.connect(server_name, tcp_stream).await?;
|
||||
MaybeTls::Tls(tls_stream)
|
||||
} else {
|
||||
MaybeTls::Plain(tcp_stream)
|
||||
};
|
||||
|
||||
let (ws_stream, _response) =
|
||||
tokio_tungstenite::client_async_with_config(request, stream, None).await?;
|
||||
Ok(ws_stream)
|
||||
}
|
||||
|
||||
// -- Public API ------------------------------------------------------------
|
||||
|
||||
pub struct WebSocketConnections {
|
||||
pub terminal_ws: WebSocketStream<MaybeTlsStream<TcpStream>>,
|
||||
pub control_ws: WebSocketStream<MaybeTlsStream<TcpStream>>,
|
||||
pub terminal_ws: WebSocketStream<MaybeTls>,
|
||||
pub control_ws: WebSocketStream<MaybeTls>,
|
||||
pub web_client_id: String,
|
||||
}
|
||||
|
||||
@@ -28,14 +192,18 @@ pub async fn establish_websocket_connections(
|
||||
ca_cert: Option<&Path>,
|
||||
insecure: bool,
|
||||
) -> Result<WebSocketConnections, Box<dyn std::error::Error>> {
|
||||
let ws_protocol = if server_base_url.starts_with("https") {
|
||||
"wss"
|
||||
} else {
|
||||
"ws"
|
||||
};
|
||||
let base_host = server_base_url
|
||||
.replace("https://", "")
|
||||
.replace("http://", "");
|
||||
let parsed_url = url::Url::parse(server_base_url)?;
|
||||
let host = parsed_url
|
||||
.host_str()
|
||||
.ok_or("no host in server URL")?
|
||||
.to_string();
|
||||
let port = parsed_url
|
||||
.port_or_known_default()
|
||||
.ok_or("no port in server URL")?;
|
||||
let is_tls = parsed_url.scheme() == "https";
|
||||
|
||||
let ws_protocol = if is_tls { "wss" } else { "ws" };
|
||||
let base_host = format!("{}:{}", host, port);
|
||||
|
||||
let terminal_url = if session_name.is_empty() {
|
||||
format!(
|
||||
@@ -59,7 +227,7 @@ pub async fn establish_websocket_connections(
|
||||
log::info!("Connecting to terminal WebSocket: {}", terminal_url);
|
||||
log::info!("Connecting to control WebSocket: {}", control_url);
|
||||
|
||||
// Create WebSocket request with cookies
|
||||
// Build WebSocket requests with cookies
|
||||
let mut terminal_request = tokio_tungstenite::tungstenite::http::Request::builder()
|
||||
.uri(&terminal_url)
|
||||
.header("Host", &base_host)
|
||||
@@ -91,29 +259,16 @@ pub async fn establish_websocket_connections(
|
||||
let terminal_request = terminal_request.body(())?;
|
||||
let control_request = control_request.body(())?;
|
||||
|
||||
// Build TLS connector based on ca_cert/insecure settings
|
||||
let connector = if insecure {
|
||||
let tls_connector = native_tls::TlsConnector::builder()
|
||||
.danger_accept_invalid_certs(true)
|
||||
.danger_accept_invalid_hostnames(true)
|
||||
.build()?;
|
||||
Some(Connector::NativeTls(tls_connector))
|
||||
} else if let Some(ca_path) = ca_cert {
|
||||
let ca_pem = std::fs::read(ca_path)?;
|
||||
let ca_cert = native_tls::Certificate::from_pem(&ca_pem)?;
|
||||
let tls_connector = native_tls::TlsConnector::builder()
|
||||
.add_root_certificate(ca_cert)
|
||||
.build()?;
|
||||
Some(Connector::NativeTls(tls_connector))
|
||||
// Build TLS config (only for wss://)
|
||||
let tls_config = if is_tls {
|
||||
Some(build_tls_config(ca_cert, insecure)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Connect to both WebSockets concurrently
|
||||
let (terminal_ws, _) =
|
||||
connect_async_tls_with_config(terminal_request, None, false, connector.clone()).await?;
|
||||
let (control_ws, _) =
|
||||
connect_async_tls_with_config(control_request, None, false, connector).await?;
|
||||
// Connect to both WebSockets
|
||||
let terminal_ws = connect_ws(terminal_request, &host, port, tls_config.clone()).await?;
|
||||
let control_ws = connect_ws(control_request, &host, port, tls_config).await?;
|
||||
|
||||
Ok(WebSocketConnections {
|
||||
terminal_ws,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::os_input_output::{AsyncSignals, AsyncStdin, ClientOsApi, SignalEvent};
|
||||
use crate::remote_attach::websockets::MaybeTls;
|
||||
use crate::remote_attach::WebSocketConnections;
|
||||
use crate::run_remote_client_terminal_loop;
|
||||
use crate::web_client::control_message::{
|
||||
@@ -11,8 +12,8 @@ use serial_test::serial;
|
||||
use std::io::{self, Write};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
use tokio::net::TcpStream;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio_tungstenite::connect_async;
|
||||
use tokio_tungstenite::tungstenite::Message;
|
||||
use zellij_utils::data::Palette;
|
||||
use zellij_utils::errors::ErrorContext;
|
||||
@@ -325,8 +326,26 @@ async fn test_stdin_forwarded_to_terminal_websocket() {
|
||||
let terminal_url = format!("ws://127.0.0.1:{}/ws/terminal", port);
|
||||
let control_url = format!("ws://127.0.0.1:{}/ws/control", port);
|
||||
|
||||
let (terminal_ws, _) = connect_async(&terminal_url).await.unwrap();
|
||||
let (control_ws, _) = connect_async(&control_url).await.unwrap();
|
||||
let terminal_tcp = TcpStream::connect(format!("127.0.0.1:{}", port))
|
||||
.await
|
||||
.unwrap();
|
||||
let (terminal_ws, _) = tokio_tungstenite::client_async_with_config(
|
||||
&terminal_url,
|
||||
MaybeTls::Plain(terminal_tcp),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let control_tcp = TcpStream::connect(format!("127.0.0.1:{}", port))
|
||||
.await
|
||||
.unwrap();
|
||||
let (control_ws, _) = tokio_tungstenite::client_async_with_config(
|
||||
&control_url,
|
||||
MaybeTls::Plain(control_tcp),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let connections = WebSocketConnections {
|
||||
terminal_ws,
|
||||
@@ -379,8 +398,26 @@ async fn test_terminal_output_written_to_stdout() {
|
||||
let terminal_url = format!("ws://127.0.0.1:{}/ws/terminal", port);
|
||||
let control_url = format!("ws://127.0.0.1:{}/ws/control", port);
|
||||
|
||||
let (terminal_ws, _) = connect_async(&terminal_url).await.unwrap();
|
||||
let (control_ws, _) = connect_async(&control_url).await.unwrap();
|
||||
let terminal_tcp = TcpStream::connect(format!("127.0.0.1:{}", port))
|
||||
.await
|
||||
.unwrap();
|
||||
let (terminal_ws, _) = tokio_tungstenite::client_async_with_config(
|
||||
&terminal_url,
|
||||
MaybeTls::Plain(terminal_tcp),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let control_tcp = TcpStream::connect(format!("127.0.0.1:{}", port))
|
||||
.await
|
||||
.unwrap();
|
||||
let (control_ws, _) = tokio_tungstenite::client_async_with_config(
|
||||
&control_url,
|
||||
MaybeTls::Plain(control_tcp),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let connections = WebSocketConnections {
|
||||
terminal_ws,
|
||||
@@ -436,8 +473,26 @@ async fn test_resize_signal_sends_control_message() {
|
||||
let terminal_url = format!("ws://127.0.0.1:{}/ws/terminal", port);
|
||||
let control_url = format!("ws://127.0.0.1:{}/ws/control", port);
|
||||
|
||||
let (terminal_ws, _) = connect_async(&terminal_url).await.unwrap();
|
||||
let (control_ws, _) = connect_async(&control_url).await.unwrap();
|
||||
let terminal_tcp = TcpStream::connect(format!("127.0.0.1:{}", port))
|
||||
.await
|
||||
.unwrap();
|
||||
let (terminal_ws, _) = tokio_tungstenite::client_async_with_config(
|
||||
&terminal_url,
|
||||
MaybeTls::Plain(terminal_tcp),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let control_tcp = TcpStream::connect(format!("127.0.0.1:{}", port))
|
||||
.await
|
||||
.unwrap();
|
||||
let (control_ws, _) = tokio_tungstenite::client_async_with_config(
|
||||
&control_url,
|
||||
MaybeTls::Plain(control_tcp),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let connections = WebSocketConnections {
|
||||
terminal_ws,
|
||||
@@ -509,8 +564,26 @@ async fn test_quit_signal_exits_loop() {
|
||||
let terminal_url = format!("ws://127.0.0.1:{}/ws/terminal", port);
|
||||
let control_url = format!("ws://127.0.0.1:{}/ws/control", port);
|
||||
|
||||
let (terminal_ws, _) = connect_async(&terminal_url).await.unwrap();
|
||||
let (control_ws, _) = connect_async(&control_url).await.unwrap();
|
||||
let terminal_tcp = TcpStream::connect(format!("127.0.0.1:{}", port))
|
||||
.await
|
||||
.unwrap();
|
||||
let (terminal_ws, _) = tokio_tungstenite::client_async_with_config(
|
||||
&terminal_url,
|
||||
MaybeTls::Plain(terminal_tcp),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let control_tcp = TcpStream::connect(format!("127.0.0.1:{}", port))
|
||||
.await
|
||||
.unwrap();
|
||||
let (control_ws, _) = tokio_tungstenite::client_async_with_config(
|
||||
&control_url,
|
||||
MaybeTls::Plain(control_tcp),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let connections = WebSocketConnections {
|
||||
terminal_ws,
|
||||
@@ -546,8 +619,26 @@ async fn test_websocket_close_exits_loop() {
|
||||
let terminal_url = format!("ws://127.0.0.1:{}/ws/terminal", port);
|
||||
let control_url = format!("ws://127.0.0.1:{}/ws/control", port);
|
||||
|
||||
let (terminal_ws, _) = connect_async(&terminal_url).await.unwrap();
|
||||
let (control_ws, _) = connect_async(&control_url).await.unwrap();
|
||||
let terminal_tcp = TcpStream::connect(format!("127.0.0.1:{}", port))
|
||||
.await
|
||||
.unwrap();
|
||||
let (terminal_ws, _) = tokio_tungstenite::client_async_with_config(
|
||||
&terminal_url,
|
||||
MaybeTls::Plain(terminal_tcp),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let control_tcp = TcpStream::connect(format!("127.0.0.1:{}", port))
|
||||
.await
|
||||
.unwrap();
|
||||
let (control_ws, _) = tokio_tungstenite::client_async_with_config(
|
||||
&control_url,
|
||||
MaybeTls::Plain(control_tcp),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let connections = WebSocketConnections {
|
||||
terminal_ws,
|
||||
@@ -586,8 +677,26 @@ async fn test_control_message_handling() {
|
||||
let terminal_url = format!("ws://127.0.0.1:{}/ws/terminal", port);
|
||||
let control_url = format!("ws://127.0.0.1:{}/ws/control", port);
|
||||
|
||||
let (terminal_ws, _) = connect_async(&terminal_url).await.unwrap();
|
||||
let (control_ws, _) = connect_async(&control_url).await.unwrap();
|
||||
let terminal_tcp = TcpStream::connect(format!("127.0.0.1:{}", port))
|
||||
.await
|
||||
.unwrap();
|
||||
let (terminal_ws, _) = tokio_tungstenite::client_async_with_config(
|
||||
&terminal_url,
|
||||
MaybeTls::Plain(terminal_tcp),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let control_tcp = TcpStream::connect(format!("127.0.0.1:{}", port))
|
||||
.await
|
||||
.unwrap();
|
||||
let (control_ws, _) = tokio_tungstenite::client_async_with_config(
|
||||
&control_url,
|
||||
MaybeTls::Plain(control_tcp),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let connections = WebSocketConnections {
|
||||
terminal_ws,
|
||||
|
||||
@@ -44,6 +44,7 @@ fn get_db_path() -> Result<PathBuf> {
|
||||
}
|
||||
|
||||
fn init_db(conn: &Connection) -> Result<()> {
|
||||
conn.execute_batch("PRAGMA busy_timeout = 5000")?;
|
||||
conn.execute(
|
||||
"CREATE TABLE IF NOT EXISTS remote_sessions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
|
||||
@@ -89,6 +89,7 @@ fn open_db() -> Result<Connection> {
|
||||
}
|
||||
|
||||
fn init_db(conn: &Connection) -> Result<()> {
|
||||
conn.execute_batch("PRAGMA busy_timeout = 5000")?;
|
||||
conn.execute_batch("PRAGMA foreign_keys = ON")?;
|
||||
|
||||
conn.execute(
|
||||
|
||||
Reference in New Issue
Block a user