Completed
Push — master ( 0327ef...0fa796 )
by Morris
52:54 queued 37:36
created
lib/private/Streamer.php 2 patches
Indentation   +121 added lines, -121 removed lines patch added patch discarded remove patch
@@ -29,135 +29,135 @@
 block discarded – undo
29 29
 use ZipStreamer\ZipStreamer;
30 30
 
31 31
 class Streamer {
32
-	// array of regexp. Matching user agents will get tar instead of zip
33
-	private $preferTarFor = [ '/macintosh|mac os x/i' ];
32
+    // array of regexp. Matching user agents will get tar instead of zip
33
+    private $preferTarFor = [ '/macintosh|mac os x/i' ];
34 34
 
35
-	// streamer instance
36
-	private $streamerInstance;
35
+    // streamer instance
36
+    private $streamerInstance;
37 37
 
38
-	/**
39
-	 * Streamer constructor.
40
-	 *
41
-	 * @param IRequest $request
42
-	 * @param int $size The size of the files in bytes
43
-	 * @param int $numberOfFiles The number of files (and directories) that will
44
-	 *        be included in the streamed file
45
-	 */
46
-	public function __construct(IRequest $request, int $size, int $numberOfFiles){
38
+    /**
39
+     * Streamer constructor.
40
+     *
41
+     * @param IRequest $request
42
+     * @param int $size The size of the files in bytes
43
+     * @param int $numberOfFiles The number of files (and directories) that will
44
+     *        be included in the streamed file
45
+     */
46
+    public function __construct(IRequest $request, int $size, int $numberOfFiles){
47 47
 
48
-		/**
49
-		 * zip32 constraints for a basic (without compression, volumes nor
50
-		 * encryption) zip file according to the Zip specification:
51
-		 * - No file size is larger than 4 bytes (file size < 4294967296); see
52
-		 *   4.4.9 uncompressed size
53
-		 * - The size of all files plus their local headers is not larger than
54
-		 *   4 bytes; see 4.4.16 relative offset of local header and 4.4.24
55
-		 *   offset of start of central directory with respect to the starting
56
-		 *   disk number
57
-		 * - The total number of entries (files and directories) in the zip file
58
-		 *   is not larger than 2 bytes (number of entries < 65536); see 4.4.22
59
-		 *   total number of entries in the central dir
60
-		 * - The size of the central directory is not larger than 4 bytes; see
61
-		 *   4.4.23 size of the central directory
62
-		 *
63
-		 * Due to all that, zip32 is used if the size is below 4GB and there are
64
-		 * less than 65536 files; the margin between 4*1000^3 and 4*1024^3
65
-		 * should give enough room for the extra zip metadata. Technically, it
66
-		 * would still be possible to create an invalid zip32 file (for example,
67
-		 * a zip file from files smaller than 4GB with a central directory
68
-		 * larger than 4GiB), but it should not happen in the real world.
69
-		 */
70
-		if ($size < 4 * 1000 * 1000 * 1000 && $numberOfFiles < 65536) {
71
-			$this->streamerInstance = new ZipStreamer(['zip64' => false]);
72
-		} else if ($request->isUserAgent($this->preferTarFor)) {
73
-			$this->streamerInstance = new TarStreamer();
74
-		} else {
75
-			$this->streamerInstance = new ZipStreamer(['zip64' => PHP_INT_SIZE !== 4]);
76
-		}
77
-	}
48
+        /**
49
+         * zip32 constraints for a basic (without compression, volumes nor
50
+         * encryption) zip file according to the Zip specification:
51
+         * - No file size is larger than 4 bytes (file size < 4294967296); see
52
+         *   4.4.9 uncompressed size
53
+         * - The size of all files plus their local headers is not larger than
54
+         *   4 bytes; see 4.4.16 relative offset of local header and 4.4.24
55
+         *   offset of start of central directory with respect to the starting
56
+         *   disk number
57
+         * - The total number of entries (files and directories) in the zip file
58
+         *   is not larger than 2 bytes (number of entries < 65536); see 4.4.22
59
+         *   total number of entries in the central dir
60
+         * - The size of the central directory is not larger than 4 bytes; see
61
+         *   4.4.23 size of the central directory
62
+         *
63
+         * Due to all that, zip32 is used if the size is below 4GB and there are
64
+         * less than 65536 files; the margin between 4*1000^3 and 4*1024^3
65
+         * should give enough room for the extra zip metadata. Technically, it
66
+         * would still be possible to create an invalid zip32 file (for example,
67
+         * a zip file from files smaller than 4GB with a central directory
68
+         * larger than 4GiB), but it should not happen in the real world.
69
+         */
70
+        if ($size < 4 * 1000 * 1000 * 1000 && $numberOfFiles < 65536) {
71
+            $this->streamerInstance = new ZipStreamer(['zip64' => false]);
72
+        } else if ($request->isUserAgent($this->preferTarFor)) {
73
+            $this->streamerInstance = new TarStreamer();
74
+        } else {
75
+            $this->streamerInstance = new ZipStreamer(['zip64' => PHP_INT_SIZE !== 4]);
76
+        }
77
+    }
78 78
 	
79
-	/**
80
-	 * Send HTTP headers
81
-	 * @param string $name 
82
-	 */
83
-	public function sendHeaders($name){
84
-		$extension = $this->streamerInstance instanceof ZipStreamer ? '.zip' : '.tar';
85
-		$fullName = $name . $extension;
86
-		$this->streamerInstance->sendHeaders($fullName);
87
-	}
79
+    /**
80
+     * Send HTTP headers
81
+     * @param string $name 
82
+     */
83
+    public function sendHeaders($name){
84
+        $extension = $this->streamerInstance instanceof ZipStreamer ? '.zip' : '.tar';
85
+        $fullName = $name . $extension;
86
+        $this->streamerInstance->sendHeaders($fullName);
87
+    }
88 88
 	
89
-	/**
90
-	 * Stream directory recursively
91
-	 * @param string $dir
92
-	 * @param string $internalDir
93
-	 */
94
-	public function addDirRecursive($dir, $internalDir='') {
95
-		$dirname = basename($dir);
96
-		$rootDir = $internalDir . $dirname;
97
-		if (!empty($rootDir)) {
98
-			$this->streamerInstance->addEmptyDir($rootDir);
99
-		}
100
-		$internalDir .= $dirname . '/';
101
-		// prevent absolute dirs
102
-		$internalDir = ltrim($internalDir, '/');
89
+    /**
90
+     * Stream directory recursively
91
+     * @param string $dir
92
+     * @param string $internalDir
93
+     */
94
+    public function addDirRecursive($dir, $internalDir='') {
95
+        $dirname = basename($dir);
96
+        $rootDir = $internalDir . $dirname;
97
+        if (!empty($rootDir)) {
98
+            $this->streamerInstance->addEmptyDir($rootDir);
99
+        }
100
+        $internalDir .= $dirname . '/';
101
+        // prevent absolute dirs
102
+        $internalDir = ltrim($internalDir, '/');
103 103
 
104
-		$files= \OC\Files\Filesystem::getDirectoryContent($dir);
105
-		foreach($files as $file) {
106
-			$filename = $file['name'];
107
-			$file = $dir . '/' . $filename;
108
-			if(\OC\Files\Filesystem::is_file($file)) {
109
-				$filesize = \OC\Files\Filesystem::filesize($file);
110
-				$fileTime = \OC\Files\Filesystem::filemtime($file);
111
-				$fh = \OC\Files\Filesystem::fopen($file, 'r');
112
-				$this->addFileFromStream($fh, $internalDir . $filename, $filesize, $fileTime);
113
-				fclose($fh);
114
-			}elseif(\OC\Files\Filesystem::is_dir($file)) {
115
-				$this->addDirRecursive($file, $internalDir);
116
-			}
117
-		}
118
-	}
104
+        $files= \OC\Files\Filesystem::getDirectoryContent($dir);
105
+        foreach($files as $file) {
106
+            $filename = $file['name'];
107
+            $file = $dir . '/' . $filename;
108
+            if(\OC\Files\Filesystem::is_file($file)) {
109
+                $filesize = \OC\Files\Filesystem::filesize($file);
110
+                $fileTime = \OC\Files\Filesystem::filemtime($file);
111
+                $fh = \OC\Files\Filesystem::fopen($file, 'r');
112
+                $this->addFileFromStream($fh, $internalDir . $filename, $filesize, $fileTime);
113
+                fclose($fh);
114
+            }elseif(\OC\Files\Filesystem::is_dir($file)) {
115
+                $this->addDirRecursive($file, $internalDir);
116
+            }
117
+        }
118
+    }
119 119
 	
120
-	/**
121
-	 * Add a file to the archive at the specified location and file name.
122
-	 *
123
-	 * @param string $stream Stream to read data from
124
-	 * @param string $internalName Filepath and name to be used in the archive.
125
-	 * @param int $size Filesize
126
-	 * @param int|bool $time File mtime as int, or false
127
-	 * @return bool $success
128
-	 */
129
-	public function addFileFromStream($stream, $internalName, $size, $time) {
130
-		$options = [];
131
-		if ($time) {
132
-			$options = [
133
-				'timestamp' => $time
134
-			];
135
-		}
120
+    /**
121
+     * Add a file to the archive at the specified location and file name.
122
+     *
123
+     * @param string $stream Stream to read data from
124
+     * @param string $internalName Filepath and name to be used in the archive.
125
+     * @param int $size Filesize
126
+     * @param int|bool $time File mtime as int, or false
127
+     * @return bool $success
128
+     */
129
+    public function addFileFromStream($stream, $internalName, $size, $time) {
130
+        $options = [];
131
+        if ($time) {
132
+            $options = [
133
+                'timestamp' => $time
134
+            ];
135
+        }
136 136
 
137
-		if ($this->streamerInstance instanceof ZipStreamer) {
138
-			return $this->streamerInstance->addFileFromStream($stream, $internalName, $options);
139
-		} else {
140
-			return $this->streamerInstance->addFileFromStream($stream, $internalName, $size, $options);
141
-		}
142
-	}
137
+        if ($this->streamerInstance instanceof ZipStreamer) {
138
+            return $this->streamerInstance->addFileFromStream($stream, $internalName, $options);
139
+        } else {
140
+            return $this->streamerInstance->addFileFromStream($stream, $internalName, $size, $options);
141
+        }
142
+    }
143 143
 
144
-	/**
145
-	 * Add an empty directory entry to the archive.
146
-	 *
147
-	 * @param string $dirName Directory Path and name to be added to the archive.
148
-	 * @return bool $success
149
-	 */
150
-	public function addEmptyDir($dirName){
151
-		return $this->streamerInstance->addEmptyDir($dirName);
152
-	}
144
+    /**
145
+     * Add an empty directory entry to the archive.
146
+     *
147
+     * @param string $dirName Directory Path and name to be added to the archive.
148
+     * @return bool $success
149
+     */
150
+    public function addEmptyDir($dirName){
151
+        return $this->streamerInstance->addEmptyDir($dirName);
152
+    }
153 153
 
154
-	/**
155
-	 * Close the archive.
156
-	 * A closed archive can no longer have new files added to it. After
157
-	 * closing, the file is completely written to the output stream.
158
-	 * @return bool $success
159
-	 */
160
-	public function finalize(){
161
-		return $this->streamerInstance->finalize();
162
-	}
154
+    /**
155
+     * Close the archive.
156
+     * A closed archive can no longer have new files added to it. After
157
+     * closing, the file is completely written to the output stream.
158
+     * @return bool $success
159
+     */
160
+    public function finalize(){
161
+        return $this->streamerInstance->finalize();
162
+    }
163 163
 }
