qwen_agent/routes/webdav.py
朱潮 425f3c5bb4 chore: replace Chinese comments and log messages with English
Convert all Chinese comments, docstrings, logger/print output,
HTTPException detail messages, and API response messages to English
across the entire codebase. Functional zh/ja localized strings
(e.g. prompt templates, timezone display names, date formats) are
preserved as-is.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-30 19:45:35 +08:00

96 lines
3.2 KiB
Python

"""
WebDAV file management routes.
Uses the open-source WsgiDAV library to provide full WebDAV protocol support.
Provides WebDAV access for the projects/{resource_type}/ directories.
Supported resource types: robot, docs
"""
from pathlib import Path
from urllib.parse import urlparse, urlunparse
from wsgidav.wsgidav_app import WsgiDAVApp
from wsgidav.fs_dav_provider import FilesystemProvider
from utils.settings import WEBDAV_USERNAME, WEBDAV_PASSWORD
PROJECTS_BASE_DIR = Path("projects")
ALLOWED_RESOURCE_TYPES = {"robot", "docs"}
# Ensure the base directories exist
for resource_type in ALLOWED_RESOURCE_TYPES:
(PROJECTS_BASE_DIR / resource_type).mkdir(parents=True, exist_ok=True)
# Build provider_mapping: map each resource type to its corresponding directory
provider_mapping = {}
for resource_type in ALLOWED_RESOURCE_TYPES:
abs_path = str((PROJECTS_BASE_DIR / resource_type).resolve())
provider_mapping[f"/{resource_type}"] = FilesystemProvider(abs_path)
config = {
"mount_path": "/webdav",
"provider_mapping": provider_mapping,
"http_authenticator": {
"domain_controller": "wsgidav.dc.simple_dc.SimpleDomainController",
"accept_basic": True,
"accept_digest": False,
"default_to_digest": False,
},
"simple_dc": {
"user_mapping": {
"*": {
WEBDAV_USERNAME: {
"password": WEBDAV_PASSWORD,
},
},
},
},
"verbose": 1,
"lock_storage": True,
"property_manager": True,
"dir_browser": {
"enable": True,
"icon": True,
"response_trailer": "",
},
"hotfixes": {
"re_encode_path_info": True,
},
}
_wsgidav_app = WsgiDAVApp(config)
def wsgidav_app(environ, start_response):
"""WSGI middleware that fixes Destination header scheme/host mismatches behind a reverse proxy.
When the service runs behind an HTTPS reverse proxy, the client sends a Destination
header with the external URL (for example https://example.com/webdav/docs/new-name),
while WsgiDAV internally sees an HTTP request. This middleware rewrites the
Destination header so its scheme and host match the internal request.
"""
# Read external request information from X-Forwarded headers and keep
# wsgi.url_scheme aligned with the forwarded protocol.
forwarded_proto = environ.get("HTTP_X_FORWARDED_PROTO")
if forwarded_proto:
environ["wsgi.url_scheme"] = forwarded_proto
# Rewrite the Destination header by replacing the external scheme/host
# with the internal values observed by the application.
destination = environ.get("HTTP_DESTINATION")
if destination:
parsed = urlparse(destination)
# Replace with the actual internal scheme and host.
internal_scheme = environ.get("wsgi.url_scheme", "http")
internal_host = environ.get("HTTP_HOST", environ.get("SERVER_NAME", "localhost"))
rewritten = urlunparse((
internal_scheme,
internal_host,
parsed.path,
parsed.params,
parsed.query,
parsed.fragment,
))
environ["HTTP_DESTINATION"] = rewritten
return _wsgidav_app(environ, start_response)