Completed
Pull Request — master (#8314)
by Robin
15:50
created
apps/files_external/lib/Lib/Storage/Swift.php 3 patches
Doc Comments   +4 added lines, -1 removed lines patch added patch discarded remove patch
@@ -83,7 +83,7 @@  discard block
 block discarded – undo
83 83
 
84 84
 	/**
85 85
 	 * @param string $path
86
-	 * @return mixed|string
86
+	 * @return string
87 87
 	 */
88 88
 	private function normalizePath(string $path) {
89 89
 		$path = trim($path, '/');
@@ -570,6 +570,9 @@  discard block
 block discarded – undo
570 570
 		return $this->container;
571 571
 	}
572 572
 
573
+	/**
574
+	 * @param string $path
575
+	 */
573 576
 	public function writeBack($tmpFile, $path) {
574 577
 		$fileData = fopen($tmpFile, 'r');
575 578
 		$this->objectStore->writeObject($path, $fileData);
Please login to merge, or discard this patch.
Indentation   +554 added lines, -554 removed lines patch added patch discarded remove patch
@@ -49,562 +49,562 @@
 block discarded – undo
49 49
 use OpenStack\ObjectStore\v1\Models\StorageObject;
50 50
 
51 51
 class Swift extends \OC\Files\Storage\Common {
52
-	/** @var SwiftFactory */
53
-	private $connectionFactory;
54
-	/**
55
-	 * @var \OpenStack\ObjectStore\v1\Models\Container
56
-	 */
57
-	private $container;
58
-	/**
59
-	 * @var string
60
-	 */
61
-	private $bucket;
62
-	/**
63
-	 * Connection parameters
64
-	 *
65
-	 * @var array
66
-	 */
67
-	private $params;
68
-
69
-	/** @var string */
70
-	private $id;
71
-
72
-	/** @var \OC\Files\ObjectStore\Swift */
73
-	private $objectStore;
74
-
75
-	/**
76
-	 * Key value cache mapping path to data object. Maps path to
77
-	 * \OpenCloud\OpenStack\ObjectStorage\Resource\DataObject for existing
78
-	 * paths and path to false for not existing paths.
79
-	 *
80
-	 * @var \OCP\ICache
81
-	 */
82
-	private $objectCache;
83
-
84
-	/**
85
-	 * @param string $path
86
-	 * @return mixed|string
87
-	 */
88
-	private function normalizePath(string $path) {
89
-		$path = trim($path, '/');
90
-
91
-		if (!$path) {
92
-			$path = '.';
93
-		}
94
-
95
-		$path = str_replace('#', '%23', $path);
96
-
97
-		return $path;
98
-	}
99
-
100
-	const SUBCONTAINER_FILE = '.subcontainers';
101
-
102
-	/**
103
-	 * translate directory path to container name
104
-	 *
105
-	 * @param string $path
106
-	 * @return string
107
-	 */
108
-
109
-	/**
110
-	 * Fetches an object from the API.
111
-	 * If the object is cached already or a
112
-	 * failed "doesn't exist" response was cached,
113
-	 * that one will be returned.
114
-	 *
115
-	 * @param string $path
116
-	 * @return StorageObject|bool object
117
-	 * or false if the object did not exist
118
-	 * @throws \OCP\Files\StorageAuthException
119
-	 * @throws \OCP\Files\StorageNotAvailableException
120
-	 */
121
-	private function fetchObject(string $path) {
122
-		if ($this->objectCache->hasKey($path)) {
123
-			// might be "false" if object did not exist from last check
124
-			return $this->objectCache->get($path);
125
-		}
126
-		try {
127
-			$object = $this->getContainer()->getObject($path);
128
-			$object->retrieve();
129
-			$this->objectCache->set($path, $object);
130
-			return $object;
131
-		} catch (BadResponseError $e) {
132
-			// Expected response is "404 Not Found", so only log if it isn't
133
-			if ($e->getResponse()->getStatusCode() !== 404) {
134
-				\OC::$server->getLogger()->logException($e, [
135
-					'level' => \OCP\Util::ERROR,
136
-					'app' => 'files_external',
137
-				]);
138
-			}
139
-			$this->objectCache->set($path, false);
140
-			return false;
141
-		}
142
-	}
143
-
144
-	/**
145
-	 * Returns whether the given path exists.
146
-	 *
147
-	 * @param string $path
148
-	 *
149
-	 * @return bool true if the object exist, false otherwise
150
-	 * @throws \OCP\Files\StorageAuthException
151
-	 * @throws \OCP\Files\StorageNotAvailableException
152
-	 */
153
-	private function doesObjectExist($path) {
154
-		return $this->fetchObject($path) !== false;
155
-	}
156
-
157
-	public function __construct($params) {
158
-		if ((empty($params['key']) and empty($params['password']))
159
-			or empty($params['user']) or empty($params['bucket'])
160
-			or empty($params['region'])
161
-		) {
162
-			throw new StorageBadConfigException("API Key or password, Username, Bucket and Region have to be configured.");
163
-		}
164
-
165
-		$this->id = 'swift::' . $params['user'] . md5($params['bucket']);
166
-
167
-		$bucketUrl = new Uri($params['bucket']);
168
-		if ($bucketUrl->getHost()) {
169
-			$params['bucket'] = basename($bucketUrl->getPath());
170
-			$params['endpoint_url'] = (string)$bucketUrl->withPath(dirname($bucketUrl->getPath()));
171
-		}
172
-
173
-		if (empty($params['url'])) {
174
-			$params['url'] = 'https://identity.api.rackspacecloud.com/v2.0/';
175
-		}
176
-
177
-		if (empty($params['service_name'])) {
178
-			$params['service_name'] = 'cloudFiles';
179
-		}
180
-
181
-		$params['autocreate'] = true;
182
-
183
-		$this->params = $params;
184
-		// FIXME: private class...
185
-		$this->objectCache = new \OC\Cache\CappedMemoryCache();
186
-		$this->connectionFactory = new SwiftFactory(\OC::$server->getMemCacheFactory()->createDistributed('swift/'), $this->params);
187
-		$this->objectStore = new \OC\Files\ObjectStore\Swift($this->params, $this->connectionFactory);
188
-		$this->bucket = $params['bucket'];
189
-	}
190
-
191
-	public function mkdir($path) {
192
-		$path = $this->normalizePath($path);
193
-
194
-		if ($this->is_dir($path)) {
195
-			return false;
196
-		}
197
-
198
-		if ($path !== '.') {
199
-			$path .= '/';
200
-		}
201
-
202
-		try {
203
-			$this->getContainer()->createObject([
204
-				'name' => $path,
205
-				'content' => '',
206
-				'headers' => ['content-type' => 'httpd/unix-directory']
207
-			]);
208
-			// invalidate so that the next access gets the real object
209
-			// with all properties
210
-			$this->objectCache->remove($path);
211
-		} catch (BadResponseError $e) {
212
-			\OC::$server->getLogger()->logException($e, [
213
-				'level' => \OCP\Util::ERROR,
214
-				'app' => 'files_external',
215
-			]);
216
-			return false;
217
-		}
218
-
219
-		return true;
220
-	}
221
-
222
-	public function file_exists($path) {
223
-		$path = $this->normalizePath($path);
224
-
225
-		if ($path !== '.' && $this->is_dir($path)) {
226
-			$path .= '/';
227
-		}
228
-
229
-		return $this->doesObjectExist($path);
230
-	}
231
-
232
-	public function rmdir($path) {
233
-		$path = $this->normalizePath($path);
234
-
235
-		if (!$this->is_dir($path) || !$this->isDeletable($path)) {
236
-			return false;
237
-		}
238
-
239
-		$dh = $this->opendir($path);
240
-		while ($file = readdir($dh)) {
241
-			if (\OC\Files\Filesystem::isIgnoredDir($file)) {
242
-				continue;
243
-			}
244
-
245
-			if ($this->is_dir($path . '/' . $file)) {
246
-				$this->rmdir($path . '/' . $file);
247
-			} else {
248
-				$this->unlink($path . '/' . $file);
249
-			}
250
-		}
251
-
252
-		try {
253
-			$this->objectStore->deleteObject($path . '/');
254
-			$this->objectCache->remove($path . '/');
255
-		} catch (BadResponseError $e) {
256
-			\OC::$server->getLogger()->logException($e, [
257
-				'level' => \OCP\Util::ERROR,
258
-				'app' => 'files_external',
259
-			]);
260
-			return false;
261
-		}
262
-
263
-		return true;
264
-	}
265
-
266
-	public function opendir($path) {
267
-		$path = $this->normalizePath($path);
268
-
269
-		if ($path === '.') {
270
-			$path = '';
271
-		} else {
272
-			$path .= '/';
273
-		}
52
+    /** @var SwiftFactory */
53
+    private $connectionFactory;
54
+    /**
55
+     * @var \OpenStack\ObjectStore\v1\Models\Container
56
+     */
57
+    private $container;
58
+    /**
59
+     * @var string
60
+     */
61
+    private $bucket;
62
+    /**
63
+     * Connection parameters
64
+     *
65
+     * @var array
66
+     */
67
+    private $params;
68
+
69
+    /** @var string */
70
+    private $id;
71
+
72
+    /** @var \OC\Files\ObjectStore\Swift */
73
+    private $objectStore;
74
+
75
+    /**
76
+     * Key value cache mapping path to data object. Maps path to
77
+     * \OpenCloud\OpenStack\ObjectStorage\Resource\DataObject for existing
78
+     * paths and path to false for not existing paths.
79
+     *
80
+     * @var \OCP\ICache
81
+     */
82
+    private $objectCache;
83
+
84
+    /**
85
+     * @param string $path
86
+     * @return mixed|string
87
+     */
88
+    private function normalizePath(string $path) {
89
+        $path = trim($path, '/');
90
+
91
+        if (!$path) {
92
+            $path = '.';
93
+        }
94
+
95
+        $path = str_replace('#', '%23', $path);
96
+
97
+        return $path;
98
+    }
99
+
100
+    const SUBCONTAINER_FILE = '.subcontainers';
101
+
102
+    /**
103
+     * translate directory path to container name
104
+     *
105
+     * @param string $path
106
+     * @return string
107
+     */
108
+
109
+    /**
110
+     * Fetches an object from the API.
111
+     * If the object is cached already or a
112
+     * failed "doesn't exist" response was cached,
113
+     * that one will be returned.
114
+     *
115
+     * @param string $path
116
+     * @return StorageObject|bool object
117
+     * or false if the object did not exist
118
+     * @throws \OCP\Files\StorageAuthException
119
+     * @throws \OCP\Files\StorageNotAvailableException
120
+     */
121
+    private function fetchObject(string $path) {
122
+        if ($this->objectCache->hasKey($path)) {
123
+            // might be "false" if object did not exist from last check
124
+            return $this->objectCache->get($path);
125
+        }
126
+        try {
127
+            $object = $this->getContainer()->getObject($path);
128
+            $object->retrieve();
129
+            $this->objectCache->set($path, $object);
130
+            return $object;
131
+        } catch (BadResponseError $e) {
132
+            // Expected response is "404 Not Found", so only log if it isn't
133
+            if ($e->getResponse()->getStatusCode() !== 404) {
134
+                \OC::$server->getLogger()->logException($e, [
135
+                    'level' => \OCP\Util::ERROR,
136
+                    'app' => 'files_external',
137
+                ]);
138
+            }
139
+            $this->objectCache->set($path, false);
140
+            return false;
141
+        }
142
+    }
143
+
144
+    /**
145
+     * Returns whether the given path exists.
146
+     *
147
+     * @param string $path
148
+     *
149
+     * @return bool true if the object exist, false otherwise
150
+     * @throws \OCP\Files\StorageAuthException
151
+     * @throws \OCP\Files\StorageNotAvailableException
152
+     */
153
+    private function doesObjectExist($path) {
154
+        return $this->fetchObject($path) !== false;
155
+    }
156
+
157
+    public function __construct($params) {
158
+        if ((empty($params['key']) and empty($params['password']))
159
+            or empty($params['user']) or empty($params['bucket'])
160
+            or empty($params['region'])
161
+        ) {
162
+            throw new StorageBadConfigException("API Key or password, Username, Bucket and Region have to be configured.");
163
+        }
164
+
165
+        $this->id = 'swift::' . $params['user'] . md5($params['bucket']);
166
+
167
+        $bucketUrl = new Uri($params['bucket']);
168
+        if ($bucketUrl->getHost()) {
169
+            $params['bucket'] = basename($bucketUrl->getPath());
170
+            $params['endpoint_url'] = (string)$bucketUrl->withPath(dirname($bucketUrl->getPath()));
171
+        }
172
+
173
+        if (empty($params['url'])) {
174
+            $params['url'] = 'https://identity.api.rackspacecloud.com/v2.0/';
175
+        }
176
+
177
+        if (empty($params['service_name'])) {
178
+            $params['service_name'] = 'cloudFiles';
179
+        }
180
+
181
+        $params['autocreate'] = true;
182
+
183
+        $this->params = $params;
184
+        // FIXME: private class...
185
+        $this->objectCache = new \OC\Cache\CappedMemoryCache();
186
+        $this->connectionFactory = new SwiftFactory(\OC::$server->getMemCacheFactory()->createDistributed('swift/'), $this->params);
187
+        $this->objectStore = new \OC\Files\ObjectStore\Swift($this->params, $this->connectionFactory);
188
+        $this->bucket = $params['bucket'];
189
+    }
190
+
191
+    public function mkdir($path) {
192
+        $path = $this->normalizePath($path);
193
+
194
+        if ($this->is_dir($path)) {
195
+            return false;
196
+        }
197
+
198
+        if ($path !== '.') {
199
+            $path .= '/';
200
+        }
201
+
202
+        try {
203
+            $this->getContainer()->createObject([
204
+                'name' => $path,
205
+                'content' => '',
206
+                'headers' => ['content-type' => 'httpd/unix-directory']
207
+            ]);
208
+            // invalidate so that the next access gets the real object
209
+            // with all properties
210
+            $this->objectCache->remove($path);
211
+        } catch (BadResponseError $e) {
212
+            \OC::$server->getLogger()->logException($e, [
213
+                'level' => \OCP\Util::ERROR,
214
+                'app' => 'files_external',
215
+            ]);
216
+            return false;
217
+        }
218
+
219
+        return true;
220
+    }
221
+
222
+    public function file_exists($path) {
223
+        $path = $this->normalizePath($path);
224
+
225
+        if ($path !== '.' && $this->is_dir($path)) {
226
+            $path .= '/';
227
+        }
228
+
229
+        return $this->doesObjectExist($path);
230
+    }
231
+
232
+    public function rmdir($path) {
233
+        $path = $this->normalizePath($path);
234
+
235
+        if (!$this->is_dir($path) || !$this->isDeletable($path)) {
236
+            return false;
237
+        }
238
+
239
+        $dh = $this->opendir($path);
240
+        while ($file = readdir($dh)) {
241
+            if (\OC\Files\Filesystem::isIgnoredDir($file)) {
242
+                continue;
243
+            }
244
+
245
+            if ($this->is_dir($path . '/' . $file)) {
246
+                $this->rmdir($path . '/' . $file);
247
+            } else {
248
+                $this->unlink($path . '/' . $file);
249
+            }
250
+        }
251
+
252
+        try {
253
+            $this->objectStore->deleteObject($path . '/');
254
+            $this->objectCache->remove($path . '/');
255
+        } catch (BadResponseError $e) {
256
+            \OC::$server->getLogger()->logException($e, [
257
+                'level' => \OCP\Util::ERROR,
258
+                'app' => 'files_external',
259
+            ]);
260
+            return false;
261
+        }
262
+
263
+        return true;
264
+    }
265
+
266
+    public function opendir($path) {
267
+        $path = $this->normalizePath($path);
268
+
269
+        if ($path === '.') {
270
+            $path = '';
271
+        } else {
272
+            $path .= '/';
273
+        }
274 274
 
275 275
 //		$path = str_replace('%23', '#', $path); // the prefix is sent as a query param, so revert the encoding of #
276 276
 
277
-		try {
278
-			$files = [];
279
-			$objects = $this->getContainer()->listObjects([
280
-				'prefix' => $path,
281
-				'delimiter' => '/'
282
-			]);
283
-
284
-			/** @var StorageObject $object */
285
-			foreach ($objects as $object) {
286
-				$file = basename($object->name);
287
-				if ($file !== basename($path) && $file !== '.') {
288
-					$files[] = $file;
289
-				}
290
-			}
291
-
292
-			return IteratorDirectory::wrap($files);
293
-		} catch (\Exception $e) {
294
-			\OC::$server->getLogger()->logException($e, [
295
-				'level' => \OCP\Util::ERROR,
296
-				'app' => 'files_external',
297
-			]);
298
-			return false;
299
-		}
300
-
301
-	}
302
-
303
-	public function stat($path) {
304
-		$path = $this->normalizePath($path);
305
-
306
-		if ($path === '.') {
307
-			$path = '';
308
-		} else if ($this->is_dir($path)) {
309
-			$path .= '/';
310
-		}
311
-
312
-		try {
313
-			$object = $this->fetchObject($path);
314
-			if (!$object) {
315
-				return false;
316
-			}
317
-		} catch (BadResponseError $e) {
318
-			\OC::$server->getLogger()->logException($e, [
319
-				'level' => \OCP\Util::ERROR,
320
-				'app' => 'files_external',
321
-			]);
322
-			return false;
323
-		}
324
-
325
-		$dateTime = $object->lastModified ? \DateTime::createFromFormat(\DateTime::RFC1123, $object->lastModified) : false;
326
-		$mtime = $dateTime ? $dateTime->getTimestamp() : null;
327
-		$objectMetadata = $object->getMetadata();
328
-		if (isset($objectMetadata['timestamp'])) {
329
-			$mtime = $objectMetadata['timestamp'];
330
-		}
331
-
332
-		if (!empty($mtime)) {
333
-			$mtime = floor($mtime);
334
-		}
335
-
336
-		$stat = array();
337
-		$stat['size'] = (int)$object->contentLength;
338
-		$stat['mtime'] = $mtime;
339
-		$stat['atime'] = time();
340
-		return $stat;
341
-	}
342
-
343
-	public function filetype($path) {
344
-		$path = $this->normalizePath($path);
345
-
346
-		if ($path !== '.' && $this->doesObjectExist($path)) {
347
-			return 'file';
348
-		}
349
-
350
-		if ($path !== '.') {
351
-			$path .= '/';
352
-		}
353
-
354
-		if ($this->doesObjectExist($path)) {
355
-			return 'dir';
356
-		}
357
-	}
358
-
359
-	public function unlink($path) {
360
-		$path = $this->normalizePath($path);
361
-
362
-		if ($this->is_dir($path)) {
363
-			return $this->rmdir($path);
364
-		}
365
-
366
-		try {
367
-			$this->objectStore->deleteObject($path);
368
-			$this->objectCache->remove($path);
369
-			$this->objectCache->remove($path . '/');
370
-		} catch (BadResponseError $e) {
371
-			if ($e->getResponse()->getStatusCode() !== 404) {
372
-				\OC::$server->getLogger()->logException($e, [
373
-					'level' => \OCP\Util::ERROR,
374
-					'app' => 'files_external',
375
-				]);
376
-				throw $e;
377
-			}
378
-		}
379
-
380
-		return true;
381
-	}
382
-
383
-	public function fopen($path, $mode) {
384
-		$path = $this->normalizePath($path);
385
-
386
-		switch ($mode) {
387
-			case 'a':
388
-			case 'ab':
389
-			case 'a+':
390
-				return false;
391
-			case 'r':
392
-			case 'rb':
393
-				try {
394
-					return $this->objectStore->readObject($path);
395
-				} catch (BadResponseError $e) {
396
-					\OC::$server->getLogger()->logException($e, [
397
-						'level' => \OCP\Util::ERROR,
398
-						'app' => 'files_external',
399
-					]);
400
-					return false;
401
-				}
402
-			case 'w':
403
-			case 'wb':
404
-			case 'r+':
405
-			case 'w+':
406
-			case 'wb+':
407
-			case 'x':
408
-			case 'x+':
409
-			case 'c':
410
-			case 'c+':
411
-				if (strrpos($path, '.') !== false) {
412
-					$ext = substr($path, strrpos($path, '.'));
413
-				} else {
414
-					$ext = '';
415
-				}
416
-				$tmpFile = \OCP\Files::tmpFile($ext);
417
-				// Fetch existing file if required
418
-				if ($mode[0] !== 'w' && $this->file_exists($path)) {
419
-					if ($mode[0] === 'x') {
420
-						// File cannot already exist
421
-						return false;
422
-					}
423
-					$source = $this->fopen($path, 'r');
424
-					file_put_contents($tmpFile, $source);
425
-				}
426
-				$handle = fopen($tmpFile, $mode);
427
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
428
-					$this->writeBack($tmpFile, $path);
429
-				});
430
-		}
431
-	}
432
-
433
-	public function touch($path, $mtime = null) {
434
-		$path = $this->normalizePath($path);
435
-		if (is_null($mtime)) {
436
-			$mtime = time();
437
-		}
438
-		$metadata = ['timestamp' => $mtime];
439
-		if ($this->file_exists($path)) {
440
-			if ($this->is_dir($path) && $path !== '.') {
441
-				$path .= '/';
442
-			}
443
-
444
-			$object = $this->fetchObject($path);
445
-			if ($object->mergeMetadata($metadata)) {
446
-				// invalidate target object to force repopulation on fetch
447
-				$this->objectCache->remove($path);
448
-			}
449
-			return true;
450
-		} else {
451
-			$mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
452
-			$this->getContainer()->createObject([
453
-				'name' => $path,
454
-				'content' => '',
455
-				'headers' => ['content-type' => 'httpd/unix-directory']
456
-			]);
457
-			// invalidate target object to force repopulation on fetch
458
-			$this->objectCache->remove($path);
459
-			return true;
460
-		}
461
-	}
462
-
463
-	public function copy($path1, $path2) {
464
-		$path1 = $this->normalizePath($path1);
465
-		$path2 = $this->normalizePath($path2);
466
-
467
-		$fileType = $this->filetype($path1);
468
-		if ($fileType) {
469
-			// make way
470
-			$this->unlink($path2);
471
-		}
472
-
473
-		if ($fileType === 'file') {
474
-			try {
475
-				$source = $this->fetchObject($path1);
476
-				$source->copy([
477
-					'destination' => $this->bucket . '/' . $path2
478
-				]);
479
-				// invalidate target object to force repopulation on fetch
480
-				$this->objectCache->remove($path2);
481
-				$this->objectCache->remove($path2 . '/');
482
-			} catch (BadResponseError $e) {
483
-				\OC::$server->getLogger()->logException($e, [
484
-					'level' => \OCP\Util::ERROR,
485
-					'app' => 'files_external',
486
-				]);
487
-				return false;
488
-			}
489
-
490
-		} else if ($fileType === 'dir') {
491
-			try {
492
-				$source = $this->fetchObject($path1 . '/');
493
-				$source->copy([
494
-					'destination' => $this->bucket . '/' . $path2 . '/'
495
-				]);
496
-				// invalidate target object to force repopulation on fetch
497
-				$this->objectCache->remove($path2);
498
-				$this->objectCache->remove($path2 . '/');
499
-			} catch (BadResponseError $e) {
500
-				\OC::$server->getLogger()->logException($e, [
501
-					'level' => \OCP\Util::ERROR,
502
-					'app' => 'files_external',
503
-				]);
504
-				return false;
505
-			}
506
-
507
-			$dh = $this->opendir($path1);
508
-			while ($file = readdir($dh)) {
509
-				if (\OC\Files\Filesystem::isIgnoredDir($file)) {
510
-					continue;
511
-				}
512
-
513
-				$source = $path1 . '/' . $file;
514
-				$target = $path2 . '/' . $file;
515
-				$this->copy($source, $target);
516
-			}
517
-
518
-		} else {
519
-			//file does not exist
520
-			return false;
521
-		}
522
-
523
-		return true;
524
-	}
525
-
526
-	public function rename($path1, $path2) {
527
-		$path1 = $this->normalizePath($path1);
528
-		$path2 = $this->normalizePath($path2);
529
-
530
-		$fileType = $this->filetype($path1);
531
-
532
-		if ($fileType === 'dir' || $fileType === 'file') {
533
-			// copy
534
-			if ($this->copy($path1, $path2) === false) {
535
-				return false;
536
-			}
537
-
538
-			// cleanup
539
-			if ($this->unlink($path1) === false) {
540
-				throw new \Exception('failed to remove original');
541
-				$this->unlink($path2);
542
-				return false;
543
-			}
544
-
545
-			return true;
546
-		}
547
-
548
-		return false;
549
-	}
550
-
551
-	public function getId() {
552
-		return $this->id;
553
-	}
554
-
555
-	/**
556
-	 * Returns the initialized object store container.
557
-	 *
558
-	 * @return \OpenStack\ObjectStore\v1\Models\Container
559
-	 * @throws \OCP\Files\StorageAuthException
560
-	 * @throws \OCP\Files\StorageNotAvailableException
561
-	 */
562
-	public function getContainer() {
563
-		if (is_null($this->container)) {
564
-			$this->container = $this->connectionFactory->getContainer();
565
-
566
-			if (!$this->file_exists('.')) {
567
-				$this->mkdir('.');
568
-			}
569
-		}
570
-		return $this->container;
571
-	}
572
-
573
-	public function writeBack($tmpFile, $path) {
574
-		$fileData = fopen($tmpFile, 'r');
575
-		$this->objectStore->writeObject($path, $fileData);
576
-		// invalidate target object to force repopulation on fetch
577
-		$this->objectCache->remove($path);
578
-		unlink($tmpFile);
579
-	}
580
-
581
-	public function hasUpdated($path, $time) {
582
-		if ($this->is_file($path)) {
583
-			return parent::hasUpdated($path, $time);
584
-		}
585
-		$path = $this->normalizePath($path);
586
-		$dh = $this->opendir($path);
587
-		$content = array();
588
-		while (($file = readdir($dh)) !== false) {
589
-			$content[] = $file;
590
-		}
591
-		if ($path === '.') {
592
-			$path = '';
593
-		}
594
-		$cachedContent = $this->getCache()->getFolderContents($path);
595
-		$cachedNames = array_map(function ($content) {
596
-			return $content['name'];
597
-		}, $cachedContent);
598
-		sort($cachedNames);
599
-		sort($content);
600
-		return $cachedNames !== $content;
601
-	}
602
-
603
-	/**
604
-	 * check if curl is installed
605
-	 */
606
-	public static function checkDependencies() {
607
-		return true;
608
-	}
277
+        try {
278
+            $files = [];
279
+            $objects = $this->getContainer()->listObjects([
280
+                'prefix' => $path,
281
+                'delimiter' => '/'
282
+            ]);
283
+
284
+            /** @var StorageObject $object */
285
+            foreach ($objects as $object) {
286
+                $file = basename($object->name);
287
+                if ($file !== basename($path) && $file !== '.') {
288
+                    $files[] = $file;
289
+                }
290
+            }
291
+
292
+            return IteratorDirectory::wrap($files);
293
+        } catch (\Exception $e) {
294
+            \OC::$server->getLogger()->logException($e, [
295
+                'level' => \OCP\Util::ERROR,
296
+                'app' => 'files_external',
297
+            ]);
298
+            return false;
299
+        }
300
+
301
+    }
302
+
303
+    public function stat($path) {
304
+        $path = $this->normalizePath($path);
305
+
306
+        if ($path === '.') {
307
+            $path = '';
308
+        } else if ($this->is_dir($path)) {
309
+            $path .= '/';
310
+        }
311
+
312
+        try {
313
+            $object = $this->fetchObject($path);
314
+            if (!$object) {
315
+                return false;
316
+            }
317
+        } catch (BadResponseError $e) {
318
+            \OC::$server->getLogger()->logException($e, [
319
+                'level' => \OCP\Util::ERROR,
320
+                'app' => 'files_external',
321
+            ]);
322
+            return false;
323
+        }
324
+
325
+        $dateTime = $object->lastModified ? \DateTime::createFromFormat(\DateTime::RFC1123, $object->lastModified) : false;
326
+        $mtime = $dateTime ? $dateTime->getTimestamp() : null;
327
+        $objectMetadata = $object->getMetadata();
328
+        if (isset($objectMetadata['timestamp'])) {
329
+            $mtime = $objectMetadata['timestamp'];
330
+        }
331
+
332
+        if (!empty($mtime)) {
333
+            $mtime = floor($mtime);
334
+        }
335
+
336
+        $stat = array();
337
+        $stat['size'] = (int)$object->contentLength;
338
+        $stat['mtime'] = $mtime;
339
+        $stat['atime'] = time();
340
+        return $stat;
341
+    }
342
+
343
+    public function filetype($path) {
344
+        $path = $this->normalizePath($path);
345
+
346
+        if ($path !== '.' && $this->doesObjectExist($path)) {
347
+            return 'file';
348
+        }
349
+
350
+        if ($path !== '.') {
351
+            $path .= '/';
352
+        }
353
+
354
+        if ($this->doesObjectExist($path)) {
355
+            return 'dir';
356
+        }
357
+    }
358
+
359
+    public function unlink($path) {
360
+        $path = $this->normalizePath($path);
361
+
362
+        if ($this->is_dir($path)) {
363
+            return $this->rmdir($path);
364
+        }
365
+
366
+        try {
367
+            $this->objectStore->deleteObject($path);
368
+            $this->objectCache->remove($path);
369
+            $this->objectCache->remove($path . '/');
370
+        } catch (BadResponseError $e) {
371
+            if ($e->getResponse()->getStatusCode() !== 404) {
372
+                \OC::$server->getLogger()->logException($e, [
373
+                    'level' => \OCP\Util::ERROR,
374
+                    'app' => 'files_external',
375
+                ]);
376
+                throw $e;
377
+            }
378
+        }
379
+
380
+        return true;
381
+    }
382
+
383
+    public function fopen($path, $mode) {
384
+        $path = $this->normalizePath($path);
385
+
386
+        switch ($mode) {
387
+            case 'a':
388
+            case 'ab':
389
+            case 'a+':
390
+                return false;
391
+            case 'r':
392
+            case 'rb':
393
+                try {
394
+                    return $this->objectStore->readObject($path);
395
+                } catch (BadResponseError $e) {
396
+                    \OC::$server->getLogger()->logException($e, [
397
+                        'level' => \OCP\Util::ERROR,
398
+                        'app' => 'files_external',
399
+                    ]);
400
+                    return false;
401
+                }
402
+            case 'w':
403
+            case 'wb':
404
+            case 'r+':
405
+            case 'w+':
406
+            case 'wb+':
407
+            case 'x':
408
+            case 'x+':
409
+            case 'c':
410
+            case 'c+':
411
+                if (strrpos($path, '.') !== false) {
412
+                    $ext = substr($path, strrpos($path, '.'));
413
+                } else {
414
+                    $ext = '';
415
+                }
416
+                $tmpFile = \OCP\Files::tmpFile($ext);
417
+                // Fetch existing file if required
418
+                if ($mode[0] !== 'w' && $this->file_exists($path)) {
419
+                    if ($mode[0] === 'x') {
420
+                        // File cannot already exist
421
+                        return false;
422
+                    }
423
+                    $source = $this->fopen($path, 'r');
424
+                    file_put_contents($tmpFile, $source);
425
+                }
426
+                $handle = fopen($tmpFile, $mode);
427
+                return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
428
+                    $this->writeBack($tmpFile, $path);
429
+                });
430
+        }
431
+    }
432
+
433
+    public function touch($path, $mtime = null) {
434
+        $path = $this->normalizePath($path);
435
+        if (is_null($mtime)) {
436
+            $mtime = time();
437
+        }
438
+        $metadata = ['timestamp' => $mtime];
439
+        if ($this->file_exists($path)) {
440
+            if ($this->is_dir($path) && $path !== '.') {
441
+                $path .= '/';
442
+            }
443
+
444
+            $object = $this->fetchObject($path);
445
+            if ($object->mergeMetadata($metadata)) {
446
+                // invalidate target object to force repopulation on fetch
447
+                $this->objectCache->remove($path);
448
+            }
449
+            return true;
450
+        } else {
451
+            $mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
452
+            $this->getContainer()->createObject([
453
+                'name' => $path,
454
+                'content' => '',
455
+                'headers' => ['content-type' => 'httpd/unix-directory']
456
+            ]);
457
+            // invalidate target object to force repopulation on fetch
458
+            $this->objectCache->remove($path);
459
+            return true;
460
+        }
461
+    }
462
+
463
+    public function copy($path1, $path2) {
464
+        $path1 = $this->normalizePath($path1);
465
+        $path2 = $this->normalizePath($path2);
466
+
467
+        $fileType = $this->filetype($path1);
468
+        if ($fileType) {
469
+            // make way
470
+            $this->unlink($path2);
471
+        }
472
+
473
+        if ($fileType === 'file') {
474
+            try {
475
+                $source = $this->fetchObject($path1);
476
+                $source->copy([
477
+                    'destination' => $this->bucket . '/' . $path2
478
+                ]);
479
+                // invalidate target object to force repopulation on fetch
480
+                $this->objectCache->remove($path2);
481
+                $this->objectCache->remove($path2 . '/');
482
+            } catch (BadResponseError $e) {
483
+                \OC::$server->getLogger()->logException($e, [
484
+                    'level' => \OCP\Util::ERROR,
485
+                    'app' => 'files_external',
486
+                ]);
487
+                return false;
488
+            }
489
+
490
+        } else if ($fileType === 'dir') {
491
+            try {
492
+                $source = $this->fetchObject($path1 . '/');
493
+                $source->copy([
494
+                    'destination' => $this->bucket . '/' . $path2 . '/'
495
+                ]);
496
+                // invalidate target object to force repopulation on fetch
497
+                $this->objectCache->remove($path2);
498
+                $this->objectCache->remove($path2 . '/');
499
+            } catch (BadResponseError $e) {
500
+                \OC::$server->getLogger()->logException($e, [
501
+                    'level' => \OCP\Util::ERROR,
502
+                    'app' => 'files_external',
503
+                ]);
504
+                return false;
505
+            }
506
+
507
+            $dh = $this->opendir($path1);
508
+            while ($file = readdir($dh)) {
509
+                if (\OC\Files\Filesystem::isIgnoredDir($file)) {
510
+                    continue;
511
+                }
512
+
513
+                $source = $path1 . '/' . $file;
514
+                $target = $path2 . '/' . $file;
515
+                $this->copy($source, $target);
516
+            }
517
+
518
+        } else {
519
+            //file does not exist
520
+            return false;
521
+        }
522
+
523
+        return true;
524
+    }
525
+
526
+    public function rename($path1, $path2) {
527
+        $path1 = $this->normalizePath($path1);
528
+        $path2 = $this->normalizePath($path2);
529
+
530
+        $fileType = $this->filetype($path1);
531
+
532
+        if ($fileType === 'dir' || $fileType === 'file') {
533
+            // copy
534
+            if ($this->copy($path1, $path2) === false) {
535
+                return false;
536
+            }
537
+
538
+            // cleanup
539
+            if ($this->unlink($path1) === false) {
540
+                throw new \Exception('failed to remove original');
541
+                $this->unlink($path2);
542
+                return false;
543
+            }
544
+
545
+            return true;
546
+        }
547
+
548
+        return false;
549
+    }
550
+
551
+    public function getId() {
552
+        return $this->id;
553
+    }
554
+
555
+    /**
556
+     * Returns the initialized object store container.
557
+     *
558
+     * @return \OpenStack\ObjectStore\v1\Models\Container
559
+     * @throws \OCP\Files\StorageAuthException
560
+     * @throws \OCP\Files\StorageNotAvailableException
561
+     */
562
+    public function getContainer() {
563
+        if (is_null($this->container)) {
564
+            $this->container = $this->connectionFactory->getContainer();
565
+
566
+            if (!$this->file_exists('.')) {
567
+                $this->mkdir('.');
568
+            }
569
+        }
570
+        return $this->container;
571
+    }
572
+
573
+    public function writeBack($tmpFile, $path) {
574
+        $fileData = fopen($tmpFile, 'r');
575
+        $this->objectStore->writeObject($path, $fileData);
576
+        // invalidate target object to force repopulation on fetch
577
+        $this->objectCache->remove($path);
578
+        unlink($tmpFile);
579
+    }
580
+
581
+    public function hasUpdated($path, $time) {
582
+        if ($this->is_file($path)) {
583
+            return parent::hasUpdated($path, $time);
584
+        }
585
+        $path = $this->normalizePath($path);
586
+        $dh = $this->opendir($path);
587
+        $content = array();
588
+        while (($file = readdir($dh)) !== false) {
589
+            $content[] = $file;
590
+        }
591
+        if ($path === '.') {
592
+            $path = '';
593
+        }
594
+        $cachedContent = $this->getCache()->getFolderContents($path);
595
+        $cachedNames = array_map(function ($content) {
596
+            return $content['name'];
597
+        }, $cachedContent);
598
+        sort($cachedNames);
599
+        sort($content);
600
+        return $cachedNames !== $content;
601
+    }
602
+
603
+    /**
604
+     * check if curl is installed
605
+     */
606
+    public static function checkDependencies() {
607
+        return true;
608
+    }
609 609
 
610 610
 }
Please login to merge, or discard this patch.
Spacing   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php
2
-declare(strict_types=1);
2
+declare(strict_types = 1);
3 3
 /**
4 4
  * @copyright Copyright (c) 2016, ownCloud, Inc.
5 5
  *
@@ -162,12 +162,12 @@  discard block
 block discarded – undo
162 162
 			throw new StorageBadConfigException("API Key or password, Username, Bucket and Region have to be configured.");
163 163
 		}
164 164
 
165
-		$this->id = 'swift::' . $params['user'] . md5($params['bucket']);
165
+		$this->id = 'swift::'.$params['user'].md5($params['bucket']);
166 166
 
167 167
 		$bucketUrl = new Uri($params['bucket']);
168 168
 		if ($bucketUrl->getHost()) {
169 169
 			$params['bucket'] = basename($bucketUrl->getPath());
170
-			$params['endpoint_url'] = (string)$bucketUrl->withPath(dirname($bucketUrl->getPath()));
170
+			$params['endpoint_url'] = (string) $bucketUrl->withPath(dirname($bucketUrl->getPath()));
171 171
 		}
172 172
 
173 173
 		if (empty($params['url'])) {
@@ -242,16 +242,16 @@  discard block
 block discarded – undo
242 242
 				continue;
243 243
 			}
244 244
 
245
-			if ($this->is_dir($path . '/' . $file)) {
246
-				$this->rmdir($path . '/' . $file);
245
+			if ($this->is_dir($path.'/'.$file)) {
246
+				$this->rmdir($path.'/'.$file);
247 247
 			} else {
248
-				$this->unlink($path . '/' . $file);
248
+				$this->unlink($path.'/'.$file);
249 249
 			}
250 250
 		}
251 251
 
252 252
 		try {
253
-			$this->objectStore->deleteObject($path . '/');
254
-			$this->objectCache->remove($path . '/');
253
+			$this->objectStore->deleteObject($path.'/');
254
+			$this->objectCache->remove($path.'/');
255 255
 		} catch (BadResponseError $e) {
256 256
 			\OC::$server->getLogger()->logException($e, [
257 257
 				'level' => \OCP\Util::ERROR,
@@ -334,7 +334,7 @@  discard block
 block discarded – undo
334 334
 		}
335 335
 
336 336
 		$stat = array();
337
-		$stat['size'] = (int)$object->contentLength;
337
+		$stat['size'] = (int) $object->contentLength;
338 338
 		$stat['mtime'] = $mtime;
339 339
 		$stat['atime'] = time();
340 340
 		return $stat;
@@ -366,7 +366,7 @@  discard block
 block discarded – undo
366 366
 		try {
367 367
 			$this->objectStore->deleteObject($path);
368 368
 			$this->objectCache->remove($path);
369
-			$this->objectCache->remove($path . '/');
369
+			$this->objectCache->remove($path.'/');
370 370
 		} catch (BadResponseError $e) {
371 371
 			if ($e->getResponse()->getStatusCode() !== 404) {
372 372
 				\OC::$server->getLogger()->logException($e, [
@@ -424,7 +424,7 @@  discard block
 block discarded – undo
424 424
 					file_put_contents($tmpFile, $source);
425 425
 				}
426 426
 				$handle = fopen($tmpFile, $mode);
427
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
427
+				return CallbackWrapper::wrap($handle, null, null, function() use ($path, $tmpFile) {
428 428
 					$this->writeBack($tmpFile, $path);
429 429
 				});
430 430
 		}
@@ -474,11 +474,11 @@  discard block
 block discarded – undo
474 474
 			try {
475 475
 				$source = $this->fetchObject($path1);
476 476
 				$source->copy([
477
-					'destination' => $this->bucket . '/' . $path2
477
+					'destination' => $this->bucket.'/'.$path2
478 478
 				]);
479 479
 				// invalidate target object to force repopulation on fetch
480 480
 				$this->objectCache->remove($path2);
481
-				$this->objectCache->remove($path2 . '/');
481
+				$this->objectCache->remove($path2.'/');
482 482
 			} catch (BadResponseError $e) {
483 483
 				\OC::$server->getLogger()->logException($e, [
484 484
 					'level' => \OCP\Util::ERROR,
@@ -489,13 +489,13 @@  discard block
 block discarded – undo
489 489
 
490 490
 		} else if ($fileType === 'dir') {
491 491
 			try {
492
-				$source = $this->fetchObject($path1 . '/');
492
+				$source = $this->fetchObject($path1.'/');
493 493
 				$source->copy([
494
-					'destination' => $this->bucket . '/' . $path2 . '/'
494
+					'destination' => $this->bucket.'/'.$path2.'/'
495 495
 				]);
496 496
 				// invalidate target object to force repopulation on fetch
497 497
 				$this->objectCache->remove($path2);
498
-				$this->objectCache->remove($path2 . '/');
498
+				$this->objectCache->remove($path2.'/');
499 499
 			} catch (BadResponseError $e) {
500 500
 				\OC::$server->getLogger()->logException($e, [
501 501
 					'level' => \OCP\Util::ERROR,
@@ -510,8 +510,8 @@  discard block
 block discarded – undo
510 510
 					continue;
511 511
 				}
512 512
 
513
-				$source = $path1 . '/' . $file;
514
-				$target = $path2 . '/' . $file;
513
+				$source = $path1.'/'.$file;
514
+				$target = $path2.'/'.$file;
515 515
 				$this->copy($source, $target);
516 516
 			}
517 517
 
@@ -592,7 +592,7 @@  discard block
 block discarded – undo
592 592
 			$path = '';
593 593
 		}
594 594
 		$cachedContent = $this->getCache()->getFolderContents($path);
595
-		$cachedNames = array_map(function ($content) {
595
+		$cachedNames = array_map(function($content) {
596 596
 			return $content['name'];
597 597
 		}, $cachedContent);
598 598
 		sort($cachedNames);
Please login to merge, or discard this patch.
lib/private/Files/ObjectStore/SwiftFactory.php 2 patches
Indentation   +120 added lines, -120 removed lines patch added patch discarded remove patch
@@ -39,136 +39,136 @@
 block discarded – undo
39 39
 use OpenStack\ObjectStore\v1\Models\Container;
40 40
 
41 41
 class SwiftFactory {
42
-	private $cache;
43
-	private $params;
44
-	/** @var Container|null */
45
-	private $container = null;
42
+    private $cache;
43
+    private $params;
44
+    /** @var Container|null */
45
+    private $container = null;
46 46
 
47
-	public function __construct(ICache $cache, array $params) {
48
-		$this->cache = $cache;
49
-		$this->params = $params;
50
-	}
47
+    public function __construct(ICache $cache, array $params) {
48
+        $this->cache = $cache;
49
+        $this->params = $params;
50
+    }
51 51
 
52
-	private function getCachedToken(string $cacheKey) {
53
-		$cachedTokenString = $this->cache->get($cacheKey . '/token');
54
-		if ($cachedTokenString) {
55
-			return json_decode($cachedTokenString);
56
-		} else {
57
-			return null;
58
-		}
59
-	}
52
+    private function getCachedToken(string $cacheKey) {
53
+        $cachedTokenString = $this->cache->get($cacheKey . '/token');
54
+        if ($cachedTokenString) {
55
+            return json_decode($cachedTokenString);
56
+        } else {
57
+            return null;
58
+        }
59
+    }
60 60
 
61
-	private function cacheToken(Token $token, string $cacheKey) {
62
-		$this->cache->set($cacheKey . '/token', json_encode($token));
63
-	}
61
+    private function cacheToken(Token $token, string $cacheKey) {
62
+        $this->cache->set($cacheKey . '/token', json_encode($token));
63
+    }
64 64
 
65
-	/**
66
-	 * @return OpenStack
67
-	 * @throws StorageAuthException
68
-	 */
69
-	private function getClient() {
70
-		if (isset($this->params['bucket'])) {
71
-			$this->params['container'] = $this->params['bucket'];
72
-		}
73
-		if (!isset($this->params['container'])) {
74
-			$this->params['container'] = 'owncloud';
75
-		}
76
-		if (!isset($this->params['autocreate'])) {
77
-			// should only be true for tests
78
-			$this->params['autocreate'] = false;
79
-		}
80
-		if (!isset($this->params['username']) && isset($this->params['user'])) {
81
-			$this->params['username'] = $this->params['user'];
82
-		}
83
-		if (!isset($this->params['tenantName']) && isset($this->params['tenant'])) {
84
-			$this->params['tenantName'] = $this->params['tenant'];
85
-		}
65
+    /**
66
+     * @return OpenStack
67
+     * @throws StorageAuthException
68
+     */
69
+    private function getClient() {
70
+        if (isset($this->params['bucket'])) {
71
+            $this->params['container'] = $this->params['bucket'];
72
+        }
73
+        if (!isset($this->params['container'])) {
74
+            $this->params['container'] = 'owncloud';
75
+        }
76
+        if (!isset($this->params['autocreate'])) {
77
+            // should only be true for tests
78
+            $this->params['autocreate'] = false;
79
+        }
80
+        if (!isset($this->params['username']) && isset($this->params['user'])) {
81
+            $this->params['username'] = $this->params['user'];
82
+        }
83
+        if (!isset($this->params['tenantName']) && isset($this->params['tenant'])) {
84
+            $this->params['tenantName'] = $this->params['tenant'];
85
+        }
86 86
 
87
-		$cacheKey = $this->params['username'] . '@' . $this->params['url'] . '/' . $this->params['bucket'];
88
-		$token = $this->getCachedToken($cacheKey);
89
-		$hasToken = is_array($token) && (new \DateTimeImmutable($token['expires_at'])) > (new \DateTimeImmutable('now'));
90
-		if ($hasToken) {
91
-			$this->params['cachedToken'] = $token;
92
-		}
93
-		$httpClient = new Client([
94
-			'base_uri' => TransportUtils::normalizeUrl($this->params['url']),
95
-			'handler' => HandlerStack::create()
96
-		]);
87
+        $cacheKey = $this->params['username'] . '@' . $this->params['url'] . '/' . $this->params['bucket'];
88
+        $token = $this->getCachedToken($cacheKey);
89
+        $hasToken = is_array($token) && (new \DateTimeImmutable($token['expires_at'])) > (new \DateTimeImmutable('now'));
90
+        if ($hasToken) {
91
+            $this->params['cachedToken'] = $token;
92
+        }
93
+        $httpClient = new Client([
94
+            'base_uri' => TransportUtils::normalizeUrl($this->params['url']),
95
+            'handler' => HandlerStack::create()
96
+        ]);
97 97
 
98
-		$authService = Service::factory($httpClient);
99
-		$this->params['identityService'] = $authService;
100
-		$this->params['authUrl'] = $this->params['url'];
101
-		$client = new OpenStack($this->params);
98
+        $authService = Service::factory($httpClient);
99
+        $this->params['identityService'] = $authService;
100
+        $this->params['authUrl'] = $this->params['url'];
101
+        $client = new OpenStack($this->params);
102 102
 
103
-		if (!$hasToken) {
104
-			try {
105
-				$token = $authService->generateToken($this->params);
106
-				$this->cacheToken($token, $cacheKey);
107
-			} catch (ConnectException $e) {
108
-				throw new StorageAuthException('Failed to connect to keystone, verify the keystone url', $e);
109
-			} catch (ClientException $e) {
110
-				$statusCode = $e->getResponse()->getStatusCode();
111
-				if ($statusCode === 404) {
112
-					throw new StorageAuthException('Keystone not found, verify the keystone url', $e);
113
-				} else if ($statusCode === 412) {
114
-					throw new StorageAuthException('Precondition failed, verify the keystone url', $e);
115
-				} else if ($statusCode === 401) {
116
-					throw new StorageAuthException('Authentication failed, verify the username, password and possibly tenant', $e);
117
-				} else {
118
-					throw new StorageAuthException('Unknown error', $e);
119
-				}
120
-			} catch (RequestException $e) {
121
-				throw new StorageAuthException('Connection reset while connecting to keystone, verify the keystone url', $e);
122
-			}
123
-		}
103
+        if (!$hasToken) {
104
+            try {
105
+                $token = $authService->generateToken($this->params);
106
+                $this->cacheToken($token, $cacheKey);
107
+            } catch (ConnectException $e) {
108
+                throw new StorageAuthException('Failed to connect to keystone, verify the keystone url', $e);
109
+            } catch (ClientException $e) {
110
+                $statusCode = $e->getResponse()->getStatusCode();
111
+                if ($statusCode === 404) {
112
+                    throw new StorageAuthException('Keystone not found, verify the keystone url', $e);
113
+                } else if ($statusCode === 412) {
114
+                    throw new StorageAuthException('Precondition failed, verify the keystone url', $e);
115
+                } else if ($statusCode === 401) {
116
+                    throw new StorageAuthException('Authentication failed, verify the username, password and possibly tenant', $e);
117
+                } else {
118
+                    throw new StorageAuthException('Unknown error', $e);
119
+                }
120
+            } catch (RequestException $e) {
121
+                throw new StorageAuthException('Connection reset while connecting to keystone, verify the keystone url', $e);
122
+            }
123
+        }
124 124
 
125
-		return $client;
126
-	}
125
+        return $client;
126
+    }
127 127
 
128
-	/**
129
-	 * @return \OpenStack\ObjectStore\v1\Models\Container
130
-	 * @throws StorageAuthException
131
-	 * @throws StorageNotAvailableException
132
-	 */
133
-	public function getContainer() {
134
-		if (is_null($this->container)) {
135
-			$this->container = $this->createContainer();
136
-		}
128
+    /**
129
+     * @return \OpenStack\ObjectStore\v1\Models\Container
130
+     * @throws StorageAuthException
131
+     * @throws StorageNotAvailableException
132
+     */
133
+    public function getContainer() {
134
+        if (is_null($this->container)) {
135
+            $this->container = $this->createContainer();
136
+        }
137 137
 
138
-		return $this->container;
139
-	}
138
+        return $this->container;
139
+    }
140 140
 
141
-	/**
142
-	 * @return \OpenStack\ObjectStore\v1\Models\Container
143
-	 * @throws StorageAuthException
144
-	 * @throws StorageNotAvailableException
145
-	 */
146
-	private function createContainer() {
147
-		$client = $this->getClient();
148
-		$objectStoreService = $client->objectStoreV1();
141
+    /**
142
+     * @return \OpenStack\ObjectStore\v1\Models\Container
143
+     * @throws StorageAuthException
144
+     * @throws StorageNotAvailableException
145
+     */
146
+    private function createContainer() {
147
+        $client = $this->getClient();
148
+        $objectStoreService = $client->objectStoreV1();
149 149
 
150
-		$autoCreate = isset($this->params['autocreate']) && $this->params['autocreate'] === true;
151
-		try {
152
-			$container = $objectStoreService->getContainer($this->params['container']);
153
-			if ($autoCreate) {
154
-				$container->getMetadata();
155
-			}
156
-			return $container;
157
-		} catch (BadResponseError $ex) {
158
-			// if the container does not exist and autocreate is true try to create the container on the fly
159
-			if ($ex->getResponse()->getStatusCode() === 404 && $autoCreate) {
160
-				return $objectStoreService->createContainer([
161
-					'name' => $this->params['container']
162
-				]);
163
-			} else {
164
-				throw new StorageNotAvailableException('Invalid response while trying to get container info', StorageNotAvailableException::STATUS_ERROR, $e);
165
-			}
166
-		} catch (ConnectException $e) {
167
-			/** @var RequestInterface $request */
168
-			$request = $e->getRequest();
169
-			$host = $request->getUri()->getHost() . ':' . $request->getUri()->getPort();
170
-			\OC::$server->getLogger()->error("Can't connect to object storage server at $host");
171
-			throw new StorageNotAvailableException("Can't connect to object storage server at $host", StorageNotAvailableException::STATUS_ERROR, $e);
172
-		}
173
-	}
150
+        $autoCreate = isset($this->params['autocreate']) && $this->params['autocreate'] === true;
151
+        try {
152
+            $container = $objectStoreService->getContainer($this->params['container']);
153
+            if ($autoCreate) {
154
+                $container->getMetadata();
155
+            }
156
+            return $container;
157
+        } catch (BadResponseError $ex) {
158
+            // if the container does not exist and autocreate is true try to create the container on the fly
159
+            if ($ex->getResponse()->getStatusCode() === 404 && $autoCreate) {
160
+                return $objectStoreService->createContainer([
161
+                    'name' => $this->params['container']
162
+                ]);
163
+            } else {
164
+                throw new StorageNotAvailableException('Invalid response while trying to get container info', StorageNotAvailableException::STATUS_ERROR, $e);
165
+            }
166
+        } catch (ConnectException $e) {
167
+            /** @var RequestInterface $request */
168
+            $request = $e->getRequest();
169
+            $host = $request->getUri()->getHost() . ':' . $request->getUri()->getPort();
170
+            \OC::$server->getLogger()->error("Can't connect to object storage server at $host");
171
+            throw new StorageNotAvailableException("Can't connect to object storage server at $host", StorageNotAvailableException::STATUS_ERROR, $e);
172
+        }
173
+    }
174 174
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php
2
-declare(strict_types=1);
2
+declare(strict_types = 1);
3 3
 /**
4 4
  * @copyright Copyright (c) 2018 Robin Appelman <[email protected]>
5 5
  *
@@ -50,7 +50,7 @@  discard block
 block discarded – undo
50 50
 	}
51 51
 
52 52
 	private function getCachedToken(string $cacheKey) {
53
-		$cachedTokenString = $this->cache->get($cacheKey . '/token');
53
+		$cachedTokenString = $this->cache->get($cacheKey.'/token');
54 54
 		if ($cachedTokenString) {
55 55
 			return json_decode($cachedTokenString);
56 56
 		} else {
@@ -59,7 +59,7 @@  discard block
 block discarded – undo
59 59
 	}
60 60
 
61 61
 	private function cacheToken(Token $token, string $cacheKey) {
62
-		$this->cache->set($cacheKey . '/token', json_encode($token));
62
+		$this->cache->set($cacheKey.'/token', json_encode($token));
63 63
 	}
64 64
 
65 65
 	/**
@@ -84,7 +84,7 @@  discard block
 block discarded – undo
84 84
 			$this->params['tenantName'] = $this->params['tenant'];
85 85
 		}
86 86
 
87
-		$cacheKey = $this->params['username'] . '@' . $this->params['url'] . '/' . $this->params['bucket'];
87
+		$cacheKey = $this->params['username'].'@'.$this->params['url'].'/'.$this->params['bucket'];
88 88
 		$token = $this->getCachedToken($cacheKey);
89 89
 		$hasToken = is_array($token) && (new \DateTimeImmutable($token['expires_at'])) > (new \DateTimeImmutable('now'));
90 90
 		if ($hasToken) {
@@ -166,7 +166,7 @@  discard block
 block discarded – undo
166 166
 		} catch (ConnectException $e) {
167 167
 			/** @var RequestInterface $request */
