Completed
Pull Request — master (#5517)
by Morris
14:14
created
apps/dav/lib/Connector/Sabre/File.php 2 patches
Indentation   +516 added lines, -516 removed lines patch added patch discarded remove patch
@@ -58,521 +58,521 @@
 block discarded – undo
58 58
 
59 59
 class File extends Node implements IFile {
60 60
 
61
-	/**
62
-	 * Updates the data
63
-	 *
64
-	 * The data argument is a readable stream resource.
65
-	 *
66
-	 * After a successful put operation, you may choose to return an ETag. The
67
-	 * etag must always be surrounded by double-quotes. These quotes must
68
-	 * appear in the actual string you're returning.
69
-	 *
70
-	 * Clients may use the ETag from a PUT request to later on make sure that
71
-	 * when they update the file, the contents haven't changed in the mean
72
-	 * time.
73
-	 *
74
-	 * If you don't plan to store the file byte-by-byte, and you return a
75
-	 * different object on a subsequent GET you are strongly recommended to not
76
-	 * return an ETag, and just return null.
77
-	 *
78
-	 * @param resource $data
79
-	 *
80
-	 * @throws Forbidden
81
-	 * @throws UnsupportedMediaType
82
-	 * @throws BadRequest
83
-	 * @throws Exception
84
-	 * @throws EntityTooLarge
85
-	 * @throws ServiceUnavailable
86
-	 * @throws FileLocked
87
-	 * @return string|null
88
-	 */
89
-	public function put($data) {
90
-		try {
91
-			$exists = $this->fileView->file_exists($this->path);
92
-			if ($this->info && $exists && !$this->info->isUpdateable()) {
93
-				throw new Forbidden();
94
-			}
95
-		} catch (StorageNotAvailableException $e) {
96
-			throw new ServiceUnavailable("File is not updatable: " . $e->getMessage());
97
-		}
98
-
99
-		// verify path of the target
100
-		$this->verifyPath();
101
-
102
-		// chunked handling
103
-		if (isset($_SERVER['HTTP_OC_CHUNKED'])) {
104
-			try {
105
-				return $this->createFileChunked($data);
106
-			} catch (\Exception $e) {
107
-				$this->convertToSabreException($e);
108
-			}
109
-		}
110
-
111
-		list($partStorage) = $this->fileView->resolvePath($this->path);
112
-		$needsPartFile = $this->needsPartFile($partStorage) && (strlen($this->path) > 1);
113
-
114
-		if ($needsPartFile) {
115
-			// mark file as partial while uploading (ignored by the scanner)
116
-			$partFilePath = $this->getPartFileBasePath($this->path) . '.ocTransferId' . rand() . '.part';
117
-		} else {
118
-			// upload file directly as the final path
119
-			$partFilePath = $this->path;
120
-		}
121
-
122
-		// the part file and target file might be on a different storage in case of a single file storage (e.g. single file share)
123
-		/** @var \OC\Files\Storage\Storage $partStorage */
124
-		list($partStorage, $internalPartPath) = $this->fileView->resolvePath($partFilePath);
125
-		/** @var \OC\Files\Storage\Storage $storage */
126
-		list($storage, $internalPath) = $this->fileView->resolvePath($this->path);
127
-		try {
128
-			$target = $partStorage->fopen($internalPartPath, 'wb');
129
-			if ($target === false) {
130
-				\OCP\Util::writeLog('webdav', '\OC\Files\Filesystem::fopen() failed', \OCP\Util::ERROR);
131
-				// because we have no clue about the cause we can only throw back a 500/Internal Server Error
132
-				throw new Exception('Could not write file contents');
133
-			}
134
-			list($count, $result) = \OC_Helper::streamCopy($data, $target);
135
-			fclose($target);
136
-
137
-			if ($result === false) {
138
-				$expected = -1;
139
-				if (isset($_SERVER['CONTENT_LENGTH'])) {
140
-					$expected = $_SERVER['CONTENT_LENGTH'];
141
-				}
142
-				throw new Exception('Error while copying file to target location (copied bytes: ' . $count . ', expected filesize: ' . $expected . ' )');
143
-			}
144
-
145
-			// if content length is sent by client:
146
-			// double check if the file was fully received
147
-			// compare expected and actual size
148
-			if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['REQUEST_METHOD'] === 'PUT') {
149
-				$expected = $_SERVER['CONTENT_LENGTH'];
150
-				if ($count != $expected) {
151
-					throw new BadRequest('expected filesize ' . $expected . ' got ' . $count);
152
-				}
153
-			}
154
-
155
-		} catch (\Exception $e) {
156
-			if ($needsPartFile) {
157
-				$partStorage->unlink($internalPartPath);
158
-			}
159
-			$this->convertToSabreException($e);
160
-		}
161
-
162
-		try {
163
-			$view = \OC\Files\Filesystem::getView();
164
-			if ($view) {
165
-				$run = $this->emitPreHooks($exists);
166
-			} else {
167
-				$run = true;
168
-			}
169
-
170
-			try {
171
-				$this->changeLock(ILockingProvider::LOCK_EXCLUSIVE);
172
-			} catch (LockedException $e) {
173
-				if ($needsPartFile) {
174
-					$partStorage->unlink($internalPartPath);
175
-				}
176
-				throw new FileLocked($e->getMessage(), $e->getCode(), $e);
177
-			}
178
-
179
-			if ($needsPartFile) {
180
-				// rename to correct path
181
-				try {
182
-					if ($run) {
183
-						$renameOkay = $storage->moveFromStorage($partStorage, $internalPartPath, $internalPath);
184
-						$fileExists = $storage->file_exists($internalPath);
185
-					}
186
-					if (!$run || $renameOkay === false || $fileExists === false) {
187
-						\OCP\Util::writeLog('webdav', 'renaming part file to final file failed ($run: ' . ( $run ? 'true' : 'false' ) . ', $renameOkay: '  . ( $renameOkay ? 'true' : 'false' ) . ', $fileExists: ' . ( $fileExists ? 'true' : 'false' ) . ')', \OCP\Util::ERROR);
188
-						throw new Exception('Could not rename part file to final file');
189
-					}
190
-				} catch (ForbiddenException $ex) {
191
-					throw new DAVForbiddenException($ex->getMessage(), $ex->getRetry());
192
-				} catch (\Exception $e) {
193
-					$partStorage->unlink($internalPartPath);
194
-					$this->convertToSabreException($e);
195
-				}
196
-			}
197
-
198
-			// since we skipped the view we need to scan and emit the hooks ourselves
199
-			$storage->getUpdater()->update($internalPath);
200
-
201
-			try {
202
-				$this->changeLock(ILockingProvider::LOCK_SHARED);
203
-			} catch (LockedException $e) {
204
-				throw new FileLocked($e->getMessage(), $e->getCode(), $e);
205
-			}
206
-
207
-			// allow sync clients to send the mtime along in a header
208
-			$request = \OC::$server->getRequest();
209
-			if (isset($request->server['HTTP_X_OC_MTIME'])) {
210
-				$mtimeStr = $request->server['HTTP_X_OC_MTIME'];
211
-				if (!is_numeric($mtimeStr)) {
212
-					throw new \InvalidArgumentException('X-OC-Mtime header must be an integer (unix timestamp).');
213
-				}
214
-				$mtime = intval($mtimeStr);
215
-				if ($this->fileView->touch($this->path, $mtime)) {
216
-					header('X-OC-MTime: accepted');
217
-				}
218
-			}
61
+    /**
62
+     * Updates the data
63
+     *
64
+     * The data argument is a readable stream resource.
65
+     *
66
+     * After a successful put operation, you may choose to return an ETag. The
67
+     * etag must always be surrounded by double-quotes. These quotes must
68
+     * appear in the actual string you're returning.
69
+     *
70
+     * Clients may use the ETag from a PUT request to later on make sure that
71
+     * when they update the file, the contents haven't changed in the mean
72
+     * time.
73
+     *
74
+     * If you don't plan to store the file byte-by-byte, and you return a
75
+     * different object on a subsequent GET you are strongly recommended to not
76
+     * return an ETag, and just return null.
77
+     *
78
+     * @param resource $data
79
+     *
80
+     * @throws Forbidden
81
+     * @throws UnsupportedMediaType
82
+     * @throws BadRequest
83
+     * @throws Exception
84
+     * @throws EntityTooLarge
85
+     * @throws ServiceUnavailable
86
+     * @throws FileLocked
87
+     * @return string|null
88
+     */
89
+    public function put($data) {
90
+        try {
91
+            $exists = $this->fileView->file_exists($this->path);
92
+            if ($this->info && $exists && !$this->info->isUpdateable()) {
93
+                throw new Forbidden();
94
+            }
95
+        } catch (StorageNotAvailableException $e) {
96
+            throw new ServiceUnavailable("File is not updatable: " . $e->getMessage());
97
+        }
98
+
99
+        // verify path of the target
100
+        $this->verifyPath();
101
+
102
+        // chunked handling
103
+        if (isset($_SERVER['HTTP_OC_CHUNKED'])) {
104
+            try {
105
+                return $this->createFileChunked($data);
106
+            } catch (\Exception $e) {
107
+                $this->convertToSabreException($e);
108
+            }
109
+        }
110
+
111
+        list($partStorage) = $this->fileView->resolvePath($this->path);
112
+        $needsPartFile = $this->needsPartFile($partStorage) && (strlen($this->path) > 1);
113
+
114
+        if ($needsPartFile) {
115
+            // mark file as partial while uploading (ignored by the scanner)
116
+            $partFilePath = $this->getPartFileBasePath($this->path) . '.ocTransferId' . rand() . '.part';
117
+        } else {
118
+            // upload file directly as the final path
119
+            $partFilePath = $this->path;
120
+        }
121
+
122
+        // the part file and target file might be on a different storage in case of a single file storage (e.g. single file share)
123
+        /** @var \OC\Files\Storage\Storage $partStorage */
124
+        list($partStorage, $internalPartPath) = $this->fileView->resolvePath($partFilePath);
125
+        /** @var \OC\Files\Storage\Storage $storage */
126
+        list($storage, $internalPath) = $this->fileView->resolvePath($this->path);
127
+        try {
128
+            $target = $partStorage->fopen($internalPartPath, 'wb');
129
+            if ($target === false) {
130
+                \OCP\Util::writeLog('webdav', '\OC\Files\Filesystem::fopen() failed', \OCP\Util::ERROR);
131
+                // because we have no clue about the cause we can only throw back a 500/Internal Server Error
132
+                throw new Exception('Could not write file contents');
133
+            }
134
+            list($count, $result) = \OC_Helper::streamCopy($data, $target);
135
+            fclose($target);
136
+
137
+            if ($result === false) {
138
+                $expected = -1;
139
+                if (isset($_SERVER['CONTENT_LENGTH'])) {
140
+                    $expected = $_SERVER['CONTENT_LENGTH'];
141
+                }
142
+                throw new Exception('Error while copying file to target location (copied bytes: ' . $count . ', expected filesize: ' . $expected . ' )');
143
+            }
144
+
145
+            // if content length is sent by client:
146
+            // double check if the file was fully received
147
+            // compare expected and actual size
148
+            if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['REQUEST_METHOD'] === 'PUT') {
149
+                $expected = $_SERVER['CONTENT_LENGTH'];
150
+                if ($count != $expected) {
151
+                    throw new BadRequest('expected filesize ' . $expected . ' got ' . $count);
152
+                }
153
+            }
154
+
155
+        } catch (\Exception $e) {
156
+            if ($needsPartFile) {
157
+                $partStorage->unlink($internalPartPath);
158
+            }
159
+            $this->convertToSabreException($e);
160
+        }
161
+
162
+        try {
163
+            $view = \OC\Files\Filesystem::getView();
164
+            if ($view) {
165
+                $run = $this->emitPreHooks($exists);
166
+            } else {
167
+                $run = true;
168
+            }
169
+
170
+            try {
171
+                $this->changeLock(ILockingProvider::LOCK_EXCLUSIVE);
172
+            } catch (LockedException $e) {
173
+                if ($needsPartFile) {
174
+                    $partStorage->unlink($internalPartPath);
175
+                }
176
+                throw new FileLocked($e->getMessage(), $e->getCode(), $e);
177
+            }
178
+
179
+            if ($needsPartFile) {
180
+                // rename to correct path
181
+                try {
182
+                    if ($run) {
183
+                        $renameOkay = $storage->moveFromStorage($partStorage, $internalPartPath, $internalPath);
184
+                        $fileExists = $storage->file_exists($internalPath);
185
+                    }
186
+                    if (!$run || $renameOkay === false || $fileExists === false) {
187
+                        \OCP\Util::writeLog('webdav', 'renaming part file to final file failed ($run: ' . ( $run ? 'true' : 'false' ) . ', $renameOkay: '  . ( $renameOkay ? 'true' : 'false' ) . ', $fileExists: ' . ( $fileExists ? 'true' : 'false' ) . ')', \OCP\Util::ERROR);
188
+                        throw new Exception('Could not rename part file to final file');
189
+                    }
190
+                } catch (ForbiddenException $ex) {
191
+                    throw new DAVForbiddenException($ex->getMessage(), $ex->getRetry());
192
+                } catch (\Exception $e) {
193
+                    $partStorage->unlink($internalPartPath);
194
+                    $this->convertToSabreException($e);
195
+                }
196
+            }
197
+
198
+            // since we skipped the view we need to scan and emit the hooks ourselves
199
+            $storage->getUpdater()->update($internalPath);
200
+
201
+            try {
202
+                $this->changeLock(ILockingProvider::LOCK_SHARED);
203
+            } catch (LockedException $e) {
204
+                throw new FileLocked($e->getMessage(), $e->getCode(), $e);
205
+            }
206
+
207
+            // allow sync clients to send the mtime along in a header
208
+            $request = \OC::$server->getRequest();
209
+            if (isset($request->server['HTTP_X_OC_MTIME'])) {
210
+                $mtimeStr = $request->server['HTTP_X_OC_MTIME'];
211
+                if (!is_numeric($mtimeStr)) {
212
+                    throw new \InvalidArgumentException('X-OC-Mtime header must be an integer (unix timestamp).');
213
+                }
214
+                $mtime = intval($mtimeStr);
215
+                if ($this->fileView->touch($this->path, $mtime)) {
216
+                    header('X-OC-MTime: accepted');
217
+                }
218
+            }
219 219
 					
220
-			if ($view) {
221
-				$this->emitPostHooks($exists);
222
-			}
223
-
224
-			$this->refreshInfo();
225
-
226
-			if (isset($request->server['HTTP_OC_CHECKSUM'])) {
227
-				$checksum = trim($request->server['HTTP_OC_CHECKSUM']);
228
-				$this->fileView->putFileInfo($this->path, ['checksum' => $checksum]);
229
-				$this->refreshInfo();
230
-			} else if ($this->getChecksum() !== null && $this->getChecksum() !== '') {
231
-				$this->fileView->putFileInfo($this->path, ['checksum' => '']);
232
-				$this->refreshInfo();
233
-			}
234
-
235
-		} catch (StorageNotAvailableException $e) {
236
-			throw new ServiceUnavailable("Failed to check file size: " . $e->getMessage());
237
-		}
238
-
239
-		return '"' . $this->info->getEtag() . '"';
240
-	}
241
-
242
-	private function getPartFileBasePath($path) {
243
-		$partFileInStorage = \OC::$server->getConfig()->getSystemValue('part_file_in_storage', true);
244
-		if ($partFileInStorage) {
245
-			return $path;
246
-		} else {
247
-			return md5($path); // will place it in the root of the view with a unique name
248
-		}
249
-	}
250
-
251
-	/**
252
-	 * @param string $path
253
-	 */
254
-	private function emitPreHooks($exists, $path = null) {
255
-		if (is_null($path)) {
256
-			$path = $this->path;
257
-		}
258
-		$hookPath = Filesystem::getView()->getRelativePath($this->fileView->getAbsolutePath($path));
259
-		$run = true;
260
-
261
-		if (!$exists) {
262
-			\OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_create, array(
263
-				\OC\Files\Filesystem::signal_param_path => $hookPath,
264
-				\OC\Files\Filesystem::signal_param_run => &$run,
265
-			));
266
-		} else {
267
-			\OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_update, array(
268
-				\OC\Files\Filesystem::signal_param_path => $hookPath,
269
-				\OC\Files\Filesystem::signal_param_run => &$run,
270
-			));
271
-		}
272
-		\OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_write, array(
273
-			\OC\Files\Filesystem::signal_param_path => $hookPath,
274
-			\OC\Files\Filesystem::signal_param_run => &$run,
275
-		));
276
-		return $run;
277
-	}
278
-
279
-	/**
280
-	 * @param string $path
281
-	 */
282
-	private function emitPostHooks($exists, $path = null) {
283
-		if (is_null($path)) {
284
-			$path = $this->path;
285
-		}
286
-		$hookPath = Filesystem::getView()->getRelativePath($this->fileView->getAbsolutePath($path));
287
-		if (!$exists) {
288
-			\OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_post_create, array(
289
-				\OC\Files\Filesystem::signal_param_path => $hookPath
290
-			));
291
-		} else {
292
-			\OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_post_update, array(
293
-				\OC\Files\Filesystem::signal_param_path => $hookPath
294
-			));
295
-		}
296
-		\OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_post_write, array(
297
-			\OC\Files\Filesystem::signal_param_path => $hookPath
298
-		));
299
-	}
300
-
301
-	/**
302
-	 * Returns the data
303
-	 *
304
-	 * @return resource
305
-	 * @throws Forbidden
306
-	 * @throws ServiceUnavailable
307
-	 */
308
-	public function get() {
309
-		//throw exception if encryption is disabled but files are still encrypted
310
-		try {
311
-			if (!$this->info->isReadable()) {
312
-				// do a if the file did not exist
313
-				throw new NotFound();
314
-			}
315
-			$res = $this->fileView->fopen(ltrim($this->path, '/'), 'rb');
316
-			if ($res === false) {
317
-				throw new ServiceUnavailable("Could not open file");
318
-			}
319
-			return $res;
320
-		} catch (GenericEncryptionException $e) {
321
-			// returning 503 will allow retry of the operation at a later point in time
322
-			throw new ServiceUnavailable("Encryption not ready: " . $e->getMessage());
323
-		} catch (StorageNotAvailableException $e) {
324
-			throw new ServiceUnavailable("Failed to open file: " . $e->getMessage());
325
-		} catch (ForbiddenException $ex) {
326
-			throw new DAVForbiddenException($ex->getMessage(), $ex->getRetry());
327
-		} catch (LockedException $e) {
328
-			throw new FileLocked($e->getMessage(), $e->getCode(), $e);
329
-		}
330
-	}
331
-
332
-	/**
333
-	 * Delete the current file
334
-	 *
335
-	 * @throws Forbidden
336
-	 * @throws ServiceUnavailable
337
-	 */
338
-	public function delete() {
339
-		if (!$this->info->isDeletable()) {
340
-			throw new Forbidden();
341
-		}
342
-
343
-		try {
344
-			if (!$this->fileView->unlink($this->path)) {
345
-				// assume it wasn't possible to delete due to permissions
346
-				throw new Forbidden();
347
-			}
348
-		} catch (StorageNotAvailableException $e) {
349
-			throw new ServiceUnavailable("Failed to unlink: " . $e->getMessage());
350
-		} catch (ForbiddenException $ex) {
351
-			throw new DAVForbiddenException($ex->getMessage(), $ex->getRetry());
352
-		} catch (LockedException $e) {
353
-			throw new FileLocked($e->getMessage(), $e->getCode(), $e);
354
-		}
355
-	}
356
-
357
-	/**
358
-	 * Returns the mime-type for a file
359
-	 *
360
-	 * If null is returned, we'll assume application/octet-stream
361
-	 *
362
-	 * @return string
363
-	 */
364
-	public function getContentType() {
365
-		$mimeType = $this->info->getMimetype();
366
-
367
-		// PROPFIND needs to return the correct mime type, for consistency with the web UI
368
-		if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PROPFIND') {
369
-			return $mimeType;
370
-		}
371
-		return \OC::$server->getMimeTypeDetector()->getSecureMimeType($mimeType);
372
-	}
373
-
374
-	/**
375
-	 * @return array|false
376
-	 */
377
-	public function getDirectDownload() {
378
-		if (\OCP\App::isEnabled('encryption')) {
379
-			return [];
380
-		}
381
-		/** @var \OCP\Files\Storage $storage */
382
-		list($storage, $internalPath) = $this->fileView->resolvePath($this->path);
383
-		if (is_null($storage)) {
384
-			return [];
385
-		}
386
-
387
-		return $storage->getDirectDownload($internalPath);
388
-	}
389
-
390
-	/**
391
-	 * @param resource $data
392
-	 * @return null|string
393
-	 * @throws Exception
394
-	 * @throws BadRequest
395
-	 * @throws NotImplemented
396
-	 * @throws ServiceUnavailable
397
-	 */
398
-	private function createFileChunked($data) {
399
-		list($path, $name) = \Sabre\HTTP\URLUtil::splitPath($this->path);
400
-
401
-		$info = \OC_FileChunking::decodeName($name);
402
-		if (empty($info)) {
403
-			throw new NotImplemented('Invalid chunk name');
404
-		}
405
-
406
-		$chunk_handler = new \OC_FileChunking($info);
407
-		$bytesWritten = $chunk_handler->store($info['index'], $data);
408
-
409
-		//detect aborted upload
410
-		if (isset ($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PUT') {
411
-			if (isset($_SERVER['CONTENT_LENGTH'])) {
412
-				$expected = $_SERVER['CONTENT_LENGTH'];
413
-				if ($bytesWritten != $expected) {
414
-					$chunk_handler->remove($info['index']);
415
-					throw new BadRequest(
416
-						'expected filesize ' . $expected . ' got ' . $bytesWritten);
417
-				}
418
-			}
419
-		}
420
-
421
-		if ($chunk_handler->isComplete()) {
422
-			list($storage,) = $this->fileView->resolvePath($path);
423
-			$needsPartFile = $this->needsPartFile($storage);
424
-			$partFile = null;
425
-
426
-			$targetPath = $path . '/' . $info['name'];
427
-			/** @var \OC\Files\Storage\Storage $targetStorage */
428
-			list($targetStorage, $targetInternalPath) = $this->fileView->resolvePath($targetPath);
429
-
430
-			$exists = $this->fileView->file_exists($targetPath);
431
-
432
-			try {
433
-				$this->fileView->lockFile($targetPath, ILockingProvider::LOCK_SHARED);
434
-
435
-				$this->emitPreHooks($exists, $targetPath);
436
-				$this->fileView->changeLock($targetPath, ILockingProvider::LOCK_EXCLUSIVE);
437
-				/** @var \OC\Files\Storage\Storage $targetStorage */
438
-				list($targetStorage, $targetInternalPath) = $this->fileView->resolvePath($targetPath);
439
-
440
-				if ($needsPartFile) {
441
-					// we first assembly the target file as a part file
442
-					$partFile = $this->getPartFileBasePath($path . '/' . $info['name']) . '.ocTransferId' . $info['transferid'] . '.part';
443
-					/** @var \OC\Files\Storage\Storage $targetStorage */
444
-					list($partStorage, $partInternalPath) = $this->fileView->resolvePath($partFile);
445
-
446
-
447
-					$chunk_handler->file_assemble($partStorage, $partInternalPath);
448
-
449
-					// here is the final atomic rename
450
-					$renameOkay = $targetStorage->moveFromStorage($partStorage, $partInternalPath, $targetInternalPath);
451
-					$fileExists = $targetStorage->file_exists($targetInternalPath);
452
-					if ($renameOkay === false || $fileExists === false) {
453
-						\OCP\Util::writeLog('webdav', '\OC\Files\Filesystem::rename() failed', \OCP\Util::ERROR);
454
-						// only delete if an error occurred and the target file was already created
455
-						if ($fileExists) {
456
-							// set to null to avoid double-deletion when handling exception
457
-							// stray part file
458
-							$partFile = null;
459
-							$targetStorage->unlink($targetInternalPath);
460
-						}
461
-						$this->fileView->changeLock($targetPath, ILockingProvider::LOCK_SHARED);
462
-						throw new Exception('Could not rename part file assembled from chunks');
463
-					}
464
-				} else {
465
-					// assemble directly into the final file
466
-					$chunk_handler->file_assemble($targetStorage, $targetInternalPath);
467
-				}
468
-
469
-				// allow sync clients to send the mtime along in a header
470
-				$request = \OC::$server->getRequest();
471
-				if (isset($request->server['HTTP_X_OC_MTIME'])) {
472
-					if ($targetStorage->touch($targetInternalPath, $request->server['HTTP_X_OC_MTIME'])) {
473
-						header('X-OC-MTime: accepted');
474
-					}
475
-				}
476
-
477
-				// since we skipped the view we need to scan and emit the hooks ourselves
478
-				$targetStorage->getUpdater()->update($targetInternalPath);
479
-
480
-				$this->fileView->changeLock($targetPath, ILockingProvider::LOCK_SHARED);
481
-
482
-				$this->emitPostHooks($exists, $targetPath);
483
-
484
-				// FIXME: should call refreshInfo but can't because $this->path is not the of the final file
485
-				$info = $this->fileView->getFileInfo($targetPath);
486
-
487
-				if (isset($request->server['HTTP_OC_CHECKSUM'])) {
488
-					$checksum = trim($request->server['HTTP_OC_CHECKSUM']);
489
-					$this->fileView->putFileInfo($targetPath, ['checksum' => $checksum]);
490
-				} else if ($info->getChecksum() !== null && $info->getChecksum() !== '') {
491
-					$this->fileView->putFileInfo($this->path, ['checksum' => '']);
492
-				}
493
-
494
-				$this->fileView->unlockFile($targetPath, ILockingProvider::LOCK_SHARED);
495
-
496
-				return $info->getEtag();
497
-			} catch (\Exception $e) {
498
-				if ($partFile !== null) {
499
-					$targetStorage->unlink($targetInternalPath);
500
-				}
501
-				$this->convertToSabreException($e);
502
-			}
503
-		}
504
-
505
-		return null;
506
-	}
507
-
508
-	/**
509
-	 * Returns whether a part file is needed for the given storage
510
-	 * or whether the file can be assembled/uploaded directly on the
511
-	 * target storage.
512
-	 *
513
-	 * @param \OCP\Files\Storage $storage
514
-	 * @return bool true if the storage needs part file handling
515
-	 */
516
-	private function needsPartFile($storage) {
517
-		// TODO: in the future use ChunkHandler provided by storage
518
-		return !$storage->instanceOfStorage('OCA\Files_Sharing\External\Storage') &&
519
-			!$storage->instanceOfStorage('OC\Files\Storage\OwnCloud') &&
520
-			$storage->needsPartFile();
521
-	}
522
-
523
-	/**
524
-	 * Convert the given exception to a SabreException instance
525
-	 *
526
-	 * @param \Exception $e
527
-	 *
528
-	 * @throws \Sabre\DAV\Exception
529
-	 */
530
-	private function convertToSabreException(\Exception $e) {
531
-		if ($e instanceof \Sabre\DAV\Exception) {
532
-			throw $e;
533
-		}
534
-		if ($e instanceof NotPermittedException) {
535
-			// a more general case - due to whatever reason the content could not be written
536
-			throw new Forbidden($e->getMessage(), 0, $e);
537
-		}
538
-		if ($e instanceof ForbiddenException) {
539
-			// the path for the file was forbidden
540
-			throw new DAVForbiddenException($e->getMessage(), $e->getRetry(), $e);
541
-		}
542
-		if ($e instanceof EntityTooLargeException) {
543
-			// the file is too big to be stored
544
-			throw new EntityTooLarge($e->getMessage(), 0, $e);
545
-		}
546
-		if ($e instanceof InvalidContentException) {
547
-			// the file content is not permitted
548
-			throw new UnsupportedMediaType($e->getMessage(), 0, $e);
549
-		}
550
-		if ($e instanceof InvalidPathException) {
551
-			// the path for the file was not valid
552
-			// TODO: find proper http status code for this case
553
-			throw new Forbidden($e->getMessage(), 0, $e);
554
-		}
555
-		if ($e instanceof LockedException || $e instanceof LockNotAcquiredException) {
556
-			// the file is currently being written to by another process
557
-			throw new FileLocked($e->getMessage(), $e->getCode(), $e);
558
-		}
559
-		if ($e instanceof GenericEncryptionException) {
560
-			// returning 503 will allow retry of the operation at a later point in time
561
-			throw new ServiceUnavailable('Encryption not ready: ' . $e->getMessage(), 0, $e);
562
-		}
563
-		if ($e instanceof StorageNotAvailableException) {
564
-			throw new ServiceUnavailable('Failed to write file contents: ' . $e->getMessage(), 0, $e);
565
-		}
566
-
567
-		throw new \Sabre\DAV\Exception($e->getMessage(), 0, $e);
568
-	}
569
-
570
-	/**
571
-	 * Get the checksum for this file
572
-	 *
573
-	 * @return string
574
-	 */
575
-	public function getChecksum() {
576
-		return $this->info->getChecksum();
577
-	}
220
+            if ($view) {
221
+                $this->emitPostHooks($exists);
222
+            }
223
+
224
+            $this->refreshInfo();
225
+
226
+            if (isset($request->server['HTTP_OC_CHECKSUM'])) {
227
+                $checksum = trim($request->server['HTTP_OC_CHECKSUM']);
228
+                $this->fileView->putFileInfo($this->path, ['checksum' => $checksum]);
229
+                $this->refreshInfo();
230
+            } else if ($this->getChecksum() !== null && $this->getChecksum() !== '') {
231
+                $this->fileView->putFileInfo($this->path, ['checksum' => '']);
232
+                $this->refreshInfo();
233
+            }
234
+
235
+        } catch (StorageNotAvailableException $e) {
236
+            throw new ServiceUnavailable("Failed to check file size: " . $e->getMessage());
237
+        }
238
+
239
+        return '"' . $this->info->getEtag() . '"';
240
+    }
241
+
242
+    private function getPartFileBasePath($path) {
243
+        $partFileInStorage = \OC::$server->getConfig()->getSystemValue('part_file_in_storage', true);
244
+        if ($partFileInStorage) {
245
+            return $path;
246
+        } else {
247
+            return md5($path); // will place it in the root of the view with a unique name
248
+        }
249
+    }
250
+
251
+    /**
252
+     * @param string $path
253
+     */
254
+    private function emitPreHooks($exists, $path = null) {
255
+        if (is_null($path)) {
256
+            $path = $this->path;
257
+        }
258
+        $hookPath = Filesystem::getView()->getRelativePath($this->fileView->getAbsolutePath($path));
259
+        $run = true;
260
+
261
+        if (!$exists) {
262
+            \OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_create, array(
263
+                \OC\Files\Filesystem::signal_param_path => $hookPath,
264
+                \OC\Files\Filesystem::signal_param_run => &$run,
265
+            ));
266
+        } else {
267
+            \OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_update, array(
268
+                \OC\Files\Filesystem::signal_param_path => $hookPath,
269
+                \OC\Files\Filesystem::signal_param_run => &$run,
270
+            ));
271
+        }
272
+        \OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_write, array(
273
+            \OC\Files\Filesystem::signal_param_path => $hookPath,
274
+            \OC\Files\Filesystem::signal_param_run => &$run,
275
+        ));
276
+        return $run;
277
+    }
278
+
279
+    /**
280
+     * @param string $path
281
+     */
282
+    private function emitPostHooks($exists, $path = null) {
283
+        if (is_null($path)) {
284
+            $path = $this->path;
285
+        }
286
+        $hookPath = Filesystem::getView()->getRelativePath($this->fileView->getAbsolutePath($path));
287
+        if (!$exists) {
288
+            \OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_post_create, array(
289
+                \OC\Files\Filesystem::signal_param_path => $hookPath
290
+            ));
291
+        } else {
292
+            \OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_post_update, array(
293
+                \OC\Files\Filesystem::signal_param_path => $hookPath
294
+            ));
295
+        }
296
+        \OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_post_write, array(
297
+            \OC\Files\Filesystem::signal_param_path => $hookPath
298
+        ));
299
+    }
300
+
301
+    /**
302
+     * Returns the data
303
+     *
304
+     * @return resource
305
+     * @throws Forbidden
306
+     * @throws ServiceUnavailable
307
+     */
308
+    public function get() {
309
+        //throw exception if encryption is disabled but files are still encrypted
310
+        try {
311
+            if (!$this->info->isReadable()) {
312
+                // do a if the file did not exist
313
+                throw new NotFound();
314
+            }
315
+            $res = $this->fileView->fopen(ltrim($this->path, '/'), 'rb');
316
+            if ($res === false) {
317
+                throw new ServiceUnavailable("Could not open file");
318
+            }
319
+            return $res;
320
+        } catch (GenericEncryptionException $e) {
321
+            // returning 503 will allow retry of the operation at a later point in time
322
+            throw new ServiceUnavailable("Encryption not ready: " . $e->getMessage());
323
+        } catch (StorageNotAvailableException $e) {
324
+            throw new ServiceUnavailable("Failed to open file: " . $e->getMessage());
325
+        } catch (ForbiddenException $ex) {
326
+            throw new DAVForbiddenException($ex->getMessage(), $ex->getRetry());
327
+        } catch (LockedException $e) {
328
+            throw new FileLocked($e->getMessage(), $e->getCode(), $e);
329
+        }
330
+    }
331
+
332
+    /**
333
+     * Delete the current file
334
+     *
335
+     * @throws Forbidden
336
+     * @throws ServiceUnavailable
337
+     */
338
+    public function delete() {
339
+        if (!$this->info->isDeletable()) {
340
+            throw new Forbidden();
341
+        }
342
+
343
+        try {
344
+            if (!$this->fileView->unlink($this->path)) {
345
+                // assume it wasn't possible to delete due to permissions
346
+                throw new Forbidden();
347
+            }
348
+        } catch (StorageNotAvailableException $e) {
349
+            throw new ServiceUnavailable("Failed to unlink: " . $e->getMessage());
350
+        } catch (ForbiddenException $ex) {
351
+            throw new DAVForbiddenException($ex->getMessage(), $ex->getRetry());
352
+        } catch (LockedException $e) {
353
+            throw new FileLocked($e->getMessage(), $e->getCode(), $e);
354
+        }
355
+    }
356
+
357
+    /**
358
+     * Returns the mime-type for a file
359
+     *
360
+     * If null is returned, we'll assume application/octet-stream
361
+     *
362
+     * @return string
363
+     */
364
+    public function getContentType() {
365
+        $mimeType = $this->info->getMimetype();
366
+
367
+        // PROPFIND needs to return the correct mime type, for consistency with the web UI
368
+        if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PROPFIND') {
369
+            return $mimeType;
370
+        }
371
+        return \OC::$server->getMimeTypeDetector()->getSecureMimeType($mimeType);
372
+    }
373
+
374
+    /**
375
+     * @return array|false
376
+     */
377
+    public function getDirectDownload() {
378
+        if (\OCP\App::isEnabled('encryption')) {
379
+            return [];
380
+        }
381
+        /** @var \OCP\Files\Storage $storage */
382
+        list($storage, $internalPath) = $this->fileView->resolvePath($this->path);
383
+        if (is_null($storage)) {
384
+            return [];
385
+        }
386
+
387
+        return $storage->getDirectDownload($internalPath);
388
+    }
389
+
390
+    /**
391
+     * @param resource $data
392
+     * @return null|string
393
+     * @throws Exception
394
+     * @throws BadRequest
395
+     * @throws NotImplemented
396
+     * @throws ServiceUnavailable
397
+     */
398
+    private function createFileChunked($data) {
399
+        list($path, $name) = \Sabre\HTTP\URLUtil::splitPath($this->path);
400
+
401
+        $info = \OC_FileChunking::decodeName($name);
402
+        if (empty($info)) {
403
+            throw new NotImplemented('Invalid chunk name');
404
+        }
405
+
406
+        $chunk_handler = new \OC_FileChunking($info);
407
+        $bytesWritten = $chunk_handler->store($info['index'], $data);
408
+
409
+        //detect aborted upload
410
+        if (isset ($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PUT') {
411
+            if (isset($_SERVER['CONTENT_LENGTH'])) {
412
+                $expected = $_SERVER['CONTENT_LENGTH'];
413
+                if ($bytesWritten != $expected) {
414
+                    $chunk_handler->remove($info['index']);
415
+                    throw new BadRequest(
416
+                        'expected filesize ' . $expected . ' got ' . $bytesWritten);
417
+                }
418
+            }
419
+        }
420
+
421
+        if ($chunk_handler->isComplete()) {
422
+            list($storage,) = $this->fileView->resolvePath($path);
423
+            $needsPartFile = $this->needsPartFile($storage);
424
+            $partFile = null;
425
+
426
+            $targetPath = $path . '/' . $info['name'];
427
+            /** @var \OC\Files\Storage\Storage $targetStorage */
428
+            list($targetStorage, $targetInternalPath) = $this->fileView->resolvePath($targetPath);
429
+
430
+            $exists = $this->fileView->file_exists($targetPath);
431
+
432
+            try {
433
+                $this->fileView->lockFile($targetPath, ILockingProvider::LOCK_SHARED);
434
+
435
+                $this->emitPreHooks($exists, $targetPath);
436
+                $this->fileView->changeLock($targetPath, ILockingProvider::LOCK_EXCLUSIVE);
437
+                /** @var \OC\Files\Storage\Storage $targetStorage */
438
+                list($targetStorage, $targetInternalPath) = $this->fileView->resolvePath($targetPath);
439
+
440
+                if ($needsPartFile) {
441
+                    // we first assembly the target file as a part file
442
+                    $partFile = $this->getPartFileBasePath($path . '/' . $info['name']) . '.ocTransferId' . $info['transferid'] . '.part';
443
+                    /** @var \OC\Files\Storage\Storage $targetStorage */
444
+                    list($partStorage, $partInternalPath) = $this->fileView->resolvePath($partFile);
445
+
446
+
447
+                    $chunk_handler->file_assemble($partStorage, $partInternalPath);
448
+
449
+                    // here is the final atomic rename
450
+                    $renameOkay = $targetStorage->moveFromStorage($partStorage, $partInternalPath, $targetInternalPath);
451
+                    $fileExists = $targetStorage->file_exists($targetInternalPath);
452
+                    if ($renameOkay === false || $fileExists === false) {
453
+                        \OCP\Util::writeLog('webdav', '\OC\Files\Filesystem::rename() failed', \OCP\Util::ERROR);
454
+                        // only delete if an error occurred and the target file was already created
455
+                        if ($fileExists) {
456
+                            // set to null to avoid double-deletion when handling exception
457
+                            // stray part file
458
+                            $partFile = null;
459
+                            $targetStorage->unlink($targetInternalPath);
460
+                        }
461
+                        $this->fileView->changeLock($targetPath, ILockingProvider::LOCK_SHARED);
462
+                        throw new Exception('Could not rename part file assembled from chunks');
463
+                    }
464
+                } else {
465
+                    // assemble directly into the final file
466
+                    $chunk_handler->file_assemble($targetStorage, $targetInternalPath);
467
+                }
468
+
469
+                // allow sync clients to send the mtime along in a header
470
+                $request = \OC::$server->getRequest();
471
+                if (isset($request->server['HTTP_X_OC_MTIME'])) {
472
+                    if ($targetStorage->touch($targetInternalPath, $request->server['HTTP_X_OC_MTIME'])) {
473
+                        header('X-OC-MTime: accepted');
474
+                    }
475
+                }
476
+
477
+                // since we skipped the view we need to scan and emit the hooks ourselves
478
+                $targetStorage->getUpdater()->update($targetInternalPath);
479
+
480
+                $this->fileView->changeLock($targetPath, ILockingProvider::LOCK_SHARED);
481
+
482
+                $this->emitPostHooks($exists, $targetPath);
483
+
484
+                // FIXME: should call refreshInfo but can't because $this->path is not the of the final file
485
+                $info = $this->fileView->getFileInfo($targetPath);
486
+
487
+                if (isset($request->server['HTTP_OC_CHECKSUM'])) {
488
+                    $checksum = trim($request->server['HTTP_OC_CHECKSUM']);
489
+                    $this->fileView->putFileInfo($targetPath, ['checksum' => $checksum]);
490
+                } else if ($info->getChecksum() !== null && $info->getChecksum() !== '') {
491
+                    $this->fileView->putFileInfo($this->path, ['checksum' => '']);
492
+                }
493
+
494
+                $this->fileView->unlockFile($targetPath, ILockingProvider::LOCK_SHARED);
495
+
496
+                return $info->getEtag();
497
+            } catch (\Exception $e) {
498
+                if ($partFile !== null) {
499
+                    $targetStorage->unlink($targetInternalPath);
500
+                }
501
+                $this->convertToSabreException($e);
502
+            }
503
+        }
504
+
505
+        return null;
506
+    }
507
+
508
+    /**
509
+     * Returns whether a part file is needed for the given storage
510
+     * or whether the file can be assembled/uploaded directly on the
511
+     * target storage.
512
+     *
513
+     * @param \OCP\Files\Storage $storage
514
+     * @return bool true if the storage needs part file handling
515
+     */
516
+    private function needsPartFile($storage) {
517
+        // TODO: in the future use ChunkHandler provided by storage
518
+        return !$storage->instanceOfStorage('OCA\Files_Sharing\External\Storage') &&
519
+            !$storage->instanceOfStorage('OC\Files\Storage\OwnCloud') &&
520
+            $storage->needsPartFile();
521
+    }
522
+
523
+    /**
524
+     * Convert the given exception to a SabreException instance
525
+     *
526
+     * @param \Exception $e
527
+     *
528
+     * @throws \Sabre\DAV\Exception
529
+     */
530
+    private function convertToSabreException(\Exception $e) {
531
+        if ($e instanceof \Sabre\DAV\Exception) {
532
+            throw $e;
533
+        }
534
+        if ($e instanceof NotPermittedException) {
535
+            // a more general case - due to whatever reason the content could not be written
536
+            throw new Forbidden($e->getMessage(), 0, $e);
537
+        }
538
+        if ($e instanceof ForbiddenException) {
539
+            // the path for the file was forbidden
540
+            throw new DAVForbiddenException($e->getMessage(), $e->getRetry(), $e);
541
+        }
542
+        if ($e instanceof EntityTooLargeException) {
543
+            // the file is too big to be stored
544
+            throw new EntityTooLarge($e->getMessage(), 0, $e);
545
+        }
546
+        if ($e instanceof InvalidContentException) {
547
+            // the file content is not permitted
548
+            throw new UnsupportedMediaType($e->getMessage(), 0, $e);
549
+        }
550
+        if ($e instanceof InvalidPathException) {
551
+            // the path for the file was not valid
552
+            // TODO: find proper http status code for this case
553
+            throw new Forbidden($e->getMessage(), 0, $e);
554
+        }
555
+        if ($e instanceof LockedException || $e instanceof LockNotAcquiredException) {
556
+            // the file is currently being written to by another process
557
+            throw new FileLocked($e->getMessage(), $e->getCode(), $e);
558
+        }
559
+        if ($e instanceof GenericEncryptionException) {
560
+            // returning 503 will allow retry of the operation at a later point in time
561
+            throw new ServiceUnavailable('Encryption not ready: ' . $e->getMessage(), 0, $e);
562
+        }
563
+        if ($e instanceof StorageNotAvailableException) {
564
+            throw new ServiceUnavailable('Failed to write file contents: ' . $e->getMessage(), 0, $e);
565
+        }
566
+
567
+        throw new \Sabre\DAV\Exception($e->getMessage(), 0, $e);
568
+    }
569
+
570
+    /**
571
+     * Get the checksum for this file
572
+     *
573
+     * @return string
574
+     */
575
+    public function getChecksum() {
576
+        return $this->info->getChecksum();
577
+    }
578 578
 }
