Skip to content
Snippets Groups Projects
Unverified Commit 010473ca authored by Daniel Kesselberg's avatar Daniel Kesselberg
Browse files

Add method to check if directory exists

parent 48a00b88
No related branches found
No related tags found
No related merge requests found
...@@ -60,6 +60,8 @@ class AmazonS3 extends \OC\Files\Storage\Common { ...@@ -60,6 +60,8 @@ class AmazonS3 extends \OC\Files\Storage\Common {
/** @var CappedMemoryCache|Result[] */ /** @var CappedMemoryCache|Result[] */
private $objectCache; private $objectCache;
/** @var CappedMemoryCache|bool[] */
private $directoryCache;
/** @var CappedMemoryCache|array */ /** @var CappedMemoryCache|array */
private $filesCache; private $filesCache;
...@@ -68,6 +70,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { ...@@ -68,6 +70,7 @@ class AmazonS3 extends \OC\Files\Storage\Common {
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->filesCache = new CappedMemoryCache(); $this->filesCache = new CappedMemoryCache();
} }
...@@ -98,6 +101,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { ...@@ -98,6 +101,7 @@ class AmazonS3 extends \OC\Files\Storage\Common {
private function clearCache() { private function clearCache() {
$this->objectCache = new CappedMemoryCache(); $this->objectCache = new CappedMemoryCache();
$this->directoryCache = new CappedMemoryCache();
$this->filesCache = new CappedMemoryCache(); $this->filesCache = new CappedMemoryCache();
} }
...@@ -135,6 +139,41 @@ class AmazonS3 extends \OC\Files\Storage\Common { ...@@ -135,6 +139,41 @@ class AmazonS3 extends \OC\Files\Storage\Common {
return $this->objectCache[$key]; return $this->objectCache[$key];
} }
/**
* Return true if directory exists
*
* There are no folders in s3. A folder like structure could be archived
* by prefixing files with the folder name.
*
* Implementation from flysystem-aws-s3-v3:
* https://github.com/thephpleague/flysystem-aws-s3-v3/blob/8241e9cc5b28f981e0d24cdaf9867f14c7498ae4/src/AwsS3Adapter.php#L670-L694
*
* @param $location
* @return bool
* @throws \Exception
*/
protected function doesDirectoryExist($location) {
if (!isset($this->directoryCache[$location])) {
// Maybe this isn't an actual key, but a prefix.
// Do a prefix listing of objects to determine.
try {
$result = $this->getConnection()->listObjects([
'Bucket' => $this->bucket,
'Prefix' => rtrim($location, '/') . '/',
'MaxKeys' => 1,
]);
$this->directoryCache[$location] = $result['Contents'] || $result['CommonPrefixes'];
} catch (S3Exception $e) {
if ($e->getStatusCode() === 403) {
$this->directoryCache[$location] = false;
}
throw $e;
}
}
return $this->directoryCache[$location];
}
/** /**
* Updates old storage ids (v0.2.1 and older) that are based on key and secret to new ones based on the bucket name. * Updates old storage ids (v0.2.1 and older) that are based on key and secret to new ones based on the bucket name.
* TODO Do this in an update.php. requires iterating over all users and loading the mount.json from their home * TODO Do this in an update.php. requires iterating over all users and loading the mount.json from their home
...@@ -393,7 +432,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { ...@@ -393,7 +432,7 @@ class AmazonS3 extends \OC\Files\Storage\Common {
public function is_dir($path) { public function is_dir($path) {
$path = $this->normalizePath($path); $path = $this->normalizePath($path);
try { try {
return $this->isRoot($path) || $this->headObject($path . '/'); return $this->isRoot($path) || $this->doesDirectoryExist($path);
} catch (S3Exception $e) { } catch (S3Exception $e) {
\OC::$server->getLogger()->logException($e, ['app' => 'files_external']); \OC::$server->getLogger()->logException($e, ['app' => 'files_external']);
return false; return false;
...@@ -411,7 +450,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { ...@@ -411,7 +450,7 @@ class AmazonS3 extends \OC\Files\Storage\Common {
if (isset($this->filesCache[$path]) || $this->headObject($path)) { if (isset($this->filesCache[$path]) || $this->headObject($path)) {
return 'file'; return 'file';
} }
if ($this->headObject($path . '/')) { if ($this->doesDirectoryExist($path)) {
return 'dir'; return 'dir';
} }
} catch (S3Exception $e) { } catch (S3Exception $e) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment