Skip to content

Commit abf0b53

Browse files
committed
First draft for metadata-only symlinks
1 parent fd1a6f9 commit abf0b53

File tree

4 files changed

+26
-31
lines changed

4 files changed

+26
-31
lines changed

apps/dav/lib/BulkUpload/BulkUploadPlugin.php

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -100,21 +100,16 @@ public function httpPost(RequestInterface $request, ResponseInterface $response)
100100
}
101101

102102
if (isset($headers['oc-file-type']) && $headers['oc-file-type'] == 1) {
103-
// TODO: store default value in global location
104-
$allowSymlinks = \OC::$server->get(\OC\AllConfig::class)->getSystemValueBool(
105-
'localstorage.allowsymlinks', false);
106-
if (!$allowSymlinks) {
107-
throw new Forbidden("Server does not allow the creation of symlinks!");
108-
}
109103
$symlinkPath = $headers['x-file-path'];
110-
$parentNode = $this->server->tree->getNodeForPath(dirname($symlinkPath));
111-
if(!$parentNode instanceof \OCA\DAV\Connector\Sabre\Directory) {
112-
throw new Exception("Unable to upload '$symlinkPath' because the remote directory does not support symlink creation!");
113-
}
114-
$etag = $parentNode->createSymlink(basename($symlinkPath), $content);
115-
$writtenFiles[$headers['x-file-path']] = [
104+
$newEtag = "'$symlinkPath'->'$content'";
105+
$infoData = [
106+
'type' => \OC\Files\FileInfo::TYPE_SYMLINK,
107+
'etag' => $newEtag,
108+
];
109+
\OC\Files\Filesystem::getView()->putFileInfo($symlinkPath, $infoData);
110+
$writtenFiles[$symlinkPath] = [
116111
"error" => false,
117-
"etag" => $etag,
112+
"etag" => $newEtag,
118113
];
119114
continue;
120115
}

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,17 +236,18 @@ public function handleDownloadToken(RequestInterface $request, ResponseInterface
236236

237237
public function httpGet(RequestInterface $request, ResponseInterface $response) {
238238
// only handle symlinks
239-
// TODO(taminob): does not work if not in cache (which it is currently not because the path here is /files/root/path/to/symlink (request path) and the path in cache is only /root/files/path/to/symlink (internal path)); to make it work without cache, e.g. \Sabre\DAV\Server::getResourceTypeForNode would have to be extended to handle symlinks
240-
$node = $this->tree->getNodeForPath($request->getPath());
241-
if (!($node instanceof \OCA\DAV\Connector\Sabre\File)) {
239+
$symlinkPath = $request->getPath();
240+
$fileInfo = \OC\Files\Filesystem::getView()->getFileInfo($symlinkPath);
241+
if (!$fileInfo || $fileInfo->getType() !== \OC\Files\FileInfo::TYPE_SYMLINK) {
242242
return;
243243
}
244-
if ($node->getFileInfo()->getType() !== \OCP\Files\FileInfo::TYPE_SYMLINK) {
245-
return;
244+
$symlinkTarget = $fileInfo->getMetadata()['symlinkTarget'];
245+
if (isset($symlinkTarget)) {
246+
throw new NotFound("Symlink has no target!");
246247
}
247248

248249
$response->addHeader('OC-File-Type', '1');
249-
$response->setBody($node->readlink());
250+
$response->setBody($symlinkTarget);
250251
// do not continue processing this request
251252
return false;
252253
}

apps/dav/lib/Upload/ChunkingV2Plugin.php

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -145,20 +145,15 @@ public function afterMkcol(RequestInterface $request, ResponseInterface $respons
145145

146146
public function beforePut(RequestInterface $request, ResponseInterface $response): bool {
147147
if ($request->getHeader('OC-File-Type') == 1) {
148-
// TODO: store default value in global location
149-
$allowSymlinks = \OC::$server->get(\OC\AllConfig::class)->getSystemValueBool(
150-
'localstorage.allowsymlinks', false);
151-
if (!$allowSymlinks) {
152-
throw new Forbidden("Server does not allow the creation of symlinks!");
153-
}
154148
$symlinkPath = $request->getPath();
155149
$symlinkTarget = $request->getBodyAsString();
156-
$parentNode = $this->server->tree->getNodeForPath(dirname($symlinkPath));
157-
if(!$parentNode instanceof \OCA\DAV\Connector\Sabre\Directory) {
158-
throw new Exception("Unable to upload '$symlinkPath' because the remote directory does not support symlink creation!");
159-
}
160-
$etag = $parentNode->createSymlink(basename($symlinkPath), $symlinkTarget);
161-
$response->setHeader("OC-ETag", $etag);
150+
$newEtag = "'$symlinkPath'->'$symlinkTarget'";
151+
$infoData = [
152+
'type' => \OC\Files\FileInfo::TYPE_SYMLINK,
153+
'etag' => $newEtag,
154+
];
155+
\OC\Files\Filesystem::getView()->putFileInfo($symlinkPath, $infoData);
156+
$response->setHeader("OC-ETag", $newEtag);
162157
$response->setStatus(201);
163158
$this->server->sapi->sendResponse($response);
164159
return false;

lib/public/Files/FileInfo.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ interface FileInfo {
4545
* @since 7.0.0
4646
*/
4747
public const TYPE_FOLDER = 'dir';
48+
/**
49+
* @since TODO
50+
*/
51+
public const TYPE_SYMLINK = 'symlink';
4852

4953
/**
5054
* @const \OCP\Files\FileInfo::SPACE_NOT_COMPUTED Return value for a not computed space value

0 commit comments

Comments
 (0)