/** * Remote upload method * Uploads file from given url * * @param string $upload_url URL pointing to file to upload, for example http://www.foobar.com/example.gif * @return filespec $file Object "filespec" is returned, all further operations can be done with this object * @access public */ protected function remote_upload($upload_url) { $upload_ary = array(); $upload_ary['local_mode'] = true; if (!preg_match('#^(https?://).*?\\.(' . implode('|', $this->upload->allowed_extensions) . ')$#i', $upload_url, $match)) { return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'URL_INVALID')); } $url = parse_url($upload_url); $upload_ary['type'] = 'application/octet-stream'; $url['path'] = explode('.', $url['path']); $ext = array_pop($url['path']); $url['path'] = implode('', $url['path']); $upload_ary['name'] = utf8_basename($url['path']) . ($ext ? '.' . $ext : ''); $remote_max_filesize = $this->get_max_file_size(); $guzzle_options = ['timeout' => $this->upload->upload_timeout, 'connect_timeout' => $this->upload->upload_timeout, 'verify' => !empty($this->config['remote_upload_verify']) ? (bool) $this->config['remote_upload_verify'] : false]; $client = new \GuzzleHttp\Client($guzzle_options); try { $response = $client->get($upload_url, $guzzle_options); } catch (\GuzzleHttp\Exception\ClientException $clientException) { return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'URL_NOT_FOUND'); } catch (\GuzzleHttp\Exception\RequestException $requestException) { if (strpos($requestException->getMessage(), 'cURL error 28') !== false || preg_match('/408|504/', $requestException->getCode())) { return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); } else { return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); } } catch (\Exception $e) { return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); } $content_length = $response->getBody()->getSize(); if ($remote_max_filesize && $content_length > $remote_max_filesize) { $max_filesize = get_formatted_filesize($remote_max_filesize, false); return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); } if ($content_length == 0) { return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'EMPTY_REMOTE_DATA'); } $data = $response->getBody(); $filename = tempnam(sys_get_temp_dir(), unique_id() . '-'); if (!($fp = @fopen($filename, 'wb'))) { return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'NOT_UPLOADED'); } $upload_ary['size'] = fwrite($fp, $data); fclose($fp); unset($data); $upload_ary['tmp_name'] = $filename; /** @var filespec $file */ $file = $this->factory->get('filespec')->set_upload_ary($upload_ary)->set_upload_namespace($this->upload); $this->upload->common_checks($file); return $file; }
/** * Move file from another location to phpBB * * @param string $source_file Filename of source file * @param array|bool $filedata Array with filedata or false * * @return filespec Object "filespec" is returned, all further operations can be done with this object */ protected function local_upload($source_file, $filedata = false) { $upload = $this->get_upload_ary($source_file, $filedata); /** @var filespec $file */ $file = $this->factory->get('filespec')->set_upload_ary($upload)->set_upload_namespace($this->upload); if ($file->init_error()) { $file->error[] = ''; return $file; } // PHP Upload file size check $file = $this->check_upload_size($file); if (sizeof($file->error)) { return $file; } // Not correctly uploaded if (!$file->is_uploaded()) { $file->error[] = $this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED'); return $file; } $this->upload->common_checks($file); $this->request->overwrite('local', $upload, request_interface::FILES); return $file; }
/** * Form upload method * Upload file from users harddisk * * @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified) * * @return filespec $file Object "filespec" is returned, all further operations can be done with this object * @access public */ protected function form_upload($form_name) { $upload = $this->request->file($form_name); unset($upload['local_mode']); $result = $this->plupload->handle_upload($form_name); if (is_array($result)) { $upload = array_merge($upload, $result); } /** @var filespec $file */ $file = $this->factory->get('filespec')->set_upload_ary($upload)->set_upload_namespace($this->upload); if ($file->init_error()) { $file->error[] = ''; return $file; } // Error array filled? if (isset($upload['error'])) { $error = $this->upload->assign_internal_error($upload['error']); if ($error !== false) { $file->error[] = $error; return $file; } } // Check if empty file got uploaded (not catched by is_uploaded_file) if (isset($upload['size']) && $upload['size'] == 0) { $file->error[] = $this->language->lang($this->upload->error_prefix . 'EMPTY_FILEUPLOAD'); return $file; } // PHP Upload file size check $file = $this->check_upload_size($file); if (sizeof($file->error)) { return $file; } // Not correctly uploaded if (!$file->is_uploaded()) { $file->error[] = $this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED'); return $file; } $this->upload->common_checks($file); return $file; }
/** * Remote upload method * Uploads file from given url * * @param string $upload_url URL pointing to file to upload, for example http://www.foobar.com/example.gif * @return filespec $file Object "filespec" is returned, all further operations can be done with this object * @access public */ protected function remote_upload($upload_url) { $upload_ary = array(); $upload_ary['local_mode'] = true; if (!preg_match('#^(https?://).*?\\.(' . implode('|', $this->upload->allowed_extensions) . ')$#i', $upload_url, $match)) { return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'URL_INVALID')); } $url = parse_url($upload_url); $host = $url['host']; $path = $url['path']; $port = !empty($url['port']) ? (int) $url['port'] : 80; $upload_ary['type'] = 'application/octet-stream'; $url['path'] = explode('.', $url['path']); $ext = array_pop($url['path']); $url['path'] = implode('', $url['path']); $upload_ary['name'] = utf8_basename($url['path']) . ($ext ? '.' . $ext : ''); $filename = $url['path']; $filesize = 0; $remote_max_filesize = $this->get_max_file_size(); $errno = 0; $errstr = ''; if (!($fsock = @fsockopen($host, $port, $errno, $errstr))) { return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); } // Make sure $path not beginning with / if (strpos($path, '/') === 0) { $path = substr($path, 1); } fputs($fsock, 'GET /' . $path . " HTTP/1.1\r\n"); fputs($fsock, "HOST: " . $host . "\r\n"); fputs($fsock, "Connection: close\r\n\r\n"); // Set a proper timeout for the socket socket_set_timeout($fsock, $this->upload->upload_timeout); $get_info = false; $data = ''; $length = false; $timer_stop = time() + $this->upload->upload_timeout; while ((!$length || $filesize < $length) && !@feof($fsock)) { if ($get_info) { if ($length) { // Don't attempt to read past end of file if server indicated length $block = @fread($fsock, min($length - $filesize, 1024)); } else { $block = @fread($fsock, 1024); } $filesize += strlen($block); if ($remote_max_filesize && $filesize > $remote_max_filesize) { $max_filesize = get_formatted_filesize($remote_max_filesize, false); return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); } $data .= $block; } else { $line = @fgets($fsock, 1024); if ($line == "\r\n") { $get_info = true; } else { if (stripos($line, 'content-type: ') !== false) { $upload_ary['type'] = rtrim(str_replace('content-type: ', '', strtolower($line))); } else { if ($this->upload->max_filesize && stripos($line, 'content-length: ') !== false) { $length = (int) str_replace('content-length: ', '', strtolower($line)); if ($remote_max_filesize && $length && $length > $remote_max_filesize) { $max_filesize = get_formatted_filesize($remote_max_filesize, false); return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); } } else { if (stripos($line, '404 not found') !== false) { return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'URL_NOT_FOUND'); } } } } } $stream_meta_data = stream_get_meta_data($fsock); // Cancel upload if we exceed timeout if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop) { return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); } } @fclose($fsock); if (empty($data)) { return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'EMPTY_REMOTE_DATA'); } $filename = tempnam(sys_get_temp_dir(), unique_id() . '-'); if (!($fp = @fopen($filename, 'wb'))) { return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'NOT_UPLOADED'); } $upload_ary['size'] = fwrite($fp, $data); fclose($fp); unset($data); $upload_ary['tmp_name'] = $filename; /** @var filespec $file */ $file = $this->factory->get('filespec')->set_upload_ary($upload_ary)->set_upload_namespace($this->upload); $this->upload->common_checks($file); return $file; }