Please login to merge, or discard this patch.
Spacing   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -93,7 +93,7 @@  discard block
 block discarded – undo
93 93
 				throw new Forbidden();
94 94
 			}
95 95
 		} catch (StorageNotAvailableException $e) {
96
-			throw new ServiceUnavailable("File is not updatable: " . $e->getMessage());
96
+			throw new ServiceUnavailable("File is not updatable: ".$e->getMessage());
97 97
 		}
98 98
 
99 99
 		// verify path of the target
@@ -113,7 +113,7 @@  discard block
 block discarded – undo
113 113
 
114 114
 		if ($needsPartFile) {
115 115
 			// mark file as partial while uploading (ignored by the scanner)
116
-			$partFilePath = $this->getPartFileBasePath($this->path) . '.ocTransferId' . rand() . '.part';
116
+			$partFilePath = $this->getPartFileBasePath($this->path).'.ocTransferId'.rand().'.part';
117 117
 		} else {
118 118
 			// upload file directly as the final path
119 119
 			$partFilePath = $this->path;
@@ -139,7 +139,7 @@  discard block
 block discarded – undo
139 139
 				if (isset($_SERVER['CONTENT_LENGTH'])) {
140 140
 					$expected = $_SERVER['CONTENT_LENGTH'];
141 141
 				}
142
-				throw new Exception('Error while copying file to target location (copied bytes: ' . $count . ', expected filesize: ' . $expected . ' )');
142
+				throw new Exception('Error while copying file to target location (copied bytes: '.$count.', expected filesize: '.$expected.' )');
143 143
 			}
