From ca122cad6608fc965fcb7364a979556f5671729e Mon Sep 17 00:00:00 2001 From: timvisee Date: Wed, 27 Feb 2019 19:42:14 +0100 Subject: [PATCH] Make API version selection possible, update for newer ffsend-api version --- Cargo.lock | 192 ++++++++++++++++++++++++++++++++++++ Cargo.toml | 8 +- README.md | 16 +-- src/action/debug.rs | 2 +- src/action/download.rs | 24 ++++- src/action/mod.rs | 42 ++++++++ src/action/upload.rs | 37 ++++++- src/client.rs | 3 +- src/cmd/arg/api.rs | 59 +++++++++++ src/cmd/arg/mod.rs | 4 +- src/cmd/handler.rs | 2 + src/cmd/matcher/download.rs | 11 +++ src/cmd/matcher/main.rs | 7 ++ src/config.rs | 8 ++ src/util.rs | 12 ++- 15 files changed, 407 insertions(+), 20 deletions(-) create mode 100644 src/cmd/arg/api.rs diff --git a/Cargo.lock b/Cargo.lock index c3d4060..33853ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,6 +77,15 @@ dependencies = [ "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "base64" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "base64" version = "0.10.1" @@ -543,6 +552,8 @@ dependencies = [ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "version-compare 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "websocket 0.22.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -673,6 +684,24 @@ name = "httparse" version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "hyper" +version = "0.10.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hyper" version = "0.12.24" @@ -754,6 +783,11 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "language-tags" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "lazy_static" version = "1.2.0" @@ -788,6 +822,14 @@ dependencies = [ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "log" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "log" version = "0.4.6" @@ -822,6 +864,14 @@ name = "memoffset" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "mime" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mime" version = "0.3.13" @@ -859,6 +909,16 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mio-uds" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "miow" version = "0.2.1" @@ -1336,6 +1396,11 @@ name = "ryu" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "safemem" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "schannel" version = "0.1.14" @@ -1420,6 +1485,11 @@ dependencies = [ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sha1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "sha2" version = "0.8.0" @@ -1575,12 +1645,28 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-fs 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-sync 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-codec" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1601,6 +1687,16 @@ dependencies = [ "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-fs" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-io" version = "0.1.11" @@ -1628,6 +1724,14 @@ dependencies = [ "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-sync" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-tcp" version = "0.1.3" @@ -1669,6 +1773,47 @@ dependencies = [ "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-tls" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-udp" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-uds" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "toml" version = "0.4.10" @@ -1677,11 +1822,21 @@ dependencies = [ "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "traitobject" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "try-lock" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "typeable" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "typenum" version = "1.10.0" @@ -1796,6 +1951,26 @@ dependencies = [ "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "websocket" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi" version = "0.2.8" @@ -1871,6 +2046,7 @@ dependencies = [ "checksum backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b5b493b66e03090ebc4343eb02f94ff944e0cbc9ac6571491d170ba026741eb5" "checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" +"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" "checksum block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49665c62e0e700857531fa5d3763e91b539ff1abeebd56808d378b495870d60d" @@ -1933,6 +2109,7 @@ dependencies = [ "checksum hmac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f127a908633569f208325f86f71255d3363c79721d7f9fe31cd5569908819771" "checksum http 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "1a10e5b573b9a0146545010f50772b9e8b1dd0a256564cc4307694c68832a2f5" "checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" +"checksum hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)" = "df0caae6b71d266b91b4a83111a61d2b94ed2e2bea024c532b933dcff867e58c" "checksum hyper 0.12.24 (registry+https://github.com/rust-lang/crates.io-index)" = "fdfa9b401ef6c4229745bb6e9b2529192d07b920eed624cdee2a82348cd550af" "checksum hyper-tls 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "32cd73f14ad370d3b4d4b7dce08f69b81536c82e39fcc89731930fe5788cd661" "checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa" @@ -1941,19 +2118,23 @@ dependencies = [ "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" "checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" "checksum libflate 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "bff3ac7d6f23730d3b533c35ed75eef638167634476a499feef16c428d74b57b" "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" +"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" +"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" "checksum mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "3e27ca21f40a310bd06d9031785f4801710d566c184a6e15bad4f1d9b65f9425" "checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed" "checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" +"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff8e08de0070bbf4c31f452ea2a70db092f36f6f2e4d897adf5674477d488fb2" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" @@ -2006,6 +2187,7 @@ dependencies = [ "checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" +"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" "checksum schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum security-framework 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfab8dda0e7a327c696d893df9ffa19cadc4bd195797997f5223cf5831beaf05" @@ -2016,6 +2198,7 @@ dependencies = [ "checksum serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "beed18e6f5175aef3ba670e57c60ef3b1b74d250d962a26604bff4c80e970dd4" "checksum serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "27dce848e7467aa0e2fcaf0a413641499c0b745452aaca1194d24dedde9e13c9" "checksum serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d48f9f99cd749a2de71d29da5f948de7f2764cc5a9d7f3c97e3514d4ee6eabf2" +"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" @@ -2035,15 +2218,23 @@ dependencies = [ "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "e0500b88064f08bebddd0c0bed39e19f5c567a5f30975bee52b0c0d3e2eeb38c" +"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" "checksum tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "331c8acc267855ec06eb0c94618dcbbfea45bed2d20b77252940095273fb58f6" "checksum tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30c6dbf2d1ad1de300b393910e8a3aa272b724a400b6531da03eed99e329fbf0" +"checksum tokio-fs 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9cbbc8a3698b7ab652340f46633364f9eaa928ddaaee79d8b8f356dd79a09d" "checksum tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b53aeb9d3f5ccf2ebb29e19788f96987fa1355f8fe45ea193928eaaaf3ae820f" "checksum tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "afbcdb0f0d2a1e4c440af82d7bbf0bf91a8a8c0575bcd20c05d15be7e9d3a02f" +"checksum tokio-sync 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3742b64166c1ee9121f1921aea5a726098458926a6b732d906ef23b1f3ef6f4f" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" "checksum tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c3fd86cb15547d02daa2b21aadaf4e37dee3368df38a526178a5afa3c034d2fb" "checksum tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2910970404ba6fa78c5539126a9ae2045d62e3713041e447f695f41405a120c6" +"checksum tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "354b8cd83825b3c20217a9dc174d6a0c67441a2fae5c41bcb1ea6679f6ae0f7c" +"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" +"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" +"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" +"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" @@ -2061,6 +2252,7 @@ dependencies = [ "checksum version-compare 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "78068add8bf1e4d37d13fa5867182fe4c03f8e525c831053733f83aaba942d37" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" +"checksum websocket 0.22.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d2c67346c042adbd4f5b2a49700e340befc5b772094fec8d36df6b825523d933" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/Cargo.toml b/Cargo.toml index e55cf89..2bf2622 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ name = "ffsend" path = "src/main.rs" [features] -default = ["archive", "clipboard", "history"] +default = ["archive", "clipboard", "history", "send2", "send3"] # Compile with file archiving support archive = ["tar"] @@ -61,6 +61,12 @@ history = [] # Compile without colored output support no-color = ["colored/no-color"] +# Support for Firefox Send v2 +send2 = ["ffsend-api/send2"] + +# Support for Firefox Send v3 +send3 = ["ffsend-api/send3"] + [dependencies] chbs = "0.0.8" chrono = "0.4" diff --git a/README.md b/README.md index ec892bc..b297695 100644 --- a/README.md +++ b/README.md @@ -268,12 +268,13 @@ The following environment variables may be used to configure the following defaults. The CLI flag is shown along with it, to better describe the relation to command line arguments: -| Variable | CLI flag | Description | -| :------------------------ | :----------------------------: | :------------------------------ | -| `FFSEND_HISTORY` | `--history ` | History file path | -| `FFSEND_HOST` | `--host ` | Upload host | -| `FFSEND_TIMEOUT` | `--timeout ` | Request timeout (0 to disable) | -| `FFSEND_TRANSFER_TIMEOUT` | `--transfer-timeout ` | Transfer timeout (0 to disable) | +| Variable | CLI flag | Description | +| :------------------------ | :----------------------------: | :-------------------------------- | +| `FFSEND_HISTORY` | `--history ` | History file path | +| `FFSEND_HOST` | `--host ` | Upload host | +| `FFSEND_TIMEOUT` | `--timeout ` | Request timeout (0 to disable) | +| `FFSEND_TRANSFER_TIMEOUT` | `--transfer-timeout ` | Transfer timeout (0 to disable) | +| `FFSEND_API` | `--api ` | Server API version, `-` to lookup | These environment variables may be used to toggle a flag, simply by making them available. The actual value of these variables is ignored, and variables may be @@ -289,7 +290,7 @@ empty. | `FFSEND_ARCHIVE` | `--archive` | Archive files uploaded | | `FFSEND_EXTRACT` | `--extract` | Extract files downloaded | | `FFSEND_COPY` | `--copy` | Copy share link to clipboard | -| `FFSEND_QUIET` | `--quiet` | Log quiet information | +| `FFSEND_QUIET` | `--quiet` | Log quiet information | | `FFSEND_VERBOSE` | `--verbose` | Log verbose information | At this time, no configuration or _dotfile_ file support is available. @@ -376,6 +377,7 @@ SUBCOMMANDS: info Fetch info about a shared file [aliases: i] parameters Change parameters of a shared file [aliases: params] password Change the password of a shared file [aliases: pass, p] + version Determine the Send server version [aliases: v] The public Send service that is used as default host is provided by Mozilla. This application is not affiliated with Mozilla, Firefox or Firefox Send. diff --git a/src/action/debug.rs b/src/action/debug.rs index 73b07fa..07e1b5f 100644 --- a/src/action/debug.rs +++ b/src/action/debug.rs @@ -74,7 +74,7 @@ impl<'a> Debug<'a> { table.add_row(Row::new(vec![ Cell::new("Default expiry:"), Cell::new(&format_duration(Duration::seconds( - SEND_DEFAULT_EXPIRE_TIME, + SEND_DEFAULT_EXPIRE_TIME as i64, ))), ])); diff --git a/src/action/download.rs b/src/action/download.rs index 857f600..b912819 100644 --- a/src/action/download.rs +++ b/src/action/download.rs @@ -10,6 +10,8 @@ use failure::Fail; use ffsend_api::action::download::{Download as ApiDownload, Error as DownloadError}; use ffsend_api::action::exists::{Error as ExistsError, Exists as ApiExists}; use ffsend_api::action::metadata::{Error as MetadataError, Metadata as ApiMetadata}; +use ffsend_api::action::version::{Version as ApiVersion, Error as VersionError}; +use ffsend_api::api::Version; use ffsend_api::file::remote_file::{FileParseError, RemoteFile}; use ffsend_api::pipe::ProgressReporter; #[cfg(feature = "archive")] @@ -25,6 +27,7 @@ use crate::progress::ProgressBar; use crate::util::{ ensure_enough_space, ensure_password, prompt_yes, quit, quit_error, quit_error_msg, ErrorHints, }; +use super::select_api_version; /// A file download action. pub struct Download<'a> { @@ -44,12 +47,18 @@ impl<'a> Download<'a> { let matcher_main = MainMatcher::with(self.cmd_matches).unwrap(); let matcher_download = DownloadMatcher::with(self.cmd_matches).unwrap(); - // Get the share URL + // Get the share URL, derive the host let url = matcher_download.url(); + let host = matcher_download.guess_host(); // Create a reqwest client capable for downloading files let client = create_transfer_client(&matcher_main); + // Determine the API version to use + let mut desired_version = matcher_main.api(); + select_api_version(&client, host, &mut desired_version)?; + let api_version = desired_version.version().unwrap(); + // Parse the remote file based on the share URL let file = RemoteFile::parse_url(url, None)?; @@ -147,7 +156,7 @@ impl<'a> Download<'a> { } else { None }; - ApiDownload::new(&file, target, password, false, Some(metadata)) + ApiDownload::new(api_version, &file, target, password, false, Some(metadata)) .invoke(&client, progress)?; // Extract the downloaded file if working with an archive @@ -324,6 +333,11 @@ impl<'a> Download<'a> { #[derive(Debug, Fail)] pub enum Error { + /// Selecting the API version to use failed. + // TODO: enable `api` hint! + #[fail(display = "failed to select API version to use")] + Version(#[cause] VersionError), + /// Failed to parse a share URL, it was invalid. /// This error is not related to a specific action. #[fail(display = "invalid share link")] @@ -351,6 +365,12 @@ pub enum Error { Expired, } +impl From for Error { + fn from(err: VersionError) -> Error { + Error::Version(err) + } +} + impl From for Error { fn from(err: FileParseError) -> Error { Error::InvalidUrl(err) diff --git a/src/action/mod.rs b/src/action/mod.rs index 3589a66..5e96c9c 100644 --- a/src/action/mod.rs +++ b/src/action/mod.rs @@ -9,3 +9,45 @@ pub mod params; pub mod password; pub mod upload; pub mod version; + +use ffsend_api::action::version::{Version as ApiVersion, Error as VersionError}; +use ffsend_api::api::DesiredVersion; +use ffsend_api::url::Url; + +use crate::client::Client; +use crate::config::API_VERSION_ASSUME; +use crate::util::print_warning; + +/// Based on the given desired API version, select a version we can use. +/// +/// If the current desired version is set to the `DesiredVersion::Lookup` variant, this method +/// will look up the server API version. It it's `DesiredVersion::Use` it will return and +/// attempt to use the specified version. +fn select_api_version(client: &Client, host: Url, desired: &mut DesiredVersion) -> Result<(), VersionError> { + // Break if already specified + if let DesiredVersion::Use(_) = desired { + return Ok(()); + } + + // TODO: only lookup if `DesiredVersion::Assume` after first operation attempt failed + + // Look up the version + match ApiVersion::new(host).invoke(&client) { + // Use the probed version + Ok(v) => *desired = DesiredVersion::Use(v), + + // If unknown, just assume the default version + Err(VersionError::Unknown) => { + *desired = DesiredVersion::Use(API_VERSION_ASSUME); + print_warning(format!( + "server API version could not be determined, assuming v{}", + API_VERSION_ASSUME, + )); + } + + // Propegate other errors + Err(e) => return Err(e) + } + + Ok(()) +} diff --git a/src/action/upload.rs b/src/action/upload.rs index 034454f..b755205 100644 --- a/src/action/upload.rs +++ b/src/action/upload.rs @@ -8,6 +8,8 @@ use clap::ArgMatches; use failure::Fail; use ffsend_api::action::params::ParamsDataBuilder; use ffsend_api::action::upload::{Error as UploadError, Upload as ApiUpload}; +use ffsend_api::action::version::{Version as ApiVersion, Error as VersionError}; +use ffsend_api::api::Version; use ffsend_api::config::{UPLOAD_SIZE_MAX, UPLOAD_SIZE_MAX_RECOMMENDED}; use ffsend_api::pipe::ProgressReporter; use prettytable::{format::FormatBuilder, Cell, Row, Table}; @@ -16,7 +18,7 @@ use tempfile::{Builder as TempBuilder, NamedTempFile}; #[cfg(feature = "archive")] use crate::archive::archiver::Archiver; -use crate::client::create_transfer_client; +use crate::client::{create_client, create_transfer_client}; use crate::cmd::matcher::{MainMatcher, Matcher, UploadMatcher}; #[cfg(feature = "history")] use crate::history_tool; @@ -27,6 +29,7 @@ use crate::util::{ format_bytes, open_url, print_error, print_error_msg, prompt_yes, quit, quit_error_msg, ErrorHintsBuilder, }; +use super::select_api_version; /// A file upload action. pub struct Upload<'a> { @@ -47,10 +50,17 @@ impl<'a> Upload<'a> { let matcher_upload = UploadMatcher::with(self.cmd_matches).unwrap(); // Get API parameters - #[allow(unused_mut)] let mut path = Path::new(matcher_upload.file()).to_path_buf(); let host = matcher_upload.host(); + // Create a reqwest client capable for uploading files + let client = create_transfer_client(&matcher_main); + + // Determine the API version to use + let mut desired_version = matcher_main.api(); + select_api_version(&client, host.clone(), &mut desired_version)?; + let api_version = desired_version.version().unwrap(); + // TODO: ensure the file exists and is accessible // Get the file size to warn about large files @@ -91,7 +101,7 @@ impl<'a> Upload<'a> { } // Create a reqwest client capable for uploading files - let client = create_transfer_client(&matcher_main); + let transfer_client = create_transfer_client(&matcher_main); // Create a progress bar reporter let progress_bar = Arc::new(Mutex::new(ProgressBar::new_upload())); @@ -203,8 +213,14 @@ impl<'a> Upload<'a> { } else { None }; - let file = ApiUpload::new(host, path.clone(), file_name, password.clone(), params) - .invoke(&client, reporter)?; + let file = ApiUpload::new( + api_version, + host, + path.clone(), + file_name, + password.clone(), + params, + ).invoke(&transfer_client, reporter)?; let url = file.download_url(true); // Report the result @@ -275,6 +291,11 @@ impl<'a> Upload<'a> { #[derive(Debug, Fail)] pub enum Error { + /// Selecting the API version to use failed. + // TODO: enable `api` hint! + #[fail(display = "failed to select API version to use")] + Version(#[cause] VersionError), + /// An error occurred while archiving the file to upload. #[cfg(feature = "archive")] #[fail(display = "failed to archive file to upload")] @@ -285,6 +306,12 @@ pub enum Error { Upload(#[cause] UploadError), } +impl From for Error { + fn from(err: VersionError) -> Error { + Error::Version(err) + } +} + #[cfg(feature = "archive")] impl From for Error { fn from(err: ArchiveError) -> Error { diff --git a/src/client.rs b/src/client.rs index a8556ca..a919db1 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,6 +1,7 @@ use std::time::Duration; -use ffsend_api::reqwest::{Client, ClientBuilder}; +pub use ffsend_api::reqwest::Client; +use ffsend_api::reqwest::ClientBuilder; use crate::cmd::matcher::MainMatcher; diff --git a/src/cmd/arg/api.rs b/src/cmd/arg/api.rs new file mode 100644 index 0000000..0a9b620 --- /dev/null +++ b/src/cmd/arg/api.rs @@ -0,0 +1,59 @@ +use clap::{Arg, ArgMatches}; +use failure::Fail; +use ffsend_api::api::{DesiredVersion, Version}; +use ffsend_api::url::Url; + +use super::{CmdArg, CmdArgOption}; +use crate::config::API_VERSION_DESIRED_DEFAULT; +use crate::util::{quit_error, ErrorHints}; + +/// The api argument. +pub struct ArgApi {} + +impl CmdArg for ArgApi { + fn name() -> &'static str { + "api" + } + + fn build<'b, 'c>() -> Arg<'b, 'c> { + Arg::with_name("api") + .long("api") + .short("A") + .value_name("VERSION") + .env("FFSEND_API") + .hide_env_values(true) + .global(true) + .help("Server API version to use, '-' to lookup") + } +} + +impl<'a> CmdArgOption<'a> for ArgApi { + type Value = DesiredVersion; + + fn value<'b: 'a>(matches: &'a ArgMatches<'b>) -> Self::Value { + // Get the version string + let version = match Self::value_raw(matches) { + Some(version) => version, + None => return API_VERSION_DESIRED_DEFAULT, + }; + + // Parse the lookup version string + if version.trim() == "-" { + return DesiredVersion::Lookup; + } + + // Parse the given API version + match Version::parse(version) { + Ok(version) => DesiredVersion::Use(version), + Err(err) => { + panic!("failed to determine given server API version, version unknown"); + + // TODO: properly quit with an application error instead + // quit_error( + // err.context("failed to determine given server API version, version unknown"), + // ErrorHints::default(), + // ) + }, + } + } +} diff --git a/src/cmd/arg/mod.rs b/src/cmd/arg/mod.rs index 9cf3518..b2688be 100644 --- a/src/cmd/arg/mod.rs +++ b/src/cmd/arg/mod.rs @@ -1,3 +1,4 @@ +pub mod api; pub mod download_limit; pub mod gen_passphrase; pub mod host; @@ -5,7 +6,8 @@ pub mod owner; pub mod password; pub mod url; -// Reexport to arg module +// Re-eexport to arg module +pub use self::api::ArgApi; pub use self::download_limit::ArgDownloadLimit; pub use self::gen_passphrase::ArgGenPassphrase; pub use self::host::ArgHost; diff --git a/src/cmd/handler.rs b/src/cmd/handler.rs index dfd3de5..91e5d88 100644 --- a/src/cmd/handler.rs +++ b/src/cmd/handler.rs @@ -2,6 +2,7 @@ extern crate directories; use clap::{App, AppSettings, Arg, ArgMatches}; +use super::arg::{ArgApi, CmdArg}; #[cfg(feature = "history")] use super::matcher::HistoryMatcher; use super::matcher::{ @@ -139,6 +140,7 @@ impl<'a: 'b, 'b> Handler<'a> { .global(true) .help("Enable verbose information and logging"), ) + .arg(ArgApi::build()) .subcommand(CmdDebug::build()) .subcommand(CmdDelete::build()) .subcommand(CmdDownload::build().display_order(2)) diff --git a/src/cmd/matcher/download.rs b/src/cmd/matcher/download.rs index f77dfb5..ea3aebd 100644 --- a/src/cmd/matcher/download.rs +++ b/src/cmd/matcher/download.rs @@ -23,6 +23,17 @@ impl<'a: 'b, 'b> DownloadMatcher<'a> { ArgUrl::value(self.matches) } + /// Guess the file share host, based on the file share URL. + /// + /// See `Self::url`. + pub fn guess_host(&'a self) -> Url { + let mut url = self.url(); + url.set_path(""); + url.set_query(None); + url.set_fragment(None); + url + } + /// Get the password. /// `None` is returned if no password was specified. pub fn password(&'a self) -> Option { diff --git a/src/cmd/matcher/main.rs b/src/cmd/matcher/main.rs index 2b8cf14..baa0011 100644 --- a/src/cmd/matcher/main.rs +++ b/src/cmd/matcher/main.rs @@ -2,8 +2,10 @@ use std::path::PathBuf; use clap::ArgMatches; +use ffsend_api::api::DesiredVersion; use super::Matcher; +use crate::cmd::arg::{ArgApi, CmdArgOption}; use crate::util::env_var_present; #[cfg(feature = "history")] use crate::util::{quit_error_msg, ErrorHintsBuilder}; @@ -29,6 +31,11 @@ impl<'a: 'b, 'b> MainMatcher<'a> { self.matches.is_present("yes") || env_var_present("FFSEND_YES") } + /// Get the desired API version to use. + pub fn api(&'a self) -> DesiredVersion { + ArgApi::value(self.matches) + } + /// Get the history file to use. #[cfg(feature = "history")] pub fn history(&self) -> PathBuf { diff --git a/src/config.rs b/src/config.rs index 55709a3..96d2e2f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,14 @@ +use ffsend_api::api::{DesiredVersion, Version}; + /// The timeout for the Send client for generic requests, `0` to disable. pub const CLIENT_TIMEOUT: u64 = 30; /// The timeout for the Send client used to transfer (upload/download) files. /// Make sure this is big enough, or file uploads will be dropped. `0` to disable. pub const CLIENT_TRANSFER_TIMEOUT: u64 = 24 * 60 * 60; + +/// The default desired version to select for the server API. +pub const API_VERSION_DESIRED_DEFAULT: DesiredVersion = DesiredVersion::Assume(API_VERSION_ASSUME); + +/// The default server API version to assume when it could not be determined. +pub const API_VERSION_ASSUME: Version = Version::V2; diff --git a/src/util.rs b/src/util.rs index 9fa6200..5809e52 100644 --- a/src/util.rs +++ b/src/util.rs @@ -78,7 +78,6 @@ where } /// Print a warning. -#[cfg(feature = "history")] pub fn print_warning(err: S) where S: AsRef + Display + Debug + Sync + Send + 'static, @@ -117,6 +116,9 @@ where #[derive(Clone, Builder)] #[builder(default)] pub struct ErrorHints { + /// Show about specifying an API version. + api: bool, + /// A list of info messages to print along with the error. info: Vec, @@ -171,6 +173,12 @@ impl ErrorHints { eprint!("\n"); // Print hints + if self.api { + eprintln!( + "Use '{}' to select a server API version", + highlight("--api ") + ); + } if self.password { eprintln!( "Use '{}' to specify a password", @@ -210,6 +218,7 @@ impl ErrorHints { impl Default for ErrorHints { fn default() -> Self { ErrorHints { + api: false, info: Vec::new(), password: false, owner: false, @@ -250,7 +259,6 @@ pub fn highlight_error(msg: &str) -> ColoredString { } /// Highlight the given text with an warning color. -#[cfg(feature = "history")] pub fn highlight_warning(msg: &str) -> ColoredString { highlight(msg).bold() }