Completed
Push — master ( e446d2...85d7e6 )
by Morris
243:09 queued 230:52
created
lib/private/legacy/files.php 1 patch
Indentation   +388 added lines, -388 removed lines patch added patch discarded remove patch
@@ -46,396 +46,396 @@
 block discarded – undo
46 46
  *
47 47
  */
48 48
 class OC_Files {
49
-	const FILE = 1;
50
-	const ZIP_FILES = 2;
51
-	const ZIP_DIR = 3;
52
-
53
-	const UPLOAD_MIN_LIMIT_BYTES = 1048576; // 1 MiB
54
-
55
-
56
-	private static $multipartBoundary = '';
57
-
58
-	/**
59
-	 * @return string
60
-	 */
61
-	private static function getBoundary() {
62
-		if (empty(self::$multipartBoundary)) {
63
-			self::$multipartBoundary = md5(mt_rand());
64
-		}
65
-		return self::$multipartBoundary;
66
-	}
67
-
68
-	/**
69
-	 * @param string $filename
70
-	 * @param string $name
71
-	 * @param array $rangeArray ('from'=>int,'to'=>int), ...
72
-	 */
73
-	private static function sendHeaders($filename, $name, array $rangeArray) {
74
-		OC_Response::setContentDispositionHeader($name, 'attachment');
75
-		header('Content-Transfer-Encoding: binary', true);
76
-		OC_Response::disableCaching();
77
-		$fileSize = \OC\Files\Filesystem::filesize($filename);
78
-		$type = \OC::$server->getMimeTypeDetector()->getSecureMimeType(\OC\Files\Filesystem::getMimeType($filename));
79
-		if ($fileSize > -1) {
80
-			if (!empty($rangeArray)) {
81
-			    header('HTTP/1.1 206 Partial Content', true);
82
-			    header('Accept-Ranges: bytes', true);
83
-			    if (count($rangeArray) > 1) {
84
-				$type = 'multipart/byteranges; boundary='.self::getBoundary();
85
-				// no Content-Length header here
86
-			    }
87
-			    else {
88
-				header(sprintf('Content-Range: bytes %d-%d/%d', $rangeArray[0]['from'], $rangeArray[0]['to'], $fileSize), true);
89
-				OC_Response::setContentLengthHeader($rangeArray[0]['to'] - $rangeArray[0]['from'] + 1);
90
-			    }
91
-			}
92
-			else {
93
-			    OC_Response::setContentLengthHeader($fileSize);
94
-			}
95
-		}
96
-		header('Content-Type: '.$type, true);
97
-	}
98
-
99
-	/**
100
-	 * return the content of a file or return a zip file containing multiple files
101
-	 *
102
-	 * @param string $dir
103
-	 * @param string $files ; separated list of files to download
104
-	 * @param array $params ; 'head' boolean to only send header of the request ; 'range' http range header
105
-	 */
106
-	public static function get($dir, $files, $params = null) {
107
-
108
-		$view = \OC\Files\Filesystem::getView();
109
-		$getType = self::FILE;
110
-		$filename = $dir;
111
-		try {
112
-
113
-			if (is_array($files) && count($files) === 1) {
114
-				$files = $files[0];
115
-			}
116
-
117
-			if (!is_array($files)) {
118
-				$filename = $dir . '/' . $files;
119
-				if (!$view->is_dir($filename)) {
120
-					self::getSingleFile($view, $dir, $files, is_null($params) ? array() : $params);
121
-					return;
122
-				}
123
-			}
124
-
125
-			$name = 'download';
126
-			if (is_array($files)) {
127
-				$getType = self::ZIP_FILES;
128
-				$basename = basename($dir);
129
-				if ($basename) {
130
-					$name = $basename;
131
-				}
132
-
133
-				$filename = $dir . '/' . $name;
134
-			} else {
135
-				$filename = $dir . '/' . $files;
136
-				$getType = self::ZIP_DIR;
137
-				// downloading root ?
138
-				if ($files !== '') {
139
-					$name = $files;
140
-				}
141
-			}
142
-
143
-			$streamer = new Streamer();
144
-			OC_Util::obEnd();
145
-
146
-			self::lockFiles($view, $dir, $files);
147
-
148
-			$streamer->sendHeaders($name);
149
-			$executionTime = intval(OC::$server->getIniWrapper()->getNumeric('max_execution_time'));
150
-			if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
151
-				@set_time_limit(0);
152
-			}
153
-			ignore_user_abort(true);
154
-			if ($getType === self::ZIP_FILES) {
155
-				foreach ($files as $file) {
156
-					$file = $dir . '/' . $file;
157
-					if (\OC\Files\Filesystem::is_file($file)) {
158
-						$fileSize = \OC\Files\Filesystem::filesize($file);
159
-						$fileTime = \OC\Files\Filesystem::filemtime($file);
160
-						$fh = \OC\Files\Filesystem::fopen($file, 'r');
161
-						$streamer->addFileFromStream($fh, basename($file), $fileSize, $fileTime);
162
-						fclose($fh);
163
-					} elseif (\OC\Files\Filesystem::is_dir($file)) {
164
-						$streamer->addDirRecursive($file);
165
-					}
166
-				}
167
-			} elseif ($getType === self::ZIP_DIR) {
168
-				$file = $dir . '/' . $files;
169
-				$streamer->addDirRecursive($file);
170
-			}
171
-			$streamer->finalize();
172
-			set_time_limit($executionTime);
173
-			self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
174
-		} catch (\OCP\Lock\LockedException $ex) {
175
-			self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
176
-			OC::$server->getLogger()->logException($ex);
177
-			$l = \OC::$server->getL10N('core');
178
-			$hint = method_exists($ex, 'getHint') ? $ex->getHint() : '';
179
-			\OC_Template::printErrorPage($l->t('File is currently busy, please try again later'), $hint);
180
-		} catch (\OCP\Files\ForbiddenException $ex) {
181
-			self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
182
-			OC::$server->getLogger()->logException($ex);
183
-			$l = \OC::$server->getL10N('core');
184
-			\OC_Template::printErrorPage($l->t('Can\'t read file'), $ex->getMessage());
185
-		} catch (\Exception $ex) {
186
-			self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
187
-			OC::$server->getLogger()->logException($ex);
188
-			$l = \OC::$server->getL10N('core');
189
-			$hint = method_exists($ex, 'getHint') ? $ex->getHint() : '';
190
-			\OC_Template::printErrorPage($l->t('Can\'t read file'), $hint);
191
-		}
192
-	}
193
-
194
-	/**
195
-	 * @param string $rangeHeaderPos
196
-	 * @param int $fileSize
197
-	 * @return array $rangeArray ('from'=>int,'to'=>int), ...
198
-	 */
199
-	private static function parseHttpRangeHeader($rangeHeaderPos, $fileSize) {
200
-		$rArray=explode(',', $rangeHeaderPos);
201
-		$minOffset = 0;
202
-		$ind = 0;
203
-
204
-		$rangeArray = array();
205
-
206
-		foreach ($rArray as $value) {
207
-			$ranges = explode('-', $value);
208
-			if (is_numeric($ranges[0])) {
209
-				if ($ranges[0] < $minOffset) { // case: bytes=500-700,601-999
210
-					$ranges[0] = $minOffset;
211
-				}
212
-				if ($ind > 0 && $rangeArray[$ind-1]['to']+1 == $ranges[0]) { // case: bytes=500-600,601-999
213
-					$ind--;
214
-					$ranges[0] = $rangeArray[$ind]['from'];
215
-				}
216
-			}
217
-
218
-			if (is_numeric($ranges[0]) && is_numeric($ranges[1]) && $ranges[0] < $fileSize && $ranges[0] <= $ranges[1]) {
219
-				// case: x-x
220
-				if ($ranges[1] >= $fileSize) {
221
-					$ranges[1] = $fileSize-1;
222
-				}
223
-				$rangeArray[$ind++] = array( 'from' => $ranges[0], 'to' => $ranges[1], 'size' => $fileSize );
224
-				$minOffset = $ranges[1] + 1;
225
-				if ($minOffset >= $fileSize) {
226
-					break;
227
-				}
228
-			}
229
-			elseif (is_numeric($ranges[0]) && $ranges[0] < $fileSize) {
230
-				// case: x-
231
-				$rangeArray[$ind++] = array( 'from' => $ranges[0], 'to' => $fileSize-1, 'size' => $fileSize );
232
-				break;
233
-			}
234
-			elseif (is_numeric($ranges[1])) {
235
-				// case: -x
236
-				if ($ranges[1] > $fileSize) {
237
-					$ranges[1] = $fileSize;
238
-				}
239
-				$rangeArray[$ind++] = array( 'from' => $fileSize-$ranges[1], 'to' => $fileSize-1, 'size' => $fileSize );
240
-				break;
241
-			}
242
-		}
243
-		return $rangeArray;
244
-	}
245
-
246
-	/**
247
-	 * @param View $view
248
-	 * @param string $name
249
-	 * @param string $dir
250
-	 * @param array $params ; 'head' boolean to only send header of the request ; 'range' http range header
251
-	 */
252
-	private static function getSingleFile($view, $dir, $name, $params) {
253
-		$filename = $dir . '/' . $name;
254
-		OC_Util::obEnd();
255
-		$view->lockFile($filename, ILockingProvider::LOCK_SHARED);
49
+    const FILE = 1;
50
+    const ZIP_FILES = 2;
51
+    const ZIP_DIR = 3;
52
+
53
+    const UPLOAD_MIN_LIMIT_BYTES = 1048576; // 1 MiB
54
+
55
+
56
+    private static $multipartBoundary = '';
57
+
58
+    /**
59
+     * @return string
60
+     */
61
+    private static function getBoundary() {
62
+        if (empty(self::$multipartBoundary)) {
63
+            self::$multipartBoundary = md5(mt_rand());
64
+        }
65
+        return self::$multipartBoundary;
66
+    }
67
+
68
+    /**
69
+     * @param string $filename
70
+     * @param string $name
71
+     * @param array $rangeArray ('from'=>int,'to'=>int), ...
72
+     */
73
+    private static function sendHeaders($filename, $name, array $rangeArray) {
74
+        OC_Response::setContentDispositionHeader($name, 'attachment');
75
+        header('Content-Transfer-Encoding: binary', true);
76
+        OC_Response::disableCaching();
77
+        $fileSize = \OC\Files\Filesystem::filesize($filename);
78
+        $type = \OC::$server->getMimeTypeDetector()->getSecureMimeType(\OC\Files\Filesystem::getMimeType($filename));
79
+        if ($fileSize > -1) {
80
+            if (!empty($rangeArray)) {
81
+                header('HTTP/1.1 206 Partial Content', true);
82
+                header('Accept-Ranges: bytes', true);
83
+                if (count($rangeArray) > 1) {
84
+                $type = 'multipart/byteranges; boundary='.self::getBoundary();
85
+                // no Content-Length header here
86
+                }
87
+                else {
88
+                header(sprintf('Content-Range: bytes %d-%d/%d', $rangeArray[0]['from'], $rangeArray[0]['to'], $fileSize), true);
89
+                OC_Response::setContentLengthHeader($rangeArray[0]['to'] - $rangeArray[0]['from'] + 1);
90
+                }
91
+            }
92
+            else {
93
+                OC_Response::setContentLengthHeader($fileSize);
94
+            }
95
+        }
96
+        header('Content-Type: '.$type, true);
97
+    }
98
+
99
+    /**
100
+     * return the content of a file or return a zip file containing multiple files
101
+     *
102
+     * @param string $dir
103
+     * @param string $files ; separated list of files to download
104
+     * @param array $params ; 'head' boolean to only send header of the request ; 'range' http range header
105
+     */
106
+    public static function get($dir, $files, $params = null) {
107
+
108
+        $view = \OC\Files\Filesystem::getView();
109
+        $getType = self::FILE;
110
+        $filename = $dir;
111
+        try {
112
+
113
+            if (is_array($files) && count($files) === 1) {
114
+                $files = $files[0];
115
+            }
116
+
117
+            if (!is_array($files)) {
118
+                $filename = $dir . '/' . $files;
119
+                if (!$view->is_dir($filename)) {
120
+                    self::getSingleFile($view, $dir, $files, is_null($params) ? array() : $params);
121
+                    return;
122
+                }
123
+            }
124
+
125
+            $name = 'download';
126
+            if (is_array($files)) {
127
+                $getType = self::ZIP_FILES;
128
+                $basename = basename($dir);
129
+                if ($basename) {
130
+                    $name = $basename;
131
+                }
132
+
133
+                $filename = $dir . '/' . $name;
134
+            } else {
135
+                $filename = $dir . '/' . $files;
136
+                $getType = self::ZIP_DIR;
137
+                // downloading root ?
138
+                if ($files !== '') {
139
+                    $name = $files;
140
+                }
141
+            }
142
+
143
+            $streamer = new Streamer();
144
+            OC_Util::obEnd();
145
+
146
+            self::lockFiles($view, $dir, $files);
147
+
148
+            $streamer->sendHeaders($name);
149
+            $executionTime = intval(OC::$server->getIniWrapper()->getNumeric('max_execution_time'));
150
+            if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
151
+                @set_time_limit(0);
152
+            }
153
+            ignore_user_abort(true);
154
+            if ($getType === self::ZIP_FILES) {
155
+                foreach ($files as $file) {
156
+                    $file = $dir . '/' . $file;
157
+                    if (\OC\Files\Filesystem::is_file($file)) {
158
+                        $fileSize = \OC\Files\Filesystem::filesize($file);
159
+                        $fileTime = \OC\Files\Filesystem::filemtime($file);
160
+                        $fh = \OC\Files\Filesystem::fopen($file, 'r');
161
+                        $streamer->addFileFromStream($fh, basename($file), $fileSize, $fileTime);
162
+                        fclose($fh);
163
+                    } elseif (\OC\Files\Filesystem::is_dir($file)) {
164
+                        $streamer->addDirRecursive($file);
165
+                    }
166
+                }
167
+            } elseif ($getType === self::ZIP_DIR) {
168
+                $file = $dir . '/' . $files;
169
+                $streamer->addDirRecursive($file);
170
+            }
171
+            $streamer->finalize();
172
+            set_time_limit($executionTime);
173
+            self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
174
+        } catch (\OCP\Lock\LockedException $ex) {
175
+            self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
176
+            OC::$server->getLogger()->logException($ex);
177
+            $l = \OC::$server->getL10N('core');
178
+            $hint = method_exists($ex, 'getHint') ? $ex->getHint() : '';
179
+            \OC_Template::printErrorPage($l->t('File is currently busy, please try again later'), $hint);
180
+        } catch (\OCP\Files\ForbiddenException $ex) {
181
+            self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
182
+            OC::$server->getLogger()->logException($ex);
183
+            $l = \OC::$server->getL10N('core');
184
+            \OC_Template::printErrorPage($l->t('Can\'t read file'), $ex->getMessage());
185
+        } catch (\Exception $ex) {
186
+            self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
187
+            OC::$server->getLogger()->logException($ex);
188
+            $l = \OC::$server->getL10N('core');
189
+            $hint = method_exists($ex, 'getHint') ? $ex->getHint() : '';
190
+            \OC_Template::printErrorPage($l->t('Can\'t read file'), $hint);
191
+        }
192
+    }
193
+
194
+    /**
195
+     * @param string $rangeHeaderPos
196
+     * @param int $fileSize
197
+     * @return array $rangeArray ('from'=>int,'to'=>int), ...
198
+     */
199
+    private static function parseHttpRangeHeader($rangeHeaderPos, $fileSize) {
200
+        $rArray=explode(',', $rangeHeaderPos);
201
+        $minOffset = 0;
202
+        $ind = 0;
203
+
204
+        $rangeArray = array();
205
+
206
+        foreach ($rArray as $value) {
207
+            $ranges = explode('-', $value);
208
+            if (is_numeric($ranges[0])) {
209
+                if ($ranges[0] < $minOffset) { // case: bytes=500-700,601-999
210
+                    $ranges[0] = $minOffset;
211
+                }
212
+                if ($ind > 0 && $rangeArray[$ind-1]['to']+1 == $ranges[0]) { // case: bytes=500-600,601-999
213
+                    $ind--;
214
+                    $ranges[0] = $rangeArray[$ind]['from'];
215
+                }
216
+            }
217
+
218
+            if (is_numeric($ranges[0]) && is_numeric($ranges[1]) && $ranges[0] < $fileSize && $ranges[0] <= $ranges[1]) {
219
+                // case: x-x
220
+                if ($ranges[1] >= $fileSize) {
221
+                    $ranges[1] = $fileSize-1;
222
+                }
223
+                $rangeArray[$ind++] = array( 'from' => $ranges[0], 'to' => $ranges[1], 'size' => $fileSize );
224
+                $minOffset = $ranges[1] + 1;
225
+                if ($minOffset >= $fileSize) {
226
+                    break;
227
+                }
228
+            }
229
+            elseif (is_numeric($ranges[0]) && $ranges[0] < $fileSize) {
230
+                // case: x-
231
+                $rangeArray[$ind++] = array( 'from' => $ranges[0], 'to' => $fileSize-1, 'size' => $fileSize );
232
+                break;
233
+            }
234
+            elseif (is_numeric($ranges[1])) {
235
+                // case: -x
236
+                if ($ranges[1] > $fileSize) {
237
+                    $ranges[1] = $fileSize;
238
+                }
239
+                $rangeArray[$ind++] = array( 'from' => $fileSize-$ranges[1], 'to' => $fileSize-1, 'size' => $fileSize );
240
+                break;
241
+            }
242
+        }
243
+        return $rangeArray;
244
+    }
245
+
246
+    /**
247
+     * @param View $view
248
+     * @param string $name
249
+     * @param string $dir
250
+     * @param array $params ; 'head' boolean to only send header of the request ; 'range' http range header
251
+     */
252
+    private static function getSingleFile($view, $dir, $name, $params) {
253
+        $filename = $dir . '/' . $name;
254
+        OC_Util::obEnd();
255
+        $view->lockFile($filename, ILockingProvider::LOCK_SHARED);
256 256
 		
257
-		$rangeArray = array();
257
+        $rangeArray = array();
258 258
 
259
-		if (isset($params['range']) && substr($params['range'], 0, 6) === 'bytes=') {
260
-			$rangeArray = self::parseHttpRangeHeader(substr($params['range'], 6), 
261
-								 \OC\Files\Filesystem::filesize($filename));
262
-		}
259
+        if (isset($params['range']) && substr($params['range'], 0, 6) === 'bytes=') {
260
+            $rangeArray = self::parseHttpRangeHeader(substr($params['range'], 6), 
261
+                                    \OC\Files\Filesystem::filesize($filename));
262
+        }
263 263
 		
264
-		if (\OC\Files\Filesystem::isReadable($filename)) {
265
-			self::sendHeaders($filename, $name, $rangeArray);
266
-		} elseif (!\OC\Files\Filesystem::file_exists($filename)) {
267
-			header("HTTP/1.1 404 Not Found");
268
-			$tmpl = new OC_Template('', '404', 'guest');
269
-			$tmpl->printPage();
270
-			exit();
271
-		} else {
272
-			header("HTTP/1.1 403 Forbidden");
273
-			die('403 Forbidden');
274
-		}
275
-		if (isset($params['head']) && $params['head']) {
276
-			return;
277
-		}
278
-		if (!empty($rangeArray)) {
279
-			try {
280
-			    if (count($rangeArray) == 1) {
281
-				$view->readfilePart($filename, $rangeArray[0]['from'], $rangeArray[0]['to']);
282
-			    }
283
-			    else {
284
-				// check if file is seekable (if not throw UnseekableException)
285
-				// we have to check it before body contents
286
-				$view->readfilePart($filename, $rangeArray[0]['size'], $rangeArray[0]['size']);
287
-
288
-				$type = \OC::$server->getMimeTypeDetector()->getSecureMimeType(\OC\Files\Filesystem::getMimeType($filename));
289
-
290
-				foreach ($rangeArray as $range) {
291
-				    echo "\r\n--".self::getBoundary()."\r\n".
292
-				         "Content-type: ".$type."\r\n".
293
-				         "Content-range: bytes ".$range['from']."-".$range['to']."/".$range['size']."\r\n\r\n";
294
-				    $view->readfilePart($filename, $range['from'], $range['to']);
295
-				}
296
-				echo "\r\n--".self::getBoundary()."--\r\n";
297
-			    }
298
-			} catch (\OCP\Files\UnseekableException $ex) {
299
-			    // file is unseekable
300
-			    header_remove('Accept-Ranges');
301
-			    header_remove('Content-Range');
302
-			    header("HTTP/1.1 200 OK");
303
-			    self::sendHeaders($filename, $name, array());
304
-			    $view->readfile($filename);
305
-			}
306
-		}
307
-		else {
308
-		    $view->readfile($filename);
309
-		}
310
-	}
311
-
312
-	/**
313
-	 * @param View $view
314
-	 * @param string $dir
315
-	 * @param string[]|string $files
316
-	 */
317
-	public static function lockFiles($view, $dir, $files) {
318
-		if (!is_array($files)) {
319
-			$file = $dir . '/' . $files;
320
-			$files = [$file];
321
-		}
322
-		foreach ($files as $file) {
323
-			$file = $dir . '/' . $file;
324
-			$view->lockFile($file, ILockingProvider::LOCK_SHARED);
325
-			if ($view->is_dir($file)) {
326
-				$contents = $view->getDirectoryContent($file);
327
-				$contents = array_map(function($fileInfo) use ($file) {
328
-					/** @var \OCP\Files\FileInfo $fileInfo */
329
-					return $file . '/' . $fileInfo->getName();
330
-				}, $contents);
331
-				self::lockFiles($view, $dir, $contents);
332
-			}
333
-		}
334
-	}
335
-
336
-	/**
337
-	 * set the maximum upload size limit for apache hosts using .htaccess
338
-	 *
339
-	 * @param int $size file size in bytes
340
-	 * @param array $files override '.htaccess' and '.user.ini' locations
341
-	 * @return bool false on failure, size on success
342
-	 */
343
-	public static function setUploadLimit($size, $files = []) {
344
-		//don't allow user to break his config
345
-		$size = intval($size);
346
-		if ($size < self::UPLOAD_MIN_LIMIT_BYTES) {
347
-			return false;
348
-		}
349
-		$size = OC_Helper::phpFileSize($size);
350
-
351
-		$phpValueKeys = array(
352
-			'upload_max_filesize',
353
-			'post_max_size'
354
-		);
355
-
356
-		// default locations if not overridden by $files
357
-		$files = array_merge([
358
-			'.htaccess' => OC::$SERVERROOT . '/.htaccess',
359
-			'.user.ini' => OC::$SERVERROOT . '/.user.ini'
360
-		], $files);
361
-
362
-		$updateFiles = [
363
-			$files['.htaccess'] => [
364
-				'pattern' => '/php_value %1$s (\S)*/',
365
-				'setting' => 'php_value %1$s %2$s'
366
-			],
367
-			$files['.user.ini'] => [
368
-				'pattern' => '/%1$s=(\S)*/',
369
-				'setting' => '%1$s=%2$s'
370
-			]
371
-		];
372
-
373
-		$success = true;
374
-
375
-		foreach ($updateFiles as $filename => $patternMap) {
376
-			// suppress warnings from fopen()
377
-			$handle = @fopen($filename, 'r+');
378
-			if (!$handle) {
379
-				\OCP\Util::writeLog('files',
380
-					'Can\'t write upload limit to ' . $filename . '. Please check the file permissions',
381
-					\OCP\Util::WARN);
382
-				$success = false;
383
-				continue; // try to update as many files as possible
384
-			}
385
-
386
-			$content = '';
387
-			while (!feof($handle)) {
388
-				$content .= fread($handle, 1000);
389
-			}
390
-
391
-			foreach ($phpValueKeys as $key) {
392
-				$pattern = vsprintf($patternMap['pattern'], [$key]);
393
-				$setting = vsprintf($patternMap['setting'], [$key, $size]);
394
-				$hasReplaced = 0;
395
-				$newContent = preg_replace($pattern, $setting, $content, 2, $hasReplaced);
396
-				if ($newContent !== null) {
397
-					$content = $newContent;
398
-				}
399
-				if ($hasReplaced === 0) {
400
-					$content .= "\n" . $setting;
401
-				}
402
-			}
403
-
404
-			// write file back
405
-			ftruncate($handle, 0);
406
-			rewind($handle);
407
-			fwrite($handle, $content);
408
-
409
-			fclose($handle);
410
-		}
411
-
412
-		if ($success) {
413
-			return OC_Helper::computerFileSize($size);
414
-		}
415
-		return false;
416
-	}
417
-
418
-	/**
419
-	 * @param string $dir
420
-	 * @param $files
421
-	 * @param integer $getType
422
-	 * @param View $view
423
-	 * @param string $filename
424
-	 */
425
-	private static function unlockAllTheFiles($dir, $files, $getType, $view, $filename) {
426
-		if ($getType === self::FILE) {
427
-			$view->unlockFile($filename, ILockingProvider::LOCK_SHARED);
428
-		}
429
-		if ($getType === self::ZIP_FILES) {
430
-			foreach ($files as $file) {
431
-				$file = $dir . '/' . $file;
432
-				$view->unlockFile($file, ILockingProvider::LOCK_SHARED);
433
-			}
434
-		}
435
-		if ($getType === self::ZIP_DIR) {
436
-			$file = $dir . '/' . $files;
437
-			$view->unlockFile($file, ILockingProvider::LOCK_SHARED);
438
-		}
439
-	}
264
+        if (\OC\Files\Filesystem::isReadable($filename)) {
265
+            self::sendHeaders($filename, $name, $rangeArray);
266
+        } elseif (!\OC\Files\Filesystem::file_exists($filename)) {
267
+            header("HTTP/1.1 404 Not Found");
268
+            $tmpl = new OC_Template('', '404', 'guest');
269
+            $tmpl->printPage();
270
+            exit();
271
+        } else {
272
+            header("HTTP/1.1 403 Forbidden");
273
+            die('403 Forbidden');
274
+        }
275
+        if (isset($params['head']) && $params['head']) {
276
+            return;
277
+        }
278
+        if (!empty($rangeArray)) {
279
+            try {
280
+                if (count($rangeArray) == 1) {
281
+                $view->readfilePart($filename, $rangeArray[0]['from'], $rangeArray[0]['to']);
282
+                }
283
+                else {
284
+                // check if file is seekable (if not throw UnseekableException)
285
+                // we have to check it before body contents
286
+                $view->readfilePart($filename, $rangeArray[0]['size'], $rangeArray[0]['size']);
287
+
288
+                $type = \OC::$server->getMimeTypeDetector()->getSecureMimeType(\OC\Files\Filesystem::getMimeType($filename));
289
+
290
+                foreach ($rangeArray as $range) {
291
+                    echo "\r\n--".self::getBoundary()."\r\n".
292
+                            "Content-type: ".$type."\r\n".
293
+                            "Content-range: bytes ".$range['from']."-".$range['to']."/".$range['size']."\r\n\r\n";
294
+                    $view->readfilePart($filename, $range['from'], $range['to']);
295
+                }
296
+                echo "\r\n--".self::getBoundary()."--\r\n";
297
+                }
298
+            } catch (\OCP\Files\UnseekableException $ex) {
299
+                // file is unseekable
300
+                header_remove('Accept-Ranges');
301
+                header_remove('Content-Range');
302
+                header("HTTP/1.1 200 OK");
303
+                self::sendHeaders($filename, $name, array());
304
+                $view->readfile($filename);
305
+            }
306
+        }
307
+        else {
308
+            $view->readfile($filename);
309
+        }
310
+    }
311
+
312
+    /**
313
+     * @param View $view
314
+     * @param string $dir
315
+     * @param string[]|string $files
316
+     */
317
+    public static function lockFiles($view, $dir, $files) {
318
+        if (!is_array($files)) {
319
+            $file = $dir . '/' . $files;
320
+            $files = [$file];
321
+        }
322
+        foreach ($files as $file) {
323
+            $file = $dir . '/' . $file;
324
+            $view->lockFile($file, ILockingProvider::LOCK_SHARED);
325
+            if ($view->is_dir($file)) {
326
+                $contents = $view->getDirectoryContent($file);
327
+                $contents = array_map(function($fileInfo) use ($file) {
328
+                    /** @var \OCP\Files\FileInfo $fileInfo */
329
+                    return $file . '/' . $fileInfo->getName();
330
+                }, $contents);
331
+                self::lockFiles($view, $dir, $contents);
332
+            }
333
+        }
334
+    }
335
+
336
+    /**
337
+     * set the maximum upload size limit for apache hosts using .htaccess
338
+     *
339
+     * @param int $size file size in bytes
340
+     * @param array $files override '.htaccess' and '.user.ini' locations
341
+     * @return bool false on failure, size on success
342
+     */
343
+    public static function setUploadLimit($size, $files = []) {
344
+        //don't allow user to break his config
345
+        $size = intval($size);
346
+        if ($size < self::UPLOAD_MIN_LIMIT_BYTES) {
347
+            return false;
348
+        }
349
+        $size = OC_Helper::phpFileSize($size);
350
+
351
+        $phpValueKeys = array(
352
+            'upload_max_filesize',
353
+            'post_max_size'
354
+        );
355
+
356
+        // default locations if not overridden by $files
357
+        $files = array_merge([
358
+            '.htaccess' => OC::$SERVERROOT . '/.htaccess',
359
+            '.user.ini' => OC::$SERVERROOT . '/.user.ini'
360
+        ], $files);
361
+
362
+        $updateFiles = [
363
+            $files['.htaccess'] => [
364
+                'pattern' => '/php_value %1$s (\S)*/',
365
+                'setting' => 'php_value %1$s %2$s'
366
+            ],
367
+            $files['.user.ini'] => [
368
+                'pattern' => '/%1$s=(\S)*/',
369
+                'setting' => '%1$s=%2$s'
370
+            ]
371
+        ];
372
+
373
+        $success = true;
374
+
375
+        foreach ($updateFiles as $filename => $patternMap) {
376
+            // suppress warnings from fopen()
377
+            $handle = @fopen($filename, 'r+');
378
+            if (!$handle) {
379
+                \OCP\Util::writeLog('files',
380
+                    'Can\'t write upload limit to ' . $filename . '. Please check the file permissions',
381
+                    \OCP\Util::WARN);
382
+                $success = false;
383
+                continue; // try to update as many files as possible
384
+            }
385
+
386
+            $content = '';
387
+            while (!feof($handle)) {
388
+                $content .= fread($handle, 1000);
389
+            }
390
+
391
+            foreach ($phpValueKeys as $key) {
392
+                $pattern = vsprintf($patternMap['pattern'], [$key]);
393
+                $setting = vsprintf($patternMap['setting'], [$key, $size]);
394
+                $hasReplaced = 0;
395
+                $newContent = preg_replace($pattern, $setting, $content, 2, $hasReplaced);
396
+                if ($newContent !== null) {
397
+                    $content = $newContent;
398
+                }
399
+                if ($hasReplaced === 0) {
400
+                    $content .= "\n" . $setting;
401
+                }
402
+            }
403
+
404
+            // write file back
405
+            ftruncate($handle, 0);
406
+            rewind($handle);
407
+            fwrite($handle, $content);
408
+
409
+            fclose($handle);
410
+        }
411
+
412
+        if ($success) {
413
+            return OC_Helper::computerFileSize($size);
414
+        }
415
+        return false;
416
+    }
417
+
418
+    /**
419
+     * @param string $dir
420
+     * @param $files
421
+     * @param integer $getType
422
+     * @param View $view
423
+     * @param string $filename
424
+     */
425
+    private static function unlockAllTheFiles($dir, $files, $getType, $view, $filename) {
426
+        if ($getType === self::FILE) {
427
+            $view->unlockFile($filename, ILockingProvider::LOCK_SHARED);
428
+        }
429
+        if ($getType === self::ZIP_FILES) {
430
+            foreach ($files as $file) {
431
+                $file = $dir . '/' . $file;
432
+                $view->unlockFile($file, ILockingProvider::LOCK_SHARED);
433
+            }
434
+        }
435
+        if ($getType === self::ZIP_DIR) {
436
+            $file = $dir . '/' . $files;
437
+            $view->unlockFile($file, ILockingProvider::LOCK_SHARED);
438
+        }
439
+    }
440 440
 
441 441
 }
Please login to merge, or discard this patch.