Merge pull request #2925 from nextcloud/remove-close-wrapper
replace close:// streamwrapper with CallBackWrapper
This commit is contained in:
commit
b847dfcee9
|
@ -42,6 +42,7 @@ require_once 'aws-autoloader.php';
|
|||
|
||||
use Aws\S3\S3Client;
|
||||
use Aws\S3\Exception\S3Exception;
|
||||
use Icewind\Streams\CallbackWrapper;
|
||||
use Icewind\Streams\IteratorDirectory;
|
||||
use OC\Files\ObjectStore\S3ConnectionTrait;
|
||||
|
||||
|
@ -366,14 +367,15 @@ class AmazonS3 extends \OC\Files\Storage\Common {
|
|||
$ext = '';
|
||||
}
|
||||
$tmpFile = \OCP\Files::tmpFile($ext);
|
||||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
|
||||
if ($this->file_exists($path)) {
|
||||
$source = $this->fopen($path, 'r');
|
||||
file_put_contents($tmpFile, $source);
|
||||
}
|
||||
self::$tmpFiles[$tmpFile] = $path;
|
||||
|
||||
return fopen('close://' . $tmpFile, $mode);
|
||||
$handle = fopen($tmpFile, $mode);
|
||||
return CallbackWrapper::wrap($handle, null, null, function() use ($path, $tmpFile) {
|
||||
$this->writeBack($tmpFile, $path);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -514,15 +516,11 @@ class AmazonS3 extends \OC\Files\Storage\Common {
|
|||
return $this->id;
|
||||
}
|
||||
|
||||
public function writeBack($tmpFile) {
|
||||
if (!isset(self::$tmpFiles[$tmpFile])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function writeBack($tmpFile, $path) {
|
||||
try {
|
||||
$this->getConnection()->putObject(array(
|
||||
'Bucket' => $this->bucket,
|
||||
'Key' => $this->cleanKey(self::$tmpFiles[$tmpFile]),
|
||||
'Key' => $this->cleanKey($path),
|
||||
'SourceFile' => $tmpFile,
|
||||
'ContentType' => \OC::$server->getMimeTypeDetector()->detect($tmpFile),
|
||||
'ContentLength' => filesize($tmpFile)
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
namespace OCA\Files_External\Lib\Storage;
|
||||
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use Icewind\Streams\CallbackWrapper;
|
||||
use Icewind\Streams\IteratorDirectory;
|
||||
use Icewind\Streams\RetryWrapper;
|
||||
use OCP\Files\StorageNotAvailableException;
|
||||
|
@ -45,8 +46,6 @@ class Dropbox extends \OC\Files\Storage\Common {
|
|||
private $metaData = array();
|
||||
private $oauth;
|
||||
|
||||
private static $tempFiles = array();
|
||||
|
||||
public function __construct($params) {
|
||||
if (isset($params['configured']) && $params['configured'] == 'true'
|
||||
&& isset($params['app_key'])
|
||||
|
@ -305,27 +304,26 @@ class Dropbox extends \OC\Files\Storage\Common {
|
|||
$ext = '';
|
||||
}
|
||||
$tmpFile = \OCP\Files::tmpFile($ext);
|
||||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
|
||||
if ($this->file_exists($path)) {
|
||||
$source = $this->fopen($path, 'r');
|
||||
file_put_contents($tmpFile, $source);
|
||||
}
|
||||
self::$tempFiles[$tmpFile] = $path;
|
||||
return fopen('close://'.$tmpFile, $mode);
|
||||
$handle = fopen($tmpFile, $mode);
|
||||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
|
||||
$this->writeBack($tmpFile, $path);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function writeBack($tmpFile) {
|
||||
if (isset(self::$tempFiles[$tmpFile])) {
|
||||
$handle = fopen($tmpFile, 'r');
|
||||
try {
|
||||
$this->dropbox->putFile(self::$tempFiles[$tmpFile], $handle);
|
||||
unlink($tmpFile);
|
||||
$this->deleteMetaData(self::$tempFiles[$tmpFile]);
|
||||
} catch (\Exception $exception) {
|
||||
\OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR);
|
||||
}
|
||||
public function writeBack($tmpFile, $path) {
|
||||
$handle = fopen($tmpFile, 'r');
|
||||
try {
|
||||
$this->dropbox->putFile($path, $handle);
|
||||
unlink($tmpFile);
|
||||
$this->deleteMetaData($path);
|
||||
} catch (\Exception $exception) {
|
||||
\OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
namespace OCA\Files_External\Lib\Storage;
|
||||
|
||||
use Icewind\Streams\CallbackWrapper;
|
||||
use Icewind\Streams\RetryWrapper;
|
||||
|
||||
class FTP extends StreamWrapper{
|
||||
|
@ -127,21 +128,20 @@ class FTP extends StreamWrapper{
|
|||
$ext='';
|
||||
}
|
||||
$tmpFile=\OCP\Files::tmpFile($ext);
|
||||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
|
||||
if ($this->file_exists($path)) {
|
||||
$this->getFile($path, $tmpFile);
|
||||
}
|
||||
self::$tempFiles[$tmpFile]=$path;
|
||||
return fopen('close://'.$tmpFile, $mode);
|
||||
$handle = fopen($tmpFile, $mode);
|
||||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
|
||||
$this->writeBack($tmpFile, $path);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function writeBack($tmpFile) {
|
||||
if (isset(self::$tempFiles[$tmpFile])) {
|
||||
$this->uploadFile($tmpFile, self::$tempFiles[$tmpFile]);
|
||||
unlink($tmpFile);
|
||||
}
|
||||
public function writeBack($tmpFile, $path) {
|
||||
$this->uploadFile($tmpFile, $path);
|
||||
unlink($tmpFile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
namespace OCA\Files_External\Lib\Storage;
|
||||
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use Icewind\Streams\CallbackWrapper;
|
||||
use Icewind\Streams\IteratorDirectory;
|
||||
use Icewind\Streams\RetryWrapper;
|
||||
|
||||
|
@ -50,8 +51,6 @@ class Google extends \OC\Files\Storage\Common {
|
|||
private $service;
|
||||
private $driveFiles;
|
||||
|
||||
private static $tempFiles = array();
|
||||
|
||||
// Google Doc mimetypes
|
||||
const FOLDER = 'application/vnd.google-apps.folder';
|
||||
const DOCUMENT = 'application/vnd.google-apps.document';
|
||||
|
@ -495,94 +494,91 @@ class Google extends \OC\Files\Storage\Common {
|
|||
case 'c':
|
||||
case 'c+':
|
||||
$tmpFile = \OCP\Files::tmpFile($ext);
|
||||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
|
||||
if ($this->file_exists($path)) {
|
||||
$source = $this->fopen($path, 'rb');
|
||||
file_put_contents($tmpFile, $source);
|
||||
}
|
||||
self::$tempFiles[$tmpFile] = $path;
|
||||
return fopen('close://'.$tmpFile, $mode);
|
||||
$handle = fopen($tmpFile, $mode);
|
||||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
|
||||
$this->writeBack($tmpFile, $path);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function writeBack($tmpFile) {
|
||||
if (isset(self::$tempFiles[$tmpFile])) {
|
||||
$path = self::$tempFiles[$tmpFile];
|
||||
$parentFolder = $this->getDriveFile(dirname($path));
|
||||
if ($parentFolder) {
|
||||
$mimetype = \OC::$server->getMimeTypeDetector()->detect($tmpFile);
|
||||
$params = array(
|
||||
'mimeType' => $mimetype,
|
||||
'uploadType' => 'media'
|
||||
);
|
||||
$result = false;
|
||||
public function writeBack($tmpFile, $path) {
|
||||
$parentFolder = $this->getDriveFile(dirname($path));
|
||||
if ($parentFolder) {
|
||||
$mimetype = \OC::$server->getMimeTypeDetector()->detect($tmpFile);
|
||||
$params = array(
|
||||
'mimeType' => $mimetype,
|
||||
'uploadType' => 'media'
|
||||
);
|
||||
$result = false;
|
||||
|
||||
$chunkSizeBytes = 10 * 1024 * 1024;
|
||||
$chunkSizeBytes = 10 * 1024 * 1024;
|
||||
|
||||
$useChunking = false;
|
||||
$size = filesize($tmpFile);
|
||||
if ($size > $chunkSizeBytes) {
|
||||
$useChunking = true;
|
||||
} else {
|
||||
$params['data'] = file_get_contents($tmpFile);
|
||||
}
|
||||
|
||||
if ($this->file_exists($path)) {
|
||||
$file = $this->getDriveFile($path);
|
||||
$this->client->setDefer($useChunking);
|
||||
$request = $this->service->files->update($file->getId(), $file, $params);
|
||||
} else {
|
||||
$file = new \Google_Service_Drive_DriveFile();
|
||||
$file->setTitle(basename($path));
|
||||
$file->setMimeType($mimetype);
|
||||
$parent = new \Google_Service_Drive_ParentReference();
|
||||
$parent->setId($parentFolder->getId());
|
||||
$file->setParents(array($parent));
|
||||
$this->client->setDefer($useChunking);
|
||||
$request = $this->service->files->insert($file, $params);
|
||||
}
|
||||
|
||||
if ($useChunking) {
|
||||
// Create a media file upload to represent our upload process.
|
||||
$media = new \Google_Http_MediaFileUpload(
|
||||
$this->client,
|
||||
$request,
|
||||
'text/plain',
|
||||
null,
|
||||
true,
|
||||
$chunkSizeBytes
|
||||
);
|
||||
$media->setFileSize($size);
|
||||
|
||||
// Upload the various chunks. $status will be false until the process is
|
||||
// complete.
|
||||
$status = false;
|
||||
$handle = fopen($tmpFile, 'rb');
|
||||
while (!$status && !feof($handle)) {
|
||||
$chunk = fread($handle, $chunkSizeBytes);
|
||||
$status = $media->nextChunk($chunk);
|
||||
}
|
||||
|
||||
// The final value of $status will be the data from the API for the object
|
||||
// that has been uploaded.
|
||||
$result = false;
|
||||
if ($status !== false) {
|
||||
$result = $status;
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
} else {
|
||||
$result = $request;
|
||||
}
|
||||
|
||||
// Reset to the client to execute requests immediately in the future.
|
||||
$this->client->setDefer(false);
|
||||
|
||||
if ($result) {
|
||||
$this->setDriveFile($path, $result);
|
||||
}
|
||||
$useChunking = false;
|
||||
$size = filesize($tmpFile);
|
||||
if ($size > $chunkSizeBytes) {
|
||||
$useChunking = true;
|
||||
} else {
|
||||
$params['data'] = file_get_contents($tmpFile);
|
||||
}
|
||||
|
||||
if ($this->file_exists($path)) {
|
||||
$file = $this->getDriveFile($path);
|
||||
$this->client->setDefer($useChunking);
|
||||
$request = $this->service->files->update($file->getId(), $file, $params);
|
||||
} else {
|
||||
$file = new \Google_Service_Drive_DriveFile();
|
||||
$file->setTitle(basename($path));
|
||||
$file->setMimeType($mimetype);
|
||||
$parent = new \Google_Service_Drive_ParentReference();
|
||||
$parent->setId($parentFolder->getId());
|
||||
$file->setParents(array($parent));
|
||||
$this->client->setDefer($useChunking);
|
||||
$request = $this->service->files->insert($file, $params);
|
||||
}
|
||||
|
||||
if ($useChunking) {
|
||||
// Create a media file upload to represent our upload process.
|
||||
$media = new \Google_Http_MediaFileUpload(
|
||||
$this->client,
|
||||
$request,
|
||||
'text/plain',
|
||||
null,
|
||||
true,
|
||||
$chunkSizeBytes
|
||||
);
|
||||
$media->setFileSize($size);
|
||||
|
||||
// Upload the various chunks. $status will be false until the process is
|
||||
// complete.
|
||||
$status = false;
|
||||
$handle = fopen($tmpFile, 'rb');
|
||||
while (!$status && !feof($handle)) {
|
||||
$chunk = fread($handle, $chunkSizeBytes);
|
||||
$status = $media->nextChunk($chunk);
|
||||
}
|
||||
|
||||
// The final value of $status will be the data from the API for the object
|
||||
// that has been uploaded.
|
||||
$result = false;
|
||||
if ($status !== false) {
|
||||
$result = $status;
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
} else {
|
||||
$result = $request;
|
||||
}
|
||||
|
||||
// Reset to the client to execute requests immediately in the future.
|
||||
$this->client->setDefer(false);
|
||||
|
||||
if ($result) {
|
||||
$this->setDriveFile($path, $result);
|
||||
}
|
||||
unlink($tmpFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace OCA\Files_External\Lib\Storage;
|
|||
|
||||
use Guzzle\Http\Url;
|
||||
use Guzzle\Http\Exception\ClientErrorResponseException;
|
||||
use Icewind\Streams\CallbackWrapper;
|
||||
use Icewind\Streams\IteratorDirectory;
|
||||
use OpenCloud;
|
||||
use OpenCloud\Common\Exceptions;
|
||||
|
@ -410,7 +411,6 @@ class Swift extends \OC\Files\Storage\Common {
|
|||
$ext = '';
|
||||
}
|
||||
$tmpFile = \OCP\Files::tmpFile($ext);
|
||||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
|
||||
// Fetch existing file if required
|
||||
if ($mode[0] !== 'w' && $this->file_exists($path)) {
|
||||
if ($mode[0] === 'x') {
|
||||
|
@ -424,9 +424,10 @@ class Swift extends \OC\Files\Storage\Common {
|
|||
fseek($tmpFile, 0, SEEK_END);
|
||||
}
|
||||
}
|
||||
self::$tmpFiles[$tmpFile] = $path;
|
||||
|
||||
return fopen('close://' . $tmpFile, $mode);
|
||||
$handle = fopen($tmpFile, $mode);
|
||||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
|
||||
$this->writeBack($tmpFile, $path);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -615,12 +616,9 @@ class Swift extends \OC\Files\Storage\Common {
|
|||
return $this->container;
|
||||
}
|
||||
|
||||
public function writeBack($tmpFile) {
|
||||
if (!isset(self::$tmpFiles[$tmpFile])) {
|
||||
return false;
|
||||
}
|
||||
public function writeBack($tmpFile, $path) {
|
||||
$fileData = fopen($tmpFile, 'r');
|
||||
$this->getContainer()->uploadObject(self::$tmpFiles[$tmpFile], $fileData);
|
||||
$this->getContainer()->uploadObject($path, $fileData);
|
||||
// invalidate target object to force repopulation on fetch
|
||||
$this->objectCache->remove(self::$tmpFiles[$tmpFile]);
|
||||
unlink($tmpFile);
|
||||
|
|
|
@ -669,9 +669,6 @@ class OC {
|
|||
OC\Log\ErrorHandler::register($debug);
|
||||
}
|
||||
|
||||
// register the stream wrappers
|
||||
stream_wrapper_register('close', 'OC\Files\Stream\Close');
|
||||
|
||||
\OC::$server->getEventLogger()->start('init_session', 'Initialize session');
|
||||
OC_App::loadApps(array('session'));
|
||||
if (!self::$CLI) {
|
||||
|
|
|
@ -554,7 +554,6 @@ return array(
|
|||
'OC\\Files\\Storage\\Wrapper\\PermissionsMask' => $baseDir . '/lib/private/Files/Storage/Wrapper/PermissionsMask.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\Quota' => $baseDir . '/lib/private/Files/Storage/Wrapper/Quota.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\Wrapper' => $baseDir . '/lib/private/Files/Storage/Wrapper/Wrapper.php',
|
||||
'OC\\Files\\Stream\\Close' => $baseDir . '/lib/private/Files/Stream/Close.php',
|
||||
'OC\\Files\\Stream\\Encryption' => $baseDir . '/lib/private/Files/Stream/Encryption.php',
|
||||
'OC\\Files\\Stream\\Quota' => $baseDir . '/lib/private/Files/Stream/Quota.php',
|
||||
'OC\\Files\\Type\\Detection' => $baseDir . '/lib/private/Files/Type/Detection.php',
|
||||
|
|
|
@ -584,7 +584,6 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
|
|||
'OC\\Files\\Storage\\Wrapper\\PermissionsMask' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Wrapper/PermissionsMask.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\Quota' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Wrapper/Quota.php',
|
||||
'OC\\Files\\Storage\\Wrapper\\Wrapper' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Wrapper/Wrapper.php',
|
||||
'OC\\Files\\Stream\\Close' => __DIR__ . '/../../..' . '/lib/private/Files/Stream/Close.php',
|
||||
'OC\\Files\\Stream\\Encryption' => __DIR__ . '/../../..' . '/lib/private/Files/Stream/Encryption.php',
|
||||
'OC\\Files\\Stream\\Quota' => __DIR__ . '/../../..' . '/lib/private/Files/Stream/Quota.php',
|
||||
'OC\\Files\\Type\\Detection' => __DIR__ . '/../../..' . '/lib/private/Files/Type/Detection.php',
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
|
||||
namespace OC\Archive;
|
||||
|
||||
use Icewind\Streams\CallbackWrapper;
|
||||
|
||||
class TAR extends Archive {
|
||||
const PLAIN = 0;
|
||||
const GZIP = 1;
|
||||
|
@ -359,22 +361,19 @@ class TAR extends Archive {
|
|||
if ($mode == 'r' or $mode == 'rb') {
|
||||
return fopen($tmpFile, $mode);
|
||||
} else {
|
||||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
|
||||
self::$tempFiles[$tmpFile] = $path;
|
||||
return fopen('close://' . $tmpFile, $mode);
|
||||
$handle = fopen($tmpFile, $mode);
|
||||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
|
||||
$this->writeBack($tmpFile, $path);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static $tempFiles = array();
|
||||
|
||||
/**
|
||||
* write back temporary files
|
||||
*/
|
||||
function writeBack($tmpFile) {
|
||||
if (isset(self::$tempFiles[$tmpFile])) {
|
||||
$this->addFile(self::$tempFiles[$tmpFile], $tmpFile);
|
||||
unlink($tmpFile);
|
||||
}
|
||||
function writeBack($tmpFile, $path) {
|
||||
$this->addFile($path, $tmpFile);
|
||||
unlink($tmpFile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
|
||||
namespace OC\Archive;
|
||||
|
||||
use Icewind\Streams\CallbackWrapper;
|
||||
|
||||
class ZIP extends Archive{
|
||||
/**
|
||||
* @var \ZipArchive zip
|
||||
|
@ -198,24 +200,22 @@ class ZIP extends Archive{
|
|||
$ext='';
|
||||
}
|
||||
$tmpFile=\OCP\Files::tmpFile($ext);
|
||||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
|
||||
if($this->fileExists($path)) {
|
||||
$this->extractFile($path, $tmpFile);
|
||||
}
|
||||
self::$tempFiles[$tmpFile]=$path;
|
||||
return fopen('close://'.$tmpFile, $mode);
|
||||
$handle = fopen($tmpFile, $mode);
|
||||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
|
||||
$this->writeBack($tmpFile, $path);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static $tempFiles=array();
|
||||
/**
|
||||
* write back temporary files
|
||||
*/
|
||||
function writeBack($tmpFile) {
|
||||
if(isset(self::$tempFiles[$tmpFile])) {
|
||||
$this->addFile(self::$tempFiles[$tmpFile], $tmpFile);
|
||||
unlink($tmpFile);
|
||||
}
|
||||
function writeBack($tmpFile, $path) {
|
||||
$this->addFile($path, $tmpFile);
|
||||
unlink($tmpFile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,16 +25,12 @@
|
|||
|
||||
namespace OC\Files\ObjectStore;
|
||||
|
||||
use Icewind\Streams\CallbackWrapper;
|
||||
use Icewind\Streams\IteratorDirectory;
|
||||
use OC\Files\Cache\CacheEntry;
|
||||
use OCP\Files\ObjectStore\IObjectStore;
|
||||
|
||||
class ObjectStoreStorage extends \OC\Files\Storage\Common {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $tmpFiles = array();
|
||||
/**
|
||||
* @var \OCP\Files\ObjectStore\IObjectStore $objectStore
|
||||
*/
|
||||
|
@ -291,14 +287,14 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common {
|
|||
$ext = '';
|
||||
}
|
||||
$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
|
||||
\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
|
||||
if ($this->file_exists($path)) {
|
||||
$source = $this->fopen($path, 'r');
|
||||
file_put_contents($tmpFile, $source);
|
||||
}
|
||||
self::$tmpFiles[$tmpFile] = $path;
|
||||
|
||||
return fopen('close://' . $tmpFile, $mode);
|
||||
$handle = fopen($tmpFile, $mode);
|
||||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
|
||||
$this->writeBack($tmpFile, $path);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -368,12 +364,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common {
|
|||
return true;
|
||||
}
|
||||
|
||||
public function writeBack($tmpFile) {
|
||||
if (!isset(self::$tmpFiles[$tmpFile])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$path = self::$tmpFiles[$tmpFile];
|
||||
public function writeBack($tmpFile, $path) {
|
||||
$stat = $this->stat($path);
|
||||
if (empty($stat)) {
|
||||
// create new file
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace OC\Files\Storage;
|
|||
use Exception;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Message\ResponseInterface;
|
||||
use Icewind\Streams\CallbackWrapper;
|
||||
use OC\Files\Filesystem;
|
||||
use OC\Files\Stream\Close;
|
||||
use Icewind\Streams\IteratorDirectory;
|
||||
|
@ -77,8 +78,6 @@ class DAV extends Common {
|
|||
private $client;
|
||||
/** @var ArrayCache */
|
||||
private $statCache;
|
||||
/** @var array */
|
||||
private static $tempFiles = [];
|
||||
/** @var \OCP\Http\Client\IClientService */
|
||||
private $httpClientService;
|
||||
|
||||
|
@ -409,20 +408,19 @@ class DAV extends Common {
|
|||
}
|
||||
$tmpFile = $tempManager->getTemporaryFile($ext);
|
||||
}
|
||||
Close::registerCallback($tmpFile, array($this, 'writeBack'));
|
||||
self::$tempFiles[$tmpFile] = $path;
|
||||
return fopen('close://' . $tmpFile, $mode);
|
||||
$handle = fopen($tmpFile, $mode);
|
||||
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
|
||||
$this->writeBack($tmpFile, $path);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tmpFile
|
||||
*/
|
||||
public function writeBack($tmpFile) {
|
||||
if (isset(self::$tempFiles[$tmpFile])) {
|
||||
$this->uploadFile($tmpFile, self::$tempFiles[$tmpFile]);
|
||||
unlink($tmpFile);
|
||||
}
|
||||
public function writeBack($tmpFile, $path) {
|
||||
$this->uploadFile($tmpFile, $path);
|
||||
unlink($tmpFile);
|
||||
}
|
||||
|
||||
/** {@inheritdoc} */
|
||||
|
|
|
@ -1,119 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Robin Appelman <robin@icewind.nl>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OC\Files\Stream;
|
||||
|
||||
/**
|
||||
* stream wrapper that provides a callback on stream close
|
||||
*/
|
||||
class Close {
|
||||
private static $callBacks = array();
|
||||
private $path = '';
|
||||
private $source;
|
||||
private static $open = array();
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path) {
|
||||
$path = substr($path, strlen('close://'));
|
||||
$this->path = $path;
|
||||
$this->source = fopen($path, $mode);
|
||||
if (is_resource($this->source)) {
|
||||
$this->meta = stream_get_meta_data($this->source);
|
||||
}
|
||||
self::$open[] = $path;
|
||||
return is_resource($this->source);
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence = SEEK_SET) {
|
||||
return fseek($this->source, $offset, $whence) === 0;
|
||||
}
|
||||
|
||||
public function stream_tell() {
|
||||
return ftell($this->source);
|
||||
}
|
||||
|
||||
public function stream_read($count) {
|
||||
return fread($this->source, $count);
|
||||
}
|
||||
|
||||
public function stream_write($data) {
|
||||
return fwrite($this->source, $data);
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2) {
|
||||
switch ($option) {
|
||||
case STREAM_OPTION_BLOCKING:
|
||||
stream_set_blocking($this->source, $arg1);
|
||||
break;
|
||||
case STREAM_OPTION_READ_TIMEOUT:
|
||||
stream_set_timeout($this->source, $arg1, $arg2);
|
||||
break;
|
||||
case STREAM_OPTION_WRITE_BUFFER:
|
||||
stream_set_write_buffer($this->source, $arg1, $arg2);
|
||||
}
|
||||
}
|
||||
|
||||
public function stream_stat() {
|
||||
return fstat($this->source);
|
||||
}
|
||||
|
||||
public function stream_lock($mode) {
|
||||
flock($this->source, $mode);
|
||||
}
|
||||
|
||||
public function stream_flush() {
|
||||
return fflush($this->source);
|
||||
}
|
||||
|
||||
public function stream_eof() {
|
||||
return feof($this->source);
|
||||
}
|
||||
|
||||
public function url_stat($path) {
|
||||
$path = substr($path, strlen('close://'));
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function stream_close() {
|
||||
fclose($this->source);
|
||||
if (isset(self::$callBacks[$this->path])) {
|
||||
call_user_func(self::$callBacks[$this->path], $this->path);
|
||||
}
|
||||
}
|
||||
|
||||
public function unlink($path) {
|
||||
$path = substr($path, strlen('close://'));
|
||||
return unlink($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*/
|
||||
public static function registerCallback($path, $callback) {
|
||||
self::$callBacks[$path] = $callback;
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Robin Appelman
|
||||
* @copyright 2012 Robin Appelman icewind@owncloud.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Test;
|
||||
|
||||
/**
|
||||
* Class StreamWrappersTest
|
||||
*
|
||||
* @group DB
|
||||
*/
|
||||
class StreamWrappersTest extends \Test\TestCase {
|
||||
|
||||
private static $trashBinStatus;
|
||||
|
||||
public static function setUpBeforeClass() {
|
||||
self::$trashBinStatus = \OC_App::isEnabled('files_trashbin');
|
||||
\OC_App::disable('files_trashbin');
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass() {
|
||||
if (self::$trashBinStatus) {
|
||||
(new \OC_App())->enable('files_trashbin');
|
||||
}
|
||||
}
|
||||
|
||||
public function testCloseStream() {
|
||||
//ensure all basic stream stuff works
|
||||
$sourceFile = \OC::$SERVERROOT . '/tests/data/lorem.txt';
|
||||
$tmpFile = \OC::$server->getTempManager()->getTemporaryFile('.txt');
|
||||
$file = 'close://' . $tmpFile;
|
||||
$this->assertTrue(file_exists($file));
|
||||
file_put_contents($file, file_get_contents($sourceFile));
|
||||
$this->assertEquals(file_get_contents($sourceFile), file_get_contents($file));
|
||||
unlink($file);
|
||||
clearstatcache();
|
||||
$this->assertFalse(file_exists($file));
|
||||
|
||||
//test callback
|
||||
$tmpFile = \OC::$server->getTempManager()->getTemporaryFile('.txt');
|
||||
$file = 'close://' . $tmpFile;
|
||||
$actual = false;
|
||||
$callback = function($path) use (&$actual) { $actual = $path; };
|
||||
\OC\Files\Stream\Close::registerCallback($tmpFile, $callback);
|
||||
$fh = fopen($file, 'w');
|
||||
fwrite($fh, 'asd');
|
||||
fclose($fh);
|
||||
$this->assertSame($tmpFile, $actual);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue