refactor(bare): enhance security and performance optimizations

- Remove unnecessary sorting in advertise_refs for deterministic output
- Add path traversal detection and validation in bare_dir construction
- Implement symlink resolution checks to prevent security vulnerabilities
- Refactor cache system with CRC validation and improved metrics
- Integrate repo-specific cache invalidation using indexed keys
- Add comprehensive unit tests for commit operations and diff functionality
- Move configuration constants to centralized config module
- Optimize string operations in disk cache random value generation
- Enhance license detection algorithm with cleaner matching logic
- Streamline argument processing in various git operations
- Update dependencies including crc32fast and flate2 for performance
- Add signal handling capability to tokio runtime configuration
This commit is contained in:
zhenyi
2026-06-12 15:04:12 +08:00
parent e386f44ee2
commit 10a4398e81
41 changed files with 1373 additions and 365 deletions
+38 -11
View File
@@ -5,7 +5,7 @@ use std::time::Duration;
use gitks::disk_cache::DiskCache;
use gitks::hooks::HookManager;
use gitks::metrics;
use gitks::server::{GitksService, serve};
use gitks::server::{GitksService, serve_with_shutdown};
use etcd_client::{Client, PutOptions};
use tokio::sync::Mutex;
@@ -141,7 +141,6 @@ fn init_tracing() -> Option<tracing_appender::non_blocking::WorkerGuard> {
.boxed(),
};
// Optional file output with rotation
if let Ok(log_dir) = std::env::var("GITKS_LOG_DIR") {
let rotation = match env_or("GITKS_LOG_ROTATION", "daily").as_str() {
"hourly" => tracing_appender::rolling::Rotation::HOURLY,
@@ -212,7 +211,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let port = env_or("GITKS_PORT", DEFAULT_PORT);
let storage_name = env_or("STORAGE_NAME", DEFAULT_STORAGE_NAME);
// --- etcd config overlay: connect etcd, override key settings ---
let etcd_endpoints: Vec<String> = std::env::var("GITKS_ETCD_ENDPOINTS")
.ok()
.filter(|s| !s.is_empty())
@@ -239,7 +237,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let grpc_addr =
std::env::var("GITKS_ADVERTISE_ADDR").unwrap_or_else(|_| format!("http://{host}:{port}"));
// Register this service so other services (appks) can discover us
if let Some(ref e) = etcd {
let addr_str = format!("{host}:{port}");
e.register("gitks", &addr_str).await.ok();
@@ -256,7 +253,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
std::fs::create_dir_all(&repo_prefix)?;
}
// Disk cache configuration
let disk_cache_enabled = env_bool("GITKS_DISK_CACHE_ENABLED", false);
let disk_cache_max_age = env_u64("GITKS_DISK_CACHE_MAX_AGE", 300);
@@ -275,7 +271,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing::info!("disk cache disabled");
}
// Pack cache configuration
let pack_cache_enabled = env_bool("GITKS_PACK_CACHE_ENABLED", false);
let pack_backpressure = env_bool("GITKS_PACK_CACHE_BACKPRESSURE", true);
@@ -293,7 +288,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
None
};
// Hook manager configuration
let hooks_enabled = env_bool("GITKS_HOOKS_ENABLED", true);
let server_hooks_dir = std::env::var("GITKS_SERVER_HOOKS_DIR")
.ok()
@@ -326,7 +320,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let _metrics_handle = metrics::start_metrics_server(metrics_port);
tracing::info!(port = metrics_port, "metrics server started");
// Slow request threshold
let _semaphore_cleanup = gitks::rate_limit::start_semaphore_cleanup_task();
let slow_request_threshold = env_u64("GITKS_SLOW_REQUEST_THRESHOLD_MS", 5000);
metrics::set_slow_request_threshold(slow_request_threshold);
tracing::info!(
@@ -357,11 +352,43 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
"starting gitks gRPC server"
);
serve(addr, svc).await?;
metrics::set_ready(true);
serve_with_shutdown(addr, svc, shutdown_signal()).await?;
metrics::set_ready(false);
// Gracefully shut down the HTTP metrics server
http_cancel.cancel();
tracing::info!("gitks shut down");
tracing::info!("gitks shut down complete");
Ok(())
}
/// Resolves when the process receives SIGTERM or SIGINT (Ctrl+C).
async fn shutdown_signal() {
let ctrl_c = async {
tokio::signal::ctrl_c()
.await
.expect("failed to install Ctrl+C handler");
};
#[cfg(unix)]
let terminate = async {
tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
.expect("failed to install SIGTERM handler")
.recv()
.await;
};
#[cfg(not(unix))]
let terminate = std::future::pending::<()>();
tokio::select! {
_ = ctrl_c => {
tracing::info!("received Ctrl+C, starting graceful shutdown");
}
_ = terminate => {
tracing::info!("received SIGTERM, starting graceful shutdown");
}
}
}