PluginProbe ʕ •ᴥ•ʔ
File Manager Pro – Filester / 1.8
File Manager Pro – Filester v1.8
2.1.1 trunk 1.6.1 1.7.6 1.8 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9 2.0 2.0.1 2.0.2 2.1.0
filester / includes / File_manager / lib / php / elFinderConnector.class.php
filester / includes / File_manager / lib / php Last commit date
.tmp 2 years ago editors 2 years ago libs 2 years ago plugins 2 years ago resources 2 years ago MySQLStorage.sql 2 years ago autoload.php 2 years ago elFinder.class.php 2 years ago elFinderConnector.class.php 2 years ago elFinderFlysystemGoogleDriveNetmount.php 2 years ago elFinderPlugin.php 2 years ago elFinderSession.php 2 years ago elFinderSessionInterface.php 2 years ago elFinderVolumeBox.class.php 2 years ago elFinderVolumeDriver.class.php 2 years ago elFinderVolumeDropbox.class.php 2 years ago elFinderVolumeDropbox2.class.php 2 years ago elFinderVolumeFTP.class.php 2 years ago elFinderVolumeGoogleDrive.class.php 2 years ago elFinderVolumeGroup.class.php 2 years ago elFinderVolumeLocalFileSystem.class.php 2 years ago elFinderVolumeMySQL.class.php 2 years ago elFinderVolumeOneDrive.class.php 2 years ago elFinderVolumeSFTPphpseclib.class.php 2 years ago elFinderVolumeTrash.class.php 2 years ago elFinderVolumeTrashMySQL.class.php 2 years ago index.php 2 years ago mime.types 2 years ago
elFinderConnector.class.php
381 lines
1 <?php
2
3 /**
4 * Default elFinder connector
5 *
6 * @author Dmitry (dio) Levashov
7 **/
8 class elFinderConnector
9 {
10 /**
11 * elFinder instance
12 *
13 * @var elFinder
14 **/
15 protected $elFinder;
16
17 /**
18 * Options
19 *
20 * @var array
21 **/
22 protected $options = array();
23
24 /**
25 * Must be use output($data) $data['header']
26 *
27 * @var string
28 * @deprecated
29 **/
30 protected $header = '';
31
32 /**
33 * HTTP request method
34 *
35 * @var string
36 */
37 protected $reqMethod = '';
38
39 /**
40 * Content type of output JSON
41 *
42 * @var string
43 */
44 protected static $contentType = 'Content-Type: application/json; charset=utf-8';
45
46 /**
47 * Constructor
48 *
49 * @param $elFinder
50 * @param bool $debug
51 *
52 * @author Dmitry (dio) Levashov
53 */
54 public function __construct($elFinder, $debug = false)
55 {
56
57 $this->elFinder = $elFinder;
58 $this->reqMethod = strtoupper($_SERVER["REQUEST_METHOD"]);
59 if ($debug) {
60 self::$contentType = 'Content-Type: text/plain; charset=utf-8';
61 }
62 }
63
64 /**
65 * Execute elFinder command and output result
66 *
67 * @return void
68 * @throws Exception
69 * @author Dmitry (dio) Levashov
70 */
71 public function run()
72 {
73 $isPost = $this->reqMethod === 'POST';
74 $src = $isPost ? array_merge($_GET, $_POST) : $_GET;
75 $maxInputVars = (!$src || isset($src['targets'])) ? ini_get('max_input_vars') : null;
76 if ((!$src || $maxInputVars) && $rawPostData = file_get_contents('php://input')) {
77 // for max_input_vars and supports IE XDomainRequest()
78 $parts = explode('&', $rawPostData);
79 if (!$src || $maxInputVars < count($parts)) {
80 $src = array();
81 foreach ($parts as $part) {
82 list($key, $value) = array_pad(explode('=', $part), 2, '');
83 $key = rawurldecode($key);
84 if (preg_match('/^(.+?)\[([^\[\]]*)\]$/', $key, $m)) {
85 $key = $m[1];
86 $idx = $m[2];
87 if (!isset($src[$key])) {
88 $src[$key] = array();
89 }
90 if ($idx) {
91 $src[$key][$idx] = rawurldecode($value);
92 } else {
93 $src[$key][] = rawurldecode($value);
94 }
95 } else {
96 $src[$key] = rawurldecode($value);
97 }
98 }
99 $_POST = $this->input_filter($src);
100 $_REQUEST = $this->input_filter(array_merge_recursive($src, $_REQUEST));
101 }
102 }
103
104 if (isset($src['targets']) && $this->elFinder->maxTargets && count($src['targets']) > $this->elFinder->maxTargets) {
105 $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_MAX_TARGTES)));
106 }
107
108 $cmd = isset($src['cmd']) ? $src['cmd'] : '';
109 $args = array();
110
111 if (!function_exists('json_encode')) {
112 $error = $this->elFinder->error(elFinder::ERROR_CONF, elFinder::ERROR_CONF_NO_JSON);
113 $this->output(array('error' => '{"error":["' . implode('","', $error) . '"]}', 'raw' => true));
114 }
115
116 if (!$this->elFinder->loaded()) {
117 $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_CONF, elFinder::ERROR_CONF_NO_VOL), 'debug' => $this->elFinder->mountErrors));
118 }
119
120 // telepat_mode: on
121 if (!$cmd && $isPost) {
122 $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_UPLOAD, elFinder::ERROR_UPLOAD_TOTAL_SIZE), 'header' => 'Content-Type: text/html'));
123 }
124 // telepat_mode: off
125
126 if (!$this->elFinder->commandExists($cmd)) {
127 $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_UNKNOWN_CMD)));
128 }
129
130 // collect required arguments to exec command
131 $hasFiles = false;
132 foreach ($this->elFinder->commandArgsList($cmd) as $name => $req) {
133 if ($name === 'FILES') {
134 if (isset($_FILES)) {
135 $hasFiles = true;
136 } elseif ($req) {
137 $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_INV_PARAMS, $cmd)));
138 }
139 } else {
140 $arg = isset($src[$name]) ? $src[$name] : '';
141
142 if (!is_array($arg) && $req !== '') {
143 $arg = trim($arg);
144 }
145 if ($req && $arg === '') {
146 $this->output(array('error' => $this->elFinder->error(elFinder::ERROR_INV_PARAMS, $cmd)));
147 }
148 $args[$name] = $arg;
149 }
150 }
151
152 $args['debug'] = isset($src['debug']) ? !!$src['debug'] : false;
153
154 $args = $this->input_filter($args);
155 if ($hasFiles) {
156 $args['FILES'] = $_FILES;
157 }
158
159 try {
160 $this->output($this->elFinder->exec($cmd, $args));
161 } catch (elFinderAbortException $e) {
162 // connection aborted
163 // unlock session data for multiple access
164 $this->elFinder->getSession()->close();
165 // HTTP response code
166 header('HTTP/1.0 204 No Content');
167 // clear output buffer
168 while (ob_get_level() && ob_end_clean()) {
169 }
170 exit();
171 }
172 }
173
174 /**
175 * Sets the header.
176 *
177 * @param array|string $value HTTP header(s)
178 */
179 public function setHeader($value)
180 {
181 $this->header = $value;
182 }
183
184 /**
185 * Output json
186 *
187 * @param array data to output
188 *
189 * @return void
190 * @throws elFinderAbortException
191 * @author Dmitry (dio) Levashov
192 */
193 protected function output(array $data)
194 {
195 // unlock session data for multiple access
196 $this->elFinder->getSession()->close();
197 // client disconnect should abort
198 ignore_user_abort(false);
199
200 if ($this->header) {
201 self::sendHeader($this->header);
202 }
203
204 if (isset($data['pointer'])) {
205 // set time limit to 0
206 elFinder::extendTimeLimit(0);
207
208 // send optional header
209 if (!empty($data['header'])) {
210 self::sendHeader($data['header']);
211 }
212
213 // clear output buffer
214 while (ob_get_level() && ob_end_clean()) {
215 }
216
217 $toEnd = true;
218 $fp = $data['pointer'];
219 $sendData = !($this->reqMethod === 'HEAD' || !empty($data['info']['xsendfile']));
220 $psize = null;
221 if (($this->reqMethod === 'GET' || !$sendData)
222 && (elFinder::isSeekableStream($fp) || elFinder::isSeekableUrl($fp))
223 && (array_search('Accept-Ranges: none', headers_list()) === false)) {
224 header('Accept-Ranges: bytes');
225 if (!empty($_SERVER['HTTP_RANGE'])) {
226 $size = $data['info']['size'];
227 $end = $size - 1;
228 if (preg_match('/bytes=(\d*)-(\d*)(,?)/i', $_SERVER['HTTP_RANGE'], $matches)) {
229 if (empty($matches[3])) {
230 if (empty($matches[1]) && $matches[1] !== '0') {
231 $start = $size - $matches[2];
232 } else {
233 $start = intval($matches[1]);
234 if (!empty($matches[2])) {
235 $end = intval($matches[2]);
236 if ($end >= $size) {
237 $end = $size - 1;
238 }
239 $toEnd = ($end == ($size - 1));
240 }
241 }
242 $psize = $end - $start + 1;
243
244 header('HTTP/1.1 206 Partial Content');
245 header('Content-Length: ' . $psize);
246 header('Content-Range: bytes ' . $start . '-' . $end . '/' . $size);
247
248 // Apache mod_xsendfile dose not support range request
249 if (isset($data['info']['xsendfile']) && strtolower($data['info']['xsendfile']) === 'x-sendfile') {
250 if (function_exists('header_remove')) {
251 header_remove($data['info']['xsendfile']);
252 } else {
253 header($data['info']['xsendfile'] . ':');
254 }
255 unset($data['info']['xsendfile']);
256 if ($this->reqMethod !== 'HEAD') {
257 $sendData = true;
258 }
259 }
260
261 $sendData && !elFinder::isSeekableUrl($fp) && fseek($fp, $start);
262 }
263 }
264 }
265 if ($sendData && is_null($psize)) {
266 elFinder::rewind($fp);
267 }
268 } else {
269 header('Accept-Ranges: none');
270 if (isset($data['info']) && !$data['info']['size']) {
271 if (function_exists('header_remove')) {
272 header_remove('Content-Length');
273 } else {
274 header('Content-Length:');
275 }
276 }
277 }
278
279 if ($sendData) {
280 if ($toEnd || elFinder::isSeekableUrl($fp)) {
281 // PHP < 5.6 has a bug of fpassthru
282 // see https://bugs.php.net/bug.php?id=66736
283 if (version_compare(PHP_VERSION, '5.6', '<')) {
284 file_put_contents('php://output', $fp);
285 } else {
286 fpassthru($fp);
287 }
288 } else {
289 $out = fopen('php://output', 'wb');
290 stream_copy_to_stream($fp, $out, $psize);
291 fclose($out);
292 }
293 }
294
295 if (!empty($data['volume'])) {
296 $data['volume']->close($fp, $data['info']['hash']);
297 } else {
298 fclose($fp);
299 }
300 exit();
301 } else {
302 self::outputJson($data);
303 exit(0);
304 }
305 }
306
307 /**
308 * Remove null & stripslashes applies on "magic_quotes_gpc"
309 *
310 * @param mixed $args
311 *
312 * @return mixed
313 * @author Naoki Sawada
314 */
315 protected function input_filter($args)
316 {
317 static $magic_quotes_gpc = NULL;
318
319 if ($magic_quotes_gpc === NULL)
320 $magic_quotes_gpc = (version_compare(PHP_VERSION, '5.4', '<') && get_magic_quotes_gpc());
321
322 if (is_array($args)) {
323 return array_map(array(& $this, 'input_filter'), $args);
324 }
325 $res = str_replace("\0", '', $args);
326 $magic_quotes_gpc && ($res = stripslashes($res));
327 return $res;
328 }
329
330 /**
331 * Send HTTP header
332 *
333 * @param string|array $header optional header
334 */
335 protected static function sendHeader($header = null)
336 {
337 if ($header) {
338 if (is_array($header)) {
339 foreach ($header as $h) {
340 header($h);
341 }
342 } else {
343 header($header);
344 }
345 }
346 }
347
348 /**
349 * Output JSON
350 *
351 * @param array $data
352 */
353 public static function outputJson($data)
354 {
355 // send header
356 $header = isset($data['header']) ? $data['header'] : self::$contentType;
357 self::sendHeader($header);
358
359 unset($data['header']);
360
361 if (!empty($data['raw']) && isset($data['error'])) {
362 $out = $data['error'];
363 } else {
364 if (isset($data['debug']) && isset($data['debug']['backendErrors'])) {
365 $data['debug']['backendErrors'] = array_merge($data['debug']['backendErrors'], elFinder::$phpErrors);
366 }
367 $out = json_encode($data);
368 }
369
370 // clear output buffer
371 while (ob_get_level() && ob_end_clean()) {
372 }
373
374 header('Content-Length: ' . strlen($out));
375
376 echo $out;
377
378 flush();
379 }
380 }// END class
381