144 144
 
145 145
 			// if content length is sent by client:
@@ -148,7 +148,7 @@  discard block
 block discarded – undo
148 148
 			if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['REQUEST_METHOD'] === 'PUT') {
149 149
 				$expected = $_SERVER['CONTENT_LENGTH'];
150 150
 				if ($count != $expected) {
151
-					throw new BadRequest('expected filesize ' . $expected . ' got ' . $count);
151
+					throw new BadRequest('expected filesize '.$expected.' got '.$count);
152 152
 				}
153 153
 			}
154 154
 
@@ -184,7 +184,7 @@  discard block
 block discarded – undo
184 184
 						$fileExists = $storage->file_exists($internalPath);
185 185
 					}
186 186
 					if (!$run || $renameOkay === false || $fileExists === false) {
187
-						\OCP\Util::writeLog('webdav', 'renaming part file to final file failed ($run: ' . ( $run ? 'true' : 'false' ) . ', $renameOkay: '  . ( $renameOkay ? 'true' : 'false' ) . ', $fileExists: ' . ( $fileExists ? 'true' : 'false' ) . ')', \OCP\Util::ERROR);
187
+						\OCP\Util::writeLog('webdav', 'renaming part file to final file failed ($run: '.($run ? 'true' : 'false').', $renameOkay: '.($renameOkay ? 'true' : 'false').', $fileExists: '.($fileExists ? 'true' : 'false').')', \OCP\Util::ERROR);
188 188
 						throw new Exception('Could not rename part file to final file');
189 189
 					}
