mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-01-28 08:31:52 +08:00
- 升级核心依赖 (axum 0.8, tower-http 0.6, alsa 0.11 等) - 简化交叉编译配置,切换至 Debian 11 提高兼容性 - 新增 Debian 包打包支持 (debuerreotype 模板) - 移除独立的 mjpeg 解码器,简化视频模块 - 静态链接 libx264/libx265/libopus 到二进制
191 lines
9.5 KiB
Rust
191 lines
9.5 KiB
Rust
use axum::{
|
|
extract::DefaultBodyLimit,
|
|
middleware,
|
|
routing::{any, delete, get, patch, post, put},
|
|
Router,
|
|
};
|
|
use std::sync::Arc;
|
|
use tower_http::{
|
|
cors::{Any, CorsLayer},
|
|
trace::TraceLayer,
|
|
};
|
|
|
|
use super::audio_ws::audio_ws_handler;
|
|
use super::handlers;
|
|
use super::ws::ws_handler;
|
|
use crate::auth::{auth_middleware, require_admin};
|
|
use crate::hid::websocket::ws_hid_handler;
|
|
use crate::state::AppState;
|
|
|
|
/// Create the main application router
|
|
pub fn create_router(state: Arc<AppState>) -> Router {
|
|
let cors = CorsLayer::new()
|
|
.allow_origin(Any)
|
|
.allow_methods(Any)
|
|
.allow_headers(Any);
|
|
|
|
// Public routes (no auth required)
|
|
// Note: /info moved to user_routes for security (contains hostname, IPs, etc.)
|
|
let public_routes = Router::new()
|
|
.route("/health", get(handlers::health_check))
|
|
.route("/auth/login", post(handlers::login))
|
|
.route("/setup", get(handlers::setup_status))
|
|
.route("/setup/init", post(handlers::setup_init));
|
|
|
|
// User routes (authenticated users - both regular and admin)
|
|
let user_routes = Router::new()
|
|
.route("/info", get(handlers::system_info))
|
|
.route("/auth/logout", post(handlers::logout))
|
|
.route("/auth/check", get(handlers::auth_check))
|
|
.route("/devices", get(handlers::list_devices))
|
|
// WebSocket endpoint for real-time events
|
|
.route("/ws", any(ws_handler))
|
|
// Stream control endpoints
|
|
.route("/stream/status", get(handlers::stream_state))
|
|
.route("/stream/start", post(handlers::stream_start))
|
|
.route("/stream/stop", post(handlers::stream_stop))
|
|
.route("/stream/mode", get(handlers::stream_mode_get))
|
|
.route("/stream/mode", post(handlers::stream_mode_set))
|
|
.route("/stream/bitrate", post(handlers::stream_set_bitrate))
|
|
.route("/stream/codecs", get(handlers::stream_codecs_list))
|
|
// WebRTC endpoints
|
|
.route("/webrtc/session", post(handlers::webrtc_create_session))
|
|
.route("/webrtc/offer", post(handlers::webrtc_offer))
|
|
.route("/webrtc/ice", post(handlers::webrtc_ice_candidate))
|
|
.route("/webrtc/ice-servers", get(handlers::webrtc_ice_servers))
|
|
.route("/webrtc/status", get(handlers::webrtc_status))
|
|
.route("/webrtc/close", post(handlers::webrtc_close_session))
|
|
// HID endpoints
|
|
.route("/hid/status", get(handlers::hid_status))
|
|
.route("/hid/reset", post(handlers::hid_reset))
|
|
// WebSocket HID endpoint (for MJPEG mode)
|
|
.route("/ws/hid", any(ws_hid_handler))
|
|
// Audio endpoints
|
|
.route("/audio/status", get(handlers::audio_status))
|
|
.route("/audio/start", post(handlers::start_audio_streaming))
|
|
.route("/audio/stop", post(handlers::stop_audio_streaming))
|
|
.route("/audio/quality", post(handlers::set_audio_quality))
|
|
.route("/audio/device", post(handlers::select_audio_device))
|
|
.route("/audio/devices", get(handlers::list_audio_devices))
|
|
// Audio WebSocket endpoint
|
|
.route("/ws/audio", any(audio_ws_handler))
|
|
// User can change their own password (handler will check ownership)
|
|
.route("/users/{id}/password", post(handlers::change_user_password));
|
|
|
|
// Admin-only routes (require admin privileges)
|
|
let admin_routes = Router::new()
|
|
// Configuration management (domain-separated endpoints)
|
|
.route("/config", get(handlers::config::get_all_config))
|
|
.route("/config", post(handlers::update_config))
|
|
.route("/config/video", get(handlers::config::get_video_config))
|
|
.route("/config/video", patch(handlers::config::update_video_config))
|
|
.route("/config/stream", get(handlers::config::get_stream_config))
|
|
.route("/config/stream", patch(handlers::config::update_stream_config))
|
|
.route("/config/hid", get(handlers::config::get_hid_config))
|
|
.route("/config/hid", patch(handlers::config::update_hid_config))
|
|
.route("/config/msd", get(handlers::config::get_msd_config))
|
|
.route("/config/msd", patch(handlers::config::update_msd_config))
|
|
.route("/config/atx", get(handlers::config::get_atx_config))
|
|
.route("/config/atx", patch(handlers::config::update_atx_config))
|
|
.route("/config/audio", get(handlers::config::get_audio_config))
|
|
.route("/config/audio", patch(handlers::config::update_audio_config))
|
|
// RustDesk configuration endpoints
|
|
.route("/config/rustdesk", get(handlers::config::get_rustdesk_config))
|
|
.route("/config/rustdesk", patch(handlers::config::update_rustdesk_config))
|
|
.route("/config/rustdesk/status", get(handlers::config::get_rustdesk_status))
|
|
.route("/config/rustdesk/password", get(handlers::config::get_device_password))
|
|
.route("/config/rustdesk/regenerate-id", post(handlers::config::regenerate_device_id))
|
|
.route("/config/rustdesk/regenerate-password", post(handlers::config::regenerate_device_password))
|
|
// Web server configuration
|
|
.route("/config/web", get(handlers::config::get_web_config))
|
|
.route("/config/web", patch(handlers::config::update_web_config))
|
|
// System control
|
|
.route("/system/restart", post(handlers::system_restart))
|
|
// MSD (Mass Storage Device) endpoints
|
|
.route("/msd/status", get(handlers::msd_status))
|
|
.route("/msd/images", get(handlers::msd_images_list))
|
|
.route("/msd/images/download", post(handlers::msd_image_download))
|
|
.route("/msd/images/download/cancel", post(handlers::msd_image_download_cancel))
|
|
.route("/msd/images/{id}", get(handlers::msd_image_get))
|
|
.route("/msd/images/{id}", delete(handlers::msd_image_delete))
|
|
.route("/msd/connect", post(handlers::msd_connect))
|
|
.route("/msd/disconnect", post(handlers::msd_disconnect))
|
|
// MSD Virtual Drive endpoints
|
|
.route("/msd/drive", get(handlers::msd_drive_info))
|
|
.route("/msd/drive", delete(handlers::msd_drive_delete))
|
|
.route("/msd/drive/init", post(handlers::msd_drive_init))
|
|
.route("/msd/drive/files", get(handlers::msd_drive_files))
|
|
.route("/msd/drive/files/{*path}", get(handlers::msd_drive_download))
|
|
.route("/msd/drive/files/{*path}", delete(handlers::msd_drive_file_delete))
|
|
.route("/msd/drive/mkdir/{*path}", post(handlers::msd_drive_mkdir))
|
|
// ATX (Power Control) endpoints
|
|
.route("/atx/status", get(handlers::atx_status))
|
|
.route("/atx/power", post(handlers::atx_power))
|
|
.route("/atx/wol", post(handlers::atx_wol))
|
|
// Device discovery endpoints
|
|
.route("/devices/atx", get(handlers::devices::list_atx_devices))
|
|
// User management endpoints
|
|
.route("/users", get(handlers::list_users))
|
|
.route("/users", post(handlers::create_user))
|
|
.route("/users/{id}", put(handlers::update_user))
|
|
.route("/users/{id}", delete(handlers::delete_user))
|
|
// Extension management endpoints
|
|
.route("/extensions", get(handlers::extensions::list_extensions))
|
|
.route("/extensions/{id}", get(handlers::extensions::get_extension))
|
|
.route("/extensions/{id}/start", post(handlers::extensions::start_extension))
|
|
.route("/extensions/{id}/stop", post(handlers::extensions::stop_extension))
|
|
.route("/extensions/{id}/logs", get(handlers::extensions::get_extension_logs))
|
|
.route("/extensions/ttyd/config", patch(handlers::extensions::update_ttyd_config))
|
|
.route("/extensions/ttyd/status", get(handlers::extensions::get_ttyd_status))
|
|
.route("/extensions/gostc/config", patch(handlers::extensions::update_gostc_config))
|
|
.route("/extensions/easytier/config", patch(handlers::extensions::update_easytier_config))
|
|
// Terminal (ttyd) reverse proxy - WebSocket and HTTP
|
|
.route("/terminal", get(handlers::terminal::terminal_index))
|
|
.route("/terminal/", get(handlers::terminal::terminal_index))
|
|
.route("/terminal/ws", get(handlers::terminal::terminal_ws))
|
|
.route("/terminal/{*path}", get(handlers::terminal::terminal_proxy))
|
|
// Apply admin middleware to all admin routes
|
|
.layer(middleware::from_fn_with_state(state.clone(), require_admin));
|
|
|
|
// Combine protected routes (user + admin)
|
|
let protected_routes = Router::new()
|
|
.merge(user_routes)
|
|
.merge(admin_routes);
|
|
|
|
// Stream endpoints (accessible with auth, but typically embedded in pages)
|
|
let stream_routes = Router::new()
|
|
.route("/stream", get(handlers::mjpeg_stream))
|
|
.route("/stream/mjpeg", get(handlers::mjpeg_stream))
|
|
.route("/snapshot", get(handlers::snapshot));
|
|
|
|
// Large file upload routes (MSD images and drive files)
|
|
// Use streaming upload to support files larger than available RAM
|
|
// Disable body limit for streaming uploads - files are written directly to disk
|
|
let upload_routes = Router::new()
|
|
.route("/msd/images", post(handlers::msd_image_upload))
|
|
.route("/msd/drive/files", post(handlers::msd_drive_upload))
|
|
.layer(DefaultBodyLimit::disable());
|
|
|
|
// Combine API routes
|
|
let api_routes = Router::new()
|
|
.merge(public_routes)
|
|
.merge(protected_routes)
|
|
.merge(stream_routes)
|
|
.merge(upload_routes)
|
|
.layer(middleware::from_fn_with_state(
|
|
state.clone(),
|
|
auth_middleware,
|
|
));
|
|
|
|
// Static file serving
|
|
let static_routes = super::static_files::static_file_router();
|
|
|
|
// Main router
|
|
Router::new()
|
|
.nest("/api", api_routes)
|
|
.merge(static_routes)
|
|
.layer(TraceLayer::new_for_http())
|
|
.layer(cors)
|
|
.with_state(state)
|
|
}
|