]> source.dussan.org Git - nextcloud-server.git/commitdiff
Add dav plugin to trigger recalculating of checksums 27378/head
authorRobin Appelman <robin@icewind.nl>
Fri, 4 Jun 2021 14:22:39 +0000 (16:22 +0200)
committerRobin Appelman <robin@icewind.nl>
Mon, 23 Aug 2021 13:38:58 +0000 (15:38 +0200)
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 13e78cee716453e667ac5b3aa3fc2f4d92a9689a..4814b52f023861659e7bf52be2901db4aed3c33f 100644 (file)
@@ -140,6 +140,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 42ba59e0582e246760240eb61d7c55bd14608c62..48db722ee033ef44080c14d80532cd3213bcbe7d 100644 (file)
@@ -155,6 +155,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 5ff5f831eb50b9251f01d5fba1aa2f87bb549a26..6bb30591d957a23043b0c2c8b4c164f8e0068952 100644 (file)
@@ -343,11 +343,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("Failed to check file size: " . $e->getMessage(), 0, $e);
@@ -688,9 +686,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 7be24014881c9ee47bbfb4d608217b42710f5910..e74fbbf47cf66fd5330d876ba3188ac8491de591 100644 (file)
@@ -177,6 +177,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 e9634f670d3acd3ce23725a04bd92a0ca2a7b9fd..a0ab68813acdf3f045372c5b5e26a0147d2267a7 100644 (file)
@@ -46,6 +46,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;
@@ -243,6 +244,7 @@ class Server {
                                                !\OC::$server->getConfig()->getSystemValue('debug', false)
                                        )
                                );
+                               $this->server->addPlugin(new ChecksumUpdatePlugin());
 
                                $this->server->addPlugin(
                                        new \Sabre\DAV\PropertyStorage\Plugin(
index 113290e2686fb98ce8d16ccf66cee1b63b9545fb..cafa6952a623888b54a53dca6254bcec8e2bc6a6 100644 (file)
@@ -1082,7 +1082,7 @@ class View {
         * @param string $type
         * @param string $path
         * @param bool $raw
-        * @return bool|null|string
+        * @return bool|string
         */
        public function hash($type, $path, $raw = false) {
                $postFix = (substr($path, -1) === '/') ? '/' : '';
@@ -1099,12 +1099,13 @@ 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);
                        }
                }
-               return null;
+               return false;
        }
 
        /**