set mimetype for objects uploaded to object storages
Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
parent
d2ea068552
commit
effb7dc8ba
|
@ -50,6 +50,7 @@ use OC\Files\Cache\CacheEntry;
|
||||||
use OC\Files\ObjectStore\S3ConnectionTrait;
|
use OC\Files\ObjectStore\S3ConnectionTrait;
|
||||||
use OC\Files\ObjectStore\S3ObjectTrait;
|
use OC\Files\ObjectStore\S3ObjectTrait;
|
||||||
use OCP\Constants;
|
use OCP\Constants;
|
||||||
|
use OCP\Files\IMimeTypeDetector;
|
||||||
|
|
||||||
class AmazonS3 extends \OC\Files\Storage\Common {
|
class AmazonS3 extends \OC\Files\Storage\Common {
|
||||||
use S3ConnectionTrait;
|
use S3ConnectionTrait;
|
||||||
|
@ -68,12 +69,16 @@ class AmazonS3 extends \OC\Files\Storage\Common {
|
||||||
/** @var CappedMemoryCache|array */
|
/** @var CappedMemoryCache|array */
|
||||||
private $filesCache;
|
private $filesCache;
|
||||||
|
|
||||||
|
/** @var IMimeTypeDetector */
|
||||||
|
private $mimeDetector;
|
||||||
|
|
||||||
public function __construct($parameters) {
|
public function __construct($parameters) {
|
||||||
parent::__construct($parameters);
|
parent::__construct($parameters);
|
||||||
$this->parseParams($parameters);
|
$this->parseParams($parameters);
|
||||||
$this->objectCache = new CappedMemoryCache();
|
$this->objectCache = new CappedMemoryCache();
|
||||||
$this->directoryCache = new CappedMemoryCache();
|
$this->directoryCache = new CappedMemoryCache();
|
||||||
$this->filesCache = new CappedMemoryCache();
|
$this->filesCache = new CappedMemoryCache();
|
||||||
|
$this->mimeDetector = \OC::$server->get(IMimeTypeDetector::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -573,7 +578,7 @@ class AmazonS3 extends \OC\Files\Storage\Common {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!$this->file_exists($path)) {
|
if (!$this->file_exists($path)) {
|
||||||
$mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
|
$mimeType = $this->mimeDetector->detectPath($path);
|
||||||
$this->getConnection()->putObject([
|
$this->getConnection()->putObject([
|
||||||
'Bucket' => $this->bucket,
|
'Bucket' => $this->bucket,
|
||||||
'Key' => $this->cleanKey($path),
|
'Key' => $this->cleanKey($path),
|
||||||
|
@ -684,7 +689,7 @@ class AmazonS3 extends \OC\Files\Storage\Common {
|
||||||
public function writeBack($tmpFile, $path) {
|
public function writeBack($tmpFile, $path) {
|
||||||
try {
|
try {
|
||||||
$source = fopen($tmpFile, 'r');
|
$source = fopen($tmpFile, 'r');
|
||||||
$this->writeObject($path, $source);
|
$this->writeObject($path, $source, $this->mimeDetector->detectPath($path));
|
||||||
$this->invalidateCache($path);
|
$this->invalidateCache($path);
|
||||||
|
|
||||||
unlink($tmpFile);
|
unlink($tmpFile);
|
||||||
|
|
|
@ -47,6 +47,7 @@ use GuzzleHttp\Psr7\Uri;
|
||||||
use Icewind\Streams\CallbackWrapper;
|
use Icewind\Streams\CallbackWrapper;
|
||||||
use Icewind\Streams\IteratorDirectory;
|
use Icewind\Streams\IteratorDirectory;
|
||||||
use OC\Files\ObjectStore\SwiftFactory;
|
use OC\Files\ObjectStore\SwiftFactory;
|
||||||
|
use OCP\Files\IMimeTypeDetector;
|
||||||
use OCP\Files\StorageBadConfigException;
|
use OCP\Files\StorageBadConfigException;
|
||||||
use OCP\ILogger;
|
use OCP\ILogger;
|
||||||
use OpenStack\Common\Error\BadResponseError;
|
use OpenStack\Common\Error\BadResponseError;
|
||||||
|
@ -76,6 +77,9 @@ class Swift extends \OC\Files\Storage\Common {
|
||||||
/** @var \OC\Files\ObjectStore\Swift */
|
/** @var \OC\Files\ObjectStore\Swift */
|
||||||
private $objectStore;
|
private $objectStore;
|
||||||
|
|
||||||
|
/** @var IMimeTypeDetector */
|
||||||
|
private $mimeDetector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key value cache mapping path to data object. Maps path to
|
* Key value cache mapping path to data object. Maps path to
|
||||||
* \OpenCloud\OpenStack\ObjectStorage\Resource\DataObject for existing
|
* \OpenCloud\OpenStack\ObjectStorage\Resource\DataObject for existing
|
||||||
|
@ -205,6 +209,7 @@ class Swift extends \OC\Files\Storage\Common {
|
||||||
);
|
);
|
||||||
$this->objectStore = new \OC\Files\ObjectStore\Swift($this->params, $this->connectionFactory);
|
$this->objectStore = new \OC\Files\ObjectStore\Swift($this->params, $this->connectionFactory);
|
||||||
$this->bucket = $params['bucket'];
|
$this->bucket = $params['bucket'];
|
||||||
|
$this->mimeDetector = \OC::$server->get(IMimeTypeDetector::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function mkdir($path) {
|
public function mkdir($path) {
|
||||||
|
@ -466,7 +471,7 @@ class Swift extends \OC\Files\Storage\Common {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
$mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
|
$mimeType = $this->mimeDetector->detectPath($path);
|
||||||
$this->getContainer()->createObject([
|
$this->getContainer()->createObject([
|
||||||
'name' => $path,
|
'name' => $path,
|
||||||
'content' => '',
|
'content' => '',
|
||||||
|
@ -588,7 +593,7 @@ class Swift extends \OC\Files\Storage\Common {
|
||||||
|
|
||||||
public function writeBack($tmpFile, $path) {
|
public function writeBack($tmpFile, $path) {
|
||||||
$fileData = fopen($tmpFile, 'r');
|
$fileData = fopen($tmpFile, 'r');
|
||||||
$this->objectStore->writeObject($path, $fileData);
|
$this->objectStore->writeObject($path, $fileData, $this->mimeDetector->detectPath($path));
|
||||||
// invalidate target object to force repopulation on fetch
|
// invalidate target object to force repopulation on fetch
|
||||||
$this->objectCache->remove($path);
|
$this->objectCache->remove($path);
|
||||||
unlink($tmpFile);
|
unlink($tmpFile);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
namespace OC\Files\ObjectStore;
|
namespace OC\Files\ObjectStore;
|
||||||
|
|
||||||
use MicrosoftAzure\Storage\Blob\BlobRestProxy;
|
use MicrosoftAzure\Storage\Blob\BlobRestProxy;
|
||||||
|
use MicrosoftAzure\Storage\Blob\Models\CreateBlockBlobOptions;
|
||||||
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;
|
use MicrosoftAzure\Storage\Common\Exceptions\ServiceException;
|
||||||
use OCP\Files\ObjectStore\IObjectStore;
|
use OCP\Files\ObjectStore\IObjectStore;
|
||||||
|
|
||||||
|
@ -100,13 +101,12 @@ class Azure implements IObjectStore {
|
||||||
return $blob->getContentStream();
|
return $blob->getContentStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function writeObject($urn, $stream, string $mimetype = null) {
|
||||||
* @param string $urn the unified resource name used to identify the object
|
$options = new CreateBlockBlobOptions();
|
||||||
* @param resource $stream stream with the data to write
|
if ($mimetype) {
|
||||||
* @throws \Exception when something goes wrong, message will be logged
|
$options->setContentType($mimetype);
|
||||||
*/
|
}
|
||||||
public function writeObject($urn, $stream) {
|
$this->getBlobClient()->createBlockBlob($this->containerName, $urn, $stream, $options);
|
||||||
$this->getBlobClient()->createBlockBlob($this->containerName, $urn, $stream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -486,13 +486,13 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common {
|
||||||
]);
|
]);
|
||||||
$size = $writtenSize;
|
$size = $writtenSize;
|
||||||
});
|
});
|
||||||
$this->objectStore->writeObject($urn, $countStream);
|
$this->objectStore->writeObject($urn, $countStream, $mimetype);
|
||||||
if (is_resource($countStream)) {
|
if (is_resource($countStream)) {
|
||||||
fclose($countStream);
|
fclose($countStream);
|
||||||
}
|
}
|
||||||
$stat['size'] = $size;
|
$stat['size'] = $size;
|
||||||
} else {
|
} else {
|
||||||
$this->objectStore->writeObject($urn, $stream);
|
$this->objectStore->writeObject($urn, $stream, $mimetype);
|
||||||
}
|
}
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
if (!$exists) {
|
if (!$exists) {
|
||||||
|
|
|
@ -78,10 +78,11 @@ trait S3ObjectTrait {
|
||||||
/**
|
/**
|
||||||
* @param string $urn the unified resource name used to identify the object
|
* @param string $urn the unified resource name used to identify the object
|
||||||
* @param resource $stream stream with the data to write
|
* @param resource $stream stream with the data to write
|
||||||
|
* @param string|null $mimetype the mimetype to set for the remove object @since 22.0.0
|
||||||
* @throws \Exception when something goes wrong, message will be logged
|
* @throws \Exception when something goes wrong, message will be logged
|
||||||
* @since 7.0.0
|
* @since 7.0.0
|
||||||
*/
|
*/
|
||||||
public function writeObject($urn, $stream) {
|
public function writeObject($urn, $stream, string $mimetype = null) {
|
||||||
$count = 0;
|
$count = 0;
|
||||||
$countStream = CallbackWrapper::wrap($stream, function ($read) use (&$count) {
|
$countStream = CallbackWrapper::wrap($stream, function ($read) use (&$count) {
|
||||||
$count += $read;
|
$count += $read;
|
||||||
|
@ -91,6 +92,9 @@ trait S3ObjectTrait {
|
||||||
'bucket' => $this->bucket,
|
'bucket' => $this->bucket,
|
||||||
'key' => $urn,
|
'key' => $urn,
|
||||||
'part_size' => $this->uploadPartSize,
|
'part_size' => $this->uploadPartSize,
|
||||||
|
'params' => [
|
||||||
|
'ContentType' => $mimetype
|
||||||
|
]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -65,13 +65,7 @@ class StorageObjectStore implements IObjectStore {
|
||||||
throw new \Exception();
|
throw new \Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function writeObject($urn, $stream, string $mimetype = null) {
|
||||||
* @param string $urn the unified resource name used to identify the object
|
|
||||||
* @param resource $stream stream with the data to write
|
|
||||||
* @throws \Exception when something goes wrong, message will be logged
|
|
||||||
* @since 7.0.0
|
|
||||||
*/
|
|
||||||
public function writeObject($urn, $stream) {
|
|
||||||
$handle = $this->storage->fopen($urn, 'w');
|
$handle = $this->storage->fopen($urn, 'w');
|
||||||
if ($handle) {
|
if ($handle) {
|
||||||
stream_copy_to_stream($stream, $handle);
|
stream_copy_to_stream($stream, $handle);
|
||||||
|
|
|
@ -74,12 +74,7 @@ class Swift implements IObjectStore {
|
||||||
return $this->params['container'];
|
return $this->params['container'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function writeObject($urn, $stream, string $mimetype = null) {
|
||||||
* @param string $urn the unified resource name used to identify the object
|
|
||||||
* @param resource $stream stream with the data to write
|
|
||||||
* @throws \Exception from openstack lib when something goes wrong
|
|
||||||
*/
|
|
||||||
public function writeObject($urn, $stream) {
|
|
||||||
$tmpFile = \OC::$server->getTempManager()->getTemporaryFile('swiftwrite');
|
$tmpFile = \OC::$server->getTempManager()->getTemporaryFile('swiftwrite');
|
||||||
file_put_contents($tmpFile, $stream);
|
file_put_contents($tmpFile, $stream);
|
||||||
$handle = fopen($tmpFile, 'rb');
|
$handle = fopen($tmpFile, 'rb');
|
||||||
|
@ -88,12 +83,14 @@ class Swift implements IObjectStore {
|
||||||
$this->getContainer()->createObject([
|
$this->getContainer()->createObject([
|
||||||
'name' => $urn,
|
'name' => $urn,
|
||||||
'stream' => stream_for($handle),
|
'stream' => stream_for($handle),
|
||||||
|
'contentType' => $mimetype,
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
$this->getContainer()->createLargeObject([
|
$this->getContainer()->createLargeObject([
|
||||||
'name' => $urn,
|
'name' => $urn,
|
||||||
'stream' => stream_for($handle),
|
'stream' => stream_for($handle),
|
||||||
'segmentSize' => SWIFT_SEGMENT_SIZE,
|
'segmentSize' => SWIFT_SEGMENT_SIZE,
|
||||||
|
'contentType' => $mimetype,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,10 +52,11 @@ interface IObjectStore {
|
||||||
/**
|
/**
|
||||||
* @param string $urn the unified resource name used to identify the object
|
* @param string $urn the unified resource name used to identify the object
|
||||||
* @param resource $stream stream with the data to write
|
* @param resource $stream stream with the data to write
|
||||||
|
* @param string|null $mimetype the mimetype to set for the remove object @since 22.0.0
|
||||||
* @throws \Exception when something goes wrong, message will be logged
|
* @throws \Exception when something goes wrong, message will be logged
|
||||||
* @since 7.0.0
|
* @since 7.0.0
|
||||||
*/
|
*/
|
||||||
public function writeObject($urn, $stream);
|
public function writeObject($urn, $stream, string $mimetype = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $urn the unified resource name used to identify the object
|
* @param string $urn the unified resource name used to identify the object
|
||||||
|
|
|
@ -40,8 +40,8 @@ class FailDeleteObjectStore implements IObjectStore {
|
||||||
return $this->objectStore->readObject($urn);
|
return $this->objectStore->readObject($urn);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function writeObject($urn, $stream) {
|
public function writeObject($urn, $stream, string $mimetype = null) {
|
||||||
return $this->objectStore->writeObject($urn, $stream);
|
return $this->objectStore->writeObject($urn, $stream, $mimetype);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteObject($urn) {
|
public function deleteObject($urn) {
|
||||||
|
|
|
@ -40,7 +40,7 @@ class FailWriteObjectStore implements IObjectStore {
|
||||||
return $this->objectStore->readObject($urn);
|
return $this->objectStore->readObject($urn);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function writeObject($urn, $stream) {
|
public function writeObject($urn, $stream, string $mimetype = null) {
|
||||||
// emulate a failed write that didn't throw an error
|
// emulate a failed write that didn't throw an error
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ use Icewind\Streams\Wrapper;
|
||||||
use OC\Files\ObjectStore\S3;
|
use OC\Files\ObjectStore\S3;
|
||||||
|
|
||||||
class MultiPartUploadS3 extends S3 {
|
class MultiPartUploadS3 extends S3 {
|
||||||
public function writeObject($urn, $stream) {
|
public function writeObject($urn, $stream, string $mimetype = null) {
|
||||||
$this->getConnection()->upload($this->bucket, $urn, $stream, 'private', [
|
$this->getConnection()->upload($this->bucket, $urn, $stream, 'private', [
|
||||||
'mup_threshold' => 1,
|
'mup_threshold' => 1,
|
||||||
]);
|
]);
|
||||||
|
|
Loading…
Reference in New Issue