Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoeland Jago Douma <rullzer@users.noreply.github.com>2017-03-29 12:23:13 +0300
committerGitHub <noreply@github.com>2017-03-29 12:23:13 +0300
commit626d03e3d47994364500bd6cd5dd9a029b862fb7 (patch)
treeea992f049c2cc71d759db0062599f83b2c7155aa
parent00839a5ac5cdff816686ed4029f91db4b693b470 (diff)
parent6991b79d40cf3f92e57fd7a7a9ea49e2404b090d (diff)
Merge pull request #4116 from nextcloud/swift-cache-token
Cache swift authentication token in memcache
m---------3rdparty0
-rw-r--r--lib/private/Files/ObjectStore/Swift.php72
2 files changed, 62 insertions, 10 deletions
diff --git a/3rdparty b/3rdparty
-Subproject 540cad1fa70205ca38dd344ea09d412bd986a1e
+Subproject 18adb82bab030a0af41e66e421a90d123a21a8f
diff --git a/lib/private/Files/ObjectStore/Swift.php b/lib/private/Files/ObjectStore/Swift.php
index 43ce32af941..38fb96e3af6 100644
--- a/lib/private/Files/ObjectStore/Swift.php
+++ b/lib/private/Files/ObjectStore/Swift.php
@@ -31,6 +31,7 @@ use OCP\Files\StorageNotAvailableException;
use OpenCloud\Common\Exceptions\EndpointError;
use OpenCloud\Common\Service\Catalog;
use OpenCloud\Common\Service\CatalogItem;
+use OpenCloud\Identity\Resource\Token;
use OpenCloud\ObjectStore\Service;
use OpenCloud\OpenStack;
use OpenCloud\Rackspace;
@@ -57,6 +58,8 @@ class Swift implements IObjectStore {
*/
private $container;
+ private $memcache;
+
public function __construct($params) {
if (isset($params['bucket'])) {
$params['container'] = $params['bucket'];
@@ -71,9 +74,15 @@ class Swift implements IObjectStore {
if (isset($params['apiKey'])) {
$this->client = new Rackspace($params['url'], $params);
+ $cacheKey = $this->params['username'] . '@' . $this->params['url'] . '/' . $this->params['bucket'];
} else {
$this->client = new OpenStack($params['url'], $params);
+ $cacheKey = $this->params['username'] . '@' . $this->params['url'] . '/' . $this->params['bucket'];
}
+
+ $cacheFactory = \OC::$server->getMemCacheFactory();
+ $this->memcache = $cacheFactory->create('swift::' . $cacheKey);
+
$this->params = $params;
}
@@ -82,19 +91,28 @@ class Swift implements IObjectStore {
return;
}
- try {
- $this->client->authenticate();
- } catch (ClientErrorResponseException $e) {
- $statusCode = $e->getResponse()->getStatusCode();
- if ($statusCode == 412) {
- throw new StorageAuthException('Precondition failed, verify the keystone url', $e);
- } else if ($statusCode === 401) {
- throw new StorageAuthException('Authentication failed, verify the username, password and possibly tenant', $e);
- } else {
- throw new StorageAuthException('Unknown error', $e);
+ $this->importToken();
+
+ /** @var Token $token */
+ $token = $this->client->getTokenObject();
+
+ if (!$token || $token->hasExpired()) {
+ try {
+ $this->client->authenticate();
+ $this->exportToken();
+ } catch (ClientErrorResponseException $e) {
+ $statusCode = $e->getResponse()->getStatusCode();
+ if ($statusCode == 412) {
+ throw new StorageAuthException('Precondition failed, verify the keystone url', $e);
+ } else if ($statusCode === 401) {
+ throw new StorageAuthException('Authentication failed, verify the username, password and possibly tenant', $e);
+ } else {
+ throw new StorageAuthException('Unknown error', $e);
+ }
}
}
+
/** @var Catalog $catalog */
$catalog = $this->client->getCatalog();
@@ -137,6 +155,40 @@ class Swift implements IObjectStore {
}
}
+ private function exportToken() {
+ $export = $this->client->exportCredentials();
+ $export['catalog'] = array_map(function (CatalogItem $item) {
+ return [
+ 'name' => $item->getName(),
+ 'endpoints' => $item->getEndpoints(),
+ 'type' => $item->getType()
+ ];
+ }, $export['catalog']->getItems());
+ $this->memcache->set('token', json_encode($export));
+ }
+
+ private function importToken() {
+ $cachedTokenString = $this->memcache->get('token');
+ if ($cachedTokenString) {
+ $cachedToken = json_decode($cachedTokenString, true);
+ $cachedToken['catalog'] = array_map(function (array $item) {
+ $itemClass = new \stdClass();
+ $itemClass->name = $item['name'];
+ $itemClass->endpoints = array_map(function (array $endpoint) {
+ return (object) $endpoint;
+ }, $item['endpoints']);
+ $itemClass->type = $item['type'];
+
+ return $itemClass;
+ }, $cachedToken['catalog']);
+ try {
+ $this->client->importCredentials($cachedToken);
+ } catch (\Exception $e) {
+ $this->client->setTokenObject(new Token());
+ }
+ }
+ }
+
/**
* @param Catalog $catalog
* @param $name