diff --git a/src/ping.rs b/src/ping.rs index 553411e..2a650ca 100644 --- a/src/ping.rs +++ b/src/ping.rs @@ -8,6 +8,7 @@ use rustls::sign::{RSASigningKey, SigningKey}; use rustls::Certificate; use serde::de::{MapAccess, Visitor}; use serde::{Deserialize, Serialize}; +use serde_repr::Deserialize_repr; use sodiumoxide::crypto::box_::PrecomputedKey; use url::Url; @@ -64,7 +65,14 @@ impl<'a> From<(&'a str, &CliArgs)> for Request<'a> { } #[derive(Deserialize, Debug)] -pub struct Response { +#[serde(untagged)] +pub enum Response { + Ok(OkResponse), + Error(ErrorResponse), +} + +#[derive(Deserialize, Debug)] +pub struct OkResponse { pub image_server: Url, pub latest_build: usize, pub url: Url, @@ -76,6 +84,20 @@ pub struct Response { pub tls: Option, } +#[derive(Deserialize, Debug)] +pub struct ErrorResponse { + pub error: String, + pub status: ErrorCode, +} + +#[derive(Deserialize_repr, Debug, Copy, Clone)] +#[repr(u16)] +pub enum ErrorCode { + MalformedJson = 400, + InvalidSecret = 401, + InvalidContentType = 415, +} + pub struct Tls { pub created_at: String, pub priv_key: Arc>, @@ -150,7 +172,7 @@ pub async fn update_server_state(secret: &str, cli: &CliArgs, data: &mut Arc match resp.json::().await { - Ok(resp) => { + Ok(Response::Ok(resp)) => { debug!("got write guard for server state"); let mut write_guard = data.0.write(); @@ -219,6 +241,12 @@ pub async fn update_server_state(secret: &str, cli: &CliArgs, data: &mut Arc { + error!( + "Got an {} error from upstream: {}", + resp.status as u16, resp.error + ); + } Err(e) => warn!("Got malformed response: {}", e), }, Err(e) => match e { diff --git a/src/state.rs b/src/state.rs index 66ebc35..f113d3a 100644 --- a/src/state.rs +++ b/src/state.rs @@ -39,6 +39,8 @@ pub enum ServerInitError { KeyParseError(String), #[error("Token key was not provided in initial request")] MissingTokenKey, + #[error("Got error response from control center")] + ErrorResponse, } impl ServerState { @@ -56,7 +58,7 @@ impl ServerState { match resp { Ok(resp) => match resp.json::().await { - Ok(mut resp) => { + Ok(Response::Ok(mut resp)) => { let key = resp .token_key .ok_or(ServerInitError::MissingTokenKey) @@ -118,6 +120,13 @@ impl ServerState { url_overridden: config.override_upstream.is_some(), }) } + Ok(Response::Error(resp)) => { + error!( + "Got an {} error from upstream: {}", + resp.status as u16, resp.error + ); + Err(ServerInitError::ErrorResponse) + } Err(e) => { error!("Got malformed response: {}. Is MangaDex@Home down?", e); Err(ServerInitError::MalformedResponse(e))