mirror of
https://github.com/veeso/termscp.git
synced 2025-12-06 17:15:35 -08:00
feat: WebDAV support (#235)
This commit is contained in:
committed by
GitHub
parent
5dfee2cbd9
commit
c7469b8594
@@ -43,8 +43,12 @@ Released on
|
||||
- Changed `-t` to `theme`
|
||||
- Changed `-u` to `update`
|
||||
- Changed `-c` to `config`
|
||||
- Introduced support for [WebDAV](https://www.rfc-editor.org/rfc/rfc4918)
|
||||
- It is now possible also to connect directly to WebDAV server with the syntax `http(s)://username:password@google.com`
|
||||
- Bugfix:
|
||||
- [Issue 232](https://github.com/veeso/termscp/issues/232): AWS S3 wasn't working anymore due to rust-s3 outdate
|
||||
- Dependencies:
|
||||
- Added `remotefs-webdav 0.1.1`
|
||||
|
||||
## 0.12.3
|
||||
|
||||
|
||||
234
Cargo.lock
generated
234
Cargo.lock
generated
@@ -194,7 +194,7 @@ checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.23",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -211,7 +211,7 @@ checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.23",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -226,7 +226,7 @@ version = "0.26.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f77d243921b0979fbbd728dd2d5162e68ac8252976797c24eb5b3a6af9090dc"
|
||||
dependencies = [
|
||||
"http",
|
||||
"http 0.2.9",
|
||||
"log",
|
||||
"rustls",
|
||||
"serde",
|
||||
@@ -254,7 +254,7 @@ dependencies = [
|
||||
"rust-ini",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"time 0.3.22",
|
||||
"time 0.3.34",
|
||||
"url",
|
||||
]
|
||||
|
||||
@@ -376,9 +376,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
|
||||
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||
|
||||
[[package]]
|
||||
name = "bytesize"
|
||||
@@ -386,6 +386,15 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38fcc2979eff34a4b84e1cf9a1e3da42a7d44b3b690a40cdcb23e3d556cfb2e5"
|
||||
|
||||
[[package]]
|
||||
name = "bytestring"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cassowary"
|
||||
version = "0.3.0"
|
||||
@@ -624,6 +633,16 @@ version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e"
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.2.0"
|
||||
@@ -772,7 +791,7 @@ checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.23",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -975,7 +994,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.23",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1046,7 +1065,7 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http 0.2.9",
|
||||
"indexmap 1.9.3",
|
||||
"slab",
|
||||
"tokio",
|
||||
@@ -1071,9 +1090,9 @@ checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.0"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
@@ -1136,6 +1155,17 @@ dependencies = [
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-body"
|
||||
version = "0.4.5"
|
||||
@@ -1143,7 +1173,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http",
|
||||
"http 0.2.9",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
@@ -1155,9 +1185,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
version = "1.0.2"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
||||
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
@@ -1170,7 +1200,7 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http 0.2.9",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
@@ -1190,13 +1220,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"http",
|
||||
"http 0.2.9",
|
||||
"hyper",
|
||||
"rustls",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-tls"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"hyper",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.57"
|
||||
@@ -1242,12 +1285,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.0.0"
|
||||
version = "2.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
|
||||
checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.0",
|
||||
"hashbrown 0.14.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1494,7 +1537,7 @@ dependencies = [
|
||||
"dirs-next",
|
||||
"objc-foundation",
|
||||
"objc_id",
|
||||
"time 0.3.22",
|
||||
"time 0.3.34",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1684,6 +1727,12 @@ dependencies = [
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nonempty"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "995defdca0a589acfdd1bd2e8e3b896b4d4f7675a31fd14c32611440c7f608e6"
|
||||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "4.0.17"
|
||||
@@ -1748,6 +1797,12 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
@@ -1899,7 +1954,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.23",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2097,6 +2152,12 @@ version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794"
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
@@ -2127,9 +2188,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.63"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
|
||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -2154,10 +2215,19 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.29"
|
||||
name = "quick-xml"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
|
||||
checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@@ -2264,13 +2334,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "remotefs-aws-s3"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3bf9e4443bef2d0f148bbcc99b852b59a12372e240ea8dc69a6f1609e90938c"
|
||||
checksum = "ff8527f19059c3246d85fa8e81be1b720eeae28099d9e6debe6d7d214875c2aa"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"log",
|
||||
"path-slash 0.2.1",
|
||||
"path-slash 0.1.5",
|
||||
"remotefs",
|
||||
"rust-s3",
|
||||
"thiserror",
|
||||
@@ -2321,6 +2391,27 @@ dependencies = [
|
||||
"users",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "remotefs-webdav"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88503e1cd53067ab639150625718bb8d88e6bcd1e165205de0d941beca66bde"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"bytestring",
|
||||
"http 1.0.0",
|
||||
"httpdate",
|
||||
"indexmap 2.2.5",
|
||||
"log",
|
||||
"mime",
|
||||
"nonempty",
|
||||
"quick-xml 0.31.0",
|
||||
"remotefs",
|
||||
"rustydav",
|
||||
"thiserror",
|
||||
"time 0.3.34",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.18"
|
||||
@@ -2333,14 +2424,16 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http 0.2.9",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-tls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
@@ -2350,6 +2443,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls",
|
||||
"tower-service",
|
||||
"url",
|
||||
@@ -2421,7 +2515,7 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"hex",
|
||||
"hmac",
|
||||
"http",
|
||||
"http 0.2.9",
|
||||
"log",
|
||||
"maybe-async",
|
||||
"md5",
|
||||
@@ -2432,7 +2526,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"sha2 0.10.7",
|
||||
"thiserror",
|
||||
"time 0.3.22",
|
||||
"time 0.3.34",
|
||||
"url",
|
||||
]
|
||||
|
||||
@@ -2487,6 +2581,15 @@ dependencies = [
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustydav"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc4c86c47126ac8bfc573084610e93f4ca8726f3ae7bf6c64bd60476731b6e42"
|
||||
dependencies = [
|
||||
"reqwest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.14"
|
||||
@@ -2599,22 +2702,22 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.166"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.166"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.23",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2636,7 +2739,7 @@ checksum = "1d89a8107374290037607734c0b73a85db7ed80cae314b3c5791f192a496e731"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.23",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2682,7 +2785,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.23",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2758,7 +2861,7 @@ checksum = "acee08041c5de3d5048c8b3f6f13fafb3026b24ba43c6a695a0c76179b844369"
|
||||
dependencies = [
|
||||
"log",
|
||||
"termcolor",
|
||||
"time 0.3.22",
|
||||
"time 0.3.34",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2860,9 +2963,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.23"
|
||||
version = "2.0.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737"
|
||||
checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2942,6 +3045,7 @@ dependencies = [
|
||||
"remotefs-ftp",
|
||||
"remotefs-smb",
|
||||
"remotefs-ssh",
|
||||
"remotefs-webdav",
|
||||
"rpassword",
|
||||
"self_update",
|
||||
"serde",
|
||||
@@ -2973,22 +3077,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.41"
|
||||
version = "1.0.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c16a64ba9387ef3fdae4f9c1a7f07a0997fce91985c0336f1ddc1822b3b37802"
|
||||
checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.41"
|
||||
version = "1.0.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d14928354b01c4d6a4f0e549069adef399a284e7995c7ccca94e8a07a5346c59"
|
||||
checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.23",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3015,13 +3119,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.22"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd"
|
||||
checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"libc",
|
||||
"num-conv",
|
||||
"num_threads",
|
||||
"powerfmt",
|
||||
"serde",
|
||||
"time-core",
|
||||
"time-macros",
|
||||
@@ -3029,16 +3136,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
|
||||
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.9"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b"
|
||||
checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
]
|
||||
|
||||
@@ -3083,6 +3191,16 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[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.24.1"
|
||||
@@ -3134,7 +3252,7 @@ version = "0.19.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78"
|
||||
dependencies = [
|
||||
"indexmap 2.0.0",
|
||||
"indexmap 2.2.5",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
@@ -3167,7 +3285,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.23",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3402,7 +3520,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.23",
|
||||
"syn 2.0.52",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -3436,7 +3554,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.23",
|
||||
"syn 2.0.52",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@@ -3931,7 +4049,7 @@ dependencies = [
|
||||
"crc32fast",
|
||||
"crossbeam-utils",
|
||||
"flate2",
|
||||
"time 0.3.22",
|
||||
"time 0.3.34",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -56,10 +56,11 @@ notify-rust = { version = "^4.5", default-features = false, features = ["d"] }
|
||||
open = "^5.0"
|
||||
rand = "^0.8.5"
|
||||
remotefs = "^0.2.0"
|
||||
remotefs-aws-s3 = { version = "^0.2.3", default-features = false, features = [
|
||||
remotefs-aws-s3 = { version = "^0.2.4", default-features = false, features = [
|
||||
"find",
|
||||
"rustls",
|
||||
] }
|
||||
remotefs-webdav = "^0.1.1"
|
||||
rpassword = "^7.0"
|
||||
self_update = { version = "^0.37", default-features = false, features = [
|
||||
"rustls",
|
||||
|
||||
@@ -133,6 +133,7 @@ Termscp is a feature rich terminal file transfer and explorer, with support for
|
||||
- **FTP** and **FTPS**
|
||||
- **S3**
|
||||
- **SMB**
|
||||
- **WebDAV**
|
||||
- 🖥 Explore and operate on the remote and on the local machine file system with a handy UI
|
||||
- Create, remove, rename, search, view and edit files
|
||||
- ⭐ Connect to your favourite hosts through built-in bookmarks and recent connections
|
||||
|
||||
@@ -138,6 +138,7 @@ Termscp ist ein funktionsreicher Terminal-Dateitransfer und Explorer mit Unterst
|
||||
- **FTP** und **FTPS**
|
||||
- **S3**
|
||||
- **SMB**
|
||||
- **WebDAV**
|
||||
- 🖥 Erkunden und bedienen Sie das Dateisystem der Fernbedienung und des lokalen Computers mit einer praktischen Benutzeroberfläche
|
||||
- Erstellen, Entfernen, Umbenennen, Suchen, Anzeigen und Bearbeiten von Dateien
|
||||
- ⭐ Verbinden Sie sich über integrierte Lesezeichen und aktuelle Verbindungen mit Ihren Lieblingshosts
|
||||
|
||||
@@ -138,6 +138,7 @@ Termscp es un explorador y transferencia de archivos de terminal rico en funcion
|
||||
- **FTP** y **FTPS**
|
||||
- **S3**
|
||||
- **SMB**
|
||||
- **WebDAV**
|
||||
- 🖥 Explore y opere en el sistema de archivos de la máquina local y remota con una interfaz de usuario práctica
|
||||
- Cree, elimine, cambie el nombre, busque, vea y edite archivos
|
||||
- ⭐ Conéctese a sus hosts favoritos y conexiones recientes
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
- [Uso ❓](#uso-)
|
||||
- [Argumento dirección 🌎](#argumento-dirección-)
|
||||
- [Argumento dirección por AWS S3](#argumento-dirección-por-aws-s3)
|
||||
- [Argumento de dirección de WebDAV](#argumento-de-dirección-de-webdav)
|
||||
- [Argumento dirección por SMB](#argumento-dirección-por-smb)
|
||||
- [Cómo se puede proporcionar la contraseña 🔐](#cómo-se-puede-proporcionar-la-contraseña-)
|
||||
- [S3 parámetros de conexión](#s3-parámetros-de-conexión)
|
||||
@@ -103,6 +104,20 @@ por ejemplo
|
||||
s3://buckethead@eu-central-1:default:/assets
|
||||
```
|
||||
|
||||
#### Argumento de dirección de WebDAV
|
||||
|
||||
En caso de que quieras conectarte a WebDAV utiliza la siguiente sintaxis
|
||||
|
||||
```txt
|
||||
http://<username>:<password>@<url></path>
|
||||
```
|
||||
|
||||
o en caso de que quieras usar https
|
||||
|
||||
```txt
|
||||
https://<username>:<password>@<url></path>
|
||||
```
|
||||
|
||||
#### Argumento dirección por SMB
|
||||
|
||||
SMB tiene una sintaxis diferente para el argumento de la dirección CLI, que es diferente si está en Windows u otros sistemas:
|
||||
|
||||
@@ -138,6 +138,7 @@ Termscp est un file transfer et explorateur de fichiers de terminal riche en fon
|
||||
- **FTP** et **FTPS**
|
||||
- **S3**
|
||||
- **SMB**
|
||||
- **WebDAV**
|
||||
- 🖥 Explorer et opérer sur le système de fichiers distant et local avec une interface utilisateur pratique.
|
||||
- Créer, supprimer, renommer, rechercher, afficher et modifier des fichiers
|
||||
- ⭐ Connectez-vous à vos hôtes préférés via des signets et des connexions récentes.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
- [Usage ❓](#usage-)
|
||||
- [Argument d'adresse 🌎](#argument-dadresse-)
|
||||
- [Argument d'adresse AWS S3](#argument-dadresse-aws-s3)
|
||||
- [Argument d'adresse WebDAV](#argument-dadresse-webdav)
|
||||
- [Argument d'adresse SMB](#argument-dadresse-smb)
|
||||
- [Comment le mot de passe peut être fourni 🔐](#comment-le-mot-de-passe-peut-être-fourni-)
|
||||
- [S3 paramètres de connexion](#s3-paramètres-de-connexion)
|
||||
@@ -101,6 +102,20 @@ e.g.
|
||||
s3://buckethead@eu-central-1:default:/assets
|
||||
```
|
||||
|
||||
#### Argument d'adresse WebDAV
|
||||
|
||||
Dans le cas où vous souhaitez vous connecter à WebDAV, utilisez la syntaxe suivante
|
||||
|
||||
```txt
|
||||
http://<username>:<password>@<url></path>
|
||||
```
|
||||
|
||||
ou dans le cas où vous souhaitez utiliser https
|
||||
|
||||
```txt
|
||||
https://<username>:<password>@<url></path>
|
||||
```
|
||||
|
||||
#### Argument d'adresse SMB
|
||||
|
||||
SMB a une syntaxe différente pour l'argument d'adresse CLI, qui est différente que vous soyez sur Windows ou sur d'autres systèmes :
|
||||
|
||||
@@ -138,6 +138,7 @@ Termscp è un file transfer ed explorer ricco di funzionalità, con supporto a S
|
||||
- **FTP** and **FTPS**
|
||||
- **S3**
|
||||
- **SMB**
|
||||
- **WebDAV**
|
||||
- 🖥 Esplora e opera sia sul file system locale che su quello remoto con una UI di facile utilizzo.
|
||||
- Crea, rimuove, rinomina, cerca, visualizza e modifica file
|
||||
- ⭐ Connettiti ai tuoi host preferiti tramite la funzionalità integrata dei segnalibri e delle connessioni recenti.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
- [Argomenti da linea di comando ❓](#argomenti-da-linea-di-comando-)
|
||||
- [Argomento indirizzo 🌎](#argomento-indirizzo-)
|
||||
- [Argomento indirizzo per AWS S3](#argomento-indirizzo-per-aws-s3)
|
||||
- [Argomento indirizzo per WebDAV](#argomento-indirizzo-per-webdav)
|
||||
- [Indirizzo SMB](#indirizzo-smb)
|
||||
- [Come fornire la password 🔐](#come-fornire-la-password-)
|
||||
- [Parametri di connessione S3](#parametri-di-connessione-s3)
|
||||
@@ -99,6 +100,20 @@ e.g.
|
||||
s3://buckethead@eu-central-1:default:/assets
|
||||
```
|
||||
|
||||
#### Argomento indirizzo per WebDAV
|
||||
|
||||
Nel caso in cui si desideri connettersi a WebDAV utilizzare la seguente sintassi
|
||||
|
||||
```txt
|
||||
http://<username>:<password>@<url></path>
|
||||
```
|
||||
|
||||
oppure nel caso in cui si desideri utilizzare https
|
||||
|
||||
```txt
|
||||
https://<username>:<password>@<url></path>
|
||||
```
|
||||
|
||||
#### Indirizzo SMB
|
||||
|
||||
SMB ha una sintassi differente rispetto agli altri protocolli e cambia in base al sistema operativo:
|
||||
|
||||
15
docs/man.md
15
docs/man.md
@@ -4,6 +4,7 @@
|
||||
- [Usage ❓](#usage-)
|
||||
- [Address argument 🌎](#address-argument-)
|
||||
- [AWS S3 address argument](#aws-s3-address-argument)
|
||||
- [WebDAV address argument](#webdav-address-argument)
|
||||
- [SMB address argument](#smb-address-argument)
|
||||
- [How Password can be provided 🔐](#how-password-can-be-provided-)
|
||||
- [Subcommands](#subcommands)
|
||||
@@ -104,6 +105,20 @@ e.g.
|
||||
s3://buckethead@eu-central-1:default:/assets
|
||||
```
|
||||
|
||||
#### WebDAV address argument
|
||||
|
||||
In case you want to connect to webDAV use the following syntax
|
||||
|
||||
```txt
|
||||
http://<username>:<password>@<url></path>
|
||||
```
|
||||
|
||||
or in case you want to use https
|
||||
|
||||
```txt
|
||||
https://<username>:<password>@<url></path>
|
||||
```
|
||||
|
||||
#### SMB address argument
|
||||
|
||||
SMB has a different syntax for CLI address argument, which is different whether you're on Windows or other systems:
|
||||
|
||||
@@ -140,6 +140,7 @@ termscp 是一个功能丰富的终端文件浏览和传输工具,支持 SCP/S
|
||||
- **FTP** and **FTPS**
|
||||
- **S3**
|
||||
- **SMB**
|
||||
- **WebDAV**
|
||||
- 🖥 使用便捷的 UI 在远程和本地文件系统上浏览和操作
|
||||
- 创建、删除、重命名、搜索、查看和编辑文件
|
||||
- ⭐ 通过“内置书签”和“最近连接”快速连接到您的主机
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
- [用法](#用法)
|
||||
- [地址参数](#地址参数)
|
||||
- [AWS S3 地址参数](#aws-s3-地址参数)
|
||||
- [WebDAV 地址参数](#webdav-地址参数)
|
||||
- [SMB 地址参数](#smb-地址参数)
|
||||
- [如何输入密码](#如何输入密码)
|
||||
- [S3 连接参数](#s3-连接参数)
|
||||
@@ -101,6 +102,19 @@ s3://<bucket-name>@<region>[:profile][:/wrkdir]
|
||||
s3://buckethead@eu-central-1:default:/assets
|
||||
```
|
||||
|
||||
#### WebDAV 地址参数
|
||||
|
||||
如果您想要连接到 WebDAV,请使用以下语法
|
||||
|
||||
```txt
|
||||
http://<username>:<password>@<url></path>
|
||||
或者如果您想要使用 https
|
||||
```
|
||||
|
||||
```txt
|
||||
https://<username>:<password>@<url></path>
|
||||
```
|
||||
|
||||
#### SMB 地址参数
|
||||
|
||||
SMB 对 CLI 地址参数有不同的语法,无论您是在 Windows 还是其他系统上,这都是不同的:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<head>
|
||||
<title>
|
||||
termscp is a terminal file transfer and explorer for SCP/SFTP/FTP/S3/SMB | termscp
|
||||
termscp is a terminal file transfer and explorer for SCP/SFTP/FTP/S3/SMB/WebDAV | termscp
|
||||
</title>
|
||||
<meta property="og:description"
|
||||
content="termscp is a feature rich terminal file transfer and explorer, with support for SCP/SFTP/FTP/S3. It is Linux, MacOS, FreeBSD, NetBSD and Windows compatible" />
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<section id="intro" class="flex flex-col mx-auto items-center justify-center w-full px-4 dark:bg-brand dark:text-gray-100">
|
||||
<section id="intro"
|
||||
class="flex flex-col mx-auto items-center justify-center w-full px-4 dark:bg-brand dark:text-gray-100">
|
||||
<h1 class="text-3xl text-center font-thin">termscp</h1>
|
||||
<img class="w-[256px] h-auto m-auto" alt="logo" src="assets/images/termscp.webp" />
|
||||
<h2 class="text-xl font-thin text-center py-6" translate="intro.caption">
|
||||
A feature rich terminal UI file transfer and explorer with support for
|
||||
SCP/SFTP/FTP/S3/SMB
|
||||
SCP/SFTP/FTP/S3/SMB/WebDAV
|
||||
</h2>
|
||||
<button class="bg-brand hover:bg-gray-800 text-white font-thin text-xl py-2 px-4 rounded-xl max-w-fit">
|
||||
<a href="/get-started.html" class="no-underline" translate="intro.getStarted">Get started →</a>
|
||||
@@ -66,7 +67,8 @@
|
||||
<div class="flex flex-row sm:flex-col justify-around gap-12">
|
||||
<div class="hook">
|
||||
<h3 class="text-center text-gray-500 dark:text-gray-100 font-light text-xl">
|
||||
<a href="/get-started.html" class="no-underline hover:underline" translate="intro.footer.getStarted">Get started</a>
|
||||
<a href="/get-started.html" class="no-underline hover:underline" translate="intro.footer.getStarted">Get
|
||||
started</a>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="hook">
|
||||
@@ -76,7 +78,8 @@
|
||||
</div>
|
||||
<div class="hook">
|
||||
<h3 class="text-center text-gray-500 dark:text-gray-100 font-light text-xl">
|
||||
<a href="/updates.html" class="no-underline hover:underline" translate="intro.footer.updates">Install updates</a>
|
||||
<a href="/updates.html" class="no-underline hover:underline" translate="intro.footer.updates">Install
|
||||
updates</a>
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
|
||||
<head>
|
||||
<title>
|
||||
termscp is a terminal file transfer and explorer for SCP/SFTP/FTP/S3/SMB | termscp
|
||||
termscp is a terminal file transfer and explorer for SCP/SFTP/FTP/S3/SMB/WebDAV | termscp
|
||||
</title>
|
||||
<meta property="og:description"
|
||||
content="a WinSCP alternative for Linux and MacOS with support for SCP/SFTP/FTP/S3/SMB. Command line file transfer with user interface compatible with all the operating systems." />
|
||||
content="a WinSCP alternative for Linux and MacOS with support for SCP/SFTP/FTP/S3/SMB/WebDAV. Command line file transfer with user interface compatible with all the operating systems." />
|
||||
<meta name="description"
|
||||
content="a WinSCP alternative for Linux and MacOS with support for SCP/SFTP/FTP/S3/SMB. Command line file transfer with user interface compatible with all the operating systems." />
|
||||
<meta property="og:title" content="termscp is a terminal file transfer and explorer for SCP/SFTP/FTP/S3/SMB | termscp" />
|
||||
content="a WinSCP alternative for Linux and MacOS with support for SCP/SFTP/FTP/S3/SMB/WebDAV. Command line file transfer with user interface compatible with all the operating systems." />
|
||||
<meta property="og:title"
|
||||
content="termscp is a terminal file transfer and explorer for SCP/SFTP/FTP/S3/SMB/WebDAV | termscp" />
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="robots" content="index, follow" />
|
||||
@@ -40,7 +41,7 @@
|
||||
|
||||
<body>
|
||||
<div id="layout" class="dark:bg-brand dark:text-gray-100">
|
||||
|
||||
|
||||
<!-- Menu -->
|
||||
<header id="menu"></header>
|
||||
<main>
|
||||
|
||||
@@ -11,6 +11,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::filetransfer::params::{
|
||||
AwsS3Params, GenericProtocolParams, ProtocolParams, SmbParams as TransferSmbParams,
|
||||
WebDAVProtocolParams,
|
||||
};
|
||||
use crate::filetransfer::{FileTransferParams, FileTransferProtocol};
|
||||
|
||||
@@ -114,6 +115,17 @@ impl From<FileTransferParams> for Bookmark {
|
||||
local_path,
|
||||
s3: None,
|
||||
},
|
||||
ProtocolParams::WebDAV(parms) => Self {
|
||||
protocol,
|
||||
address: Some(parms.uri),
|
||||
port: None,
|
||||
username: Some(parms.username),
|
||||
password: Some(parms.password),
|
||||
remote_path,
|
||||
local_path,
|
||||
s3: None,
|
||||
smb: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,6 +173,14 @@ impl From<Bookmark> for FileTransferParams {
|
||||
|
||||
Self::new(bookmark.protocol, ProtocolParams::Smb(params))
|
||||
}
|
||||
FileTransferProtocol::WebDAV => Self::new(
|
||||
FileTransferProtocol::WebDAV,
|
||||
ProtocolParams::WebDAV(WebDAVProtocolParams {
|
||||
uri: bookmark.address.unwrap_or_default(),
|
||||
username: bookmark.username.unwrap_or_default(),
|
||||
password: bookmark.password.unwrap_or_default(),
|
||||
}),
|
||||
),
|
||||
}
|
||||
.remote_path(bookmark.remote_path) // Set entry remote_path
|
||||
.local_path(bookmark.local_path) // Set entry local path
|
||||
@@ -390,6 +410,35 @@ mod tests {
|
||||
assert_eq!(gparams.password.as_deref().unwrap(), "password");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ftparams_from_webdav() {
|
||||
let bookmark: Bookmark = Bookmark {
|
||||
address: Some(String::from("192.168.1.1")),
|
||||
port: None,
|
||||
protocol: FileTransferProtocol::WebDAV,
|
||||
username: Some(String::from("root")),
|
||||
password: Some(String::from("password")),
|
||||
remote_path: Some(PathBuf::from("/tmp")),
|
||||
local_path: Some(PathBuf::from("/usr")),
|
||||
s3: None,
|
||||
smb: None,
|
||||
};
|
||||
let params = FileTransferParams::from(bookmark);
|
||||
assert_eq!(params.protocol, FileTransferProtocol::WebDAV);
|
||||
assert_eq!(
|
||||
params.remote_path.as_deref().unwrap(),
|
||||
std::path::Path::new("/tmp")
|
||||
);
|
||||
assert_eq!(
|
||||
params.local_path.as_deref().unwrap(),
|
||||
std::path::Path::new("/usr")
|
||||
);
|
||||
let gparams = params.params.webdav_params().unwrap();
|
||||
assert_eq!(gparams.uri.as_str(), "192.168.1.1");
|
||||
assert_eq!(gparams.username, "root");
|
||||
assert_eq!(gparams.password, "password");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ftparams_from_s3_bookmark() {
|
||||
let bookmark: Bookmark = Bookmark {
|
||||
|
||||
@@ -12,7 +12,9 @@ use remotefs_smb::SmbOptions;
|
||||
#[cfg(smb)]
|
||||
use remotefs_smb::{SmbCredentials, SmbFs};
|
||||
use remotefs_ssh::{ScpFs, SftpFs, SshConfigParseRule, SshOpts};
|
||||
use remotefs_webdav::WebDAVFs;
|
||||
|
||||
use super::params::WebDAVProtocolParams;
|
||||
#[cfg(not(smb))]
|
||||
use super::params::{AwsS3Params, GenericProtocolParams};
|
||||
#[cfg(smb)]
|
||||
@@ -51,6 +53,9 @@ impl Builder {
|
||||
(FileTransferProtocol::Smb, ProtocolParams::Smb(params)) => {
|
||||
Box::new(Self::smb_client(params))
|
||||
}
|
||||
(FileTransferProtocol::WebDAV, ProtocolParams::WebDAV(params)) => {
|
||||
Box::new(Self::webdav_client(params))
|
||||
}
|
||||
(protocol, params) => {
|
||||
error!("Invalid params for protocol '{:?}'", protocol);
|
||||
panic!("Invalid protocol '{protocol:?}' with parameters of type {params:?}")
|
||||
@@ -154,6 +159,10 @@ impl Builder {
|
||||
SmbFs::new(credentials)
|
||||
}
|
||||
|
||||
fn webdav_client(params: WebDAVProtocolParams) -> WebDAVFs {
|
||||
WebDAVFs::new(¶ms.username, ¶ms.password, ¶ms.uri)
|
||||
}
|
||||
|
||||
/// Build ssh options from generic protocol params and client configuration
|
||||
fn build_ssh_opts(params: GenericProtocolParams, config_client: &ConfigClient) -> SshOpts {
|
||||
let mut opts = SshOpts::new(params.address.clone())
|
||||
|
||||
@@ -18,6 +18,7 @@ pub enum FileTransferProtocol {
|
||||
Scp,
|
||||
Sftp,
|
||||
Smb,
|
||||
WebDAV,
|
||||
}
|
||||
|
||||
// Traits
|
||||
@@ -33,6 +34,7 @@ impl std::string::ToString for FileTransferProtocol {
|
||||
FileTransferProtocol::Scp => "SCP",
|
||||
FileTransferProtocol::Sftp => "SFTP",
|
||||
FileTransferProtocol::Smb => "SMB",
|
||||
FileTransferProtocol::WebDAV => "WEBDAV",
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -47,6 +49,7 @@ impl std::str::FromStr for FileTransferProtocol {
|
||||
"SCP" => Ok(FileTransferProtocol::Scp),
|
||||
"SFTP" => Ok(FileTransferProtocol::Sftp),
|
||||
"SMB" => Ok(FileTransferProtocol::Smb),
|
||||
"WEBDAV" | "HTTP" | "HTTPS" => Ok(FileTransferProtocol::WebDAV),
|
||||
_ => Err(s.to_string()),
|
||||
}
|
||||
}
|
||||
@@ -134,9 +137,17 @@ mod tests {
|
||||
FileTransferProtocol::Ftp(false).to_string(),
|
||||
String::from("FTP")
|
||||
);
|
||||
assert_eq!(
|
||||
FileTransferProtocol::WebDAV.to_string(),
|
||||
String::from("WEBDAV")
|
||||
);
|
||||
assert_eq!(FileTransferProtocol::Scp.to_string(), String::from("SCP"));
|
||||
assert_eq!(FileTransferProtocol::Sftp.to_string(), String::from("SFTP"));
|
||||
assert_eq!(FileTransferProtocol::AwsS3.to_string(), String::from("S3"));
|
||||
assert_eq!(FileTransferProtocol::Smb.to_string(), String::from("SMB"));
|
||||
assert_eq!(
|
||||
FileTransferProtocol::WebDAV.to_string(),
|
||||
String::from("WEBDAV")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ pub enum ProtocolParams {
|
||||
Generic(GenericProtocolParams),
|
||||
AwsS3(AwsS3Params),
|
||||
Smb(SmbParams),
|
||||
WebDAV(WebDAVProtocolParams),
|
||||
}
|
||||
|
||||
/// Protocol params used by most common protocols
|
||||
@@ -89,6 +90,7 @@ impl FileTransferParams {
|
||||
ProtocolParams::AwsS3(params) => params.password_missing(),
|
||||
ProtocolParams::Generic(params) => params.password_missing(),
|
||||
ProtocolParams::Smb(params) => params.password_missing(),
|
||||
ProtocolParams::WebDAV(params) => params.password_missing(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,10 +100,29 @@ impl FileTransferParams {
|
||||
ProtocolParams::AwsS3(params) => params.set_default_secret(secret),
|
||||
ProtocolParams::Generic(params) => params.set_default_secret(secret),
|
||||
ProtocolParams::Smb(params) => params.set_default_secret(secret),
|
||||
ProtocolParams::WebDAV(params) => params.set_default_secret(secret),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Protocol params used by WebDAV
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct WebDAVProtocolParams {
|
||||
pub uri: String,
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
impl WebDAVProtocolParams {
|
||||
fn set_default_secret(&mut self, secret: String) {
|
||||
self.password = secret;
|
||||
}
|
||||
|
||||
fn password_missing(&self) -> bool {
|
||||
self.password.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FileTransferParams {
|
||||
fn default() -> Self {
|
||||
Self::new(FileTransferProtocol::Sftp, ProtocolParams::default())
|
||||
@@ -149,6 +170,15 @@ impl ProtocolParams {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
/// Retrieve WebDAV parameters if any
|
||||
pub fn webdav_params(&self) -> Option<&WebDAVProtocolParams> {
|
||||
match self {
|
||||
ProtocolParams::WebDAV(params) => Some(params),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- Generic protocol params
|
||||
@@ -512,6 +542,40 @@ mod test {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(linux)]
|
||||
fn set_default_secret_smb() {
|
||||
let mut params = FileTransferParams::new(
|
||||
FileTransferProtocol::Scp,
|
||||
ProtocolParams::Smb(SmbParams::new("localhost", "temp")),
|
||||
);
|
||||
params.set_default_secret(String::from("secret"));
|
||||
assert_eq!(
|
||||
params
|
||||
.params
|
||||
.smb_params()
|
||||
.unwrap()
|
||||
.password
|
||||
.as_deref()
|
||||
.unwrap(),
|
||||
"secret"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_default_secret_webdav() {
|
||||
let mut params = FileTransferParams::new(
|
||||
FileTransferProtocol::Scp,
|
||||
ProtocolParams::WebDAV(WebDAVProtocolParams {
|
||||
uri: "http://localhost".to_string(),
|
||||
username: "user".to_string(),
|
||||
password: "pass".to_string(),
|
||||
}),
|
||||
);
|
||||
params.set_default_secret(String::from("secret"));
|
||||
assert_eq!(params.params.webdav_params().unwrap().password, "secret");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_default_secret_generic() {
|
||||
let mut params =
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
// Locals
|
||||
use super::{AuthActivity, FileTransferParams};
|
||||
use crate::filetransfer::params::{AwsS3Params, GenericProtocolParams, ProtocolParams, SmbParams};
|
||||
use crate::filetransfer::params::{
|
||||
AwsS3Params, GenericProtocolParams, ProtocolParams, SmbParams, WebDAVProtocolParams,
|
||||
};
|
||||
|
||||
impl AuthActivity {
|
||||
/// Delete bookmark
|
||||
@@ -164,6 +166,7 @@ impl AuthActivity {
|
||||
ProtocolParams::AwsS3(params) => self.load_bookmark_s3_into_gui(params),
|
||||
ProtocolParams::Generic(params) => self.load_bookmark_generic_into_gui(params),
|
||||
ProtocolParams::Smb(params) => self.load_bookmark_smb_into_gui(params),
|
||||
ProtocolParams::WebDAV(params) => self.load_bookmark_webdav_into_gui(params),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,4 +199,10 @@ impl AuthActivity {
|
||||
#[cfg(unix)]
|
||||
self.mount_smb_workgroup(params.workgroup.as_deref().unwrap_or(""));
|
||||
}
|
||||
|
||||
fn load_bookmark_webdav_into_gui(&mut self, params: WebDAVProtocolParams) {
|
||||
self.mount_webdav_uri(¶ms.uri);
|
||||
self.mount_username(¶ms.username);
|
||||
self.mount_password(¶ms.password);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use tuirealm::{Component, Event, MockComponent, NoUserEvent, State, StateValue};
|
||||
use super::{FileTransferProtocol, FormMsg, Msg, UiMsg};
|
||||
use crate::ui::activities::auth::{
|
||||
RADIO_PROTOCOL_FTP, RADIO_PROTOCOL_FTPS, RADIO_PROTOCOL_S3, RADIO_PROTOCOL_SCP,
|
||||
RADIO_PROTOCOL_SFTP, RADIO_PROTOCOL_SMB,
|
||||
RADIO_PROTOCOL_SFTP, RADIO_PROTOCOL_SMB, RADIO_PROTOCOL_WEBDAV,
|
||||
};
|
||||
|
||||
// -- protocol
|
||||
@@ -31,9 +31,9 @@ impl ProtocolRadio {
|
||||
.modifiers(BorderType::Rounded),
|
||||
)
|
||||
.choices(if cfg!(smb) {
|
||||
&["SFTP", "SCP", "FTP", "FTPS", "S3", "SMB"]
|
||||
&["SFTP", "SCP", "FTP", "FTPS", "S3", "WebDAV", "SMB"]
|
||||
} else {
|
||||
&["SFTP", "SCP", "FTP", "FTPS", "S3"]
|
||||
&["SFTP", "SCP", "FTP", "FTPS", "S3", "WebDAV"]
|
||||
})
|
||||
.foreground(color)
|
||||
.rewind(true)
|
||||
@@ -50,6 +50,7 @@ impl ProtocolRadio {
|
||||
RADIO_PROTOCOL_FTPS => FileTransferProtocol::Ftp(true),
|
||||
RADIO_PROTOCOL_S3 => FileTransferProtocol::AwsS3,
|
||||
RADIO_PROTOCOL_SMB => FileTransferProtocol::Smb,
|
||||
RADIO_PROTOCOL_WEBDAV => FileTransferProtocol::WebDAV,
|
||||
_ => FileTransferProtocol::Sftp,
|
||||
}
|
||||
}
|
||||
@@ -63,6 +64,7 @@ impl ProtocolRadio {
|
||||
FileTransferProtocol::Ftp(true) => RADIO_PROTOCOL_FTPS,
|
||||
FileTransferProtocol::AwsS3 => RADIO_PROTOCOL_S3,
|
||||
FileTransferProtocol::Smb => RADIO_PROTOCOL_SMB,
|
||||
FileTransferProtocol::WebDAV => RADIO_PROTOCOL_WEBDAV,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -788,3 +790,40 @@ impl Component<Msg, NoUserEvent> for InputSmbWorkgroup {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(MockComponent)]
|
||||
pub struct InputWebDAVUri {
|
||||
component: Input,
|
||||
}
|
||||
|
||||
impl InputWebDAVUri {
|
||||
pub fn new(host: &str, color: Color) -> Self {
|
||||
Self {
|
||||
component: Input::default()
|
||||
.borders(
|
||||
Borders::default()
|
||||
.color(color)
|
||||
.modifiers(BorderType::Rounded),
|
||||
)
|
||||
.foreground(color)
|
||||
.placeholder(
|
||||
"http://localhost:8080",
|
||||
Style::default().fg(Color::Rgb(128, 128, 128)),
|
||||
)
|
||||
.title("HTTP url", Alignment::Left)
|
||||
.input_type(InputType::Text)
|
||||
.value(host),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Component<Msg, NoUserEvent> for InputWebDAVUri {
|
||||
fn on(&mut self, ev: Event<NoUserEvent>) -> Option<Msg> {
|
||||
handle_input_ev(
|
||||
self,
|
||||
ev,
|
||||
Msg::Ui(UiMsg::WebDAVUriBlurDown),
|
||||
Msg::Ui(UiMsg::WebDAVUriBlurUp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ pub use form::{
|
||||
InputAddress, InputLocalDirectory, InputPassword, InputPort, InputRemoteDirectory,
|
||||
InputS3AccessKey, InputS3Bucket, InputS3Endpoint, InputS3Profile, InputS3Region,
|
||||
InputS3SecretAccessKey, InputS3SecurityToken, InputS3SessionToken, InputSmbShare,
|
||||
InputUsername, ProtocolRadio, RadioS3NewPathStyle,
|
||||
InputUsername, InputWebDAVUri, ProtocolRadio, RadioS3NewPathStyle,
|
||||
};
|
||||
pub use popup::{
|
||||
ErrorPopup, InfoPopup, InstallUpdatePopup, Keybindings, QuitPopup, ReleaseNotes, WaitPopup,
|
||||
|
||||
@@ -15,6 +15,7 @@ impl AuthActivity {
|
||||
FileTransferProtocol::Ftp(_) => 21,
|
||||
FileTransferProtocol::AwsS3 => 22, // Doesn't matter, since not used
|
||||
FileTransferProtocol::Smb => 445,
|
||||
FileTransferProtocol::WebDAV => 80, // Doesn't matter, since not used
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +42,7 @@ impl AuthActivity {
|
||||
FileTransferProtocol::Ftp(_)
|
||||
| FileTransferProtocol::Scp
|
||||
| FileTransferProtocol::Sftp => self.collect_generic_host_params(self.protocol),
|
||||
FileTransferProtocol::WebDAV => self.collect_webdav_host_params(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,6 +100,19 @@ impl AuthActivity {
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn collect_webdav_host_params(&self) -> Result<FileTransferParams, &'static str> {
|
||||
let params = self.get_webdav_params_input();
|
||||
if params.uri.is_empty() {
|
||||
return Err("Invalid URI");
|
||||
}
|
||||
Ok(FileTransferParams {
|
||||
protocol: FileTransferProtocol::WebDAV,
|
||||
params: ProtocolParams::WebDAV(params),
|
||||
local_path: self.get_input_local_directory(),
|
||||
remote_path: self.get_input_remote_directory(),
|
||||
})
|
||||
}
|
||||
|
||||
// -- update install
|
||||
|
||||
/// If enabled in configuration, check for updates from Github
|
||||
|
||||
@@ -29,7 +29,8 @@ const RADIO_PROTOCOL_SCP: usize = 1;
|
||||
const RADIO_PROTOCOL_FTP: usize = 2;
|
||||
const RADIO_PROTOCOL_FTPS: usize = 3;
|
||||
const RADIO_PROTOCOL_S3: usize = 4;
|
||||
const RADIO_PROTOCOL_SMB: usize = 5;
|
||||
const RADIO_PROTOCOL_WEBDAV: usize = 5;
|
||||
const RADIO_PROTOCOL_SMB: usize = 6;
|
||||
|
||||
// -- components
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
|
||||
@@ -71,6 +72,7 @@ pub enum Id {
|
||||
Title,
|
||||
Username,
|
||||
WaitPopup,
|
||||
WebDAVUri,
|
||||
WindowSizeError,
|
||||
}
|
||||
|
||||
@@ -155,6 +157,8 @@ pub enum UiMsg {
|
||||
ShowSaveBookmarkPopup,
|
||||
UsernameBlurDown,
|
||||
UsernameBlurUp,
|
||||
WebDAVUriBlurDown,
|
||||
WebDAVUriBlurUp,
|
||||
WindowResized,
|
||||
}
|
||||
|
||||
@@ -164,6 +168,7 @@ enum InputMask {
|
||||
Generic,
|
||||
AwsS3,
|
||||
Smb,
|
||||
WebDAV,
|
||||
}
|
||||
|
||||
// Store keys
|
||||
@@ -240,6 +245,7 @@ impl AuthActivity {
|
||||
| FileTransferProtocol::Scp
|
||||
| FileTransferProtocol::Sftp => InputMask::Generic,
|
||||
FileTransferProtocol::Smb => InputMask::Smb,
|
||||
FileTransferProtocol::WebDAV => InputMask::WebDAV,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ impl AuthActivity {
|
||||
InputMask::Generic => &Id::Password,
|
||||
InputMask::Smb => &Id::Password,
|
||||
InputMask::AwsS3 => &Id::S3Bucket,
|
||||
InputMask::WebDAV => &Id::Password,
|
||||
})
|
||||
.is_ok());
|
||||
}
|
||||
@@ -82,6 +83,7 @@ impl AuthActivity {
|
||||
InputMask::Generic => &Id::Password,
|
||||
InputMask::Smb => &Id::Password,
|
||||
InputMask::AwsS3 => &Id::S3Bucket,
|
||||
InputMask::WebDAV => &Id::Password,
|
||||
})
|
||||
.is_ok());
|
||||
}
|
||||
@@ -177,6 +179,7 @@ impl AuthActivity {
|
||||
#[cfg(windows)]
|
||||
InputMask::Smb => &Id::RemoteDirectory,
|
||||
InputMask::AwsS3 => panic!("this shouldn't happen (password on s3)"),
|
||||
InputMask::WebDAV => &Id::RemoteDirectory,
|
||||
})
|
||||
.is_ok());
|
||||
}
|
||||
@@ -189,7 +192,8 @@ impl AuthActivity {
|
||||
.active(match self.input_mask() {
|
||||
InputMask::Generic => &Id::Username,
|
||||
InputMask::Smb => &Id::SmbShare,
|
||||
InputMask::AwsS3 => panic!("this shouldn't happen (port on s3)"),
|
||||
InputMask::AwsS3 | InputMask::WebDAV =>
|
||||
panic!("this shouldn't happen (port on s3)"),
|
||||
})
|
||||
.is_ok());
|
||||
}
|
||||
@@ -203,6 +207,7 @@ impl AuthActivity {
|
||||
InputMask::Generic => &Id::Address,
|
||||
InputMask::Smb => &Id::Address,
|
||||
InputMask::AwsS3 => &Id::S3Bucket,
|
||||
InputMask::WebDAV => &Id::WebDAVUri,
|
||||
})
|
||||
.is_ok());
|
||||
}
|
||||
@@ -225,6 +230,7 @@ impl AuthActivity {
|
||||
#[cfg(windows)]
|
||||
InputMask::Smb => &Id::Password,
|
||||
InputMask::AwsS3 => &Id::S3NewPathStyle,
|
||||
InputMask::WebDAV => &Id::Password,
|
||||
})
|
||||
.is_ok());
|
||||
}
|
||||
@@ -332,9 +338,16 @@ impl AuthActivity {
|
||||
InputMask::Generic => &Id::Port,
|
||||
InputMask::Smb => &Id::SmbShare,
|
||||
InputMask::AwsS3 => panic!("this shouldn't happen (username on s3)"),
|
||||
InputMask::WebDAV => &Id::WebDAVUri,
|
||||
})
|
||||
.is_ok());
|
||||
}
|
||||
UiMsg::WebDAVUriBlurDown => {
|
||||
assert!(self.app.active(&Id::Username).is_ok());
|
||||
}
|
||||
UiMsg::WebDAVUriBlurUp => {
|
||||
assert!(self.app.active(&Id::Protocol).is_ok());
|
||||
}
|
||||
UiMsg::WindowResized => {
|
||||
self.redraw = true;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@ use tuirealm::tui::widgets::Clear;
|
||||
use tuirealm::{State, StateValue, Sub, SubClause, SubEventClause};
|
||||
|
||||
use super::{components, AuthActivity, Context, FileTransferProtocol, Id, InputMask};
|
||||
use crate::filetransfer::params::{AwsS3Params, GenericProtocolParams, ProtocolParams, SmbParams};
|
||||
use crate::filetransfer::params::{
|
||||
AwsS3Params, GenericProtocolParams, ProtocolParams, SmbParams, WebDAVProtocolParams,
|
||||
};
|
||||
use crate::filetransfer::FileTransferParams;
|
||||
use crate::utils::ui::{Popup, Size};
|
||||
|
||||
@@ -61,6 +63,7 @@ impl AuthActivity {
|
||||
self.mount_smb_share("");
|
||||
#[cfg(unix)]
|
||||
self.mount_smb_workgroup("");
|
||||
self.mount_webdav_uri("");
|
||||
// Version notice
|
||||
if let Some(version) = self
|
||||
.context()
|
||||
@@ -195,6 +198,18 @@ impl AuthActivity {
|
||||
)
|
||||
.direction(Direction::Vertical)
|
||||
.split(auth_chunks[4]),
|
||||
InputMask::WebDAV => Layout::default()
|
||||
.constraints(
|
||||
[
|
||||
Constraint::Length(3), // uri
|
||||
Constraint::Length(3), // username
|
||||
Constraint::Length(3), // password
|
||||
Constraint::Length(3), // dir
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.direction(Direction::Vertical)
|
||||
.split(auth_chunks[4]),
|
||||
};
|
||||
// Create bookmark chunks
|
||||
let bookmark_chunks = Layout::default()
|
||||
@@ -230,6 +245,13 @@ impl AuthActivity {
|
||||
self.app.view(&view_ids[2], f, input_mask[2]);
|
||||
self.app.view(&view_ids[3], f, input_mask[3]);
|
||||
}
|
||||
InputMask::WebDAV => {
|
||||
let view_ids = self.get_webdav_view();
|
||||
self.app.view(&view_ids[0], f, input_mask[0]);
|
||||
self.app.view(&view_ids[1], f, input_mask[1]);
|
||||
self.app.view(&view_ids[2], f, input_mask[2]);
|
||||
self.app.view(&view_ids[3], f, input_mask[3]);
|
||||
}
|
||||
}
|
||||
// Bookmark chunks
|
||||
self.app.view(&Id::BookmarksList, f, bookmark_chunks[0]);
|
||||
@@ -794,6 +816,18 @@ impl AuthActivity {
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
pub(super) fn mount_webdav_uri(&mut self, uri: &str) {
|
||||
let addr_color = self.theme().auth_address;
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::WebDAVUri,
|
||||
Box::new(components::InputWebDAVUri::new(uri, addr_color)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
// -- query
|
||||
|
||||
/// Collect input values from view
|
||||
@@ -860,6 +894,18 @@ impl AuthActivity {
|
||||
.password(password)
|
||||
}
|
||||
|
||||
pub(super) fn get_webdav_params_input(&self) -> WebDAVProtocolParams {
|
||||
let uri: String = self.get_webdav_uri();
|
||||
let username = self.get_input_username().unwrap_or_default();
|
||||
let password = self.get_input_password().unwrap_or_default();
|
||||
|
||||
WebDAVProtocolParams {
|
||||
uri,
|
||||
username,
|
||||
password,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_input_remote_directory(&self) -> Option<PathBuf> {
|
||||
match self.app.state(&Id::RemoteDirectory) {
|
||||
Ok(State::One(StateValue::String(x))) if !x.is_empty() => {
|
||||
@@ -878,6 +924,13 @@ impl AuthActivity {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_webdav_uri(&self) -> String {
|
||||
match self.app.state(&Id::WebDAVUri) {
|
||||
Ok(State::One(StateValue::String(x))) => x,
|
||||
_ => String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_input_addr(&self) -> String {
|
||||
match self.app.state(&Id::Address) {
|
||||
Ok(State::One(StateValue::String(x))) => x,
|
||||
@@ -1011,6 +1064,7 @@ impl AuthActivity {
|
||||
InputMask::AwsS3 => 12,
|
||||
InputMask::Generic => 12,
|
||||
InputMask::Smb => 12,
|
||||
InputMask::WebDAV => 12,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1069,6 +1123,7 @@ impl AuthActivity {
|
||||
};
|
||||
format!("\\\\{username}{}\\{}", params.address, params.share)
|
||||
}
|
||||
ProtocolParams::WebDAV(params) => params.uri,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1180,6 +1235,23 @@ impl AuthActivity {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_webdav_view(&self) -> [Id; 4] {
|
||||
match self.app.focus() {
|
||||
Some(&Id::LocalDirectory) => [
|
||||
Id::Username,
|
||||
Id::Password,
|
||||
Id::RemoteDirectory,
|
||||
Id::LocalDirectory,
|
||||
],
|
||||
_ => [
|
||||
Id::WebDAVUri,
|
||||
Id::Username,
|
||||
Id::Password,
|
||||
Id::RemoteDirectory,
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
fn init_global_listener(&mut self) {
|
||||
use tuirealm::event::{Key, KeyEvent, KeyModifiers};
|
||||
assert!(self
|
||||
|
||||
@@ -112,6 +112,7 @@ impl FileTransferActivity {
|
||||
ProtocolParams::Generic(params) => params.address.clone(),
|
||||
ProtocolParams::AwsS3(params) => params.bucket_name.clone(),
|
||||
ProtocolParams::Smb(params) => params.address.clone(),
|
||||
ProtocolParams::WebDAV(params) => params.uri.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +142,13 @@ impl FileTransferActivity {
|
||||
);
|
||||
format!("Connecting to \\\\{}\\{}…", params.address, params.share)
|
||||
}
|
||||
ProtocolParams::WebDAV(params) => {
|
||||
info!(
|
||||
"Client is not connected to remote; connecting to {}",
|
||||
params.uri
|
||||
);
|
||||
format!("Connecting to {}…", params.uri)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::explorer::GroupDirs as GroupDirsEnum;
|
||||
use crate::filetransfer::FileTransferProtocol;
|
||||
use crate::ui::activities::setup::{
|
||||
RADIO_PROTOCOL_FTP, RADIO_PROTOCOL_FTPS, RADIO_PROTOCOL_S3, RADIO_PROTOCOL_SCP,
|
||||
RADIO_PROTOCOL_SFTP, RADIO_PROTOCOL_SMB,
|
||||
RADIO_PROTOCOL_SFTP, RADIO_PROTOCOL_SMB, RADIO_PROTOCOL_WEBDAV,
|
||||
};
|
||||
use crate::utils::parser::parse_bytesize;
|
||||
|
||||
@@ -67,7 +67,7 @@ impl DefaultProtocol {
|
||||
.color(Color::Cyan)
|
||||
.modifiers(BorderType::Rounded),
|
||||
)
|
||||
.choices(&["SFTP", "SCP", "FTP", "FTPS", "S3", "SMB"])
|
||||
.choices(&["SFTP", "SCP", "FTP", "FTPS", "S3", "SMB", "WebDAV"])
|
||||
.foreground(Color::Cyan)
|
||||
.rewind(true)
|
||||
.title("Default protocol", Alignment::Left)
|
||||
@@ -78,6 +78,7 @@ impl DefaultProtocol {
|
||||
FileTransferProtocol::Ftp(true) => RADIO_PROTOCOL_FTPS,
|
||||
FileTransferProtocol::AwsS3 => RADIO_PROTOCOL_S3,
|
||||
FileTransferProtocol::Smb => RADIO_PROTOCOL_SMB,
|
||||
FileTransferProtocol::WebDAV => RADIO_PROTOCOL_WEBDAV,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ const RADIO_PROTOCOL_FTP: usize = 2;
|
||||
const RADIO_PROTOCOL_FTPS: usize = 3;
|
||||
const RADIO_PROTOCOL_S3: usize = 4;
|
||||
const RADIO_PROTOCOL_SMB: usize = 5;
|
||||
const RADIO_PROTOCOL_WEBDAV: usize = 6;
|
||||
|
||||
// -- components
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
|
||||
|
||||
@@ -10,7 +10,9 @@ use std::path::PathBuf;
|
||||
use tuirealm::tui::layout::{Constraint, Direction, Layout};
|
||||
use tuirealm::{State, StateValue};
|
||||
|
||||
use super::{components, Context, Id, IdCommon, IdConfig, SetupActivity, ViewLayout};
|
||||
use super::{
|
||||
components, Context, Id, IdCommon, IdConfig, SetupActivity, ViewLayout, RADIO_PROTOCOL_WEBDAV,
|
||||
};
|
||||
use crate::explorer::GroupDirs;
|
||||
use crate::filetransfer::FileTransferProtocol;
|
||||
use crate::ui::activities::setup::{
|
||||
@@ -277,6 +279,7 @@ impl SetupActivity {
|
||||
RADIO_PROTOCOL_FTPS => FileTransferProtocol::Ftp(true),
|
||||
RADIO_PROTOCOL_S3 => FileTransferProtocol::AwsS3,
|
||||
RADIO_PROTOCOL_SMB => FileTransferProtocol::Smb,
|
||||
RADIO_PROTOCOL_WEBDAV => FileTransferProtocol::WebDAV,
|
||||
_ => FileTransferProtocol::Sftp,
|
||||
};
|
||||
self.config_mut().set_default_protocol(protocol);
|
||||
|
||||
@@ -14,7 +14,9 @@ use tuirealm::utils::parser as tuirealm_parser;
|
||||
|
||||
#[cfg(smb)]
|
||||
use crate::filetransfer::params::SmbParams;
|
||||
use crate::filetransfer::params::{AwsS3Params, GenericProtocolParams, ProtocolParams};
|
||||
use crate::filetransfer::params::{
|
||||
AwsS3Params, GenericProtocolParams, ProtocolParams, WebDAVProtocolParams,
|
||||
};
|
||||
use crate::filetransfer::{FileTransferParams, FileTransferProtocol};
|
||||
#[cfg(not(test))] // NOTE: don't use configuration during tests
|
||||
use crate::system::config_client::ConfigClient;
|
||||
@@ -43,6 +45,16 @@ static REMOTE_GENERIC_OPT_REGEX: Lazy<Regex> = lazy_regex!(
|
||||
r"(?:([^@]+)@)?(?:([^:]+))(?::((?:[0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(?:[0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])))?(?::([^:]+))?"
|
||||
);
|
||||
|
||||
/**
|
||||
* Regex matches:
|
||||
* - group 1: Username
|
||||
* - group 2: Password
|
||||
* - group 2: Uri
|
||||
* - group 4: Some(path) | None
|
||||
*/
|
||||
static REMOTE_WEBDAV_OPT_REGEX: Lazy<Regex> =
|
||||
lazy_regex!(r"(?:([^:]+):)(?:([^@]+)@)(?:([^/]+))(?:/(.+))?");
|
||||
|
||||
/**
|
||||
* Regex matches:
|
||||
* - group 1: Bucket
|
||||
@@ -145,14 +157,24 @@ pub fn parse_remote_opt(s: &str) -> Result<FileTransferParams, String> {
|
||||
#[cfg(test)] // NOTE: during test set protocol just to Sftp
|
||||
let default_protocol: FileTransferProtocol = FileTransferProtocol::Sftp;
|
||||
// Get protocol
|
||||
let (protocol, s): (FileTransferProtocol, String) =
|
||||
let (protocol, remote): (FileTransferProtocol, String) =
|
||||
parse_remote_opt_protocol(s, default_protocol)?;
|
||||
// Match against regex for protocol type
|
||||
match protocol {
|
||||
FileTransferProtocol::AwsS3 => parse_s3_remote_opt(s.as_str()),
|
||||
FileTransferProtocol::AwsS3 => parse_s3_remote_opt(remote.as_str()),
|
||||
#[cfg(smb)]
|
||||
FileTransferProtocol::Smb => parse_smb_remote_opts(s.as_str()),
|
||||
protocol => parse_generic_remote_opt(s.as_str(), protocol),
|
||||
FileTransferProtocol::Smb => parse_smb_remote_opts(remote.as_str()),
|
||||
FileTransferProtocol::WebDAV => {
|
||||
// get the differnece between s and remote
|
||||
let prefix = if s.starts_with("https") {
|
||||
"https"
|
||||
} else {
|
||||
"http"
|
||||
};
|
||||
|
||||
parse_webdav_remote_opt(remote.as_str(), prefix)
|
||||
}
|
||||
protocol => parse_generic_remote_opt(remote.as_str(), protocol),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,6 +254,29 @@ fn parse_generic_remote_opt(
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_webdav_remote_opt(s: &str, prefix: &str) -> Result<FileTransferParams, String> {
|
||||
match REMOTE_WEBDAV_OPT_REGEX.captures(s) {
|
||||
Some(groups) => {
|
||||
let username = groups.get(1).map(|x| x.as_str().to_string()).unwrap();
|
||||
let password = groups.get(2).map(|x| x.as_str().to_string()).unwrap();
|
||||
let uri = groups.get(3).map(|x| x.as_str().to_string()).unwrap();
|
||||
let remote_path: Option<PathBuf> =
|
||||
groups.get(4).map(|group| PathBuf::from(group.as_str()));
|
||||
|
||||
let params = ProtocolParams::WebDAV(WebDAVProtocolParams {
|
||||
uri: format!("{}://{}", prefix, uri),
|
||||
username,
|
||||
password,
|
||||
});
|
||||
Ok(
|
||||
FileTransferParams::new(FileTransferProtocol::WebDAV, params)
|
||||
.remote_path(remote_path),
|
||||
)
|
||||
}
|
||||
None => Err(String::from("Bad remote host syntax!")),
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse remote options for s3 protocol
|
||||
fn parse_s3_remote_opt(s: &str) -> Result<FileTransferParams, String> {
|
||||
match REMOTE_S3_OPT_REGEX.captures(s) {
|
||||
@@ -553,6 +598,25 @@ mod tests {
|
||||
assert!(parse_remote_opt(&String::from("scp://172.26.104.1:650000")).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_should_parse_webdav_opt() {
|
||||
let result =
|
||||
parse_remote_opt("https://omar:password@myserver:4445/myshare/dir/subdir").unwrap();
|
||||
|
||||
let params = result.params.webdav_params().unwrap();
|
||||
assert_eq!(params.uri.as_str(), "https://myserver:4445");
|
||||
assert_eq!(params.username.as_str(), "omar");
|
||||
assert_eq!(params.password.as_str(), "password");
|
||||
|
||||
let result =
|
||||
parse_remote_opt("http://omar:password@myserver:4445/myshare/dir/subdir").unwrap();
|
||||
|
||||
let params = result.params.webdav_params().unwrap();
|
||||
assert_eq!(params.uri.as_str(), "http://myserver:4445");
|
||||
assert_eq!(params.username.as_str(), "omar");
|
||||
assert_eq!(params.password.as_str(), "password");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_aws_s3_opt() {
|
||||
// Simple
|
||||
|
||||
Reference in New Issue
Block a user