Setting Up WebDAV for Profile Backup and Synchronization in Clash Verge Rev
Clash Verge Rev provides a complete WebDAV integration that enables secure, automated backup and synchronization of your proxy profiles across devices using any WebDAV-compatible server.
Clash Verge Rev, an open-source GUI client for Clash cores, ships with a robust WebDAV backup system that stores your configuration archives on remote servers. This feature leverages a React and TypeScript front-end paired with a Rust/Tauri back-end to handle compression, credential stripping, and network resilience. According to the clash-verge-rev/clash-verge-rev source code, the implementation spans from UI dialogs in src/components/setting/mods/backup-webdav-dialog.tsx to low-level client logic in src-tauri/src/core/backup.rs.
How WebDAV Backup Works in Clash Verge Rev
The backup system follows a strict separation of concerns: the front-end manages UI state and thin API wrappers, while the Rust back-end handles all heavy I/O, including zip creation, network transport, and file system operations.
Front-End to Back-End Data Flow
The synchronization flow begins when a user enters URL, username, and password into the BackupWebdavDialog React component. This triggers the saveWebdavConfig wrapper in src/services/cmds.ts, which invokes the Tauri command save_webdav_config defined in src-tauri/src/cmd/webdav.rs. The Rust side writes these credentials to verge.yaml and immediately resets the global WebDavClient singleton to ensure subsequent operations use fresh authentication.
When creating a backup, the front-end calls createWebdavBackup, which routes to src-tauri/src/feat/backup.rs. Here, the create_backup function in src-tauri/src/core/backup.rs generates a timestamped .zip file containing profiles, configuration, and DNS settings. Critically, this function strips WebDAV credentials from the exported verge.yaml before adding it to the archive, ensuring your secrets never leave the local machine in plain text.
The WebDavClient::global().upload() method then pushes the zip to <WEB_DAV_ROOT>/backup/<filename>.zip using a cached reqwest_dav::Client with 5-minute timeouts and automatic retry logic. For listing operations, list_webdav_backup filters the remote directory to plain files and normalizes filenames, while restore_webdav_backup downloads archives, extracts them to the app home directory, and calls finalize_restored_verge_config to re-inject the original WebDAV credentials back into the active configuration.
Core Modules and File Structure
| Module | Responsibility | Key Symbols |
|---|---|---|
src-tauri/src/cmd/webdav.rs |
Tauri command definitions exposing WebDAV actions to the UI | save_webdav_config, create_webdav_backup, list_webdav_backup |
src-tauri/src/feat/backup.rs |
Business logic orchestrating zip creation and client calls | create_backup_and_upload_webdav, restore_webdav_backup |
src-tauri/src/core/backup.rs |
WebDavClient singleton with lazy loading and network handling | WebDavClient::global(), upload, download, reset |
src/services/webdav-status.ts |
Front-end status caching in localStorage |
buildWebdavSignature, getWebdavStatus |
src/components/setting/mods/backup-webdav-dialog.tsx |
React UI for configuration and backup triggers | BackupWebdavDialog component |
Configuring WebDAV Settings
To enable remote backup, store your server credentials using the TypeScript wrapper. This writes the configuration to verge.yaml and resets the internal client to prevent stale authentication errors.
import { saveWebdavConfig } from "@/services/cmds";
const url = "https://webdav.example.com/backup";
const username = "myuser";
const password = "s3cr3t";
await saveWebdavConfig(url, username, password);
The Rust back-end validates the connection by resetting the WebDavClient singleton via core::backup::WebDavClient::reset, ensuring the next operation instantiates a fresh reqwest_dav::Client with the updated credentials.
Creating and Managing Backups
Once configured, the system supports full lifecycle management of remote archives through idiomatic async functions.
Creating a Backup Archive
The createWebdavBackup function triggers a compressed export of your entire configuration state. The Rust side handles zipping and upload with built-in retry logic.
import { createWebdavBackup } from "@/services/cmds";
try {
await createWebdavBackup();
console.log("Backup uploaded to WebDAV");
} catch (e) {
console.error("Backup failed:", e);
}
Behind the scenes, src-tauri/src/core/backup.rs creates the archive and explicitly removes WebDAV credentials from the bundled verge.yaml before compression.
Listing Remote Backups
Retrieve existing archives to populate management UIs or verify synchronization status. The function returns a filtered list of plain files with normalized paths.
import { listWebDavBackup } from "@/services/cmds";
const backups = await listWebDavBackup();
// Returns: [{ filename: "mac-backup-2024-01-01.zip", ... }]
console.table(backups);
Restoring from WebDAV
Restoration downloads the specified zip, extracts it to the application home directory, and securely re-injects your WebDAV credentials into the restored verge.yaml via finalize_restored_verge_config.
import { restoreWebDavBackup } from "@/services/cmds";
await restoreWebDavBackup("mac-backup-2024-01-01.zip");
console.log("Configuration restored from WebDAV");
Deleting Old Backups
Remove stale archives directly from the remote server using the filename returned by the list operation.
import { deleteWebdavBackup } from "@/services/cmds";
await deleteWebdavBackup("mac-backup-2024-01-01.zip");
Security and Performance Design
The implementation prioritizes credential isolation and network resilience through several architectural safeguards.
Credential Stripping: During create_backup in src-tauri/src/core/backup.rs, the system parses verge.yaml and removes WebDAV username and password fields before adding the file to the zip archive. This prevents accidental credential exposure in remote storage.
Singleton Client Caching: The WebDavClient maintains a per-operation cache of reqwest_dav::Client instances, avoiding expensive TLS session renegotiation for every upload or download. The client is rebuilt only when reset is called after configuration changes.
Timeout and Retry Policy: Network operations use aggressive timeouts—5 minutes for upload and download operations, 30 seconds for list and delete—to prevent UI blocking. A single automatic retry protects against transient network failures.
Status Signature Caching: The front-end stores a status signature in localStorage under the key webdav_status_cache. By hashing the JSON.stringify([url, username, password]) tuple, the BackupWebdavDialog can display "WebDAV ready" or "WebDAV failed" instantly without redundant network probes.
Extending the Backup System
Developers can customize the backup behavior by modifying specific Rust modules:
- Change backup location: Edit
dirs::BACKUP_DIRinsrc-tauri/src/utils/dirs.rsto redirect the local staging directory. - Add files to archives: Extend the
zip.start_file(...)calls increate_backupwithinsrc-tauri/src/core/backup.rsto include additional resources like custom scripts or logs. - Implement exponential backoff: Replace the simple timeout wrappers in
WebDavClient::uploadanddownloadwith exponential back-off loops for improved reliability on unstable connections.
Summary
- WebDAV integration in Clash Verge Rev spans React front-end dialogs and Rust/Tauri back-end commands for secure, cross-device configuration sync.
- Credential security is enforced by stripping WebDAV secrets from exported archives during
create_backupand re-injecting them only after restoration. - Performance optimization relies on a singleton
WebDavClientthat caches HTTP clients and uses 5-minute timeouts for large uploads. - UI responsiveness is maintained through
localStorage-based status caching that avoids redundant network checks when opening the backup dialog. - Extensible architecture allows modification of backup directories, archive contents, and retry logic by editing files in
src-tauri/src/core/backup.rsandsrc-tauri/src/utils/dirs.rs.
Frequently Asked Questions
How does Clash Verge Rev protect my WebDAV password during backup?
The create_backup function in src-tauri/src/core/backup.rs explicitly removes the username and password fields from the exported verge.yaml before adding it to the zip archive. Your credentials remain only in local memory and are never transmitted to the WebDAV server inside the backup file. After restoration, finalize_restored_verge_config re-inserts the credentials into the active configuration.
What network timeouts does the WebDAV client use?
According to the source in src-tauri/src/core/backup.rs, upload and download operations use a 5-minute timeout, while list and delete operations use a 30-second timeout. Each operation includes one automatic retry to handle transient network failures without hanging the UI.
Why does the WebDAV dialog show "ready" status immediately without testing the connection?
The front-end implements a signature-based cache in src/services/webdav-status.ts that stores the last known status in localStorage under the key webdav_status_cache. The signature is built from JSON.stringify([url, username, password]), allowing the UI to display the cached state instantly rather than probing the server on every dialog open.
Can I change where local backup files are staged before upload?
Yes. The temporary staging directory is defined by dirs::BACKUP_DIR in src-tauri/src/utils/dirs.rs. Modifying this constant redirects the local zip creation path, though the remote WebDAV destination path (/backup/) is currently fixed in the upload logic.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →