mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-06 13:27:43 +00:00
feat(webdav): add WebDAV protocol gateway (#2158)
Signed-off-by: yxrxy <1532529704@qq.com> Co-authored-by: houseme <housemecn@gmail.com> Co-authored-by: 马登山 <Cxymds@qq.com> Co-authored-by: heihutu <30542132+heihutu@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: 安正超 <anzhengchao@gmail.com>
This commit is contained in:
+2
-1
@@ -35,7 +35,8 @@ default = ["metrics"]
|
||||
metrics = []
|
||||
ftps = ["rustfs-protocols/ftps"]
|
||||
swift = ["rustfs-protocols/swift"]
|
||||
full = ["metrics", "ftps", "swift"]
|
||||
webdav = ["rustfs-protocols/webdav"]
|
||||
full = ["metrics", "ftps", "swift", "webdav"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
@@ -508,3 +508,73 @@ pub async fn init_ftps_system() -> Result<Option<tokio::sync::broadcast::Sender<
|
||||
Ok(Some(shutdown_tx))
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize the WebDAV system
|
||||
///
|
||||
/// This function initializes the WebDAV server if enabled in the configuration.
|
||||
/// It sets up the WebDAV server with the appropriate configuration and starts
|
||||
/// the server in a background task.
|
||||
#[cfg(feature = "webdav")]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn init_webdav_system() -> Result<Option<tokio::sync::broadcast::Sender<()>>, Box<dyn std::error::Error + Send + Sync>>
|
||||
{
|
||||
{
|
||||
use crate::protocols::ProtocolStorageClient;
|
||||
use rustfs_config::{
|
||||
DEFAULT_WEBDAV_ADDRESS, ENV_WEBDAV_ADDRESS, ENV_WEBDAV_CA_FILE, ENV_WEBDAV_CERTS_DIR, ENV_WEBDAV_ENABLE,
|
||||
ENV_WEBDAV_MAX_BODY_SIZE, ENV_WEBDAV_REQUEST_TIMEOUT, ENV_WEBDAV_TLS_ENABLED,
|
||||
};
|
||||
use rustfs_protocols::{WebDavConfig, WebDavServer};
|
||||
|
||||
// Check if WebDAV is enabled
|
||||
let webdav_enable = rustfs_utils::get_env_bool(ENV_WEBDAV_ENABLE, false);
|
||||
if !webdav_enable {
|
||||
debug!("WebDAV system is disabled");
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// Parse WebDAV address
|
||||
let webdav_address_str = rustfs_utils::get_env_str(ENV_WEBDAV_ADDRESS, DEFAULT_WEBDAV_ADDRESS);
|
||||
let addr = rustfs_utils::net::parse_and_resolve_address(&webdav_address_str)
|
||||
.map_err(|e| format!("Invalid WebDAV address '{webdav_address_str}': {e}"))?;
|
||||
|
||||
// Get WebDAV configuration from environment variables
|
||||
let tls_enabled = rustfs_utils::get_env_bool(ENV_WEBDAV_TLS_ENABLED, true);
|
||||
let cert_dir = rustfs_utils::get_env_opt_str(ENV_WEBDAV_CERTS_DIR);
|
||||
let ca_file = rustfs_utils::get_env_opt_str(ENV_WEBDAV_CA_FILE);
|
||||
let max_body_size = rustfs_utils::get_env_u64(ENV_WEBDAV_MAX_BODY_SIZE, WebDavConfig::DEFAULT_MAX_BODY_SIZE);
|
||||
let request_timeout_secs =
|
||||
rustfs_utils::get_env_u64(ENV_WEBDAV_REQUEST_TIMEOUT, WebDavConfig::DEFAULT_REQUEST_TIMEOUT_SECS);
|
||||
|
||||
// Create WebDAV configuration
|
||||
let config = WebDavConfig {
|
||||
bind_addr: addr,
|
||||
tls_enabled,
|
||||
cert_dir,
|
||||
ca_file,
|
||||
max_body_size,
|
||||
request_timeout_secs,
|
||||
};
|
||||
|
||||
// Create WebDAV server with protocol storage client
|
||||
let fs = crate::storage::ecfs::FS::new();
|
||||
let storage_client = ProtocolStorageClient::new(fs);
|
||||
let server: WebDavServer<crate::protocols::ProtocolStorageClient> = WebDavServer::new(config, storage_client).await?;
|
||||
|
||||
// Log server configuration
|
||||
info!("WebDAV server configured on {}", server.config().bind_addr);
|
||||
|
||||
// Start WebDAV server in background task with proper shutdown support
|
||||
let (shutdown_tx, shutdown_rx) = tokio::sync::broadcast::channel(1);
|
||||
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = server.start(shutdown_rx).await {
|
||||
error!("WebDAV server error: {}", e);
|
||||
}
|
||||
info!("WebDAV server shutdown completed");
|
||||
});
|
||||
|
||||
info!("WebDAV system initialized successfully");
|
||||
Ok(Some(shutdown_tx))
|
||||
}
|
||||
}
|
||||
|
||||
+36
-1
@@ -21,7 +21,7 @@ mod error;
|
||||
mod init;
|
||||
mod license;
|
||||
mod profiling;
|
||||
#[cfg(feature = "ftps")]
|
||||
#[cfg(any(feature = "ftps", feature = "webdav"))]
|
||||
mod protocols;
|
||||
mod server;
|
||||
mod storage;
|
||||
@@ -37,6 +37,9 @@ use crate::init::{
|
||||
#[cfg(feature = "ftps")]
|
||||
use crate::init::{init_ftp_system, init_ftps_system};
|
||||
|
||||
#[cfg(feature = "webdav")]
|
||||
use crate::init::init_webdav_system;
|
||||
|
||||
use crate::server::{
|
||||
SHUTDOWN_TIMEOUT, ServiceState, ServiceStateManager, ShutdownSignal, init_cert, init_event_notifier, shutdown_event_notifier,
|
||||
start_audit_system, start_http_server, stop_audit_system, wait_for_shutdown,
|
||||
@@ -348,6 +351,26 @@ async fn run(config: config::Config) -> Result<()> {
|
||||
#[cfg(not(feature = "ftps"))]
|
||||
let ftps_shutdown_tx: Option<tokio::sync::broadcast::Sender<()>> = None;
|
||||
|
||||
// Initialize WebDAV system if enabled
|
||||
#[cfg(feature = "webdav")]
|
||||
let webdav_shutdown_tx = match init_webdav_system().await {
|
||||
Ok(Some(tx)) => {
|
||||
info!("WebDAV system initialized successfully");
|
||||
Some(tx)
|
||||
}
|
||||
Ok(None) => {
|
||||
info!("WebDAV system disabled");
|
||||
None
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to initialize WebDAV system: {}", e);
|
||||
return Err(Error::other(e));
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "webdav"))]
|
||||
let webdav_shutdown_tx: Option<tokio::sync::broadcast::Sender<()>> = None;
|
||||
|
||||
// Initialize buffer profiling system
|
||||
init_buffer_profile_system(&config);
|
||||
|
||||
@@ -471,6 +494,7 @@ async fn run(config: config::Config) -> Result<()> {
|
||||
console_shutdown_tx,
|
||||
ftp_shutdown_tx,
|
||||
ftps_shutdown_tx,
|
||||
webdav_shutdown_tx,
|
||||
ctx.clone(),
|
||||
)
|
||||
.await;
|
||||
@@ -483,6 +507,7 @@ async fn run(config: config::Config) -> Result<()> {
|
||||
console_shutdown_tx,
|
||||
ftp_shutdown_tx,
|
||||
ftps_shutdown_tx,
|
||||
webdav_shutdown_tx,
|
||||
ctx.clone(),
|
||||
)
|
||||
.await;
|
||||
@@ -500,6 +525,7 @@ async fn handle_shutdown(
|
||||
console_shutdown_tx: Option<tokio::sync::broadcast::Sender<()>>,
|
||||
ftp_shutdown_tx: Option<tokio::sync::broadcast::Sender<()>>,
|
||||
ftps_shutdown_tx: Option<tokio::sync::broadcast::Sender<()>>,
|
||||
webdav_shutdown_tx: Option<tokio::sync::broadcast::Sender<()>>,
|
||||
ctx: CancellationToken,
|
||||
) {
|
||||
ctx.cancel();
|
||||
@@ -552,6 +578,15 @@ async fn handle_shutdown(
|
||||
let _ = ftps_shutdown_tx.send(());
|
||||
}
|
||||
|
||||
// Shutdown WebDAV server
|
||||
if let Some(webdav_shutdown_tx) = webdav_shutdown_tx {
|
||||
info!(
|
||||
target: "rustfs::main::handle_shutdown",
|
||||
"Shutting down WebDAV server..."
|
||||
);
|
||||
let _ = webdav_shutdown_tx.send(());
|
||||
}
|
||||
|
||||
// Stop the notification system
|
||||
info!(
|
||||
target: "rustfs::main::handle_shutdown",
|
||||
|
||||
Reference in New Issue
Block a user