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