190 190
 				} catch (ForbiddenException $ex) {
@@ -233,10 +233,10 @@  discard block
 block discarded – undo
233 233
 			}
234 234
 
235 235
 		} catch (StorageNotAvailableException $e) {
236
-			throw new ServiceUnavailable("Failed to check file size: " . $e->getMessage());
236
+			throw new ServiceUnavailable("Failed to check file size: ".$e->getMessage());
237 237
 		}
238 238
 
239
-		return '"' . $this->info->getEtag() . '"';
239
+		return '"'.$this->info->getEtag().'"';
240 240
 	}
241 241
 
242 242
 	private function getPartFileBasePath($path) {
@@ -319,9 +319,9 @@  discard block
 block discarded – undo
319 319
 			return $res;
320 320
 		} catch (GenericEncryptionException $e) {
321 321
 			// returning 503 will allow retry of the operation at a later point in time
322
-			throw new ServiceUnavailable("Encryption not ready: " . $e->getMessage());
322
+			throw new ServiceUnavailable("Encryption not ready: ".$e->getMessage());
323 323
 		} catch (StorageNotAvailableException $e) {
324
-			throw new ServiceUnavailable("Failed to open file: " . $e->getMessage());
324
+			throw new ServiceUnavailable("Failed to open file: ".$e->getMessage());
325 325
 		} catch (ForbiddenException $ex) {
326 326
 			throw new DAVForbiddenException($ex->getMessage(), $ex->getRetry());
327 327
 		} catch (LockedException $e) {
@@ -346,7 +346,7 @@  discard block
 block discarded – undo
346 346
 				throw new Forbidden();
347 347
 			}
