]> source.dussan.org Git - nextcloud-server.git/commitdiff
Add dav plugin to trigger recalculating of checksums 29510/head
authorRobin Appelman <robin@icewind.nl>
Fri, 4 Jun 2021 14:22:39 +0000 (16:22 +0200)
committerVincent Petry (Rebase PR Action) <PVince81@users.noreply.github.com>
Thu, 31 Mar 2022 07:44:13 +0000 (07:44 +0000)
Signed-off-by: Robin Appelman <robin@icewind.nl>
apps/dav/composer/composer/autoload_classmap.php
apps/dav/composer/composer/autoload_static.php
apps/dav/lib/Connector/Sabre/ChecksumUpdatePlugin.php [new file with mode: 0644]
apps/dav/lib/Connector/Sabre/File.php
apps/dav/lib/Connector/Sabre/ServerFactory.php
apps/dav/lib/Server.php
lib/private/Files/View.php

index cf02a3221fbe0bfd949527c984e4c8da057a487a..834b6de9a9c58eac9f1e231f8c67f65f4bdad2e7 100644 (file)
@@ -145,6 +145,7 @@ return array(
     'OCA\\DAV\\Connector\\Sabre\\BlockLegacyClientPlugin' => $baseDir . '/../lib/Connector/Sabre/BlockLegacyClientPlugin.php',
     'OCA\\DAV\\Connector\\Sabre\\CachingTree' => $baseDir . '/../lib/Connector/Sabre/CachingTree.php',
     'OCA\\DAV\\Connector\\Sabre\\ChecksumList' => $baseDir . '/../lib/Connector/Sabre/ChecksumList.php',
+    'OCA\\DAV\\Connector\\Sabre\\ChecksumUpdatePlugin' => $baseDir . '/../lib/Connector/Sabre/ChecksumUpdatePlugin.php',
     'OCA\\DAV\\Connector\\Sabre\\CommentPropertiesPlugin' => $baseDir . '/../lib/Connector/Sabre/CommentPropertiesPlugin.php',
     'OCA\\DAV\\Connector\\Sabre\\CopyEtagHeaderPlugin' => $baseDir . '/../lib/Connector/Sabre/CopyEtagHeaderPlugin.php',
     'OCA\\DAV\\Connector\\Sabre\\DavAclPlugin' => $baseDir . '/../lib/Connector/Sabre/DavAclPlugin.php',
index d164ab2b1ce712d50d68c18118e8ef0964fc6d49..e84a93b2865ee52fee9a3438c3fcde408f127a9f 100644 (file)
@@ -160,6 +160,7 @@ class ComposerStaticInitDAV
         'OCA\\DAV\\Connector\\Sabre\\BlockLegacyClientPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/BlockLegacyClientPlugin.php',
         'OCA\\DAV\\Connector\\Sabre\\CachingTree' => __DIR__ . '/..' . '/../lib/Connector/Sabre/CachingTree.php',
         'OCA\\DAV\\Connector\\Sabre\\ChecksumList' => __DIR__ . '/..' . '/../lib/Connector/Sabre/ChecksumList.php',
+        'OCA\\DAV\\Connector\\Sabre\\ChecksumUpdatePlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/ChecksumUpdatePlugin.php',
         'OCA\\DAV\\Connector\\Sabre\\CommentPropertiesPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/CommentPropertiesPlugin.php',
         'OCA\\DAV\\Connector\\Sabre\\CopyEtagHeaderPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/CopyEtagHeaderPlugin.php',
         'OCA\\DAV\\Connector\\Sabre\\DavAclPlugin' => __DIR__ . '/..' . '/../lib/Connector/Sabre/DavAclPlugin.php',
diff --git a/apps/dav/lib/Connector/Sabre/ChecksumUpdatePlugin.php b/apps/dav/lib/Connector/Sabre/ChecksumUpdatePlugin.php
new file mode 100644 (file)
index 0000000..3247259
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2021 Robin Appelman <robin@icewind.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\DAV\Connector\Sabre;
+
+use Sabre\DAV\ServerPlugin;
+use Sabre\HTTP\RequestInterface;
+use Sabre\HTTP\ResponseInterface;
+
+class ChecksumUpdatePlugin extends ServerPlugin {
+       /**
+        * @var \Sabre\DAV\Server
+        */
+       protected $server;
+
+       public function initialize(\Sabre\DAV\Server $server) {
+               $this->server = $server;
+               $server->on('method:PATCH', [$this, 'httpPatch']);
+       }
+
+       public function getPluginName(): string {
+               return 'checksumupdate';
+       }
+
+       public function getHTTPMethods($path): array {
+               $tree = $this->server->tree;
+
+               if ($tree->nodeExists($path)) {
+                       $node = $tree->getNodeForPath($path);
+                       if ($node instanceof File) {
+                               return ['PATCH'];
+                       }
+               }
+
+               return [];
+       }
+
+       public function getFeatures(): array {
+               return ['nextcloud-checksum-update'];
+       }
+
+       public function httpPatch(RequestInterface $request, ResponseInterface $response) {
+               $path = $request->getPath();
+
+               $node = $this->server->tree->getNodeForPath($path);
+               if ($node instanceof File) {
+                       $type = strtolower(
+                               (string)$request->getHeader('X-Recalculate-Hash')
+                       );
+
+                       $hash = $node->hash($type);
+                       if ($hash) {
+                               $checksum = strtoupper($type) . ':' . $hash;
+                               $node->setChecksum($checksum);
+                               $response->addHeader('OC-Checksum', $checksum);
+                               $response->setHeader('Content-Length', '0');
+                               $response->setStatus(204);
+
+                               return false;
+                       }
+               }
+       }
+}
index 4768fc3dc44ebf37ed44e998c94f2ba4724c9345..70dffbaaaed1369450cdf66501e497fd2ded3acc 100644 (file)
@@ -388,11 +388,9 @@ class File extends Node implements IFile {
 
                        if (isset($this->request->server['HTTP_OC_CHECKSUM'])) {
                                $checksum = trim($this->request->server['HTTP_OC_CHECKSUM']);
-                               $this->fileView->putFileInfo($this->path, ['checksum' => $checksum]);
-                               $this->refreshInfo();
+                               $this->setChecksum($checksum);
                        } elseif ($this->getChecksum() !== null && $this->getChecksum() !== '') {
-                               $this->fileView->putFileInfo($this->path, ['checksum' => '']);
-                               $this->refreshInfo();
+                               $this->setChecksum('');
                        }
                } catch (StorageNotAvailableException $e) {
                        throw new ServiceUnavailable($this->l10n->t('Failed to check file size: %1$s', [$e->getMessage()]), 0, $e);
@@ -741,9 +739,18 @@ class File extends Node implements IFile {
                return $this->info->getChecksum();
        }
 
+       public function setChecksum(string $checksum) {
+               $this->fileView->putFileInfo($this->path, ['checksum' => $checksum]);
+               $this->refreshInfo();
+       }
+
        protected function header($string) {
                if (!\OC::$CLI) {
                        \header($string);
                }
        }
+
+       public function hash(string $type) {
+               return $this->fileView->hash($type, $this->path);
+       }
 }
index 095fb631c2b3e66115827b5327b13ff468f9aa17..b13dbd20ca9f2f41eff3002fe8abf6b837839b77 100644 (file)
@@ -180,6 +180,7 @@ class ServerFactory {
                                )
                        );
                        $server->addPlugin(new \OCA\DAV\Connector\Sabre\QuotaPlugin($view, true));
