diff options
-rw-r--r-- | Cargo.lock | 7 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/error.rs | 13 | ||||
-rw-r--r-- | src/main.rs | 33 | ||||
-rw-r--r-- | src/requests/device.rs | 23 | ||||
-rw-r--r-- | src/requests/start.rs | 24 |
6 files changed, 66 insertions, 35 deletions
@@ -66,6 +66,12 @@ dependencies = [ | |||
66 | ] | 66 | ] |
67 | 67 | ||
68 | [[package]] | 68 | [[package]] |
69 | name = "anyhow" | ||
70 | version = "1.0.80" | ||
71 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
72 | checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" | ||
73 | |||
74 | [[package]] | ||
69 | name = "async-trait" | 75 | name = "async-trait" |
70 | version = "0.1.74" | 76 | version = "0.1.74" |
71 | source = "registry+https://github.com/rust-lang/crates.io-index" | 77 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1725,6 +1731,7 @@ dependencies = [ | |||
1725 | name = "webol-cli" | 1731 | name = "webol-cli" |
1726 | version = "0.2.0" | 1732 | version = "0.2.0" |
1727 | dependencies = [ | 1733 | dependencies = [ |
1734 | "anyhow", | ||
1728 | "clap", | 1735 | "clap", |
1729 | "clap_complete", | 1736 | "clap_complete", |
1730 | "config", | 1737 | "config", |
@@ -10,6 +10,7 @@ name = "webol" | |||
10 | path = "src/main.rs" | 10 | path = "src/main.rs" |
11 | 11 | ||
12 | [dependencies] | 12 | [dependencies] |
13 | anyhow = "1.0" | ||
13 | clap = { version = "4.5", features = ["derive"] } | 14 | clap = { version = "4.5", features = ["derive"] } |
14 | clap_complete = "4.5" | 15 | clap_complete = "4.5" |
15 | config = "0.14" | 16 | config = "0.14" |
diff --git a/src/error.rs b/src/error.rs index 15e4308..1e6eac1 100644 --- a/src/error.rs +++ b/src/error.rs | |||
@@ -27,8 +27,17 @@ pub enum Error { | |||
27 | #[error("parse header: {source}")] | 27 | #[error("parse header: {source}")] |
28 | InvalidHeaderValue { | 28 | InvalidHeaderValue { |
29 | #[from] | 29 | #[from] |
30 | source: InvalidHeaderValue | 30 | source: InvalidHeaderValue, |
31 | }, | 31 | }, |
32 | #[error("ws")] | 32 | #[error("tungstenite: {source}")] |
33 | Tungstenite { | ||
34 | #[from] | ||
35 | source: tokio_tungstenite::tungstenite::Error, | ||
36 | }, | ||
37 | #[error("faulty websocket response")] | ||
33 | WsResponse, | 38 | WsResponse, |
39 | #[error("authorization failed")] | ||
40 | Authorization, | ||
41 | #[error("Http error status: {0}")] | ||
42 | HttpStatus(u16), | ||
34 | } | 43 | } |
diff --git a/src/main.rs b/src/main.rs index cdca6cb..d76341f 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -6,7 +6,10 @@ use clap_complete::{generate, Generator, Shell}; | |||
6 | use error::Error; | 6 | use error::Error; |
7 | use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; | 7 | use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; |
8 | use requests::{device, start::start}; | 8 | use requests::{device, start::start}; |
9 | use reqwest::header::{HeaderMap, HeaderValue}; | 9 | use reqwest::{ |
10 | header::{HeaderMap, HeaderValue}, | ||
11 | Response, | ||
12 | }; | ||
10 | use serde::Deserialize; | 13 | use serde::Deserialize; |
11 | 14 | ||
12 | mod config; | 15 | mod config; |
@@ -66,7 +69,7 @@ enum DeviceCmd { | |||
66 | } | 69 | } |
67 | 70 | ||
68 | #[tokio::main] | 71 | #[tokio::main] |
69 | async fn main() -> Result<(), Error> { | 72 | async fn main() -> Result<(), anyhow::Error> { |
70 | let config = Config::load()?; | 73 | let config = Config::load()?; |
71 | 74 | ||
72 | let cli = Args::parse(); | 75 | let cli = Args::parse(); |
@@ -112,18 +115,9 @@ fn print_completions<G: Generator>(gen: G, cmd: &mut Command) { | |||
112 | 115 | ||
113 | fn default_headers(config: &Config) -> Result<HeaderMap, Error> { | 116 | fn default_headers(config: &Config) -> Result<HeaderMap, Error> { |
114 | let mut map = HeaderMap::new(); | 117 | let mut map = HeaderMap::new(); |
115 | map.append( | 118 | map.append("Accept-Content", HeaderValue::from_str("application/json")?); |
116 | "Accept-Content", | 119 | map.append("Content-Type", HeaderValue::from_str("application/json")?); |
117 | HeaderValue::from_str("application/json")? | 120 | map.append("Authorization", HeaderValue::from_str(&config.apikey)?); |
118 | ); | ||
119 | map.append( | ||
120 | "Content-Type", | ||
121 | HeaderValue::from_str("application/json")? | ||
122 | ); | ||
123 | map.append( | ||
124 | "Authorization", | ||
125 | HeaderValue::from_str(&config.apikey)? | ||
126 | ); | ||
127 | 121 | ||
128 | Ok(map) | 122 | Ok(map) |
129 | } | 123 | } |
@@ -132,6 +126,17 @@ fn format_url(config: &Config, path: &str, protocol: &Protocols) -> String { | |||
132 | format!("{}://{}/{}", protocol, config.server, path) | 126 | format!("{}://{}/{}", protocol, config.server, path) |
133 | } | 127 | } |
134 | 128 | ||
129 | async fn check_success(res: Response) -> Result<String, Error> { | ||
130 | let status = res.status(); | ||
131 | if status.is_success() { | ||
132 | Ok(res.text().await?) | ||
133 | } else if status.as_u16() == 401 { | ||
134 | Err(Error::Authorization) | ||
135 | } else { | ||
136 | Err(Error::HttpStatus(status.as_u16())) | ||
137 | } | ||
138 | } | ||
139 | |||
135 | fn add_pb(mp: &MultiProgress, template: &str, message: String) -> ProgressBar { | 140 | fn add_pb(mp: &MultiProgress, template: &str, message: String) -> ProgressBar { |
136 | let pb = mp.add(ProgressBar::new(1)); | 141 | let pb = mp.add(ProgressBar::new(1)); |
137 | pb.set_style(ProgressStyle::with_template(template).unwrap()); | 142 | pb.set_style(ProgressStyle::with_template(template).unwrap()); |
diff --git a/src/requests/device.rs b/src/requests/device.rs index a612978..7583406 100644 --- a/src/requests/device.rs +++ b/src/requests/device.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use crate::{config::Config, default_headers, error::Error, format_url, Protocols}; | 1 | use crate::{check_success, config::Config, default_headers, error::Error, format_url, Protocols}; |
2 | 2 | ||
3 | pub async fn put( | 3 | pub async fn put( |
4 | config: &Config, | 4 | config: &Config, |
@@ -16,11 +16,10 @@ pub async fn put( | |||
16 | r#"{{"id": "{id}", "mac": "{mac}", "broadcast_addr": "{broadcast_addr}", "ip": "{ip}"}}"#, | 16 | r#"{{"id": "{id}", "mac": "{mac}", "broadcast_addr": "{broadcast_addr}", "ip": "{ip}"}}"#, |
17 | )) | 17 | )) |
18 | .send() | 18 | .send() |
19 | .await? | 19 | .await?; |
20 | .text() | ||
21 | .await; | ||
22 | 20 | ||
23 | println!("{res:?}"); | 21 | let body = check_success(res).await?; |
22 | println!("{body}"); | ||
24 | Ok(()) | 23 | Ok(()) |
25 | } | 24 | } |
26 | 25 | ||
@@ -30,11 +29,10 @@ pub async fn get(config: &Config, id: String) -> Result<(), Error> { | |||
30 | .headers(default_headers(config)?) | 29 | .headers(default_headers(config)?) |
31 | .body(format!(r#"{{"id": "{id}"}}"#)) | 30 | .body(format!(r#"{{"id": "{id}"}}"#)) |
32 | .send() | 31 | .send() |
33 | .await? | 32 | .await?; |
34 | .text() | ||
35 | .await; | ||
36 | 33 | ||
37 | println!("{res:?}"); | 34 | let body = check_success(res).await?; |
35 | println!("{body}"); | ||
38 | Ok(()) | 36 | Ok(()) |
39 | } | 37 | } |
40 | 38 | ||
@@ -52,10 +50,9 @@ pub async fn post( | |||
52 | r#"{{"id": "{id}", "mac": "{mac}", "broadcast_addr": "{broadcast_addr}", "ip": "{ip}"}}"#, | 50 | r#"{{"id": "{id}", "mac": "{mac}", "broadcast_addr": "{broadcast_addr}", "ip": "{ip}"}}"#, |
53 | )) | 51 | )) |
54 | .send() | 52 | .send() |
55 | .await? | 53 | .await?; |
56 | .text() | ||
57 | .await; | ||
58 | 54 | ||
59 | println!("{res:?}"); | 55 | let body = check_success(res).await?; |
56 | println!("{body}"); | ||
60 | Ok(()) | 57 | Ok(()) |
61 | } | 58 | } |
diff --git a/src/requests/start.rs b/src/requests/start.rs index 7abbbe0..d07177e 100644 --- a/src/requests/start.rs +++ b/src/requests/start.rs | |||
@@ -2,7 +2,10 @@ use futures_util::{SinkExt, StreamExt}; | |||
2 | use indicatif::{MultiProgress, ProgressBar}; | 2 | use indicatif::{MultiProgress, ProgressBar}; |
3 | use reqwest::StatusCode; | 3 | use reqwest::StatusCode; |
4 | use serde::Deserialize; | 4 | use serde::Deserialize; |
5 | use tokio_tungstenite::{connect_async, tungstenite::Message}; | 5 | use tokio_tungstenite::{ |
6 | connect_async, | ||
7 | tungstenite::{http::Request, Message}, | ||
8 | }; | ||
6 | 9 | ||
7 | use crate::{ | 10 | use crate::{ |
8 | add_pb, config::Config, default_headers, error::Error, finish_pb, format_url, ErrorResponse, | 11 | add_pb, config::Config, default_headers, error::Error, finish_pb, format_url, ErrorResponse, |
@@ -66,17 +69,26 @@ async fn status_socket( | |||
66 | id: String, | 69 | id: String, |
67 | ) -> Result<bool, Error> { | 70 | ) -> Result<bool, Error> { |
68 | let ws_pb = add_pb(pb, DEFAULT_STYLE, "connect to websocket".to_string()); | 71 | let ws_pb = add_pb(pb, DEFAULT_STYLE, "connect to websocket".to_string()); |
69 | let (mut ws_stream, _response) = | 72 | |
70 | connect_async(format_url(config, "status", &Protocols::Websocket)) | 73 | let request = Request::builder() |
71 | .await | 74 | .uri(format_url(config, "status", &Protocols::Websocket)) |
72 | .expect("Failed to connect"); | 75 | .header("Authorization", &config.apikey) |
76 | .header("sec-websocket-key", "") | ||
77 | .header("host", &config.server) | ||
78 | .header("upgrade", "websocket") | ||
79 | .header("connection", "upgrade") | ||
80 | .header("sec-websocket-version", 13) | ||
81 | .body(()) | ||
82 | .unwrap(); | ||
83 | |||
84 | let (mut ws_stream, _response) = connect_async(request).await?; | ||
73 | finish_pb(&ws_pb, "connected to websocket".to_string(), DONE_STYLE); | 85 | finish_pb(&ws_pb, "connected to websocket".to_string(), DONE_STYLE); |
74 | 86 | ||
75 | ws_stream.send(Message::Text(uuid.clone())).await.unwrap(); | 87 | ws_stream.send(Message::Text(uuid.clone())).await.unwrap(); |
76 | 88 | ||
77 | // Get ETA | 89 | // Get ETA |
78 | let eta_msg = ws_stream.next().await.unwrap().unwrap(); | 90 | let eta_msg = ws_stream.next().await.unwrap().unwrap(); |
79 | let eta = get_eta(&eta_msg.into_text().unwrap(), &uuid)? + overview.elapsed().as_secs(); | 91 | let eta = get_eta(&eta_msg.into_text().unwrap(), &uuid)?; |
80 | overview.set_message(format!("/{eta}) start {id}")); | 92 | overview.set_message(format!("/{eta}) start {id}")); |
81 | 93 | ||
82 | let msg_pb = add_pb(pb, DEFAULT_STYLE, "await message".to_string()); | 94 | let msg_pb = add_pb(pb, DEFAULT_STYLE, "await message".to_string()); |