348 348
 		} catch (StorageNotAvailableException $e) {
349
-			throw new ServiceUnavailable("Failed to unlink: " . $e->getMessage());
349
+			throw new ServiceUnavailable("Failed to unlink: ".$e->getMessage());
350 350
 		} catch (ForbiddenException $ex) {
351 351
 			throw new DAVForbiddenException($ex->getMessage(), $ex->getRetry());
352 352
 		} catch (LockedException $e) {
@@ -413,7 +413,7 @@  discard block
 block discarded – undo
413 413
 				if ($bytesWritten != $expected) {
414 414
 					$chunk_handler->remove($info['index']);
415 415
 					throw new BadRequest(
416
-						'expected filesize ' . $expected . ' got ' . $bytesWritten);
416
+						'expected filesize '.$expected.' got '.$bytesWritten);
417 417
 				}
418 418
 			}
419 419
 		}
@@ -423,7 +423,7 @@  discard block
 block discarded – undo
423 423
 			$needsPartFile = $this->needsPartFile($storage);
424 424
 			$partFile = null;
425 425
 
426
-			$targetPath = $path . '/' . $info['name'];
426
+			$targetPath = $path.'/'.$info['name'];
427 427
 			/** @var \OC\Files\Storage\Storage $targetStorage */
428 428
 			list($targetStorage, $targetInternalPath) = $this->fileView->resolvePath($targetPath);