+                       $server->addPlugin(new \OCA\DAV\Connector\Sabre\ChecksumUpdatePlugin());
 
                        if ($this->userSession->isLoggedIn()) {
                                $server->addPlugin(new \OCA\DAV\Connector\Sabre\TagsPlugin($objectTree, $this->tagManager));
index 759d39c02339d7a43b63555416fb84be0e9a48aa..ef8c8eea558b7eb64a78d6a594b0c6660c7e9345 100644 (file)
@@ -49,6 +49,7 @@ use OCA\DAV\Connector\Sabre\Auth;
 use OCA\DAV\Connector\Sabre\BearerAuth;
 use OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin;
 use OCA\DAV\Connector\Sabre\CachingTree;
+use OCA\DAV\Connector\Sabre\ChecksumUpdatePlugin;
 use OCA\DAV\Connector\Sabre\CommentPropertiesPlugin;
 use OCA\DAV\Connector\Sabre\CopyEtagHeaderPlugin;
 use OCA\DAV\Connector\Sabre\DavAclPlugin;
@@ -247,6 +248,7 @@ class Server {
                                                !\OC::$server->getConfig()->getSystemValue('debug', false)
                                        )
                                );
+                               $this->server->addPlugin(new ChecksumUpdatePlugin());
 
                                $this->server->addPlugin(
                                        new \Sabre\DAV\PropertyStorage\Plugin(
index 779e0611591fe178f2d5f80ead0af825667fa119..d80ae041d5790c36ae8fd0a264b7966966ecaa48 100644 (file)
@@ -1099,6 +1099,7 @@ class View {
                                        [Filesystem::signal_param_path => $this->getHookPath($path)]
                                );
                        }
+                       /** @var Storage|null $storage */
                        [$storage, $internalPath] = Filesystem::resolvePath($absolutePath . $postFix);
                        if ($storage) {
                                return $storage->hash($type, $internalPath, $raw);