mirror of
https://github.com/nextcloud/server.git
synced 2026-04-15 22:11:17 -04:00
Merge pull request #52890 from nextcloud/chore/move-stream-copy-implementation
chore: move streamCopy implementation from `OC_Helper` to `OCP\Files`
This commit is contained in:
commit
e2a331f53d
11 changed files with 81 additions and 44 deletions
|
|
@ -19,6 +19,7 @@ use OCA\DAV\Connector\Sabre\Exception\Forbidden as DAVForbiddenException;
|
|||
use OCA\DAV\Connector\Sabre\Exception\UnsupportedMediaType;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\Encryption\Exceptions\GenericEncryptionException;
|
||||
use OCP\Files;
|
||||
use OCP\Files\EntityTooLargeException;
|
||||
use OCP\Files\FileInfo;
|
||||
use OCP\Files\ForbiddenException;
|
||||
|
|
@ -229,7 +230,7 @@ class File extends Node implements IFile {
|
|||
// because we have no clue about the cause we can only throw back a 500/Internal Server Error
|
||||
throw new Exception($this->l10n->t('Could not write file contents'));
|
||||
}
|
||||
[$count, $result] = \OC_Helper::streamCopy($data, $target);
|
||||
[$count, $result] = Files::streamCopy($data, $target, true);
|
||||
fclose($target);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ use OCA\Files_Versions\Versions\IVersionManager;
|
|||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\Command\IBus;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files;
|
||||
use OCP\Files\FileInfo;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\Files\IMimeTypeDetector;
|
||||
|
|
@ -32,6 +33,7 @@ use OCP\Files\NotFoundException;
|
|||
use OCP\Files\NotPermittedException;
|
||||
use OCP\Files\Search\ISearchBinaryOperator;
|
||||
use OCP\Files\Search\ISearchComparison;
|
||||
use OCP\Files\Storage\IWriteStreamStorage;
|
||||
use OCP\Files\StorageInvalidException;
|
||||
use OCP\Files\StorageNotAvailableException;
|
||||
use OCP\IURLGenerator;
|
||||
|
|
@ -416,12 +418,25 @@ class Storage {
|
|||
|
||||
try {
|
||||
// TODO add a proper way of overwriting a file while maintaining file ids
|
||||
if ($storage1->instanceOfStorage('\OC\Files\ObjectStore\ObjectStoreStorage') || $storage2->instanceOfStorage('\OC\Files\ObjectStore\ObjectStoreStorage')) {
|
||||
if ($storage1->instanceOfStorage(\OC\Files\ObjectStore\ObjectStoreStorage::class)
|
||||
|| $storage2->instanceOfStorage(\OC\Files\ObjectStore\ObjectStoreStorage::class)
|
||||
) {
|
||||
$source = $storage1->fopen($internalPath1, 'r');
|
||||
$target = $storage2->fopen($internalPath2, 'w');
|
||||
[, $result] = \OC_Helper::streamCopy($source, $target);
|
||||
fclose($source);
|
||||
fclose($target);
|
||||
$result = $source !== false;
|
||||
if ($result) {
|
||||
if ($storage2->instanceOfStorage(IWriteStreamStorage::class)) {
|
||||
/** @var IWriteStreamStorage $storage2 */
|
||||
$storage2->writeStream($internalPath2, $source);
|
||||
} else {
|
||||
$target = $storage2->fopen($internalPath2, 'w');
|
||||
$result = $target !== false;
|
||||
if ($target !== false) {
|
||||
[, $result] = Files::streamCopy($source, $target, true);
|
||||
fclose($target);
|
||||
}
|
||||
}
|
||||
fclose($source);
|
||||
}
|
||||
|
||||
if ($result !== false) {
|
||||
$storage1->unlink($internalPath1);
|
||||
|
|
|
|||
|
|
@ -675,6 +675,12 @@
|
|||
</ParamNameMismatch>
|
||||
</file>
|
||||
<file src="apps/dav/lib/Connector/Sabre/File.php">
|
||||
<DeprecatedClass>
|
||||
<code><![CDATA[Files::streamCopy($data, $target, true)]]></code>
|
||||
</DeprecatedClass>
|
||||
<DeprecatedMethod>
|
||||
<code><![CDATA[Files::streamCopy($data, $target, true)]]></code>
|
||||
</DeprecatedMethod>
|
||||
<LessSpecificReturnStatement>
|
||||
<code><![CDATA[$this->node]]></code>
|
||||
</LessSpecificReturnStatement>
|
||||
|
|
@ -1964,14 +1970,13 @@
|
|||
</file>
|
||||
<file src="apps/files_versions/lib/Storage.php">
|
||||
<DeprecatedClass>
|
||||
<code><![CDATA[Files::streamCopy($source, $target, true)]]></code>
|
||||
<code><![CDATA[\OC_Util::setupFS($uid)]]></code>
|
||||
</DeprecatedClass>
|
||||
<DeprecatedMethod>
|
||||
<code><![CDATA[Files::streamCopy($source, $target, true)]]></code>
|
||||
<code><![CDATA[dispatch]]></code>
|
||||
</DeprecatedMethod>
|
||||
<RedundantCondition>
|
||||
<code><![CDATA[$storage1->instanceOfStorage('\OC\Files\ObjectStore\ObjectStoreStorage')]]></code>
|
||||
</RedundantCondition>
|
||||
</file>
|
||||
<file src="apps/oauth2/lib/Controller/OauthApiController.php">
|
||||
<NoInterfaceProperties>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ use OC\Files\ObjectStore\ObjectStoreStorage;
|
|||
use OC\Files\Storage\Wrapper\Encryption;
|
||||
use OC\Files\Storage\Wrapper\Jail;
|
||||
use OC\Files\Storage\Wrapper\Wrapper;
|
||||
use OCP\Files;
|
||||
use OCP\Files\Cache\ICache;
|
||||
use OCP\Files\Cache\IPropagator;
|
||||
use OCP\Files\Cache\IScanner;
|
||||
|
|
@ -205,7 +206,7 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage,
|
|||
} else {
|
||||
$sourceStream = $this->fopen($source, 'r');
|
||||
$targetStream = $this->fopen($target, 'w');
|
||||
[, $result] = \OC_Helper::streamCopy($sourceStream, $targetStream);
|
||||
[, $result] = Files::streamCopy($sourceStream, $targetStream, true);
|
||||
if (!$result) {
|
||||
Server::get(LoggerInterface::class)->warning("Failed to write data while copying $source to $target");
|
||||
}
|
||||
|
|
@ -734,7 +735,7 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage,
|
|||
throw new GenericFileException("Failed to open $path for writing");
|
||||
}
|
||||
try {
|
||||
[$count, $result] = \OC_Helper::streamCopy($stream, $target);
|
||||
[$count, $result] = Files::streamCopy($stream, $target, true);
|
||||
if (!$result) {
|
||||
throw new GenericFileException('Failed to copy stream');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
*/
|
||||
namespace OC\Files\Storage;
|
||||
|
||||
use OCP\Files;
|
||||
|
||||
/**
|
||||
* Storage backend class for providing common filesystem operation methods
|
||||
* which are not storage-backend specific.
|
||||
|
|
@ -45,7 +47,7 @@ trait LocalTempFileTrait {
|
|||
}
|
||||
$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($extension);
|
||||
$target = fopen($tmpFile, 'w');
|
||||
\OC_Helper::streamCopy($source, $target);
|
||||
Files::streamCopy($source, $target);
|
||||
fclose($target);
|
||||
return $tmpFile;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ use OCP\Encryption\Exceptions\InvalidHeaderException;
|
|||
use OCP\Encryption\IFile;
|
||||
use OCP\Encryption\IManager;
|
||||
use OCP\Encryption\Keys\IStorage;
|
||||
use OCP\Files;
|
||||
use OCP\Files\Cache\ICacheEntry;
|
||||
use OCP\Files\Mount\IMountPoint;
|
||||
use OCP\Files\Storage;
|
||||
|
|
@ -684,7 +685,7 @@ class Encryption extends Wrapper {
|
|||
try {
|
||||
$source = $sourceStorage->fopen($sourceInternalPath, 'r');
|
||||
$target = $this->fopen($targetInternalPath, 'w');
|
||||
[, $result] = \OC_Helper::streamCopy($source, $target);
|
||||
[, $result] = Files::streamCopy($source, $target, true);
|
||||
} finally {
|
||||
if (is_resource($source)) {
|
||||
fclose($source);
|
||||
|
|
@ -893,7 +894,7 @@ class Encryption extends Wrapper {
|
|||
public function writeStream(string $path, $stream, ?int $size = null): int {
|
||||
// always fall back to fopen
|
||||
$target = $this->fopen($path, 'w');
|
||||
[$count, $result] = \OC_Helper::streamCopy($stream, $target);
|
||||
[$count, $result] = Files::streamCopy($stream, $target, true);
|
||||
fclose($stream);
|
||||
fclose($target);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use OC\Files\Cache\Wrapper\CacheJail;
|
|||
use OC\Files\Cache\Wrapper\JailPropagator;
|
||||
use OC\Files\Cache\Wrapper\JailWatcher;
|
||||
use OC\Files\Filesystem;
|
||||
use OCP\Files;
|
||||
use OCP\Files\Cache\ICache;
|
||||
use OCP\Files\Cache\IPropagator;
|
||||
use OCP\Files\Cache\IWatcher;
|
||||
|
|
@ -253,7 +254,7 @@ class Jail extends Wrapper {
|
|||
return $storage->writeStream($this->getUnjailedPath($path), $stream, $size);
|
||||
} else {
|
||||
$target = $this->fopen($path, 'w');
|
||||
[$count, $result] = \OC_Helper::streamCopy($stream, $target);
|
||||
$count = Files::streamCopy($stream, $target);
|
||||
fclose($stream);
|
||||
fclose($target);
|
||||
return $count;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ namespace OC\Files\Storage\Wrapper;
|
|||
|
||||
use OC\Files\Storage\FailedStorage;
|
||||
use OC\Files\Storage\Storage;
|
||||
use OCP\Files;
|
||||
use OCP\Files\Cache\ICache;
|
||||
use OCP\Files\Cache\IPropagator;
|
||||
use OCP\Files\Cache\IScanner;
|
||||
|
|
@ -322,7 +323,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage, IWriteStrea
|
|||
return $storage->writeStream($path, $stream, $size);
|
||||
} else {
|
||||
$target = $this->fopen($path, 'w');
|
||||
[$count, $result] = \OC_Helper::streamCopy($stream, $target);
|
||||
$count = Files::streamCopy($stream, $target);
|
||||
fclose($stream);
|
||||
fclose($target);
|
||||
return $count;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ use OC\User\Manager as UserManager;
|
|||
use OC\User\User;
|
||||
use OCA\Files_Sharing\SharedMount;
|
||||
use OCP\Constants;
|
||||
use OCP\Files;
|
||||
use OCP\Files\Cache\ICacheEntry;
|
||||
use OCP\Files\ConnectionLostException;
|
||||
use OCP\Files\EmptyFileNameException;
|
||||
|
|
@ -629,7 +630,7 @@ class View {
|
|||
[$storage, $internalPath] = $this->resolvePath($path);
|
||||
$target = $storage->fopen($internalPath, 'w');
|
||||
if ($target) {
|
||||
[, $result] = \OC_Helper::streamCopy($data, $target);
|
||||
[, $result] = Files::streamCopy($data, $target, true);
|
||||
fclose($target);
|
||||
fclose($data);
|
||||
|
||||
|
|
|
|||
|
|
@ -123,31 +123,10 @@ class OC_Helper {
|
|||
* @param resource $source
|
||||
* @param resource $target
|
||||
* @return array the number of bytes copied and result
|
||||
* @deprecated 5.0.0 - Use \OCP\Files::streamCopy
|
||||
*/
|
||||
public static function streamCopy($source, $target) {
|
||||
if (!$source or !$target) {
|
||||
return [0, false];
|
||||
}
|
||||
$bufSize = 8192;
|
||||
$result = true;
|
||||
$count = 0;
|
||||
while (!feof($source)) {
|
||||
$buf = fread($source, $bufSize);
|
||||
$bytesWritten = fwrite($target, $buf);
|
||||
if ($bytesWritten !== false) {
|
||||
$count += $bytesWritten;
|
||||
}
|
||||
// note: strlen is expensive so only use it when necessary,
|
||||
// on the last block
|
||||
if ($bytesWritten === false
|
||||
|| ($bytesWritten < $bufSize && $bytesWritten < strlen($buf))
|
||||
) {
|
||||
// write error, could be disk full ?
|
||||
$result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return [$count, $result];
|
||||
return \OCP\Files::streamCopy($source, $target, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -85,15 +85,45 @@ class Files {
|
|||
|
||||
/**
|
||||
* Copy the contents of one stream to another
|
||||
*
|
||||
* @template T of null|true
|
||||
* @param resource $source
|
||||
* @param resource $target
|
||||
* @return int the number of bytes copied
|
||||
* @param T $includeResult
|
||||
* @return int|array
|
||||
* @psalm-return (T is true ? array{0: int, 1: bool} : int)
|
||||
* @since 5.0.0
|
||||
* @since 32.0.0 added $includeResult parameter
|
||||
* @deprecated 14.0.0
|
||||
*/
|
||||
public static function streamCopy($source, $target) {
|
||||
[$count, ] = \OC_Helper::streamCopy($source, $target);
|
||||
return $count;
|
||||
public static function streamCopy($source, $target, ?bool $includeResult = null) {
|
||||
if (!$source or !$target) {
|
||||
return $includeResult ? [0, false] : 0;
|
||||
}
|
||||
|
||||
$bufSize = 8192;
|
||||
$count = 0;
|
||||
$result = true;
|
||||
while (!feof($source)) {
|
||||
$buf = fread($source, $bufSize);
|
||||
if ($buf === false) {
|
||||
$result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
$bytesWritten = fwrite($target, $buf);
|
||||
if ($bytesWritten !== false) {
|
||||
$count += $bytesWritten;
|
||||
}
|
||||
|
||||
if ($bytesWritten === false
|
||||
|| ($bytesWritten < $bufSize && $bytesWritten < strlen($buf))
|
||||
) {
|
||||
$result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $includeResult ? [$count, $result] : $count;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue