Merge pull request #1968 from laurisvr/fix-move-urlencode-destination

Fix MOVE failing with URL-encoded Destination header
This commit is contained in:
Peter Bieringer
2026-01-22 06:29:48 +01:00
committed by GitHub

View File

@@ -22,7 +22,7 @@ import errno
import posixpath import posixpath
import re import re
from http import client from http import client
from urllib.parse import urlparse from urllib.parse import unquote, urlparse
from radicale import httputils, pathutils, storage, types from radicale import httputils, pathutils, storage, types
from radicale.app.base import Access, ApplicationBase from radicale.app.base import Access, ApplicationBase
@@ -51,7 +51,13 @@ class ApplicationPartMove(ApplicationBase):
path: str, user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse: path: str, user: str, remote_host: str, remote_useragent: str) -> types.WSGIResponse:
"""Manage MOVE request.""" """Manage MOVE request."""
raw_dest = environ.get("HTTP_DESTINATION", "") raw_dest = environ.get("HTTP_DESTINATION", "")
to_url = urlparse(raw_dest)
# Decode URL-encoded characters (e.g. %40 -> @) before parsing
raw_dest_decoded = unquote(raw_dest)
to_url = urlparse(raw_dest_decoded)
# Only check netloc for absolute URLs
if to_url.netloc:
to_netloc_with_port = to_url.netloc to_netloc_with_port = to_url.netloc
if to_url.port is None: if to_url.port is None:
to_netloc_with_port += (":443" if to_url.scheme == "https" to_netloc_with_port += (":443" if to_url.scheme == "https"
@@ -60,6 +66,7 @@ class ApplicationPartMove(ApplicationBase):
logger.info("Unsupported destination address: %r", raw_dest) logger.info("Unsupported destination address: %r", raw_dest)
# Remote destination server, not supported # Remote destination server, not supported
return httputils.REMOTE_DESTINATION return httputils.REMOTE_DESTINATION
access = Access(self._rights, user, path) access = Access(self._rights, user, path)
if not access.check("w"): if not access.check("w"):
return httputils.NOT_ALLOWED return httputils.NOT_ALLOWED