feat: simplify server

This commit is contained in:
Tien Do Nam
2025-07-15 17:31:09 +02:00
parent e605e78ebd
commit 5a7a15a553
3 changed files with 53 additions and 40 deletions
+32 -28
View File
@@ -9,7 +9,7 @@ use crate::{crypto, util};
use bytes::Bytes;
use http_body_util::{BodyExt, Full};
use hyper::body::{Body, Incoming};
use hyper::{Method, Request, Response, StatusCode};
use hyper::{http, Method, Request, Response, StatusCode};
use hyper_util::rt::{TokioExecutor, TokioIo};
use hyper_util::server::conn::auto::Builder;
use lru::LruCache;
@@ -237,37 +237,41 @@ impl ClientInfoExt for ClientInfo {
}
}
fn build_response<T: Serialize>(status: StatusCode, body: Option<T>) -> Response<Full<Bytes>> {
let mut response = Response::new(Full::default());
*response.status_mut() = status;
if let Some(body) = body {
*response.body_mut() = Full::from(Bytes::from(
serde_json::to_string(&body).unwrap_or_else(|_| "{}".to_string()),
));
}
response
}
async fn handle_request(req: Request<Incoming>) -> Result<Response<Full<Bytes>>, hyper::Error> {
Ok(handle_request_inner(req).await.unwrap_or_else(|err| {
tracing::error!("Error handling request: {err:?}");
build_response(
err.status,
err.message.map(|msg| ErrorResponse { message: msg }),
)
JsonResponse {
status: err.status,
body: ErrorResponse {
message: err
.message
.unwrap_or_else(|| "Internal Server Error".to_string()),
},
}
.into_response()
}))
}
trait IntoResponse {
fn into_response(self) -> Response<Full<Bytes>>;
struct JsonResponse<T: Serialize> {
status: StatusCode,
body: T,
}
impl<T: Serialize> IntoResponse for (StatusCode, T) {
impl<T: Serialize> JsonResponse<T> {
fn into_response(self) -> Response<Full<Bytes>> {
let (status, body) = self;
build_response(status, Some(body))
let mut response = Response::new(Full::default());
*response.status_mut() = self.status;
response.headers_mut().insert(
http::header::CONTENT_TYPE,
http::HeaderValue::from_static("application/json"),
);
*response.body_mut() = Full::from(Bytes::from(
serde_json::to_string(&self.body).unwrap_or_else(|_| "{}".to_string()),
));
response
}
}
@@ -300,7 +304,7 @@ async fn nonce_exchange(
body: Incoming,
state: AppState,
client_info: ClientInfo,
) -> Result<(StatusCode, NonceResponse), AppError> {
) -> Result<JsonResponse<NonceResponse>, AppError> {
let bytes = body.collect().await?.to_bytes();
let request = match serde_json::from_slice::<NonceRequest>(&bytes) {
Ok(json) => json,
@@ -342,10 +346,10 @@ async fn nonce_exchange(
tracing::info!("Nonce exchange successful for client: {}", client_info.ip);
Ok((
StatusCode::OK,
NonceResponse {
Ok(JsonResponse {
status: StatusCode::OK,
body: NonceResponse {
nonce: new_nonce_base64,
},
))
})
}
+19 -8
View File
@@ -28,7 +28,19 @@ async fn main() -> Result<()> {
.with_max_level(Level::DEBUG)
.init();
server_test().await?;
let a = tokio::spawn(async move {
let _ = server_test().await;
});
let b = tokio::spawn(async move {
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
let _ = client_test().await;
});
tokio::select! {
_ = a => {},
_ = b => {},
}
Ok(())
}
@@ -117,11 +129,10 @@ MCowBQYDK2VwAyEAZmdXP230oqK92o65ra3XaF2F8r3+fK5DEBK4c40qVts=
async fn server_test() -> Result<()> {
let server = http::server::LsHttpServer::start_with_port(
53317,
// Some(TlsConfig {
// cert: CERT.to_string(),
// private_key: PRIVATE_KEY.to_string(),
// }),
None,
Some(TlsConfig {
cert: CERT.to_string(),
private_key: PRIVATE_KEY.to_string(),
}),
)
.await?;
tokio::time::sleep(std::time::Duration::from_secs(u64::MAX)).await;
@@ -129,14 +140,14 @@ async fn server_test() -> Result<()> {
Ok(())
}
async fn http_test() -> Result<()> {
async fn client_test() -> Result<()> {
let client = LsHttpClient::try_new(PRIVATE_KEY, CERT)?;
let register_dto = RegisterDto {
alias: "test 2".to_string(),
version: "2.3".to_string(),
device_model: Some("test".to_string()),
device_type: Some(crate::model::discovery::DeviceType::Headless),
device_type: Some(DeviceType::Headless),
fingerprint: "test".to_string(),
port: 53317,
protocol: ProtocolType::Https,
+2 -4
View File
@@ -29,10 +29,8 @@ pub struct RegisterResponseDto {
pub download: bool,
}
// TODO: Change enums to SCREAMING_SNAKE_CASE for v3
#[derive(Clone, Debug, Deserialize, Eq, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum DeviceType {
Mobile,
Desktop,
@@ -42,7 +40,7 @@ pub enum DeviceType {
}
#[derive(Clone, Debug, Deserialize, Eq, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum ProtocolType {
Http,
Https,