168 168
 			$request = $e->getRequest();
169
-			$host = $request->getUri()->getHost() . ':' . $request->getUri()->getPort();
169
+			$host = $request->getUri()->getHost().':'.$request->getUri()->getPort();
170 170
 			\OC::$server->getLogger()->error("Can't connect to object storage server at $host");
171 171
 			throw new StorageNotAvailableException("Can't connect to object storage server at $host", StorageNotAvailableException::STATUS_ERROR, $e);
172 172
 		}
Please login to merge, or discard this patch.
lib/private/Files/ObjectStore/Swift.php 1 patch
Indentation   +82 added lines, -82 removed lines patch added patch discarded remove patch
@@ -31,87 +31,87 @@
 block discarded – undo
31 31
 use OCP\Files\StorageAuthException;
32 32
 
33 33
 class Swift implements IObjectStore {
34
-	/**
35
-	 * @var array
36
-	 */
37
-	private $params;
38
-
39
-	/**
40
-	 * @var \OpenStack\ObjectStore\v1\Models\Container|null
41
-	 */
42
-	private $container = null;
43
-
44
-	/** @var SwiftFactory */
45
-	private $swiftFactory;
46
-
47
-	public function __construct($params, SwiftFactory $connectionFactory = null) {
48
-		$this->swiftFactory = $connectionFactory ?: new SwiftFactory(\OC::$server->getMemCacheFactory()->createDistributed('swift::'), $params);
49
-		$this->params = $params;
50
-	}
51
-
52
-	/**
53
-	 * @return \OpenStack\ObjectStore\v1\Models\Container
54
-	 * @throws StorageAuthException
55
-	 * @throws \OCP\Files\StorageNotAvailableException
56
-	 */
57
-	private function getContainer() {
58
-		return $this->swiftFactory->getContainer();
59
-	}
60
-
61
-	/**
62
-	 * @return string the container name where objects are stored
63
-	 */
64
-	public function getStorageId() {
65
-		return $this->params['container'];
66
-	}
67
-
68
-	/**
69
-	 * @param string $urn the unified resource name used to identify the object
70
-	 * @param resource $stream stream with the data to write
71
-	 * @throws \Exception from openstack lib when something goes wrong
72
-	 */
73
-	public function writeObject($urn, $stream) {
74
-		$this->getContainer()->createObject([
75
-			'name' => $urn,
76
-			'stream' => stream_for($stream)
77
-		]);
78
-	}
79
-
80
-	/**
81
-	 * @param string $urn the unified resource name used to identify the object
82
-	 * @return resource stream with the read data
83
-	 * @throws \Exception from openstack lib when something goes wrong
84
-	 */
85
-	public function readObject($urn) {
86
-		$object = $this->getContainer()->getObject($urn);
87
-
88
-		// we need to keep a reference to objectContent or
89
-		// the stream will be closed before we can do anything with it
90
-		$objectContent = $object->download();
91
-		$objectContent->rewind();
92
-
93
-		$stream = $objectContent->detach();
94
-		// save the object content in the context of the stream to prevent it being gc'd until the stream is closed
95
-		stream_context_set_option($stream, 'swift', 'content', $objectContent);
96
-
97
-		return RetryWrapper::wrap($stream);
98
-	}
99
-
100
-	/**
101
-	 * @param string $urn Unified Resource Name
102
-	 * @return void
103
-	 * @throws \Exception from openstack lib when something goes wrong
104
-	 */
105
-	public function deleteObject($urn) {
106
-		$this->getContainer()->getObject($urn)->delete();
107
-	}
108
-
109
-	/**
110
-	 * @return void
111
-	 * @throws \Exception from openstack lib when something goes wrong
112
-	 */
113
-	public function deleteContainer() {
114
-		$this->getContainer()->delete();
115
-	}
34
+    /**
35
+     * @var array
36
+     */
37
+    private $params;
38
+
39
+    /**
40
+     * @var \OpenStack\ObjectStore\v1\Models\Container|null
41
+     */
42
+    private $container = null;
43
+
44
+    /** @var SwiftFactory */
45
+    private $swiftFactory;
46
+
47
+    public function __construct($params, SwiftFactory $connectionFactory = null) {
48
+        $this->swiftFactory = $connectionFactory ?: new SwiftFactory(\OC::$server->getMemCacheFactory()->createDistributed('swift::'), $params);
49
+        $this->params = $params;
50
+    }
51
+
52
+    /**
53
+     * @return \OpenStack\ObjectStore\v1\Models\Container
54
+     * @throws StorageAuthException
55
+     * @throws \OCP\Files\StorageNotAvailableException
56
+     */
57
+    private function getContainer() {
58
+        return $this->swiftFactory->getContainer();
59
+    }
60
+
61
+    /**
62
+     * @return string the container name where objects are stored
63
+     */
64
+    public function getStorageId() {
65
+        return $this->params['container'];
66
+    }
67
+
68
+    /**
69
+     * @param string $urn the unified resource name used to identify the object
70
+     * @param resource $stream stream with the data to write
71
+     * @throws \Exception from openstack lib when something goes wrong
72
+     */
73
+    public function writeObject($urn, $stream) {
74
+        $this->getContainer()->createObject([
75
+            'name' => $urn,
76
+            'stream' => stream_for($stream)
77
+        ]);
78
+    }
79
+
80
+    /**
81
+     * @param string $urn the unified resource name used to identify the object
82
+     * @return resource stream with the read data
83
+     * @throws \Exception from openstack lib when something goes wrong
84
+     */
85
+    public function readObject($urn) {
86
+        $object = $this->getContainer()->getObject($urn);
87
+
88
+        // we need to keep a reference to objectContent or
89
+        // the stream will be closed before we can do anything with it
90
+        $objectContent = $object->download();
91
+        $objectContent->rewind();
92
+
93
+        $stream = $objectContent->detach();
94
+        // save the object content in the context of the stream to prevent it being gc'd until the stream is closed
95
+        stream_context_set_option($stream, 'swift', 'content', $objectContent);
96
+
97
+        return RetryWrapper::wrap($stream);
98
+    }
99
+
100
+    /**
101
+     * @param string $urn Unified Resource Name
102
+     * @return void
103
+     * @throws \Exception from openstack lib when something goes wrong
104
+     */
105
+    public function deleteObject($urn) {
106
+        $this->getContainer()->getObject($urn)->delete();
107
+    }
108
+
109
+    /**
110
+     * @return void
111
+     * @throws \Exception from openstack lib when something goes wrong
112
+     */
113
+    public function deleteContainer() {
114
+        $this->getContainer()->delete();
115
+    }
116 116
 
117 117
 }
Please login to merge, or discard this patch.