429 429
 
@@ -439,7 +439,7 @@  discard block
 block discarded – undo
439 439
 
440 440
 				if ($needsPartFile) {
441 441
 					// we first assembly the target file as a part file
442
-					$partFile = $this->getPartFileBasePath($path . '/' . $info['name']) . '.ocTransferId' . $info['transferid'] . '.part';
442
+					$partFile = $this->getPartFileBasePath($path.'/'.$info['name']).'.ocTransferId'.$info['transferid'].'.part';
443 443
 					/** @var \OC\Files\Storage\Storage $targetStorage */
444 444
 					list($partStorage, $partInternalPath) = $this->fileView->resolvePath($partFile);
445 445
 
@@ -558,10 +558,10 @@  discard block
 block discarded – undo
558 558
 		}
559 559
 		if ($e instanceof GenericEncryptionException) {
560 560
 			// returning 503 will allow retry of the operation at a later point in time
561
-			throw new ServiceUnavailable('Encryption not ready: ' . $e->getMessage(), 0, $e);
561
+			throw new ServiceUnavailable('Encryption not ready: '.$e->getMessage(), 0, $e);
562 562
 		}
563 563
 		if ($e instanceof StorageNotAvailableException) {
564
-			throw new ServiceUnavailable('Failed to write file contents: ' . $e->getMessage(), 0, $e);
564
+			throw new ServiceUnavailable('Failed to write file contents: '.$e->getMessage(), 0, $e);
565 565
 		}
566 566
 
567 567
 		throw new \Sabre\DAV\Exception($e->getMessage(), 0, $e);
Please login to merge, or discard this patch.