Seditio Source
Root |
./othercms/phpBB3/phpbb/files/types/remote.php
<?php
/**
 *
 * This file is part of the phpBB Forum Software package.
 *
 * @copyright (c) phpBB Limited <https://www.phpbb.com>
 * @license GNU General Public License, version 2 (GPL-2.0)
 *
 * For full copyright and license information, please see
 * the docs/CREDITS.txt file.
 *
 */

namespace phpbb\files\types;

use
bantu\IniGetWrapper\IniGetWrapper;
use
phpbb\config\config;
use
phpbb\files\factory;
use
phpbb\files\filespec;
use
phpbb\language\language;
use
phpbb\request\request_interface;

class
remote extends base
{
   
/** @var config phpBB config */
   
protected $config;

   
/** @var factory Files factory */
   
protected $factory;

   
/** @var language */
   
protected $language;

   
/** @var IniGetWrapper */
   
protected $php_ini;

   
/** @var request_interface */
   
protected $request;

   
/** @var \phpbb\files\upload */
   
protected $upload;

   
/** @var string phpBB root path */
   
protected $phpbb_root_path;

   
/**
     * Construct a form upload type
     *
     * @param config $config phpBB config
     * @param factory $factory Files factory
     * @param language $language Language class
     * @param IniGetWrapper $php_ini ini_get() wrapper
     * @param request_interface $request Request object
     * @param string $phpbb_root_path phpBB root path
     */
   
public function __construct(config $config, factory $factory, language $language, IniGetWrapper $php_ini, request_interface $request, $phpbb_root_path)
    {
       
$this->config = $config;
       
$this->factory = $factory;
       
$this->language = $language;
       
$this->php_ini = $php_ini;
       
$this->request = $request;
       
$this->phpbb_root_path = $phpbb_root_path;
    }

   
/**
     * {@inheritdoc}
     */
   
public function upload()
    {
       
$args = func_get_args();
        return
$this->remote_upload($args[0]);
    }

   
/**
     * 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;
    }

   
/**
     * Get maximum file size for remote uploads
     *
     * @return int Maximum file size
     */
   
protected function get_max_file_size()
    {
       
$max_file_size = $this->upload->max_filesize;
        if (!
$max_file_size)
        {
           
$max_file_size = $this->php_ini->getString('upload_max_filesize');

            if (!empty(
$max_file_size))
            {
               
$unit = strtolower(substr($max_file_size, -1, 1));
               
$max_file_size = (int) $max_file_size;

                switch (
$unit)
                {
                    case
'g':
                       
$max_file_size *= 1024;
                   
// no break
                   
case 'm':
                       
$max_file_size *= 1024;
                   
// no break
                   
case 'k':
                       
$max_file_size *= 1024;
                   
// no break
               
}
            }
        }

        return
$max_file_size;
    }
}