From 80c43caf71b3b3ec22bd868ef0ed4b28a8a63be6 Mon Sep 17 00:00:00 2001 From: Trisha Lefler Date: Fri, 25 Mar 2022 16:53:51 -0500 Subject: [PATCH 01/13] :mute: remove debugging stuff --- crates/ptth_server_gui/src/main.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/ptth_server_gui/src/main.rs b/crates/ptth_server_gui/src/main.rs index a8565ab..c5de016 100644 --- a/crates/ptth_server_gui/src/main.rs +++ b/crates/ptth_server_gui/src/main.rs @@ -54,9 +54,7 @@ fn main () let fltk_tx = fltk_tx.clone (); rt.spawn (async move { - eprintln! ("Entering channel task"); while let Some (_) = hit_rx.recv ().await { - eprintln! ("fltk_tx"); fltk_tx.send (Message::Hit); } }); From 140434cf660d03ba3f41eeec11a4e8b74e0b2fbd Mon Sep 17 00:00:00 2001 From: _ <_@_> Date: Wed, 27 Jul 2022 17:31:28 -0500 Subject: [PATCH 02/13] :construction: wip: placeholder metrics page --- crates/ptth_relay/src/scraper_api.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/crates/ptth_relay/src/scraper_api.rs b/crates/ptth_relay/src/scraper_api.rs index ddb2e93..f448410 100644 --- a/crates/ptth_relay/src/scraper_api.rs +++ b/crates/ptth_relay/src/scraper_api.rs @@ -205,6 +205,22 @@ async fn api_v1 ( } } +#[instrument (level = "trace", skip (req, state))] +async fn metrics ( + req: Request , + state: &Relay, +) +-> Result , RequestError> +{ + let mut s = String::with_capacity (4 * 1_024); + s.push_str ("# HELP forty_two Forty-two\n"); + s.push_str ("# TYPE forty_two counter\n"); + s.push_str ("forty_two 42\n"); + + Ok (Response::builder () + .body (Body::from (s))?) +} + #[instrument (level = "trace", skip (req, state))] pub async fn handle ( req: Request , @@ -225,6 +241,9 @@ pub async fn handle ( else if let Some (rest) = path_rest.strip_prefix ("api/") { api_v1 (req, state, rest).await } + else if path_rest == "metrics" { + metrics (req, state).await + } else { Ok (error_reply (StatusCode::NOT_FOUND, strings::UNKNOWN_API_VERSION)?) } From 96fdf642c36dce4af776dcca13b964af260b864a Mon Sep 17 00:00:00 2001 From: _ <_@_> Date: Wed, 27 Jul 2022 17:31:37 -0500 Subject: [PATCH 03/13] :white_check_mark: test: start adding Bearer Auth so Prometheus can connect to the scraper API --- crates/ptth_relay/src/scraper_api.rs | 72 ++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/crates/ptth_relay/src/scraper_api.rs b/crates/ptth_relay/src/scraper_api.rs index f448410..7c24b68 100644 --- a/crates/ptth_relay/src/scraper_api.rs +++ b/crates/ptth_relay/src/scraper_api.rs @@ -265,8 +265,9 @@ mod tests { struct TestCase { // Inputs path_rest: &'static str, + auth_header: Option <&'static str>, valid_key: Option <&'static str>, - input_key: Option <&'static str>, + x_api_key: Option <&'static str>, // Expected expected_status: StatusCode, @@ -287,9 +288,15 @@ mod tests { x } - fn input_key (&self, v: Option <&'static str>) -> Self { + fn auth_header (&self, v: Option <&'static str>) -> Self { let mut x = self.clone (); - x.input_key = v; + x.auth_header = v; + x + } + + fn x_api_key (&self, v: Option <&'static str>) -> Self { + let mut x = self.clone (); + x.x_api_key = v; x } @@ -322,8 +329,11 @@ mod tests { .method ("GET") .uri (format! ("http://127.0.0.1:4000/scraper/{}", self.path_rest)); - if let Some (input_key) = self.input_key { - input = input.header ("X-ApiKey", input_key); + if let Some (auth_header) = self.auth_header { + input = input.header ("Authorization", auth_header); + } + if let Some (x_api_key) = self.x_api_key { + input = input.header ("X-ApiKey", x_api_key); } let input = input.body (Body::empty ()).unwrap (); @@ -370,7 +380,8 @@ mod tests { let base_case = TestCase { path_rest: "v1/test", valid_key: Some ("bogus"), - input_key: Some ("bogus"), + auth_header: None, + x_api_key: Some ("bogus"), expected_status: StatusCode::OK, expected_headers: vec! [ ("content-type", "text/plain"), @@ -378,21 +389,40 @@ mod tests { expected_body: "You're valid!\n".to_string (), }; - for case in &[ - base_case.clone (), - base_case.path_rest ("v9999/test") - .expected (StatusCode::NOT_FOUND, strings::UNKNOWN_API_VERSION), - base_case.valid_key (None) - .expected (StatusCode::FORBIDDEN, strings::FORBIDDEN), - base_case.input_key (Some ("borgus")) - .expected (StatusCode::FORBIDDEN, strings::FORBIDDEN), - base_case.path_rest ("v1/toast") - .expected (StatusCode::NOT_FOUND, strings::UNKNOWN_API_ENDPOINT), - base_case.input_key (None) - .expected (StatusCode::FORBIDDEN, strings::NO_API_KEY), - ] { - case.test ().await; - } + base_case + .test ().await; + + base_case + .path_rest ("v9999/test") + .expected (StatusCode::NOT_FOUND, strings::UNKNOWN_API_VERSION) + .test ().await; + + base_case + .valid_key (None) + .expected (StatusCode::FORBIDDEN, strings::FORBIDDEN) + .test ().await; + + base_case + .x_api_key (Some ("borgus")) + .expected (StatusCode::FORBIDDEN, strings::FORBIDDEN) + .test ().await; + + base_case + .path_rest ("v1/toast") + .expected (StatusCode::NOT_FOUND, strings::UNKNOWN_API_ENDPOINT) + .test ().await; + + base_case + .x_api_key (None) + .expected (StatusCode::FORBIDDEN, strings::NO_API_KEY) + .test ().await; + + base_case + .x_api_key (None) + .auth_header (Some ("Bearer: bogus")) + .expected (StatusCode::FORBIDDEN, strings::NO_API_KEY) + .test ().await; + }); } } From 70eb419fdca71e809a1c75ec3b693e5205b02423 Mon Sep 17 00:00:00 2001 From: _ <_@_> Date: Fri, 29 Jul 2022 16:45:10 -0500 Subject: [PATCH 04/13] :bug: bug: move the metrics page behind auth --- crates/ptth_relay/src/scraper_api.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/ptth_relay/src/scraper_api.rs b/crates/ptth_relay/src/scraper_api.rs index 7c24b68..004118c 100644 --- a/crates/ptth_relay/src/scraper_api.rs +++ b/crates/ptth_relay/src/scraper_api.rs @@ -176,7 +176,10 @@ async fn api_v1 ( path: path_rest.to_string (), })).await; - if path_rest == "test" { + if path_rest == "metrics" { + Ok (metrics (req, state).await?) + } + else if path_rest == "test" { Ok (error_reply (StatusCode::OK, "You're valid!")?) } else if path_rest == "server_list" { @@ -241,9 +244,6 @@ pub async fn handle ( else if let Some (rest) = path_rest.strip_prefix ("api/") { api_v1 (req, state, rest).await } - else if path_rest == "metrics" { - metrics (req, state).await - } else { Ok (error_reply (StatusCode::NOT_FOUND, strings::UNKNOWN_API_VERSION)?) } From 7fe4444b656d636e9ae966e6ec22c17a61ba3b62 Mon Sep 17 00:00:00 2001 From: _ <_@_> Date: Fri, 29 Jul 2022 16:56:45 -0500 Subject: [PATCH 05/13] :heavy_plus_sign: linux-only memory measurement --- crates/ptth_relay/src/scraper_api.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/crates/ptth_relay/src/scraper_api.rs b/crates/ptth_relay/src/scraper_api.rs index 004118c..3bf6512 100644 --- a/crates/ptth_relay/src/scraper_api.rs +++ b/crates/ptth_relay/src/scraper_api.rs @@ -249,6 +249,20 @@ pub async fn handle ( } } +fn get_rss_from_status (proc_status: &str) -> Option +{ + use std::str::FromStr; + + for line in proc_status.lines () { + if let Some (rest) = line.strip_prefix ("VmRSS:\t").and_then (|s| s.strip_suffix (" kB")) + { + return u64::from_str (rest.trim_start ()).ok (); + } + } + + None +} + #[cfg (test)] mod tests { use std::{ @@ -425,4 +439,11 @@ mod tests { }); } + + #[test] + fn rss () { + let input = "VmHWM: 584 kB\nVmRSS: 584 kB\nRssAnon: 68 kB\n"; + + assert_eq! (get_rss_from_status (input), Some (584)); + } } From fff278a4945f0d1d4e4b406959c65e692a6ce370 Mon Sep 17 00:00:00 2001 From: "(on company time)" <_@_> Date: Fri, 29 Jul 2022 17:02:25 -0500 Subject: [PATCH 06/13] report VmRSS in metrics --- crates/ptth_relay/src/scraper_api.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/crates/ptth_relay/src/scraper_api.rs b/crates/ptth_relay/src/scraper_api.rs index 3bf6512..299ecde 100644 --- a/crates/ptth_relay/src/scraper_api.rs +++ b/crates/ptth_relay/src/scraper_api.rs @@ -216,10 +216,23 @@ async fn metrics ( -> Result , RequestError> { let mut s = String::with_capacity (4 * 1_024); + s.push_str ("# HELP forty_two Forty-two\n"); s.push_str ("# TYPE forty_two counter\n"); s.push_str ("forty_two 42\n"); + #[cfg (target_os = "linux")] + { + if let Some (rss) = tokio::fs::read_to_string ("/proc/self/status").await + .ok () + .and_then (|s| get_rss_from_status (s.as_str ())) + { + s.push_str ("# HELP relay_vm_rss VmRSS of the relay process, in kB\n"); + s.push_str ("# TYPE relay_vm_rss gauge\n"); + s.push_str (format! ("relay_vm_rss {}\n", rss).as_str ()); + } + } + Ok (Response::builder () .body (Body::from (s))?) } From 77f842485f0950db035e4b3bb8677d448d0b182b Mon Sep 17 00:00:00 2001 From: "(on company time)" <_@_> Date: Fri, 29 Jul 2022 17:13:53 -0500 Subject: [PATCH 07/13] :heavy_plus_sign: support Bearer auth --- crates/ptth_relay/src/scraper_api.rs | 43 +++++++++++++++++++--------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/crates/ptth_relay/src/scraper_api.rs b/crates/ptth_relay/src/scraper_api.rs index 299ecde..e06234d 100644 --- a/crates/ptth_relay/src/scraper_api.rs +++ b/crates/ptth_relay/src/scraper_api.rs @@ -119,6 +119,21 @@ pub async fn v1_server_list (state: &Relay) } } +fn get_api_key (headers: &hyper::HeaderMap) -> Option <&str> +{ + if let Some (key) = headers.get ("X-ApiKey").and_then (|v| v.to_str ().ok ()) { + return Some (key); + } + + if let Some (s) = headers.get ("Authorization").and_then (|v| v.to_str ().ok ()) { + if let Some (key) = s.strip_prefix ("Bearer ") { + return Some (key); + } + } + + None +} + #[instrument (level = "trace", skip (req, state))] async fn api_v1 ( req: Request , @@ -132,7 +147,7 @@ async fn api_v1 ( AuditEvent, }; - let api_key = req.headers ().get ("X-ApiKey"); + let api_key = get_api_key (req.headers ()); let api_key = match api_key { None => return Ok (error_reply (StatusCode::FORBIDDEN, strings::NO_API_KEY)?), @@ -351,7 +366,7 @@ mod tests { .expected_body (format! ("{}\n", body)) } - async fn test (&self) { + async fn test (&self, name: &str) { let mut input = Request::builder () .method ("GET") .uri (format! ("http://127.0.0.1:4000/scraper/{}", self.path_rest)); @@ -387,15 +402,15 @@ mod tests { expected_headers.insert (*key, (*value).try_into ().expect ("Couldn't convert header value")); } - assert_eq! (actual_head.status, self.expected_status); - assert_eq! (actual_head.headers, expected_headers); + assert_eq! (actual_head.status, self.expected_status, "{}", name); + assert_eq! (actual_head.headers, expected_headers, "{}", name); let actual_body = hyper::body::to_bytes (actual_body).await; let actual_body = actual_body.expect ("Body should be convertible to bytes"); let actual_body = actual_body.to_vec (); let actual_body = String::from_utf8 (actual_body).expect ("Body should be UTF-8"); - assert_eq! (actual_body, self.expected_body); + assert_eq! (actual_body, self.expected_body, "{}", name); } } @@ -417,38 +432,38 @@ mod tests { }; base_case - .test ().await; + .test ("00").await; base_case .path_rest ("v9999/test") .expected (StatusCode::NOT_FOUND, strings::UNKNOWN_API_VERSION) - .test ().await; + .test ("01").await; base_case .valid_key (None) .expected (StatusCode::FORBIDDEN, strings::FORBIDDEN) - .test ().await; + .test ("02").await; base_case .x_api_key (Some ("borgus")) .expected (StatusCode::FORBIDDEN, strings::FORBIDDEN) - .test ().await; + .test ("03").await; base_case .path_rest ("v1/toast") .expected (StatusCode::NOT_FOUND, strings::UNKNOWN_API_ENDPOINT) - .test ().await; + .test ("04").await; base_case .x_api_key (None) .expected (StatusCode::FORBIDDEN, strings::NO_API_KEY) - .test ().await; + .test ("05").await; base_case .x_api_key (None) - .auth_header (Some ("Bearer: bogus")) - .expected (StatusCode::FORBIDDEN, strings::NO_API_KEY) - .test ().await; + .auth_header (Some ("Bearer bogus")) + .expected (StatusCode::OK, "You're valid!") + .test ("06").await; }); } From c30747d9540a8c2fa30adbf069104b801bc57375 Mon Sep 17 00:00:00 2001 From: "(on company time)" <_@_> Date: Mon, 1 Aug 2022 12:22:30 -0500 Subject: [PATCH 08/13] :heavy_plus_sign: add more metrics --- crates/ptth_relay/src/scraper_api.rs | 42 ++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/crates/ptth_relay/src/scraper_api.rs b/crates/ptth_relay/src/scraper_api.rs index e06234d..b41ac80 100644 --- a/crates/ptth_relay/src/scraper_api.rs +++ b/crates/ptth_relay/src/scraper_api.rs @@ -232,9 +232,41 @@ async fn metrics ( { let mut s = String::with_capacity (4 * 1_024); - s.push_str ("# HELP forty_two Forty-two\n"); - s.push_str ("# TYPE forty_two counter\n"); - s.push_str ("forty_two 42\n"); + let mut push_metric = |name, help, kind, value| { + if let Some (help) = help { + s.push_str (format! ("# HELP {} {}\n", name, help).as_str ()); + } + s.push_str (format! ("# TYPE {} {}\n", name, kind).as_str ()); + s.push_str (format! ("{} {}\n", name, value).as_str ()); + }; + + let request_rendezvous_count = { + let g = state.request_rendezvous.lock ().await; + g.len () + }; + + let server_status_count; + let connected_server_count; + + let now = Utc::now (); + + { + let g = state.server_status.lock ().await; + server_status_count = g.len (); + connected_server_count = g.iter () + .filter (|(_, s)| now - s.last_seen < chrono::Duration::seconds (60)) + .count (); + } + + let response_rendezvous_count = { + let g = state.response_rendezvous.read ().await; + g.len () + }; + + push_metric ("request_rendezvous_count", None, "gauge", request_rendezvous_count.to_string ()); + push_metric ("server_status_count", None, "gauge", server_status_count.to_string ()); + push_metric ("connected_server_count", None, "gauge", connected_server_count.to_string ()); + push_metric ("response_rendezvous_count", None, "gauge", response_rendezvous_count.to_string ()); #[cfg (target_os = "linux")] { @@ -242,9 +274,7 @@ async fn metrics ( .ok () .and_then (|s| get_rss_from_status (s.as_str ())) { - s.push_str ("# HELP relay_vm_rss VmRSS of the relay process, in kB\n"); - s.push_str ("# TYPE relay_vm_rss gauge\n"); - s.push_str (format! ("relay_vm_rss {}\n", rss).as_str ()); + push_metric ("relay_vm_rss", Some ("VmRSS of the relay process, in kB"), "gauge", rss.to_string ()); } } From ce7ce4216870f5906cf99573d5fb0d957e9104ac Mon Sep 17 00:00:00 2001 From: "(on company time)" <_@_> Date: Mon, 1 Aug 2022 13:15:53 -0500 Subject: [PATCH 09/13] time out requests if the server doesn't rendezvous in 2 minutes --- crates/ptth_relay/src/lib.rs | 20 +++++++++++++++++++- crates/ptth_relay/src/relay_state.rs | 5 ++++- crates/ptth_relay/src/server_endpoint.rs | 2 +- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/crates/ptth_relay/src/lib.rs b/crates/ptth_relay/src/lib.rs index 2f29ca8..d351ce7 100644 --- a/crates/ptth_relay/src/lib.rs +++ b/crates/ptth_relay/src/lib.rs @@ -135,6 +135,11 @@ async fn handle_http_request ( let (tx, rx) = oneshot::channel (); + let tx = relay_state::ResponseRendezvous { + timeout: Instant::now () + Duration::from_secs (120), + tx, + }; + let req_id = rusty_ulid::generate_ulid_string (); debug! ("Forwarding {}", req_id); @@ -791,6 +796,19 @@ pub async fn run_relay ( }); } + let state_2 = Arc::clone (&state); + tokio::spawn (async move { + let mut interval = tokio::time::interval (Duration::from_secs (60)); + interval.set_missed_tick_behavior (tokio::time::MissedTickBehavior::Skip); + + loop { + interval.tick ().await; + let now = Instant::now (); + let response_rendezvous = state_2.response_rendezvous.read ().await; + response_rendezvous.retain (|_, v| v.timeout >= now); + } + }); + let make_svc = make_service_fn (|_conn| { let state = state.clone (); let handlebars = handlebars.clone (); @@ -849,7 +867,7 @@ pub async fn run_relay ( std::mem::swap (&mut swapped, &mut response_rendezvous); for (_, sender) in swapped { - sender.send (Err (ShuttingDown)).ok (); + sender.tx.send (Err (ShuttingDown)).ok (); } let mut request_rendezvous = state.request_rendezvous.lock ().await; diff --git a/crates/ptth_relay/src/relay_state.rs b/crates/ptth_relay/src/relay_state.rs index 9f66ffa..4ad3bcb 100644 --- a/crates/ptth_relay/src/relay_state.rs +++ b/crates/ptth_relay/src/relay_state.rs @@ -61,7 +61,10 @@ pub enum RequestRendezvous { ParkedServer (oneshot::Sender >), } -type ResponseRendezvous = oneshot::Sender >; +pub (crate) struct ResponseRendezvous { + pub timeout: Instant, + pub tx: oneshot::Sender >, +} #[derive (Clone)] pub struct ServerStatus { diff --git a/crates/ptth_relay/src/server_endpoint.rs b/crates/ptth_relay/src/server_endpoint.rs index 84333dd..71e8b6a 100644 --- a/crates/ptth_relay/src/server_endpoint.rs +++ b/crates/ptth_relay/src/server_endpoint.rs @@ -188,7 +188,7 @@ pub async fn handle_response ( }; // UKAUFFY4 (Send half) - if tx.send (Ok ((resp_parts, body))).is_err () { + if tx.tx.send (Ok ((resp_parts, body))).is_err () { let msg = "Failed to connect to client"; error! (msg); return Ok (error_reply (StatusCode::BAD_GATEWAY, msg)?); From 1f398462b788af8d0fae011416b9f1d6f735cef0 Mon Sep 17 00:00:00 2001 From: "(on company time)" <_@_> Date: Tue, 2 Aug 2022 10:19:52 -0500 Subject: [PATCH 10/13] :bug: bug: sweep request_rendezvous for timed-out requests, too --- crates/ptth_relay/src/lib.rs | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/crates/ptth_relay/src/lib.rs b/crates/ptth_relay/src/lib.rs index d351ce7..80512c1 100644 --- a/crates/ptth_relay/src/lib.rs +++ b/crates/ptth_relay/src/lib.rs @@ -796,16 +796,42 @@ pub async fn run_relay ( }); } + // Set a task to periodically sweep and time-out requests where the client + // and server are never going to rendezvous + let state_2 = Arc::clone (&state); tokio::spawn (async move { let mut interval = tokio::time::interval (Duration::from_secs (60)); interval.set_missed_tick_behavior (tokio::time::MissedTickBehavior::Skip); loop { + use std::convert::TryFrom; + + use rusty_ulid::Ulid; + interval.tick ().await; - let now = Instant::now (); - let response_rendezvous = state_2.response_rendezvous.read ().await; - response_rendezvous.retain (|_, v| v.timeout >= now); + + { + let timeout_ms = Utc::now ().timestamp () - 120_000; + if let Ok (timeout_ms) = u64::try_from (timeout_ms) { + let timeout_ulid = Ulid::from_timestamp_with_rng (timeout_ms, &mut rand::thread_rng ()).to_string (); + + let mut request_rendezvous = state_2.request_rendezvous.lock ().await; + request_rendezvous.iter_mut () + .for_each (|(k, v)| { + match v { + RequestRendezvous::ParkedServer (_) => (), + RequestRendezvous::ParkedClients (requests) => requests.retain (|req| req.id.as_str () >= timeout_ulid.as_str ()), + } + }); + } + } + + { + let now = Instant::now (); + let response_rendezvous = state_2.response_rendezvous.read ().await; + response_rendezvous.retain (|_, v| v.timeout >= now); + } } }); From 863bbe18e41484369ca2fd24cc06e01c44863757 Mon Sep 17 00:00:00 2001 From: "(on company time)" <_@_> Date: Wed, 14 Sep 2022 14:54:42 -0500 Subject: [PATCH 11/13] :arrow_up: update hyper dep and allow HTTP/2 for the relay This makes it easier for a gateway like Nginx to terminate TLS for a PTTH relay without needing an entire TCP connection for each connected PTTH server. --- Cargo.lock | 10 +++++----- crates/ptth_relay/Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index af842dc..c95212f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -636,9 +636,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.5.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -648,9 +648,9 @@ checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" [[package]] name = "hyper" -version = "0.14.13" +version = "0.14.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15d1cfb9e4f68655fa04c01f59edb405b6074a0f7118ea881e5026e4a1cd8593" +checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" dependencies = [ "bytes", "futures-channel", @@ -661,7 +661,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa 0.4.8", + "itoa 1.0.1", "pin-project-lite", "socket2 0.4.4", "tokio", diff --git a/crates/ptth_relay/Cargo.toml b/crates/ptth_relay/Cargo.toml index a44c080..28dae70 100644 --- a/crates/ptth_relay/Cargo.toml +++ b/crates/ptth_relay/Cargo.toml @@ -20,7 +20,7 @@ futures = "0.3.7" futures-util = "0.3.8" handlebars = "3.5.3" http = "0.2.3" -hyper = { version = "0.14.4", features = ["http1", "server", "stream", "tcp"] } +hyper = { version = "0.14.20", features = ["http1", "http2", "server", "stream", "tcp"] } itertools = "0.9.0" rand = "0.8.3" rmp-serde = "0.15.5" From 5b6adc13055b5e8140613f3635347b4298daeb8b Mon Sep 17 00:00:00 2001 From: "(on company time)" <_@_> Date: Fri, 21 Oct 2022 15:21:35 -0500 Subject: [PATCH 12/13] :bug: bug: fix colons in filenames not linking properly https://stackoverflow.com/questions/1737575/are-colons-allowed-in-urls --- handlebars/server/file_server_dir.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handlebars/server/file_server_dir.html b/handlebars/server/file_server_dir.html index 857daca..3b837ab 100644 --- a/handlebars/server/file_server_dir.html +++ b/handlebars/server/file_server_dir.html @@ -115,7 +115,7 @@ AIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAA" rel="icon" type="image/x-icon" /> {{#each entries}} - + {{this.icon}} {{this.file_name}}{{this.trailing_slash}} {{this.size}} From 89d4fdbcc3ce3a99083cb049301bd715d83bedd7 Mon Sep 17 00:00:00 2001 From: Trisha Lefler Date: Tue, 25 Oct 2022 10:28:45 -0500 Subject: [PATCH 13/13] :loud_sound: add error message for config file --- crates/ptth_server_gui/src/main.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/crates/ptth_server_gui/src/main.rs b/crates/ptth_server_gui/src/main.rs index c5de016..90748ac 100644 --- a/crates/ptth_server_gui/src/main.rs +++ b/crates/ptth_server_gui/src/main.rs @@ -47,7 +47,13 @@ fn main () let app = app::App::default(); let mut wind = Window::new (100, 100, 500, 180, "PTTH server"); - let config_file_opt = ptth_server::load_toml::load:: ("./config/ptth_server.toml").ok (); + let config_file_opt = match ptth_server::load_toml::load:: ("./config/ptth_server.toml") { + Ok (x) => Some (x), + Err (e) => { + eprintln! ("Error in `./config/ptth_server.toml`: {:?}", e); + None + }, + }; let (hit_tx, mut hit_rx) = mpsc::channel (1); {