From 28cca601b57a1b28e6e0c80d75e84a00f27a5f0a Mon Sep 17 00:00:00 2001 From: 21pages Date: Tue, 31 Mar 2026 11:05:54 +0800 Subject: [PATCH] oidc: route auth requests through shared HTTP/tcp-proxy path while keeping TLS warmup Signed-off-by: 21pages --- src/hbbs_http/account.rs | 79 ++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/src/hbbs_http/account.rs b/src/hbbs_http/account.rs index 8e6141200..827480bb2 100644 --- a/src/hbbs_http/account.rs +++ b/src/hbbs_http/account.rs @@ -1,9 +1,10 @@ use super::HbbHttpResponse; use crate::hbbs_http::create_http_client_with_url; use hbb_common::{config::LocalConfig, log, ResultType}; -use reqwest::blocking::Client; +use serde::de::DeserializeOwned; use serde_derive::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; +use serde_json::{Map, Value}; use std::{ collections::HashMap, sync::{Arc, RwLock}, @@ -109,7 +110,7 @@ pub struct AuthBody { } pub struct OidcSession { - client: Option, + warmed_api_server: Option, state_msg: &'static str, failed_msg: String, code_url: Option, @@ -136,7 +137,7 @@ impl Default for UserStatus { impl OidcSession { fn new() -> Self { Self { - client: None, + warmed_api_server: None, state_msg: REQUESTING_ACCOUNT_AUTH, failed_msg: "".to_owned(), code_url: None, @@ -149,11 +150,28 @@ impl OidcSession { fn ensure_client(api_server: &str) { let mut write_guard = OIDC_SESSION.write().unwrap(); - if write_guard.client.is_none() { - // This URL is used to detect the appropriate TLS implementation for the server. - let login_option_url = format!("{}/api/login-options", &api_server); - let client = create_http_client_with_url(&login_option_url); - write_guard.client = Some(client); + if write_guard.warmed_api_server.as_deref() == Some(api_server) { + return; + } + // This URL is used to detect the appropriate TLS implementation for the server. + let login_option_url = format!("{}/api/login-options", api_server); + let _ = create_http_client_with_url(&login_option_url); + write_guard.warmed_api_server = Some(api_server.to_owned()); + } + + fn parse_hbb_http_response(body: &str) -> ResultType> { + let map = serde_json::from_str::>(body)?; + if let Some(error) = map.get("error") { + if let Some(err) = error.as_str() { + Ok(HbbHttpResponse::Error(err.to_owned())) + } else { + Ok(HbbHttpResponse::ErrorFormat) + } + } else { + match serde_json::from_value(Value::Object(map)) { + Ok(v) => Ok(HbbHttpResponse::Data(v)), + Err(_) => Ok(HbbHttpResponse::DataTypeFormat), + } } } @@ -164,26 +182,15 @@ impl OidcSession { uuid: &str, ) -> ResultType> { Self::ensure_client(api_server); - let resp = if let Some(client) = &OIDC_SESSION.read().unwrap().client { - client - .post(format!("{}/api/oidc/auth", api_server)) - .json(&serde_json::json!({ - "op": op, - "id": id, - "uuid": uuid, - "deviceInfo": crate::ui_interface::get_login_device_info(), - })) - .send()? - } else { - hbb_common::bail!("http client not initialized"); - }; - let status = resp.status(); - match resp.try_into() { - Ok(v) => Ok(v), - Err(err) => { - hbb_common::bail!("Http status: {}, err: {}", status, err); - } - } + let body = serde_json::json!({ + "op": op, + "id": id, + "uuid": uuid, + "deviceInfo": crate::ui_interface::get_login_device_info(), + }) + .to_string(); + let resp = crate::post_request_sync(format!("{}/api/oidc/auth", api_server), body, "")?; + Self::parse_hbb_http_response(&resp) } fn query( @@ -197,11 +204,19 @@ impl OidcSession { &[("code", code), ("id", id), ("uuid", uuid)], )?; Self::ensure_client(api_server); - if let Some(client) = &OIDC_SESSION.read().unwrap().client { - Ok(client.get(url).send()?.try_into()?) - } else { - hbb_common::bail!("http client not initialized") + #[derive(Deserialize)] + struct HttpResponseBody { + body: String, } + + let resp = crate::http_request_sync( + url.to_string(), + "GET".to_owned(), + None, + "{}".to_owned(), + )?; + let resp = serde_json::from_str::(&resp)?; + Self::parse_hbb_http_response(&resp.body) } fn reset(&mut self) {