Skip to content

Commit

Permalink
Merge pull request #18433 from nextcloud/fix/noid/fsusage
Browse files Browse the repository at this point in the history
Use File Node API for more download cases, skip unreadable files
  • Loading branch information
blizzz authored Dec 19, 2019
2 parents aa46fc2 + af91efd commit 59402bf
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 33 deletions.
53 changes: 36 additions & 17 deletions lib/private/Streamer.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@

namespace OC;

use OC\Files\Filesystem;
use OCP\Files\File;
use OCP\Files\Folder;
use OCP\Files\InvalidPathException;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OCP\IRequest;
use ownCloud\TarStreamer\TarStreamer;
use ZipStreamer\ZipStreamer;
Expand Down Expand Up @@ -77,23 +83,25 @@ public function __construct(IRequest $request, int $size, int $numberOfFiles){
$this->streamerInstance = new ZipStreamer(['zip64' => PHP_INT_SIZE !== 4]);
}
}

/**
* Send HTTP headers
* @param string $name
* @param string $name
*/
public function sendHeaders($name){
$extension = $this->streamerInstance instanceof ZipStreamer ? '.zip' : '.tar';
$fullName = $name . $extension;
$this->streamerInstance->sendHeaders($fullName);
}

/**
* Stream directory recursively
* @param string $dir
* @param string $internalDir
*
* @throws NotFoundException
* @throws NotPermittedException
* @throws InvalidPathException
*/
public function addDirRecursive($dir, $internalDir='') {
public function addDirRecursive(string $dir, string $internalDir = ''): void {
$dirname = basename($dir);
$rootDir = $internalDir . $dirname;
if (!empty($rootDir)) {
Expand All @@ -103,22 +111,33 @@ public function addDirRecursive($dir, $internalDir='') {
// prevent absolute dirs
$internalDir = ltrim($internalDir, '/');

$files= \OC\Files\Filesystem::getDirectoryContent($dir);
$userFolder = \OC::$server->getRootFolder()->get(Filesystem::getRoot());
/** @var Folder $dirNode */
$dirNode = $userFolder->get($dir);
$files = $dirNode->getDirectoryListing();

foreach($files as $file) {
$filename = $file['name'];
$file = $dir . '/' . $filename;
if(\OC\Files\Filesystem::is_file($file)) {
$filesize = \OC\Files\Filesystem::filesize($file);
$fileTime = \OC\Files\Filesystem::filemtime($file);
$fh = \OC\Files\Filesystem::fopen($file, 'r');
$this->addFileFromStream($fh, $internalDir . $filename, $filesize, $fileTime);
if($file instanceof File) {
try {
$fh = $file->fopen('r');
} catch (NotPermittedException $e) {
continue;
}
$this->addFileFromStream(
$fh,
$internalDir . $file->getName(),
$file->getSize(),
$file->getMTime()
);
fclose($fh);
}elseif(\OC\Files\Filesystem::is_dir($file)) {
$this->addDirRecursive($file, $internalDir);
} elseif ($file instanceof Folder) {
if($file->isReadable()) {
$this->addDirRecursive($dir . '/' . $file->getName(), $internalDir);
}
}
}
}

/**
* Add a file to the archive at the specified location and file name.
*
Expand Down
50 changes: 34 additions & 16 deletions lib/private/legacy/files.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,11 @@ public static function get($dir, $files, $params = null) {
$userFolder = \OC::$server->getRootFolder()->get(\OC\Files\Filesystem::getRoot());
$file = $userFolder->get($file);
if($file instanceof \OC\Files\Node\File) {
$fh = $file->fopen('r');
try {
$fh = $file->fopen('r');
} catch (\OCP\Files\NotPermittedException $e) {
continue;
}
$fileSize = $file->getSize();
$fileTime = $file->getMTime();
} else {
Expand Down Expand Up @@ -284,30 +288,44 @@ private static function parseHttpRangeHeader($rangeHeaderPos, $fileSize) {
*/
private static function getSingleFile($view, $dir, $name, $params) {
$filename = $dir . '/' . $name;
OC_Util::obEnd();
$view->lockFile($filename, ILockingProvider::LOCK_SHARED);

$rangeArray = array();
$file = null;

if (isset($params['range']) && substr($params['range'], 0, 6) === 'bytes=') {
$rangeArray = self::parseHttpRangeHeader(substr($params['range'], 6),
\OC\Files\Filesystem::filesize($filename));
}

if (\OC\Files\Filesystem::isReadable($filename)) {
self::sendHeaders($filename, $name, $rangeArray);
} elseif (!\OC\Files\Filesystem::file_exists($filename)) {
try {
$userFolder = \OC::$server->getRootFolder()->get(\OC\Files\Filesystem::getRoot());
$file = $userFolder->get($filename);
if(!$file instanceof \OC\Files\Node\File || !$file->isReadable()) {
http_response_code(403);
die('403 Forbidden');
}
$fileSize = $file->getSize();
} catch (\OCP\Files\NotPermittedException $e) {
http_response_code(403);
die('403 Forbidden');
} catch (\OCP\Files\InvalidPathException $e) {
http_response_code(403);
die('403 Forbidden');
} catch (\OCP\Files\NotFoundException $e) {
http_response_code(404);
$tmpl = new OC_Template('', '404', 'guest');
$tmpl->printPage();
exit();
} else {
http_response_code(403);
die('403 Forbidden');
}

OC_Util::obEnd();
$view->lockFile($filename, ILockingProvider::LOCK_SHARED);

$rangeArray = array();

if (isset($params['range']) && substr($params['range'], 0, 6) === 'bytes=') {
$rangeArray = self::parseHttpRangeHeader(substr($params['range'], 6), $fileSize);
}

self::sendHeaders($filename, $name, $rangeArray);

if (isset($params['head']) && $params['head']) {
return;
}

if (!empty($rangeArray)) {
try {
if (count($rangeArray) == 1) {
Expand Down

0 comments on commit 59402bf

Please sign in to comment.