Skip to content

Commit

Permalink
First draft for metadata-only symlinks
Browse files Browse the repository at this point in the history
  • Loading branch information
taminob committed Nov 15, 2023
1 parent fd1a6f9 commit abf0b53
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 31 deletions.
21 changes: 8 additions & 13 deletions apps/dav/lib/BulkUpload/BulkUploadPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,21 +100,16 @@ public function httpPost(RequestInterface $request, ResponseInterface $response)
}

if (isset($headers['oc-file-type']) && $headers['oc-file-type'] == 1) {
// TODO: store default value in global location
$allowSymlinks = \OC::$server->get(\OC\AllConfig::class)->getSystemValueBool(
'localstorage.allowsymlinks', false);
if (!$allowSymlinks) {
throw new Forbidden("Server does not allow the creation of symlinks!");
}
$symlinkPath = $headers['x-file-path'];
$parentNode = $this->server->tree->getNodeForPath(dirname($symlinkPath));
if(!$parentNode instanceof \OCA\DAV\Connector\Sabre\Directory) {
throw new Exception("Unable to upload '$symlinkPath' because the remote directory does not support symlink creation!");
}
$etag = $parentNode->createSymlink(basename($symlinkPath), $content);
$writtenFiles[$headers['x-file-path']] = [
$newEtag = "'$symlinkPath'->'$content'";
$infoData = [
'type' => \OC\Files\FileInfo::TYPE_SYMLINK,
'etag' => $newEtag,
];
\OC\Files\Filesystem::getView()->putFileInfo($symlinkPath, $infoData);
$writtenFiles[$symlinkPath] = [
"error" => false,
"etag" => $etag,
"etag" => $newEtag,
];
continue;
}
Expand Down
13 changes: 7 additions & 6 deletions apps/dav/lib/Connector/Sabre/FilesPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -236,17 +236,18 @@ public function handleDownloadToken(RequestInterface $request, ResponseInterface

public function httpGet(RequestInterface $request, ResponseInterface $response) {
// only handle symlinks
// 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
$node = $this->tree->getNodeForPath($request->getPath());
if (!($node instanceof \OCA\DAV\Connector\Sabre\File)) {
$symlinkPath = $request->getPath();
$fileInfo = \OC\Files\Filesystem::getView()->getFileInfo($symlinkPath);
if (!$fileInfo || $fileInfo->getType() !== \OC\Files\FileInfo::TYPE_SYMLINK) {
return;
}
if ($node->getFileInfo()->getType() !== \OCP\Files\FileInfo::TYPE_SYMLINK) {
return;
$symlinkTarget = $fileInfo->getMetadata()['symlinkTarget'];
if (isset($symlinkTarget)) {
throw new NotFound("Symlink has no target!");
}

$response->addHeader('OC-File-Type', '1');
$response->setBody($node->readlink());
$response->setBody($symlinkTarget);
// do not continue processing this request
return false;
}
Expand Down
19 changes: 7 additions & 12 deletions apps/dav/lib/Upload/ChunkingV2Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,20 +145,15 @@ public function afterMkcol(RequestInterface $request, ResponseInterface $respons

public function beforePut(RequestInterface $request, ResponseInterface $response): bool {
if ($request->getHeader('OC-File-Type') == 1) {
// TODO: store default value in global location
$allowSymlinks = \OC::$server->get(\OC\AllConfig::class)->getSystemValueBool(
'localstorage.allowsymlinks', false);
if (!$allowSymlinks) {
throw new Forbidden("Server does not allow the creation of symlinks!");
}
$symlinkPath = $request->getPath();
$symlinkTarget = $request->getBodyAsString();
$parentNode = $this->server->tree->getNodeForPath(dirname($symlinkPath));
if(!$parentNode instanceof \OCA\DAV\Connector\Sabre\Directory) {
throw new Exception("Unable to upload '$symlinkPath' because the remote directory does not support symlink creation!");
}
$etag = $parentNode->createSymlink(basename($symlinkPath), $symlinkTarget);
$response->setHeader("OC-ETag", $etag);
$newEtag = "'$symlinkPath'->'$symlinkTarget'";
$infoData = [
'type' => \OC\Files\FileInfo::TYPE_SYMLINK,
'etag' => $newEtag,
];
\OC\Files\Filesystem::getView()->putFileInfo($symlinkPath, $infoData);
$response->setHeader("OC-ETag", $newEtag);
$response->setStatus(201);
$this->server->sapi->sendResponse($response);
return false;
Expand Down
4 changes: 4 additions & 0 deletions lib/public/Files/FileInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ interface FileInfo {
* @since 7.0.0
*/
public const TYPE_FOLDER = 'dir';
/**
* @since TODO
*/
public const TYPE_SYMLINK = 'symlink';

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

0 comments on commit abf0b53

Please sign in to comment.