From 0ab236f8a2cad9f8ce490f9508887218fd78fb5e Mon Sep 17 00:00:00 2001 From: flymarq Date: Fri, 25 Jul 2025 12:26:35 +0200 Subject: [PATCH 1/5] Uri in xml response must be url encoded. The Uri is derived from the request with the method getPath, which generates a valid path fragment suitable for file and directory names. In the XML-response to a lock-request the uri is used for lockroot element. If the uri contains a space or german umlauts, a strict client like libneon, which is used in davfs2, refuses the lock reponse and files cannot be copied. --- lib/DAV/Locks/Plugin.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/DAV/Locks/Plugin.php b/lib/DAV/Locks/Plugin.php index a7e2b44adf..99e317e217 100644 --- a/lib/DAV/Locks/Plugin.php +++ b/lib/DAV/Locks/Plugin.php @@ -234,6 +234,7 @@ public function httpLock(RequestInterface $request, ResponseInterface $response) } $this->lockNode($uri, $lockInfo); + $lockInfo->uri = urlencode($lockInfo->uri); $response->setHeader('Content-Type', 'application/xml; charset=utf-8'); $response->setHeader('Lock-Token', 'token.'>'); From 03940b85bf7b17efd0bf41d475d6c059d972b38f Mon Sep 17 00:00:00 2001 From: flymarq Date: Fri, 25 Jul 2025 13:07:52 +0200 Subject: [PATCH 2/5] Multiple unlimited uploads with progress bar. - allow upload of multipe files - uploads are not limited by php upload size using PUT - progress bar for each file --- lib/DAV/Browser/Plugin.php | 108 +++++++++++++++++++++++++++++++++++-- 1 file changed, 104 insertions(+), 4 deletions(-) diff --git a/lib/DAV/Browser/Plugin.php b/lib/DAV/Browser/Plugin.php index 5b453ac751..197404f90b 100644 --- a/lib/DAV/Browser/Plugin.php +++ b/lib/DAV/Browser/Plugin.php @@ -512,11 +512,111 @@ public function htmlActionsPanel(DAV\INode $node, &$output, $path)

Upload file

- -
-
- +Select one or more file(s), then you can upload.
+ +
+ +
+ HTML; } From 3aca3d516c05f978333dc77714b3a27ffeea8f9a Mon Sep 17 00:00:00 2001 From: Flynn Marquardt Date: Fri, 21 Nov 2025 18:50:02 +0100 Subject: [PATCH 3/5] Revert "Multiple unlimited uploads with progress bar." This reverts commit 03940b85bf7b17efd0bf41d475d6c059d972b38f. --- lib/DAV/Browser/Plugin.php | 108 ++----------------------------------- 1 file changed, 4 insertions(+), 104 deletions(-) diff --git a/lib/DAV/Browser/Plugin.php b/lib/DAV/Browser/Plugin.php index 197404f90b..5b453ac751 100644 --- a/lib/DAV/Browser/Plugin.php +++ b/lib/DAV/Browser/Plugin.php @@ -512,111 +512,11 @@ public function htmlActionsPanel(DAV\INode $node, &$output, $path)

Upload file

-Select one or more file(s), then you can upload.
- -
- -
+ +
+
+
- HTML; } From e33db5e088b15801a7570137807a53d9174eec0a Mon Sep 17 00:00:00 2001 From: Flynn Marquardt Date: Fri, 21 Nov 2025 19:23:33 +0100 Subject: [PATCH 4/5] Add test for locking urls with spaces. --- tests/Sabre/DAV/Locks/PluginTest.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/Sabre/DAV/Locks/PluginTest.php b/tests/Sabre/DAV/Locks/PluginTest.php index 465bbc1609..3f7ffd4cef 100644 --- a/tests/Sabre/DAV/Locks/PluginTest.php +++ b/tests/Sabre/DAV/Locks/PluginTest.php @@ -920,4 +920,14 @@ public function testGetTimeoutHeaderInvalid() $this->server->httpRequest = $request; $this->locksPlugin->getTimeoutHeader(); } + + public function testLockWithSpaces() + { + $request = new HTTP\Request('LOCK', '/test .txt', [ + 'Timeout' => 'second-5, infinite', + ]); + $this->server->httpRequest = $request; + $this->server->exec(); + self::assertEquals(201, $this->response->status); + } } From 863d6c3cf683ee93998f1805348684a832018188 Mon Sep 17 00:00:00 2001 From: Flynn Marquardt Date: Tue, 2 Dec 2025 10:40:39 +0100 Subject: [PATCH 5/5] Add check for lock token. --- tests/Sabre/DAV/Locks/PluginTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/Sabre/DAV/Locks/PluginTest.php b/tests/Sabre/DAV/Locks/PluginTest.php index 3f7ffd4cef..19ce42b68b 100644 --- a/tests/Sabre/DAV/Locks/PluginTest.php +++ b/tests/Sabre/DAV/Locks/PluginTest.php @@ -929,5 +929,9 @@ public function testLockWithSpaces() $this->server->httpRequest = $request; $this->server->exec(); self::assertEquals(201, $this->response->status); + $xml = $this->getSanitizedBodyAsXml(); + $xml->registerXPathNamespace('d', 'prop:DAV'); + $token = $xml->xpath('/d:prop/d:lockdiscovery/d:activelock/d:locktoken/d:href'); + self::assertEquals($this->response->getHeader('Lock-Token'), '<'.(string) $token[0].'>', 'Token in response body didn\'t match token in response header.'); } }