mirror of
https://github.com/localsend/localsend.git
synced 2026-06-23 04:10:07 +00:00
feat: simplify server
This commit is contained in:
+32
-28
@@ -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
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user