Please login to merge, or discard this patch.
Spacing   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -30,7 +30,7 @@  discard block
 block discarded – undo
30 30
 
31 31
 class Streamer {
32 32
 	// array of regexp. Matching user agents will get tar instead of zip
33
-	private $preferTarFor = [ '/macintosh|mac os x/i' ];
33
+	private $preferTarFor = ['/macintosh|mac os x/i'];
34 34
 
35 35
 	// streamer instance
36 36
 	private $streamerInstance;
@@ -43,7 +43,7 @@  discard block
 block discarded – undo
43 43
 	 * @param int $numberOfFiles The number of files (and directories) that will
44 44
 	 *        be included in the streamed file
45 45
 	 */
46
-	public function __construct(IRequest $request, int $size, int $numberOfFiles){
46
+	public function __construct(IRequest $request, int $size, int $numberOfFiles) {
47 47
 
48 48
 		/**
49 49
 		 * zip32 constraints for a basic (without compression, volumes nor
@@ -80,9 +80,9 @@  discard block
 block discarded – undo
80 80
 	 * Send HTTP headers
81 81
 	 * @param string $name 
82 82
 	 */
83
-	public function sendHeaders($name){
83
+	public function sendHeaders($name) {
84 84
 		$extension = $this->streamerInstance instanceof ZipStreamer ? '.zip' : '.tar';
85
-		$fullName = $name . $extension;
85
+		$fullName = $name.$extension;
86 86
 		$this->streamerInstance->sendHeaders($fullName);
87 87
 	}
88 88
 	
@@ -91,27 +91,27 @@  discard block
 block discarded – undo
91 91
 	 * @param string $dir
92 92
 	 * @param string $internalDir
93 93
 	 */
94
-	public function addDirRecursive($dir, $internalDir='') {
94
+	public function addDirRecursive($dir, $internalDir = '') {
95 95
 		$dirname = basename($dir);
96
-		$rootDir = $internalDir . $dirname;
96
+		$rootDir = $internalDir.$dirname;
97 97
 		if (!empty($rootDir)) {
98 98
 			$this->streamerInstance->addEmptyDir($rootDir);
99 99
 		}
100
-		$internalDir .= $dirname . '/';
100
+		$internalDir .= $dirname.'/';
101 101
 		// prevent absolute dirs
102 102
 		$internalDir = ltrim($internalDir, '/');
103 103
 
104
-		$files= \OC\Files\Filesystem::getDirectoryContent($dir);
105
-		foreach($files as $file) {
104
+		$files = \OC\Files\Filesystem::getDirectoryContent($dir);
105
+		foreach ($files as $file) {
106 106
 			$filename = $file['name'];
107
-			$file = $dir . '/' . $filename;
108
-			if(\OC\Files\Filesystem::is_file($file)) {
107
+			$file = $dir.'/'.$filename;
108
+			if (\OC\Files\Filesystem::is_file($file)) {
109 109
 				$filesize = \OC\Files\Filesystem::filesize($file);
110 110
 				$fileTime = \OC\Files\Filesystem::filemtime($file);
111 111
 				$fh = \OC\Files\Filesystem::fopen($file, 'r');
112
-				$this->addFileFromStream($fh, $internalDir . $filename, $filesize, $fileTime);
112
+				$this->addFileFromStream($fh, $internalDir.$filename, $filesize, $fileTime);
113 113
 				fclose($fh);
114
-			}elseif(\OC\Files\Filesystem::is_dir($file)) {
114
+			}elseif (\OC\Files\Filesystem::is_dir($file)) {
115 115
 				$this->addDirRecursive($file, $internalDir);
116 116
 			}
117 117
 		}
@@ -147,7 +147,7 @@  discard block
 block discarded – undo
147 147
 	 * @param string $dirName Directory Path and name to be added to the archive.
148 148
 	 * @return bool $success
149 149
 	 */
150
-	public function addEmptyDir($dirName){
150
+	public function addEmptyDir($dirName) {
151 151
 		return $this->streamerInstance->addEmptyDir($dirName);
152 152
 	}
153 153
 
@@ -157,7 +157,7 @@  discard block
 block discarded – undo
157 157
 	 * closing, the file is completely written to the output stream.
158 158
 	 * @return bool $success
159 159
 	 */
160
-	public function finalize(){
160
+	public function finalize() {
161 161
 		return $this->streamerInstance->finalize();
162 162
 	}
163 163
 }
Please login to merge, or discard this patch.
lib/private/legacy/files.php 2 patches
Indentation   +430 added lines, -430 removed lines patch added patch discarded remove patch
@@ -48,438 +48,438 @@
 block discarded – undo
48 48
  *
49 49
  */
50 50
 class OC_Files {
51
-	const FILE = 1;
52
-	const ZIP_FILES = 2;
53
-	const ZIP_DIR = 3;
54
-
55
-	const UPLOAD_MIN_LIMIT_BYTES = 1048576; // 1 MiB
56
-
57
-
58
-	private static $multipartBoundary = '';
59
-
60
-	/**
61
-	 * @return string
62
-	 */
63
-	private static function getBoundary() {
64
-		if (empty(self::$multipartBoundary)) {
65
-			self::$multipartBoundary = md5(mt_rand());
66
-		}
67
-		return self::$multipartBoundary;
68
-	}
69
-
70
-	/**
71
-	 * @param string $filename
72
-	 * @param string $name
73
-	 * @param array $rangeArray ('from'=>int,'to'=>int), ...
74
-	 */
75
-	private static function sendHeaders($filename, $name, array $rangeArray) {
76
-		OC_Response::setContentDispositionHeader($name, 'attachment');
77
-		header('Content-Transfer-Encoding: binary', true);
78
-		header('Pragma: public');// enable caching in IE
79
-		header('Expires: 0');
80
-		header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
81
-		$fileSize = \OC\Files\Filesystem::filesize($filename);
82
-		$type = \OC::$server->getMimeTypeDetector()->getSecureMimeType(\OC\Files\Filesystem::getMimeType($filename));
83
-		if ($fileSize > -1) {
84
-			if (!empty($rangeArray)) {
85
-			    header('HTTP/1.1 206 Partial Content', true);
86
-			    header('Accept-Ranges: bytes', true);
87
-			    if (count($rangeArray) > 1) {
88
-				$type = 'multipart/byteranges; boundary='.self::getBoundary();
89
-				// no Content-Length header here
90
-			    }
91
-			    else {
92
-				header(sprintf('Content-Range: bytes %d-%d/%d', $rangeArray[0]['from'], $rangeArray[0]['to'], $fileSize), true);
93
-				OC_Response::setContentLengthHeader($rangeArray[0]['to'] - $rangeArray[0]['from'] + 1);
94
-			    }
95
-			}
96
-			else {
97
-			    OC_Response::setContentLengthHeader($fileSize);
98
-			}
99
-		}
100
-		header('Content-Type: '.$type, true);
101
-	}
102
-
103
-	/**
104
-	 * return the content of a file or return a zip file containing multiple files
105
-	 *
106
-	 * @param string $dir
107
-	 * @param string $files ; separated list of files to download
108
-	 * @param array $params ; 'head' boolean to only send header of the request ; 'range' http range header
109
-	 */
110
-	public static function get($dir, $files, $params = null) {
111
-
112
-		$view = \OC\Files\Filesystem::getView();
113
-		$getType = self::FILE;
114
-		$filename = $dir;
115
-		try {
116
-
117
-			if (is_array($files) && count($files) === 1) {
118
-				$files = $files[0];
119
-			}
120
-
121
-			if (!is_array($files)) {
122
-				$filename = $dir . '/' . $files;
123
-				if (!$view->is_dir($filename)) {
124
-					self::getSingleFile($view, $dir, $files, is_null($params) ? array() : $params);
125
-					return;
126
-				}
127
-			}
128
-
129
-			$name = 'download';
130
-			if (is_array($files)) {
131
-				$getType = self::ZIP_FILES;
132
-				$basename = basename($dir);
133
-				if ($basename) {
134
-					$name = $basename;
135
-				}
136
-
137
-				$filename = $dir . '/' . $name;
138
-			} else {
139
-				$filename = $dir . '/' . $files;
140
-				$getType = self::ZIP_DIR;
141
-				// downloading root ?
142
-				if ($files !== '') {
143
-					$name = $files;
144
-				}
145
-			}
146
-
147
-			self::lockFiles($view, $dir, $files);
148
-
149
-			/* Calculate filesize and number of files */
150
-			if ($getType === self::ZIP_FILES) {
151
-				$fileInfos = array();
152
-				$fileSize = 0;
153
-				foreach ($files as $file) {
154
-					$fileInfo = \OC\Files\Filesystem::getFileInfo($dir . '/' . $file);
155
-					$fileSize += $fileInfo->getSize();
156
-					$fileInfos[] = $fileInfo;
157
-				}
158
-				$numberOfFiles = self::getNumberOfFiles($fileInfos);
159
-			} elseif ($getType === self::ZIP_DIR) {
160
-				$fileInfo = \OC\Files\Filesystem::getFileInfo($dir . '/' . $files);
161
-				$fileSize = $fileInfo->getSize();
162
-				$numberOfFiles = self::getNumberOfFiles(array($fileInfo));
163
-			}
164
-
165
-			$streamer = new Streamer(\OC::$server->getRequest(), $fileSize, $numberOfFiles);
166
-			OC_Util::obEnd();
167
-
168
-			$streamer->sendHeaders($name);
169
-			$executionTime = (int)OC::$server->getIniWrapper()->getNumeric('max_execution_time');
170
-			if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
171
-				@set_time_limit(0);
172
-			}
173
-			ignore_user_abort(true);
174
-
175
-			if ($getType === self::ZIP_FILES) {
176
-				foreach ($files as $file) {
177
-					$file = $dir . '/' . $file;
178
-					if (\OC\Files\Filesystem::is_file($file)) {
179
-						$fileSize = \OC\Files\Filesystem::filesize($file);
180
-						$fileTime = \OC\Files\Filesystem::filemtime($file);
181
-						$fh = \OC\Files\Filesystem::fopen($file, 'r');
182
-						$streamer->addFileFromStream($fh, basename($file), $fileSize, $fileTime);
183
-						fclose($fh);
184
-					} elseif (\OC\Files\Filesystem::is_dir($file)) {
185
-						$streamer->addDirRecursive($file);
186
-					}
187
-				}
188
-			} elseif ($getType === self::ZIP_DIR) {
189
-				$file = $dir . '/' . $files;
190
-				$streamer->addDirRecursive($file);
191
-			}
192
-			$streamer->finalize();
193
-			set_time_limit($executionTime);
194
-			self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
195
-		} catch (\OCP\Lock\LockedException $ex) {
196
-			self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
197
-			OC::$server->getLogger()->logException($ex);
198
-			$l = \OC::$server->getL10N('core');
199
-			$hint = method_exists($ex, 'getHint') ? $ex->getHint() : '';
200
-			\OC_Template::printErrorPage($l->t('File is currently busy, please try again later'), $hint);
201
-		} catch (\OCP\Files\ForbiddenException $ex) {
202
-			self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
203
-			OC::$server->getLogger()->logException($ex);
204
-			$l = \OC::$server->getL10N('core');
205
-			\OC_Template::printErrorPage($l->t('Can\'t read file'), $ex->getMessage());
206
-		} catch (\Exception $ex) {
207
-			self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
208
-			OC::$server->getLogger()->logException($ex);
209
-			$l = \OC::$server->getL10N('core');
210
-			$hint = method_exists($ex, 'getHint') ? $ex->getHint() : '';
211
-			\OC_Template::printErrorPage($l->t('Can\'t read file'), $hint);
212
-		}
213
-	}
214
-
215
-	/**
216
-	 * @param string $rangeHeaderPos
217
-	 * @param int $fileSize
218
-	 * @return array $rangeArray ('from'=>int,'to'=>int), ...
219
-	 */
220
-	private static function parseHttpRangeHeader($rangeHeaderPos, $fileSize) {
221
-		$rArray=explode(',', $rangeHeaderPos);
222
-		$minOffset = 0;
223
-		$ind = 0;
224
-
225
-		$rangeArray = array();
226
-
227
-		foreach ($rArray as $value) {
228
-			$ranges = explode('-', $value);
229
-			if (is_numeric($ranges[0])) {
230
-				if ($ranges[0] < $minOffset) { // case: bytes=500-700,601-999
231
-					$ranges[0] = $minOffset;
232
-				}
233
-				if ($ind > 0 && $rangeArray[$ind-1]['to']+1 == $ranges[0]) { // case: bytes=500-600,601-999
234
-					$ind--;
235
-					$ranges[0] = $rangeArray[$ind]['from'];
236
-				}
237
-			}
238
-
239
-			if (is_numeric($ranges[0]) && is_numeric($ranges[1]) && $ranges[0] < $fileSize && $ranges[0] <= $ranges[1]) {
240
-				// case: x-x
241
-				if ($ranges[1] >= $fileSize) {
242
-					$ranges[1] = $fileSize-1;
243
-				}
244
-				$rangeArray[$ind++] = array( 'from' => $ranges[0], 'to' => $ranges[1], 'size' => $fileSize );
245
-				$minOffset = $ranges[1] + 1;
246
-				if ($minOffset >= $fileSize) {
247
-					break;
248
-				}
249
-			}
250
-			elseif (is_numeric($ranges[0]) && $ranges[0] < $fileSize) {
251
-				// case: x-
252
-				$rangeArray[$ind++] = array( 'from' => $ranges[0], 'to' => $fileSize-1, 'size' => $fileSize );
253
-				break;
254
-			}
255
-			elseif (is_numeric($ranges[1])) {
256
-				// case: -x
257
-				if ($ranges[1] > $fileSize) {
258
-					$ranges[1] = $fileSize;
259
-				}
260
-				$rangeArray[$ind++] = array( 'from' => $fileSize-$ranges[1], 'to' => $fileSize-1, 'size' => $fileSize );
261
-				break;
262
-			}
263
-		}
264
-		return $rangeArray;
265
-	}
266
-
267
-	/**
268
-	 * @param View $view
269
-	 * @param string $name
270
-	 * @param string $dir
271
-	 * @param array $params ; 'head' boolean to only send header of the request ; 'range' http range header
272
-	 */
273
-	private static function getSingleFile($view, $dir, $name, $params) {
274
-		$filename = $dir . '/' . $name;
275
-		OC_Util::obEnd();
276
-		$view->lockFile($filename, ILockingProvider::LOCK_SHARED);
51
+    const FILE = 1;
52
+    const ZIP_FILES = 2;
53
+    const ZIP_DIR = 3;
54
+
55
+    const UPLOAD_MIN_LIMIT_BYTES = 1048576; // 1 MiB
56
+
57
+
58
+    private static $multipartBoundary = '';
59
+
60
+    /**
61
+     * @return string
62
+     */
63
+    private static function getBoundary() {
64
+        if (empty(self::$multipartBoundary)) {
65
+            self::$multipartBoundary = md5(mt_rand());
66
+        }
67
+        return self::$multipartBoundary;
68
+    }
69
+
70
+    /**
71
+     * @param string $filename
72
+     * @param string $name
73
+     * @param array $rangeArray ('from'=>int,'to'=>int), ...
74
+     */
75
+    private static function sendHeaders($filename, $name, array $rangeArray) {
76
+        OC_Response::setContentDispositionHeader($name, 'attachment');
77
+        header('Content-Transfer-Encoding: binary', true);
78
+        header('Pragma: public');// enable caching in IE
79
+        header('Expires: 0');
80
+        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
81
+        $fileSize = \OC\Files\Filesystem::filesize($filename);
82
+        $type = \OC::$server->getMimeTypeDetector()->getSecureMimeType(\OC\Files\Filesystem::getMimeType($filename));
83
+        if ($fileSize > -1) {
84
+            if (!empty($rangeArray)) {
85
+                header('HTTP/1.1 206 Partial Content', true);
86
+                header('Accept-Ranges: bytes', true);
87
+                if (count($rangeArray) > 1) {
88
+                $type = 'multipart/byteranges; boundary='.self::getBoundary();
89
+                // no Content-Length header here
90
+                }
91
+                else {
92
+                header(sprintf('Content-Range: bytes %d-%d/%d', $rangeArray[0]['from'], $rangeArray[0]['to'], $fileSize), true);
93
+                OC_Response::setContentLengthHeader($rangeArray[0]['to'] - $rangeArray[0]['from'] + 1);
94
+                }
95
+            }
96
+            else {
97
+                OC_Response::setContentLengthHeader($fileSize);
98
+            }
99
+        }
100
+        header('Content-Type: '.$type, true);
101
+    }
102
+
103
+    /**
104
+     * return the content of a file or return a zip file containing multiple files
105
+     *
106
+     * @param string $dir
107
+     * @param string $files ; separated list of files to download
108
+     * @param array $params ; 'head' boolean to only send header of the request ; 'range' http range header
109
+     */
110
+    public static function get($dir, $files, $params = null) {
111
+
112
+        $view = \OC\Files\Filesystem::getView();
113
+        $getType = self::FILE;
114
+        $filename = $dir;
115
+        try {
116
+
117
+            if (is_array($files) && count($files) === 1) {
118
+                $files = $files[0];
119
+            }
120
+
121
+            if (!is_array($files)) {
122
+                $filename = $dir . '/' . $files;
123
+                if (!$view->is_dir($filename)) {
124
+                    self::getSingleFile($view, $dir, $files, is_null($params) ? array() : $params);
125
+                    return;
126
+                }
127
+            }
128
+
129
+            $name = 'download';
130
+            if (is_array($files)) {
131
+                $getType = self::ZIP_FILES;
132
+                $basename = basename($dir);
133
+                if ($basename) {
134
+                    $name = $basename;
135
+                }
136
+
137
+                $filename = $dir . '/' . $name;
138
+            } else {
139
+                $filename = $dir . '/' . $files;
140
+                $getType = self::ZIP_DIR;
141
+                // downloading root ?
142
+                if ($files !== '') {
143
+                    $name = $files;
144
+                }
145
+            }
146
+
147
+            self::lockFiles($view, $dir, $files);
148
+
149
+            /* Calculate filesize and number of files */
150
+            if ($getType === self::ZIP_FILES) {
151
+                $fileInfos = array();
152
+                $fileSize = 0;
153
+                foreach ($files as $file) {
154
+                    $fileInfo = \OC\Files\Filesystem::getFileInfo($dir . '/' . $file);
155
+                    $fileSize += $fileInfo->getSize();
156
+                    $fileInfos[] = $fileInfo;
157
+                }
158
+                $numberOfFiles = self::getNumberOfFiles($fileInfos);
159
+            } elseif ($getType === self::ZIP_DIR) {
160
+                $fileInfo = \OC\Files\Filesystem::getFileInfo($dir . '/' . $files);
161
+                $fileSize = $fileInfo->getSize();
162
+                $numberOfFiles = self::getNumberOfFiles(array($fileInfo));
163
+            }
164
+
165
+            $streamer = new Streamer(\OC::$server->getRequest(), $fileSize, $numberOfFiles);
166
+            OC_Util::obEnd();
167
+
168
+            $streamer->sendHeaders($name);
169
+            $executionTime = (int)OC::$server->getIniWrapper()->getNumeric('max_execution_time');
170
+            if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
171
+                @set_time_limit(0);
172
+            }
173
+            ignore_user_abort(true);
174
+
175
+            if ($getType === self::ZIP_FILES) {
176
+                foreach ($files as $file) {
177
+                    $file = $dir . '/' . $file;
178
+                    if (\OC\Files\Filesystem::is_file($file)) {
179
+                        $fileSize = \OC\Files\Filesystem::filesize($file);
180
+                        $fileTime = \OC\Files\Filesystem::filemtime($file);
181
+                        $fh = \OC\Files\Filesystem::fopen($file, 'r');
182
+                        $streamer->addFileFromStream($fh, basename($file), $fileSize, $fileTime);
183
+                        fclose($fh);
184
+                    } elseif (\OC\Files\Filesystem::is_dir($file)) {
185
+                        $streamer->addDirRecursive($file);
186
+                    }
187
+                }
188
+            } elseif ($getType === self::ZIP_DIR) {
189
+                $file = $dir . '/' . $files;
190
+                $streamer->addDirRecursive($file);
191
+            }
192
+            $streamer->finalize();
193
+            set_time_limit($executionTime);
194
+            self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
195
+        } catch (\OCP\Lock\LockedException $ex) {
196
+            self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
197
+            OC::$server->getLogger()->logException($ex);
198
+            $l = \OC::$server->getL10N('core');
199
+            $hint = method_exists($ex, 'getHint') ? $ex->getHint() : '';
200
+            \OC_Template::printErrorPage($l->t('File is currently busy, please try again later'), $hint);
201
+        } catch (\OCP\Files\ForbiddenException $ex) {
202
+            self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
203
+            OC::$server->getLogger()->logException($ex);
204
+            $l = \OC::$server->getL10N('core');
205
+            \OC_Template::printErrorPage($l->t('Can\'t read file'), $ex->getMessage());
206
+        } catch (\Exception $ex) {
207
+            self::unlockAllTheFiles($dir, $files, $getType, $view, $filename);
208
+            OC::$server->getLogger()->logException($ex);
209
+            $l = \OC::$server->getL10N('core');
210
+            $hint = method_exists($ex, 'getHint') ? $ex->getHint() : '';
211
+            \OC_Template::printErrorPage($l->t('Can\'t read file'), $hint);
212
+        }
213
+    }
214
+
215
+    /**
216
+     * @param string $rangeHeaderPos
217
+     * @param int $fileSize
218
+     * @return array $rangeArray ('from'=>int,'to'=>int), ...
219
+     */
220
+    private static function parseHttpRangeHeader($rangeHeaderPos, $fileSize) {
221
+        $rArray=explode(',', $rangeHeaderPos);
222
+        $minOffset = 0;
223
+        $ind = 0;
224
+
225
+        $rangeArray = array();
226
+
227
+        foreach ($rArray as $value) {
228
+            $ranges = explode('-', $value);
229
+            if (is_numeric($ranges[0])) {
230
+                if ($ranges[0] < $minOffset) { // case: bytes=500-700,601-999
231
+                    $ranges[0] = $minOffset;
232
+                }
233
+                if ($ind > 0 && $rangeArray[$ind-1]['to']+1 == $ranges[0]) { // case: bytes=500-600,601-999
234
+                    $ind--;
235
+                    $ranges[0] = $rangeArray[$ind]['from'];
236
+                }
237
+            }
238
+
239
+            if (is_numeric($ranges[0]) && is_numeric($ranges[1]) && $ranges[0] < $fileSize && $ranges[0] <= $ranges[1]) {
240
+                // case: x-x
241
+                if ($ranges[1] >= $fileSize) {
242
+                    $ranges[1] = $fileSize-1;
243
+                }
244
+                $rangeArray[$ind++] = array( 'from' => $ranges[0], 'to' => $ranges[1], 'size' => $fileSize );
245
+                $minOffset = $ranges[1] + 1;
246
+                if ($minOffset >= $fileSize) {
247
+                    break;
248
+                }
249
+            }
250
+            elseif (is_numeric($ranges[0]) && $ranges[0] < $fileSize) {
251
+                // case: x-
252
+                $rangeArray[$ind++] = array( 'from' => $ranges[0], 'to' => $fileSize-1, 'size' => $fileSize );
253
+                break;
254
+            }
255
+            elseif (is_numeric($ranges[1])) {
256
+                // case: -x
257
+                if ($ranges[1] > $fileSize) {
258
+                    $ranges[1] = $fileSize;
259
+                }
260
+                $rangeArray[$ind++] = array( 'from' => $fileSize-$ranges[1], 'to' => $fileSize-1, 'size' => $fileSize );
261
+                break;
262
+            }
263
+        }
264
+        return $rangeArray;
265
+    }
266
+
267
+    /**
268
+     * @param View $view
269
+     * @param string $name
270
+     * @param string $dir
271
+     * @param array $params ; 'head' boolean to only send header of the request ; 'range' http range header
272
+     */
273
+    private static function getSingleFile($view, $dir, $name, $params) {
274
+        $filename = $dir . '/' . $name;
275
+        OC_Util::obEnd();
276
+        $view->lockFile($filename, ILockingProvider::LOCK_SHARED);
277 277
 		
278
-		$rangeArray = array();
278
+        $rangeArray = array();
279 279
 
280
-		if (isset($params['range']) && substr($params['range'], 0, 6) === 'bytes=') {
281
-			$rangeArray = self::parseHttpRangeHeader(substr($params['range'], 6), 
282
-								 \OC\Files\Filesystem::filesize($filename));
283
-		}
280
+        if (isset($params['range']) && substr($params['range'], 0, 6) === 'bytes=') {
281
+            $rangeArray = self::parseHttpRangeHeader(substr($params['range'], 6), 
282
+                                    \OC\Files\Filesystem::filesize($filename));
283
+        }
284 284
 		
285
-		if (\OC\Files\Filesystem::isReadable($filename)) {
286
-			self::sendHeaders($filename, $name, $rangeArray);
287
-		} elseif (!\OC\Files\Filesystem::file_exists($filename)) {
288
-			header("HTTP/1.1 404 Not Found");
289
-			$tmpl = new OC_Template('', '404', 'guest');
290
-			$tmpl->printPage();
291
-			exit();
292
-		} else {
293
-			header("HTTP/1.1 403 Forbidden");
294
-			die('403 Forbidden');
295
-		}
296
-		if (isset($params['head']) && $params['head']) {
297
-			return;
298
-		}
299
-		if (!empty($rangeArray)) {
300
-			try {
301
-			    if (count($rangeArray) == 1) {
302
-				$view->readfilePart($filename, $rangeArray[0]['from'], $rangeArray[0]['to']);
303
-			    }
304
-			    else {
305
-				// check if file is seekable (if not throw UnseekableException)
306
-				// we have to check it before body contents
307
-				$view->readfilePart($filename, $rangeArray[0]['size'], $rangeArray[0]['size']);
308
-
309
-				$type = \OC::$server->getMimeTypeDetector()->getSecureMimeType(\OC\Files\Filesystem::getMimeType($filename));
310
-
311
-				foreach ($rangeArray as $range) {
312
-				    echo "\r\n--".self::getBoundary()."\r\n".
313
-				         "Content-type: ".$type."\r\n".
314
-				         "Content-range: bytes ".$range['from']."-".$range['to']."/".$range['size']."\r\n\r\n";
315
-				    $view->readfilePart($filename, $range['from'], $range['to']);
316
-				}
317
-				echo "\r\n--".self::getBoundary()."--\r\n";
318
-			    }
319
-			} catch (\OCP\Files\UnseekableException $ex) {
320
-			    // file is unseekable
321
-			    header_remove('Accept-Ranges');
322
-			    header_remove('Content-Range');
323
-			    header("HTTP/1.1 200 OK");
324
-			    self::sendHeaders($filename, $name, array());
325
-			    $view->readfile($filename);
326
-			}
327
-		}
328
-		else {
329
-		    $view->readfile($filename);
330
-		}
331
-	}
332
-
333
-	/**
334
-	 * Returns the total (recursive) number of files and folders in the given
335
-	 * FileInfos.
336
-	 *
337
-	 * @param \OCP\Files\FileInfo[] $fileInfos the FileInfos to count
338
-	 * @return int the total number of files and folders
339
-	 */
340
-	private static function getNumberOfFiles($fileInfos) {
341
-		$numberOfFiles = 0;
342
-
343
-		$view = new View();
344
-
345
-		while ($fileInfo = array_pop($fileInfos)) {
346
-			$numberOfFiles++;
347
-
348
-			if ($fileInfo->getType() === \OCP\Files\FileInfo::TYPE_FOLDER) {
349
-				$fileInfos = array_merge($fileInfos, $view->getDirectoryContent($fileInfo->getPath()));
350
-			}
351
-		}
352
-
353
-		return $numberOfFiles;
354
-	}
355
-
356
-	/**
357
-	 * @param View $view
358
-	 * @param string $dir
359
-	 * @param string[]|string $files
360
-	 */
361
-	public static function lockFiles($view, $dir, $files) {
362
-		if (!is_array($files)) {
363
-			$file = $dir . '/' . $files;
364
-			$files = [$file];
365
-		}
366
-		foreach ($files as $file) {
367
-			$file = $dir . '/' . $file;
368
-			$view->lockFile($file, ILockingProvider::LOCK_SHARED);
369
-			if ($view->is_dir($file)) {
370
-				$contents = $view->getDirectoryContent($file);
371
-				$contents = array_map(function($fileInfo) use ($file) {
372
-					/** @var \OCP\Files\FileInfo $fileInfo */
373
-					return $file . '/' . $fileInfo->getName();
374
-				}, $contents);
375
-				self::lockFiles($view, $dir, $contents);
376
-			}
377
-		}
378
-	}
379
-
380
-	/**
381
-	 * set the maximum upload size limit for apache hosts using .htaccess
382
-	 *
383
-	 * @param int $size file size in bytes
384
-	 * @param array $files override '.htaccess' and '.user.ini' locations
385
-	 * @return bool|int false on failure, size on success
386
-	 */
387
-	public static function setUploadLimit($size, $files = []) {
388
-		//don't allow user to break his config
389
-		$size = (int)$size;
390
-		if ($size < self::UPLOAD_MIN_LIMIT_BYTES) {
391
-			return false;
392
-		}
393
-		$size = OC_Helper::phpFileSize($size);
394
-
395
-		$phpValueKeys = array(
396
-			'upload_max_filesize',
397
-			'post_max_size'
398
-		);
399
-
400
-		// default locations if not overridden by $files
401
-		$files = array_merge([
402
-			'.htaccess' => OC::$SERVERROOT . '/.htaccess',
403
-			'.user.ini' => OC::$SERVERROOT . '/.user.ini'
404
-		], $files);
405
-
406
-		$updateFiles = [
407
-			$files['.htaccess'] => [
408
-				'pattern' => '/php_value %1$s (\S)*/',
409
-				'setting' => 'php_value %1$s %2$s'
410
-			],
411
-			$files['.user.ini'] => [
412
-				'pattern' => '/%1$s=(\S)*/',
413
-				'setting' => '%1$s=%2$s'
414
-			]
415
-		];
416
-
417
-		$success = true;
418
-
419
-		foreach ($updateFiles as $filename => $patternMap) {
420
-			// suppress warnings from fopen()
421
-			$handle = @fopen($filename, 'r+');
422
-			if (!$handle) {
423
-				\OCP\Util::writeLog('files',
424
-					'Can\'t write upload limit to ' . $filename . '. Please check the file permissions',
425
-					\OCP\Util::WARN);
426
-				$success = false;
427
-				continue; // try to update as many files as possible
428
-			}
429
-
430
-			$content = '';
431
-			while (!feof($handle)) {
432
-				$content .= fread($handle, 1000);
433
-			}
434
-
435
-			foreach ($phpValueKeys as $key) {
436
-				$pattern = vsprintf($patternMap['pattern'], [$key]);
437
-				$setting = vsprintf($patternMap['setting'], [$key, $size]);
438
-				$hasReplaced = 0;
439
-				$newContent = preg_replace($pattern, $setting, $content, 2, $hasReplaced);
440
-				if ($newContent !== null) {
441
-					$content = $newContent;
442
-				}
443
-				if ($hasReplaced === 0) {
444
-					$content .= "\n" . $setting;
445
-				}
446
-			}
447
-
448
-			// write file back
449
-			ftruncate($handle, 0);
450
-			rewind($handle);
451
-			fwrite($handle, $content);
452
-
453
-			fclose($handle);
454
-		}
455
-
456
-		if ($success) {
457
-			return OC_Helper::computerFileSize($size);
458
-		}
459
-		return false;
460
-	}
461
-
462
-	/**
463
-	 * @param string $dir
464
-	 * @param $files
465
-	 * @param integer $getType
466
-	 * @param View $view
467
-	 * @param string $filename
468
-	 */
469
-	private static function unlockAllTheFiles($dir, $files, $getType, $view, $filename) {
470
-		if ($getType === self::FILE) {
471
-			$view->unlockFile($filename, ILockingProvider::LOCK_SHARED);
472
-		}
473
-		if ($getType === self::ZIP_FILES) {
474
-			foreach ($files as $file) {
475
-				$file = $dir . '/' . $file;
476
-				$view->unlockFile($file, ILockingProvider::LOCK_SHARED);
477
-			}
478
-		}
479
-		if ($getType === self::ZIP_DIR) {
480
-			$file = $dir . '/' . $files;
481
-			$view->unlockFile($file, ILockingProvider::LOCK_SHARED);
482
-		}
483
-	}
285
+        if (\OC\Files\Filesystem::isReadable($filename)) {
286
+            self::sendHeaders($filename, $name, $rangeArray);
287
+        } elseif (!\OC\Files\Filesystem::file_exists($filename)) {
288
+            header("HTTP/1.1 404 Not Found");
289
+            $tmpl = new OC_Template('', '404', 'guest');
290
+            $tmpl->printPage();
291
+            exit();
292
+        } else {
293
+            header("HTTP/1.1 403 Forbidden");
294
+            die('403 Forbidden');
295
+        }
296
+        if (isset($params['head']) && $params['head']) {
297
+            return;
298
+        }
299
+        if (!empty($rangeArray)) {
300
+            try {
301
+                if (count($rangeArray) == 1) {
302
+                $view->readfilePart($filename, $rangeArray[0]['from'], $rangeArray[0]['to']);
303
+                }
304
+                else {
305
+                // check if file is seekable (if not throw UnseekableException)
306
+                // we have to check it before body contents
307
+                $view->readfilePart($filename, $rangeArray[0]['size'], $rangeArray[0]['size']);
308
+
309
+                $type = \OC::$server->getMimeTypeDetector()->getSecureMimeType(\OC\Files\Filesystem::getMimeType($filename));
310
+
311
+                foreach ($rangeArray as $range) {
312
+                    echo "\r\n--".self::getBoundary()."\r\n".
313
+                            "Content-type: ".$type."\r\n".
314
+                            "Content-range: bytes ".$range['from']."-".$range['to']."/".$range['size']."\r\n\r\n";
315
+                    $view->readfilePart($filename, $range['from'], $range['to']);
316
+                }
317
+                echo "\r\n--".self::getBoundary()."--\r\n";
318
+                }
319
+            } catch (\OCP\Files\UnseekableException $ex) {
320
+                // file is unseekable
321
+                header_remove('Accept-Ranges');
322
+                header_remove('Content-Range');
323
+                header("HTTP/1.1 200 OK");
324
+                self::sendHeaders($filename, $name, array());
325
+                $view->readfile($filename);
326
+            }
327
+        }
328
+        else {
329
+            $view->readfile($filename);
330
+        }
331
+    }
332
+
333
+    /**
334
+     * Returns the total (recursive) number of files and folders in the given
335
+     * FileInfos.
336
+     *
337
+     * @param \OCP\Files\FileInfo[] $fileInfos the FileInfos to count
338
+     * @return int the total number of files and folders
339
+     */
340
+    private static function getNumberOfFiles($fileInfos) {
341
+        $numberOfFiles = 0;
342
+
343
+        $view = new View();
344
+
345
+        while ($fileInfo = array_pop($fileInfos)) {
346
+            $numberOfFiles++;
347
+
348
+            if ($fileInfo->getType() === \OCP\Files\FileInfo::TYPE_FOLDER) {
349
+                $fileInfos = array_merge($fileInfos, $view->getDirectoryContent($fileInfo->getPath()));
350
+            }
351
+        }
352
+
353
+        return $numberOfFiles;
354
+    }
355
+
356
+    /**
357
+     * @param View $view
358
+     * @param string $dir
359
+     * @param string[]|string $files
360
+     */
361
+    public static function lockFiles($view, $dir, $files) {
362
+        if (!is_array($files)) {
363
+            $file = $dir . '/' . $files;
364
+            $files = [$file];
365
+        }
366
+        foreach ($files as $file) {
367
+            $file = $dir . '/' . $file;
368
+            $view->lockFile($file, ILockingProvider::LOCK_SHARED);
369
+            if ($view->is_dir($file)) {
370
+                $contents = $view->getDirectoryContent($file);
371
+                $contents = array_map(function($fileInfo) use ($file) {
372
+                    /** @var \OCP\Files\FileInfo $fileInfo */
373
+                    return $file . '/' . $fileInfo->getName();
374
+                }, $contents);
375
+                self::lockFiles($view, $dir, $contents);
376
+            }
377
+        }
378
+    }
379
+
380
+    /**
381
+     * set the maximum upload size limit for apache hosts using .htaccess
382
+     *
383
+     * @param int $size file size in bytes
384
+     * @param array $files override '.htaccess' and '.user.ini' locations
385
+     * @return bool|int false on failure, size on success
386
+     */
387
+    public static function setUploadLimit($size, $files = []) {
388
+        //don't allow user to break his config
389
+        $size = (int)$size;
390
+        if ($size < self::UPLOAD_MIN_LIMIT_BYTES) {
391
+            return false;
392
+        }
393
+        $size = OC_Helper::phpFileSize($size);
394
+
395
+        $phpValueKeys = array(
396
+            'upload_max_filesize',
397
+            'post_max_size'
398
+        );
399
+
400
+        // default locations if not overridden by $files
401
+        $files = array_merge([
402
+            '.htaccess' => OC::$SERVERROOT . '/.htaccess',
403
+            '.user.ini' => OC::$SERVERROOT . '/.user.ini'
404
+        ], $files);
405
+
406
+        $updateFiles = [
407
+            $files['.htaccess'] => [
408
+                'pattern' => '/php_value %1$s (\S)*/',
409
+                'setting' => 'php_value %1$s %2$s'
410
+            ],
411
+            $files['.user.ini'] => [
412
+                'pattern' => '/%1$s=(\S)*/',
413
+                'setting' => '%1$s=%2$s'
414
+            ]
415
+        ];
416
+
417
+        $success = true;
418
+
419
+        foreach ($updateFiles as $filename => $patternMap) {
420
+            // suppress warnings from fopen()
421
+            $handle = @fopen($filename, 'r+');
422
+            if (!$handle) {
423
+                \OCP\Util::writeLog('files',
424
+                    'Can\'t write upload limit to ' . $filename . '. Please check the file permissions',
425
+                    \OCP\Util::WARN);
426
+                $success = false;
427
+                continue; // try to update as many files as possible
428
+            }
429
+
430
+            $content = '';
431
+            while (!feof($handle)) {
432
+                $content .= fread($handle, 1000);
433
+            }
434
+
435
+            foreach ($phpValueKeys as $key) {
436
+                $pattern = vsprintf($patternMap['pattern'], [$key]);
437
+                $setting = vsprintf($patternMap['setting'], [$key, $size]);
438
+                $hasReplaced = 0;
439
+                $newContent = preg_replace($pattern, $setting, $content, 2, $hasReplaced);
440
+                if ($newContent !== null) {
441
+                    $content = $newContent;
442
+                }
443
+                if ($hasReplaced === 0) {
444
+                    $content .= "\n" . $setting;
445
+                }
446
+            }
447
+
448
+            // write file back
449
+            ftruncate($handle, 0);
450
+            rewind($handle);
451
+            fwrite($handle, $content);
452
+
453
+            fclose($handle);
454
+        }
455
+
456
+        if ($success) {
457
+            return OC_Helper::computerFileSize($size);
458
+        }
459
+        return false;
460
+    }
461
+
462
+    /**
463
+     * @param string $dir
464
+     * @param $files
465
+     * @param integer $getType
466
+     * @param View $view
467
+     * @param string $filename
468
+     */
469
+    private static function unlockAllTheFiles($dir, $files, $getType, $view, $filename) {
470
+        if ($getType === self::FILE) {
471
+            $view->unlockFile($filename, ILockingProvider::LOCK_SHARED);
472
+        }
473
+        if ($getType === self::ZIP_FILES) {
474
+            foreach ($files as $file) {
475
+                $file = $dir . '/' . $file;
476
+                $view->unlockFile($file, ILockingProvider::LOCK_SHARED);
477
+            }
478
+        }
479
+        if ($getType === self::ZIP_DIR) {
480
+            $file = $dir . '/' . $files;
481
+            $view->unlockFile($file, ILockingProvider::LOCK_SHARED);
482
+        }
483
+    }
484 484
 
485 485
 }
Please login to merge, or discard this patch.
Spacing   +26 added lines, -26 removed lines patch added patch discarded remove patch
@@ -75,7 +75,7 @@  discard block
 block discarded – undo
75 75
 	private static function sendHeaders($filename, $name, array $rangeArray) {
76 76
 		OC_Response::setContentDispositionHeader($name, 'attachment');
77 77
 		header('Content-Transfer-Encoding: binary', true);
78
-		header('Pragma: public');// enable caching in IE
78
+		header('Pragma: public'); // enable caching in IE
79 79
 		header('Expires: 0');
80 80
 		header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
81 81
 		$fileSize = \OC\Files\Filesystem::filesize($filename);
@@ -119,7 +119,7 @@  discard block
 block discarded – undo
119 119
 			}
120 120
 
121 121
 			if (!is_array($files)) {
122
-				$filename = $dir . '/' . $files;
122
+				$filename = $dir.'/'.$files;
123 123
 				if (!$view->is_dir($filename)) {
124 124
 					self::getSingleFile($view, $dir, $files, is_null($params) ? array() : $params);
125 125
 					return;
@@ -134,9 +134,9 @@  discard block
 block discarded – undo
134 134
 					$name = $basename;
135 135
 				}
136 136
 
137
-				$filename = $dir . '/' . $name;
137
+				$filename = $dir.'/'.$name;
138 138
 			} else {
139
-				$filename = $dir . '/' . $files;
139
+				$filename = $dir.'/'.$files;
140 140
 				$getType = self::ZIP_DIR;
141 141
 				// downloading root ?
142 142
 				if ($files !== '') {
@@ -151,13 +151,13 @@  discard block
 block discarded – undo
151 151
 				$fileInfos = array();
152 152
 				$fileSize = 0;
153 153
 				foreach ($files as $file) {
154
-					$fileInfo = \OC\Files\Filesystem::getFileInfo($dir . '/' . $file);
154
+					$fileInfo = \OC\Files\Filesystem::getFileInfo($dir.'/'.$file);
155 155
 					$fileSize += $fileInfo->getSize();
156 156
 					$fileInfos[] = $fileInfo;
157 157
 				}
158 158
 				$numberOfFiles = self::getNumberOfFiles($fileInfos);
159 159
 			} elseif ($getType === self::ZIP_DIR) {
160
-				$fileInfo = \OC\Files\Filesystem::getFileInfo($dir . '/' . $files);
160
+				$fileInfo = \OC\Files\Filesystem::getFileInfo($dir.'/'.$files);
161 161
 				$fileSize = $fileInfo->getSize();
162 162
 				$numberOfFiles = self::getNumberOfFiles(array($fileInfo));
163 163
 			}
@@ -166,7 +166,7 @@  discard block
 block discarded – undo
166 166
 			OC_Util::obEnd();
167 167
 
168 168
 			$streamer->sendHeaders($name);
169
-			$executionTime = (int)OC::$server->getIniWrapper()->getNumeric('max_execution_time');
169
+			$executionTime = (int) OC::$server->getIniWrapper()->getNumeric('max_execution_time');
170 170
 			if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
171 171
 				@set_time_limit(0);
172 172
 			}
@@ -174,7 +174,7 @@  discard block
 block discarded – undo
174 174
 
175 175
 			if ($getType === self::ZIP_FILES) {
176 176
 				foreach ($files as $file) {
177
-					$file = $dir . '/' . $file;
177
+					$file = $dir.'/'.$file;
178 178
 					if (\OC\Files\Filesystem::is_file($file)) {
179 179
 						$fileSize = \OC\Files\Filesystem::filesize($file);
180 180
 						$fileTime = \OC\Files\Filesystem::filemtime($file);
@@ -186,7 +186,7 @@  discard block
 block discarded – undo
186 186
 					}
187 187
 				}
188 188
 			} elseif ($getType === self::ZIP_DIR) {
189
-				$file = $dir . '/' . $files;
189
+				$file = $dir.'/'.$files;
190 190
 				$streamer->addDirRecursive($file);
191 191
 			}
192 192
 			$streamer->finalize();
@@ -218,7 +218,7 @@  discard block
 block discarded – undo
218 218
 	 * @return array $rangeArray ('from'=>int,'to'=>int), ...
219 219
 	 */
220 220
 	private static function parseHttpRangeHeader($rangeHeaderPos, $fileSize) {
221
-		$rArray=explode(',', $rangeHeaderPos);
221
+		$rArray = explode(',', $rangeHeaderPos);
222 222
 		$minOffset = 0;
223 223
 		$ind = 0;
224 224
 
@@ -230,7 +230,7 @@  discard block
 block discarded – undo
230 230
 				if ($ranges[0] < $minOffset) { // case: bytes=500-700,601-999
231 231
 					$ranges[0] = $minOffset;
232 232
 				}
233
-				if ($ind > 0 && $rangeArray[$ind-1]['to']+1 == $ranges[0]) { // case: bytes=500-600,601-999
233
+				if ($ind > 0 && $rangeArray[$ind - 1]['to'] + 1 == $ranges[0]) { // case: bytes=500-600,601-999
234 234
 					$ind--;
235 235
 					$ranges[0] = $rangeArray[$ind]['from'];
236 236
 				}
@@ -239,9 +239,9 @@  discard block
 block discarded – undo
239 239
 			if (is_numeric($ranges[0]) && is_numeric($ranges[1]) && $ranges[0] < $fileSize && $ranges[0] <= $ranges[1]) {
240 240
 				// case: x-x
241 241
 				if ($ranges[1] >= $fileSize) {
242
-					$ranges[1] = $fileSize-1;
242
+					$ranges[1] = $fileSize - 1;
243 243
 				}
244
-				$rangeArray[$ind++] = array( 'from' => $ranges[0], 'to' => $ranges[1], 'size' => $fileSize );
244
+				$rangeArray[$ind++] = array('from' => $ranges[0], 'to' => $ranges[1], 'size' => $fileSize);
245 245
 				$minOffset = $ranges[1] + 1;
246 246
 				if ($minOffset >= $fileSize) {
247 247
 					break;
@@ -249,7 +249,7 @@  discard block
 block discarded – undo
249 249
 			}
250 250
 			elseif (is_numeric($ranges[0]) && $ranges[0] < $fileSize) {
251 251
 				// case: x-
252
-				$rangeArray[$ind++] = array( 'from' => $ranges[0], 'to' => $fileSize-1, 'size' => $fileSize );
252
+				$rangeArray[$ind++] = array('from' => $ranges[0], 'to' => $fileSize - 1, 'size' => $fileSize);
253 253
 				break;
254 254
 			}
255 255
 			elseif (is_numeric($ranges[1])) {
@@ -257,7 +257,7 @@  discard block
 block discarded – undo
257 257
 				if ($ranges[1] > $fileSize) {
258 258
 					$ranges[1] = $fileSize;
259 259
 				}
260
-				$rangeArray[$ind++] = array( 'from' => $fileSize-$ranges[1], 'to' => $fileSize-1, 'size' => $fileSize );
260
+				$rangeArray[$ind++] = array('from' => $fileSize - $ranges[1], 'to' => $fileSize - 1, 'size' => $fileSize);
261 261
 				break;
262 262
 			}
263 263
 		}
@@ -271,7 +271,7 @@  discard block
 block discarded – undo
271 271
 	 * @param array $params ; 'head' boolean to only send header of the request ; 'range' http range header
272 272
 	 */
273 273
 	private static function getSingleFile($view, $dir, $name, $params) {
274
-		$filename = $dir . '/' . $name;
274
+		$filename = $dir.'/'.$name;
275 275
 		OC_Util::obEnd();
276 276
 		$view->lockFile($filename, ILockingProvider::LOCK_SHARED);
277 277
 		
@@ -360,17 +360,17 @@  discard block
 block discarded – undo
360 360
 	 */
361 361
 	public static function lockFiles($view, $dir, $files) {
362 362
 		if (!is_array($files)) {
363
-			$file = $dir . '/' . $files;
363
+			$file = $dir.'/'.$files;
364 364
 			$files = [$file];
365 365
 		}
366 366
 		foreach ($files as $file) {
367
-			$file = $dir . '/' . $file;
367
+			$file = $dir.'/'.$file;
368 368
 			$view->lockFile($file, ILockingProvider::LOCK_SHARED);
369 369
 			if ($view->is_dir($file)) {
370 370
 				$contents = $view->getDirectoryContent($file);
371 371
 				$contents = array_map(function($fileInfo) use ($file) {
372 372
 					/** @var \OCP\Files\FileInfo $fileInfo */
373
-					return $file . '/' . $fileInfo->getName();
373
+					return $file.'/'.$fileInfo->getName();
374 374
 				}, $contents);
375 375
 				self::lockFiles($view, $dir, $contents);
376 376
 			}
@@ -386,7 +386,7 @@  discard block
 block discarded – undo
386 386
 	 */
387 387
 	public static function setUploadLimit($size, $files = []) {
388 388
 		//don't allow user to break his config
389
-		$size = (int)$size;
389
+		$size = (int) $size;
390 390
 		if ($size < self::UPLOAD_MIN_LIMIT_BYTES) {
391 391
 			return false;
392 392
 		}
@@ -399,8 +399,8 @@  discard block
 block discarded – undo
399 399
 
400 400
 		// default locations if not overridden by $files
401 401
 		$files = array_merge([
402
-			'.htaccess' => OC::$SERVERROOT . '/.htaccess',
403
-			'.user.ini' => OC::$SERVERROOT . '/.user.ini'
402
+			'.htaccess' => OC::$SERVERROOT.'/.htaccess',
403
+			'.user.ini' => OC::$SERVERROOT.'/.user.ini'
404 404
 		], $files);
405 405
 
406 406
 		$updateFiles = [
@@ -421,7 +421,7 @@  discard block
 block discarded – undo
421 421
 			$handle = @fopen($filename, 'r+');
422 422
 			if (!$handle) {
423 423
 				\OCP\Util::writeLog('files',
424
-					'Can\'t write upload limit to ' . $filename . '. Please check the file permissions',
424
+					'Can\'t write upload limit to '.$filename.'. Please check the file permissions',
425 425
 					\OCP\Util::WARN);
426 426
 				$success = false;
427 427
 				continue; // try to update as many files as possible
@@ -441,7 +441,7 @@  discard block
 block discarded – undo
441 441
 					$content = $newContent;
442 442
 				}
443 443
 				if ($hasReplaced === 0) {
444
-					$content .= "\n" . $setting;
444
+					$content .= "\n".$setting;
445 445
 				}
446 446
 			}
447 447
 
@@ -472,12 +472,12 @@  discard block
 block discarded – undo
472 472
 		}
473 473
 		if ($getType === self::ZIP_FILES) {
474 474
 			foreach ($files as $file) {
475
-				$file = $dir . '/' . $file;
475
+				$file = $dir.'/'.$file;
476 476
 				$view->unlockFile($file, ILockingProvider::LOCK_SHARED);
477 477
 			}
478 478
 		}
479 479
 		if ($getType === self::ZIP_DIR) {
480
-			$file = $dir . '/' . $files;
480
+			$file = $dir.'/'.$files;
481 481
 			$view->unlockFile($file, ILockingProvider::LOCK_SHARED);
482 482
 		}
483 483
 	}
Please login to merge, or discard this patch.