From cec63974c393b71770eae7d740e136b43ed1c78f Mon Sep 17 00:00:00 2001 From: Scott Dutton Date: Mon, 25 Jan 2016 21:45:43 +0000 Subject: [ticket/14431] Remote avatar uploading replace the 3.1 way with guzzle Adds guzzle as a dependency Removed a test as it wont wont with guzzle (as far as I know) PHPBB3-14431 --- phpBB/phpbb/files/types/remote.php | 122 ++++++------------------------------- 1 file changed, 19 insertions(+), 103 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index d311face98..e990149501 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -86,19 +86,6 @@ class remote extends base $url = parse_url($upload_url); - $default_port = 80; - $hostname = $url['host']; - - if ($url['scheme'] == 'https') - { - $default_port = 443; - $hostname = 'tls://' . $url['host']; - } - - $host = $url['host']; - $path = $url['path']; - $port = (!empty($url['port'])) ? (int) $url['port'] : $default_port; - $upload_ary['type'] = 'application/octet-stream'; $url['path'] = explode('.', $url['path']); @@ -110,103 +97,32 @@ class remote extends base $remote_max_filesize = $this->get_max_file_size(); - $errno = 0; - $errstr = ''; - - if (!($fsock = @fsockopen($hostname, $port, $errno, $errstr))) - { + $client = new \Guzzle\Http\Client([ + 'timeout' => $this->upload->upload_timeout, + 'connect_timeout' => $this->upload->upload_timeout, + ]); + + try { + $response = $client->get($upload_url)->send(); + } catch (\Guzzle\Http\Exception\ClientErrorResponseException $responseException) { + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'URL_NOT_FOUND'); + } catch (\Guzzle\Http\Exception\CurlException $curlException) { + //curl exceptions are when the DNS fails etc + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); + } catch (\Guzzle\Http\Exception\RequestException $requestException) { + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); + } catch (\Exception $e) { 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 ($remote_max_filesize && $response->getContentType() > $remote_max_filesize) { - 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); - } + $max_filesize = get_formatted_filesize($remote_max_filesize, false); - $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'); - } + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); } - @fclose($fsock); - if (empty($data)) - { - 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() . '-'); -- cgit v1.2.1 From 49dd9f021924551bf0cfc5db3962ddb50c9e98a2 Mon Sep 17 00:00:00 2001 From: Scott Dutton Date: Wed, 3 Feb 2016 05:45:24 +0000 Subject: [ticket/14431] Remote avatar uploading Fixed content length bug Ran composer update PHPBB3-14431 --- phpBB/phpbb/files/types/remote.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index e990149501..92e0e3b9bc 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -115,13 +115,19 @@ class remote extends base return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); } - if ($remote_max_filesize && $response->getContentType() > $remote_max_filesize) + $content_length = $response->getContentLength(); + 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() . '-'); -- cgit v1.2.1 From c83db45f55858c78648a6650aec39a9fc627a50b Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 3 Feb 2016 14:06:10 +0100 Subject: [ticket/14448] Use GuzzleHttp and try to verify certs PHPBB3-14448 --- phpBB/phpbb/files/types/remote.php | 48 ++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 12 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index 92e0e3b9bc..f4a4fa70d1 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -93,29 +93,53 @@ class remote extends base $url['path'] = implode('', $url['path']); $upload_ary['name'] = utf8_basename($url['path']) . (($ext) ? '.' . $ext : ''); - $filesize = 0; $remote_max_filesize = $this->get_max_file_size(); - $client = new \Guzzle\Http\Client([ + $guzzle_options = [ 'timeout' => $this->upload->upload_timeout, 'connect_timeout' => $this->upload->upload_timeout, - ]); + ]; + $client = new \GuzzleHttp\Client($guzzle_options); - try { - $response = $client->get($upload_url)->send(); - } catch (\Guzzle\Http\Exception\ClientErrorResponseException $responseException) { + 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 (\Guzzle\Http\Exception\CurlException $curlException) { - //curl exceptions are when the DNS fails etc - return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); - } catch (\Guzzle\Http\Exception\RequestException $requestException) { - return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); + } + 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 + { + if (strpos($requestException->getMessage(), 'cURL error 60') !== false) + { + // Work around non existent CA file + try + { + $response = $client->get($upload_url, array_merge($guzzle_options, ['verify' => false])); + } + catch (\GuzzleHttp\Exception\RequestException $requestException) + { + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); + } + } + 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->getContentLength(); + $content_length = $response->getBody()->getSize(); if ($remote_max_filesize && $content_length > $remote_max_filesize) { $max_filesize = get_formatted_filesize($remote_max_filesize, false); -- cgit v1.2.1 From fd9c05309d186332728b533467aaecad5c543c52 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 4 Feb 2016 17:10:59 +0100 Subject: [ticket/14448] Let user decide if remote upload certs should be checked Also fixed some minor issues like coding style. PHPBB3-14448 --- .../data/v320/remote_upload_validation.php | 31 ++++++++++++++++++++ phpBB/phpbb/files/types/remote.php | 34 +++++++++------------- 2 files changed, 45 insertions(+), 20 deletions(-) create mode 100644 phpBB/phpbb/db/migration/data/v320/remote_upload_validation.php (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/db/migration/data/v320/remote_upload_validation.php b/phpBB/phpbb/db/migration/data/v320/remote_upload_validation.php new file mode 100644 index 0000000000..d61f6b96fd --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/remote_upload_validation.php @@ -0,0 +1,31 @@ + +* @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\db\migration\data\v320; + +class remote_upload_validation extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\v320a2', + ); + } + + public function update_data() + { + return array( + array('config.add', array('remote_upload_verify', '0')), + ); + } +} diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index f4a4fa70d1..7e5157baa9 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -14,6 +14,7 @@ namespace phpbb\files\types; use bantu\IniGetWrapper\IniGetWrapper; +use phpbb\config\config; use phpbb\files\factory; use phpbb\files\filespec; use phpbb\language\language; @@ -21,6 +22,9 @@ use phpbb\request\request_interface; class remote extends base { + /** @var config phpBB config */ + protected $config; + /** @var factory Files factory */ protected $factory; @@ -42,14 +46,16 @@ class remote extends base /** * 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(factory $factory, language $language, IniGetWrapper $php_ini, request_interface $request, $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; @@ -97,8 +103,9 @@ class remote extends base $remote_max_filesize = $this->get_max_file_size(); $guzzle_options = [ - 'timeout' => $this->upload->upload_timeout, - 'connect_timeout' => $this->upload->upload_timeout, + 'timeout' => $this->upload->upload_timeout, + 'connect_timeout' => $this->upload->upload_timeout, + 'verify' => !empty($this->config['remote_upload_verify']), ]; $client = new \GuzzleHttp\Client($guzzle_options); @@ -118,24 +125,11 @@ class remote extends base } else { - if (strpos($requestException->getMessage(), 'cURL error 60') !== false) - { - // Work around non existent CA file - try - { - $response = $client->get($upload_url, array_merge($guzzle_options, ['verify' => false])); - } - catch (\GuzzleHttp\Exception\RequestException $requestException) - { - return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); - } - } - else - { - return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); - } + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); } - } catch (\Exception $e) { + } + catch (\Exception $e) + { return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); } -- cgit v1.2.1 From 8cf086ef9b200f0b59348c0f0d4946f9ebc4adae Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 8 Feb 2016 13:26:19 +0100 Subject: [ticket/14448] Correctly pass verify setting if available PHPBB3-14448 --- phpBB/phpbb/files/types/remote.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index 7e5157baa9..1fdba0ca32 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -105,7 +105,7 @@ class remote extends base $guzzle_options = [ 'timeout' => $this->upload->upload_timeout, 'connect_timeout' => $this->upload->upload_timeout, - 'verify' => !empty($this->config['remote_upload_verify']), + 'verify' => !empty($this->config['remote_upload_verify']) ? (bool) $this->config['remote_upload_verify'] : false, ]; $client = new \GuzzleHttp\Client($guzzle_options); -- cgit v1.2.1