Skip to content

Commit ff26c8b

Browse files
Merge pull request #63435 from nextcloud/carl/propfind-404
fix(dav): Handle correctly not found while streaming output
2 parents 5480cda + 1668edb commit ff26c8b

4 files changed

Lines changed: 41 additions & 0 deletions

File tree

apps/dav/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@
268268
'OCA\\DAV\\Connector\\Sabre\\ShareTypeList' => $baseDir . '/../lib/Connector/Sabre/ShareTypeList.php',
269269
'OCA\\DAV\\Connector\\Sabre\\ShareeList' => $baseDir . '/../lib/Connector/Sabre/ShareeList.php',
270270
'OCA\\DAV\\Connector\\Sabre\\SharesPlugin' => $baseDir . '/../lib/Connector/Sabre/SharesPlugin.php',
271+
'OCA\\DAV\\Connector\\Sabre\\StreamedPropFindNotFoundPlugin' => $baseDir . '/../lib/Connector/Sabre/StreamedPropFindNotFoundPlugin.php',
271272
'OCA\\DAV\\Connector\\Sabre\\TagList' => $baseDir . '/../lib/Connector/Sabre/TagList.php',
272273
'OCA\\DAV\\Connector\\Sabre\\TagsPlugin' => $baseDir . '/../lib/Connector/Sabre/TagsPlugin.php',
273274
'OCA\\DAV\\Connector\\Sabre\\UserIdHeaderPlugin' => $baseDir . '/../lib/Connector/Sabre/UserIdHeaderPlugin.php',

apps/dav/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ class ComposerStaticInitDAV
283283
'OCA\\DAV\\Connector\\Sabre\\ShareTypeList' => __DIR__ . '/..' . '/../lib/Connector/Sabre/ShareTypeList.php',
284284
'OCA\\DAV\\Connector\\Sabre\\ShareeList' => __DIR__ . '/..' . '/../lib/Connector/Sabre/ShareeList.php',
285285
'OCA\\DAV\\Connector\\Sabre\\SharesPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/SharesPlugin.php',
286+
'OCA\\DAV\\Connector\\Sabre\\StreamedPropFindNotFoundPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/StreamedPropFindNotFoundPlugin.php',
286287
'OCA\\DAV\\Connector\\Sabre\\TagList' => __DIR__ . '/..' . '/../lib/Connector/Sabre/TagList.php',
287288
'OCA\\DAV\\Connector\\Sabre\\TagsPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/TagsPlugin.php',
288289
'OCA\\DAV\\Connector\\Sabre\\UserIdHeaderPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/UserIdHeaderPlugin.php',

apps/dav/lib/Connector/Sabre/ServerFactory.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ public function createServer(
8484
Server::$streamMultiStatus = true;
8585

8686
$server = new Server($tree);
87+
$server->addPlugin(new StreamedPropFindNotFoundPlugin());
8788

8889
// Set URL explicitly due to reverse-proxy situations
8990
$server->httpRequest->setUrl($requestUri);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace OCA\DAV\Connector\Sabre;
11+
12+
use Sabre\DAV\Server;
13+
use Sabre\DAV\ServerPlugin;
14+
use Sabre\HTTP\RequestInterface;
15+
16+
/**
17+
* With Server::$streamMultiStatus enabled, CorePlugin::httpPropFind() commits
18+
* the 207 status and starts streaming the body before resolving the
19+
* requested node, so a missing node throws too late to still return a 404.
20+
*
21+
* Resolving the node here first, before the status is set, fixes that. The
22+
* tree caches the result.
23+
*/
24+
class StreamedPropFindNotFoundPlugin extends ServerPlugin {
25+
private Server $server;
26+
27+
#[\Override]
28+
public function initialize(Server $server): void {
29+
$this->server = $server;
30+
// Higher priorities than the default handling
31+
$this->server->on('method:PROPFIND', $this->ensureNodeExists(...), 10);
32+
}
33+
34+
public function ensureNodeExists(RequestInterface $request): bool {
35+
$this->server->tree->getNodeForPath($request->getPath());
36+
return true;
37+
}
38+
}

0 commit comments

Comments
 (0)