diff --git a/crates/librqbit/src/api_error.rs b/crates/librqbit/src/api_error.rs index 8c08529..0c2f8f4 100644 --- a/crates/librqbit/src/api_error.rs +++ b/crates/librqbit/src/api_error.rs @@ -56,7 +56,11 @@ impl ApiError { } pub const fn unathorized() -> Self { - Self::new_from_text(StatusCode::UNAUTHORIZED, "unauthorized") + Self { + status: Some(StatusCode::UNAUTHORIZED), + kind: ApiErrorKind::Unauthorized, + plaintext: true, + } } pub fn status(&self) -> StatusCode { @@ -84,6 +88,7 @@ impl ApiError { enum ApiErrorKind { TorrentNotFound(TorrentIdOrHash), DhtDisabled, + Unauthorized, Text(&'static str), Other(anyhow::Error), } @@ -106,6 +111,7 @@ impl Serialize for ApiError { error_kind: match self.kind { ApiErrorKind::TorrentNotFound(_) => "torrent_not_found", ApiErrorKind::DhtDisabled => "dht_disabled", + ApiErrorKind::Unauthorized => "unathorized", ApiErrorKind::Other(_) => "internal_error", ApiErrorKind::Text(_) => "internal_error", }, @@ -146,6 +152,7 @@ impl std::fmt::Display for ApiError { match &self.kind { ApiErrorKind::TorrentNotFound(idx) => write!(f, "torrent {idx} not found"), ApiErrorKind::Other(err) => write!(f, "{err:?}"), + ApiErrorKind::Unauthorized => write!(f, "unathorized"), ApiErrorKind::DhtDisabled => write!(f, "DHT is disabled"), ApiErrorKind::Text(t) => write!(f, "{t}"), } diff --git a/crates/librqbit/src/http_api.rs b/crates/librqbit/src/http_api.rs index acd008c..bd229be 100644 --- a/crates/librqbit/src/http_api.rs +++ b/crates/librqbit/src/http_api.rs @@ -67,7 +67,13 @@ async fn simple_basic_auth( .and_then(|v| String::from_utf8(v).ok()); let user_pass = match user_pass { Some(user_pass) => user_pass, - None => return Err(ApiError::unathorized()), + None => { + return Ok(( + StatusCode::UNAUTHORIZED, + [("WWW-Authenticate", "Basic realm=\"API\"")], + ) + .into_response()) + } }; // TODO: constant time compare match user_pass.split_once(':') {