diff --git a/crates/ptth_relay/src/lib.rs b/crates/ptth_relay/src/lib.rs index 2e5b49a..088daa4 100644 --- a/crates/ptth_relay/src/lib.rs +++ b/crates/ptth_relay/src/lib.rs @@ -60,8 +60,9 @@ pub mod config; pub mod errors; pub mod git_version; pub mod key_validity; -mod relay_state; +mod relay_state; +mod routing; mod scraper_api; mod server_endpoint; @@ -469,7 +470,7 @@ async fn handle_endless_source (gib: usize, throttle: Option ) .body (Body::wrap_stream (ReceiverStream::new (rx))) } -async fn handle_gen_scraper_key () +async fn handle_gen_scraper_key (state: Arc ) -> Result , http::Error> { let key = ptth_core::gen_key (); @@ -559,7 +560,7 @@ async fn handle_all ( Ok (error_reply (StatusCode::METHOD_NOT_ALLOWED, "Don't GET this URL, POST to it.")?) } else if rest == "gen_key" { - Ok (handle_gen_scraper_key ().await?) + Ok (handle_gen_scraper_key (state).await?) } else { Ok (error_reply (StatusCode::NOT_FOUND, "Can't route URL")?) diff --git a/crates/ptth_relay/src/routing.rs b/crates/ptth_relay/src/routing.rs new file mode 100644 index 0000000..9b81f2a --- /dev/null +++ b/crates/ptth_relay/src/routing.rs @@ -0,0 +1,138 @@ +use hyper::Method; + +#[derive (Debug, PartialEq)] +pub enum Route <'a> { + ClientAuditLog, + ClientRelayIsUp, + ClientServerGet { + listen_code: &'a str, + path: &'a str, + }, + ClientServerList, + ClientUnregisteredServers, + Debug, + DebugEndlessSink, + DebugEndlessSource (Option ), + DebugGenKey, + DebugMysteriousError, + ErrorBadUriFormat, + ErrorCantPost, + ErrorMethodNotAllowed, + ErrorRoutingFailed, + Root, + Scraper { + rest: &'a str, + }, + ServerHttpListen { + listen_code: &'a str + }, + ServerHttpResponse { + request_code: &'a str, + }, +} + +pub fn route_url (method: Method, path: &str) -> Route { + if method == Method::POST { + return if let Some (request_code) = path.strip_prefix ("/7ZSFUKGV/http_response/") { + Route::ServerHttpResponse { + request_code + } + } + else if path == "/frontend/debug/endless_sink" { + Route::DebugEndlessSink + } + else { + Route::ErrorCantPost + } + } + + if let Some (listen_code) = path.strip_prefix ("/7ZSFUKGV/http_listen/") { + Route::ServerHttpListen { + listen_code + } + } + else if let Some (rest) = path.strip_prefix ("/frontend/servers/") { + // DRY T4H76LB3 + + if rest.is_empty () { + Route::ClientServerList + } + else if let Some (idx) = rest.find ('/') { + let listen_code = &rest [0..idx]; + let path = &rest [idx..]; + + Route::ClientServerGet { + listen_code, + path, + } + } + else { + Route::ErrorBadUriFormat + } + } + else if path == "/frontend/unregistered_servers" { + Route::ClientUnregisteredServers + } + else if path == "/frontend/audit_log" { + Route::ClientAuditLog + } + else if let Some (rest) = path.strip_prefix ("/frontend/debug/") { + if rest.is_empty () { + Route::Debug + } + else if rest == "endless_source" { + Route::DebugEndlessSource (None) + } + else if rest == "endless_source_throttled" { + Route::DebugEndlessSource (Some (1024 / 64)) + } + else if rest == "endless_sink" { + Route::ErrorMethodNotAllowed + } + else if rest == "gen_key" { + Route::DebugGenKey + } + else { + Route::ErrorRoutingFailed + } + } + else if path == "/" { + Route::Root + } + else if path == "/frontend/relay_up_check" { + Route::ClientRelayIsUp + } + else if path == "/frontend/test_mysterious_error" { + Route::DebugMysteriousError + } + else if let Some (rest) = path.strip_prefix ("/scraper/") { + Route::Scraper { + rest + } + } + else { + Route::ErrorRoutingFailed + } +} + +#[cfg (test)] +mod tests { + use super::*; + + #[test] + fn routing () { + for (input, expected) in vec! [ + ("/", Route::Root), + ].into_iter () { + let actual = route_url (Method::GET, input); + assert_eq! (actual, expected); + } + + for (input, expected) in vec! [ + ("/", Route::ErrorCantPost), + ].into_iter () { + let actual = route_url (Method::POST, input); + assert_eq! (actual, expected); + } + } +}