From f0f5d87770592b4a6a0b86f950dacd556497ed31 Mon Sep 17 00:00:00 2001 From: xxnuo <54252779+xxnuo@users.noreply.github.com> Date: Sun, 12 Oct 2025 14:45:14 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E4=BC=98=E9=9B=85=E5=85=B3?= =?UTF-8?q?=E9=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.rs | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index e376cfc..bb8af9b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ use axum::{ use isolang::Language; use linguaspark::Translator; use std::{fs, io, net::SocketAddr, path::PathBuf, sync::Arc}; -use tokio::net::TcpListener; +use tokio::{net::TcpListener, signal}; use tower_http::{ cors::{Any, CorsLayer}, trace::TraceLayer, @@ -130,6 +130,34 @@ fn load_models_manually( Ok(models) } +async fn shutdown_signal() { + let ctrl_c = async { + signal::ctrl_c() + .await + .expect("failed to install Ctrl+C handler"); + }; + + #[cfg(unix)] + let terminate = async { + signal::unix::signal(signal::unix::SignalKind::terminate()) + .expect("failed to install signal handler") + .recv() + .await; + }; + + #[cfg(not(unix))] + let terminate = std::future::pending::<()>(); + + tokio::select! { + _ = ctrl_c => { + info!("Received Ctrl+C, shutting down gracefully..."); + }, + _ = terminate => { + info!("Received SIGTERM, shutting down gracefully..."); + }, + } +} + #[tokio::main] async fn main() -> anyhow::Result<()> { if std::env::var(ENV_LOG_LEVEL).is_err() { @@ -214,7 +242,11 @@ async fn main() -> anyhow::Result<()> { .await .context(format!("Failed to bind to address: {}", addr))?; - axum::serve(listener, app).await.context("Server error")?; + axum::serve(listener, app) + .with_graceful_shutdown(shutdown_signal()) + .await + .context("Server error")?; + info!("Server has been shut down gracefully"); Ok(()) } From 5d836e1cf86faddb80ae677873879db19c73d083 Mon Sep 17 00:00:00 2001 From: xxnuo <54252779+xxnuo@users.noreply.github.com> Date: Sun, 12 Oct 2025 14:45:54 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=E6=B5=8F=E8=A7=88=E5=99=A8=E8=B7=A8?= =?UTF-8?q?=E5=9F=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index bb8af9b..733812a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,9 @@ use linguaspark::Translator; use std::{fs, io, net::SocketAddr, path::PathBuf, sync::Arc}; use tokio::{net::TcpListener, signal}; use tower_http::{ - cors::{Any, CorsLayer}, + cors::{ + AllowCredentials, AllowHeaders, AllowMethods, AllowOrigin, AllowPrivateNetwork, CorsLayer, + }, trace::TraceLayer, }; use tracing::{debug, error, info}; @@ -206,9 +208,11 @@ async fn main() -> anyhow::Result<()> { let app_state = Arc::new(AppState { translator, models }); let cors = CorsLayer::new() - .allow_origin(Any) - .allow_methods(Any) - .allow_headers(Any); + .allow_origin(AllowOrigin::mirror_request()) + .allow_credentials(AllowCredentials::yes()) + .allow_methods(AllowMethods::mirror_request()) + .allow_headers(AllowHeaders::mirror_request()) + .allow_private_network(AllowPrivateNetwork::yes()); let app = Router::new() .route("/translate", post(endpoint::translate)) From b8548fee91fd733e99f6610bfb8736bce79276d5 Mon Sep 17 00:00:00 2001 From: xxnuo <54252779+xxnuo@users.noreply.github.com> Date: Sun, 12 Oct 2025 14:46:03 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=E5=90=8C=E8=AF=AD=E8=A8=80?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5=E8=BF=94=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/translation.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/translation.rs b/src/translation.rs index e4b6fc4..9dd0298 100644 --- a/src/translation.rs +++ b/src/translation.rs @@ -70,6 +70,11 @@ pub async fn perform_translation( let from_code = get_iso_code(&source_lang)?; let to_code = get_iso_code(&target_lang)?; + // If source and target languages are the same, return the original text + if from_code == to_code { + return Ok((text.to_string(), from_code.to_string(), to_code.to_string())); + } + if !state.translator.is_supported(from_code, to_code)? { return Err(AppError::TranslationError(format!( "Translation from '{}' to '{}' is not supported",