aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Darricau <tristan.darricau@sensiolabs.com>2016-02-11 22:16:10 +0100
committerTristan Darricau <tristan.darricau@sensiolabs.com>2016-02-11 22:16:10 +0100
commitc9e5d308f2ebaae5ddaa70faf25af93fe2eb368b (patch)
treed1a901b18261466f47a5db5cc1cf9362a9974a1f
parentaa6dd6d4ff28f38f9596b7bb3adf19a8a7988b67 (diff)
parent8cf086ef9b200f0b59348c0f0d4946f9ebc4adae (diff)
downloadforums-c9e5d308f2ebaae5ddaa70faf25af93fe2eb368b.tar
forums-c9e5d308f2ebaae5ddaa70faf25af93fe2eb368b.tar.gz
forums-c9e5d308f2ebaae5ddaa70faf25af93fe2eb368b.tar.bz2
forums-c9e5d308f2ebaae5ddaa70faf25af93fe2eb368b.tar.xz
forums-c9e5d308f2ebaae5ddaa70faf25af93fe2eb368b.zip
Merge pull request #4159 from marc1706/ticket/14448
[ticket/14448] Use guzzle for remote files uploading * marc1706/ticket/14448: [ticket/14448] Correctly pass verify setting if available [ticket/14448] Let user decide if remote upload certs should be checked [ticket/14448] Add new vendor files and dirs to clean task [ticket/14448] Do not try to test remote upload timeout [ticket/14448] Remove no longer needed guzzle 3.9.3 [ticket/14448] Use GuzzleHttp and try to verify certs [ticket/14448] Update composer.json and lock file for guzzlehttp [ticket/14431] Remote avatar uploading [ticket/14431] Remote avatar uploading
-rw-r--r--build/build.xml36
-rw-r--r--phpBB/composer.json1
-rw-r--r--phpBB/composer.lock505
-rw-r--r--phpBB/config/default/container/services_files.yml1
-rw-r--r--phpBB/includes/acp/acp_board.php1
-rw-r--r--phpBB/install/schemas/schema_data.sql1
-rw-r--r--phpBB/language/en/acp/board.php2
-rw-r--r--phpBB/phpbb/db/migration/data/v320/remote_upload_validation.php31
-rw-r--r--phpBB/phpbb/files/types/remote.php128
-rw-r--r--tests/files/types_remote_test.php24
-rw-r--r--tests/functional/fileupload_remote_test.php5
11 files changed, 323 insertions, 412 deletions
diff --git a/build/build.xml b/build/build.xml
index e6862c0886..6d5b652b0a 100644
--- a/build/build.xml
+++ b/build/build.xml
@@ -318,6 +318,35 @@
<delete file="${dir}/vendor/google/recaptcha/phpunit.xml.dist" />
<delete file="${dir}/vendor/google/recaptcha/README.md" />
+ <delete dir="${dir}/vendor/guzzlehttp/guzzle/build" />
+ <delete dir="${dir}/vendor/guzzlehttp/guzzle/docs" />
+ <delete dir="${dir}/vendor/guzzlehttp/guzzle/tests" />
+ <delete file="${dir}/vendor/guzzlehttp/guzzle/CHANGELOG.md" />
+ <delete file="${dir}/vendor/guzzlehttp/guzzle/.editorconfig" />
+ <delete file="${dir}/vendor/guzzlehttp/guzzle/.gitignore" />
+ <delete file="${dir}/vendor/guzzlehttp/guzzle/Makefile" />
+ <delete file="${dir}/vendor/guzzlehttp/guzzle/phpunit.xml.dist" />
+ <delete file="${dir}/vendor/guzzlehttp/guzzle/README.md" />
+ <delete file="${dir}/vendor/guzzlehttp/guzzle/.travis.yml" />
+ <delete file="${dir}/vendor/guzzlehttp/guzzle/UPGRADING.md" />
+
+ <delete dir="${dir}/vendor/guzzlehttp/ringphp/docs" />
+ <delete dir="${dir}/vendor/guzzlehttp/ringphp/tests" />
+ <delete file="${dir}/vendor/guzzlehttp/ringphp/CHANGELOG.md" />
+ <delete file="${dir}/vendor/guzzlehttp/ringphp/.gitignore" />
+ <delete file="${dir}/vendor/guzzlehttp/ringphp/Makefile" />
+ <delete file="${dir}/vendor/guzzlehttp/ringphp/phpunit.xml.dist" />
+ <delete file="${dir}/vendor/guzzlehttp/ringphp/README.rst" />
+ <delete file="${dir}/vendor/guzzlehttp/ringphp/.travis.yml" />
+
+ <delete dir="${dir}/vendor/guzzlehttp/streams/tests" />
+ <delete file="${dir}/vendor/guzzlehttp/streams/CHANGELOG.rst" />
+ <delete file="${dir}/vendor/guzzlehttp/streams/.gitignore" />
+ <delete file="${dir}/vendor/guzzlehttp/streams/Makefile" />
+ <delete file="${dir}/vendor/guzzlehttp/streams/phpunit.xml.dist" />
+ <delete file="${dir}/vendor/guzzlehttp/streams/README.rst" />
+ <delete file="${dir}/vendor/guzzlehttp/streams/.travis.yml" />
+
<delete dir="${dir}/vendor/lusitanian/oauth/examples" />
<delete dir="${dir}/vendor/lusitanian/oauth/tests" />
<delete file="${dir}/vendor/lusitanian/oauth/.gitignore" />
@@ -335,6 +364,13 @@
<delete file="${dir}/vendor/psr/log/.gitignore" />
<delete file="${dir}/vendor/psr/log/README.md" />
+ <delete dir="${dir}/vendor/react/promise/tests" />
+ <delete file="${dir}/vendor/react/promise/CHANGELOG.md" />
+ <delete file="${dir}/vendor/react/promise/.gitignore" />
+ <delete file="${dir}/vendor/react/promise/phpunit.xml.dist" />
+ <delete file="${dir}/vendor/react/promise/README.md" />
+ <delete file="${dir}/vendor/react/promise/.travis.yml" />
+
<delete dir="${dir}/vendor/s9e/text-formatter/.git" />
<delete dir="${dir}/vendor/symfony/config/.git" />
diff --git a/phpBB/composer.json b/phpBB/composer.json
index 89bbce4588..a6c3a2aa93 100644
--- a/phpBB/composer.json
+++ b/phpBB/composer.json
@@ -28,6 +28,7 @@
"php": ">=5.4,<7.1",
"bantu/ini-get-wrapper": "1.0.*",
"google/recaptcha": "~1.1",
+ "guzzlehttp/guzzle": "~5.3",
"lusitanian/oauth": "^0.8.1",
"marc1706/fast-image-size": "1.1.*",
"patchwork/utf8": "1.1.*",
diff --git a/phpBB/composer.lock b/phpBB/composer.lock
index 6412029b0b..cad14d8913 100644
--- a/phpBB/composer.lock
+++ b/phpBB/composer.lock
@@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "f76b5185058599cad6a87ef7c8c35fbf",
- "content-hash": "b89d3c18f8d9b3c4dc476f92030a83a1",
+ "hash": "d4e2fb7ee961c4734df4e385db2e6995",
+ "content-hash": "b15dfee84d1e9f3e2f5a3cc290b0be58",
"packages": [
{
"name": "bantu/ini-get-wrapper",
@@ -83,6 +83,165 @@
"time": "2015-09-02 17:23:59"
},
{
+ "name": "guzzlehttp/guzzle",
+ "version": "5.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle.git",
+ "reference": "f3c8c22471cb55475105c14769644a49c3262b93"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f3c8c22471cb55475105c14769644a49c3262b93",
+ "reference": "f3c8c22471cb55475105c14769644a49c3262b93",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/ringphp": "^1.1",
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "ext-curl": "*",
+ "phpunit/phpunit": "^4.0",
+ "psr/log": "^1.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "rest",
+ "web service"
+ ],
+ "time": "2015-05-20 03:47:55"
+ },
+ {
+ "name": "guzzlehttp/ringphp",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/RingPHP.git",
+ "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/RingPHP/zipball/dbbb91d7f6c191e5e405e900e3102ac7f261bc0b",
+ "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/streams": "~3.0",
+ "php": ">=5.4.0",
+ "react/promise": "~2.0"
+ },
+ "require-dev": {
+ "ext-curl": "*",
+ "phpunit/phpunit": "~4.0"
+ },
+ "suggest": {
+ "ext-curl": "Guzzle will use specific adapters if cURL is present"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Ring\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.",
+ "time": "2015-05-20 03:37:09"
+ },
+ {
+ "name": "guzzlehttp/streams",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/streams.git",
+ "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
+ "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Stream\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Provides a simple abstraction over streams of data",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": [
+ "Guzzle",
+ "stream"
+ ],
+ "time": "2014-10-12 19:18:40"
+ },
+ {
"name": "ircmaxell/password-compat",
"version": "v1.0.4",
"source": {
@@ -332,6 +491,50 @@
"time": "2012-12-21 11:40:51"
},
{
+ "name": "react/promise",
+ "version": "v2.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/reactphp/promise.git",
+ "reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/reactphp/promise/zipball/3b6fca09c7d56321057fa8867c8dbe1abf648627",
+ "reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "React\\Promise\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jan Sorgalla",
+ "email": "jsorgalla@gmail.com"
+ }
+ ],
+ "description": "A lightweight implementation of CommonJS Promises/A for PHP",
+ "time": "2015-07-03 13:48:55"
+ },
+ {
"name": "s9e/text-formatter",
"version": "0.4.8",
"source": {
@@ -1404,260 +1607,6 @@
"time": "2015-05-05 21:14:57"
},
{
- "name": "guzzle/guzzle",
- "version": "v3.9.3",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/guzzle3.git",
- "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9",
- "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9",
- "shasum": ""
- },
- "require": {
- "ext-curl": "*",
- "php": ">=5.3.3",
- "symfony/event-dispatcher": "~2.1"
- },
- "replace": {
- "guzzle/batch": "self.version",
- "guzzle/cache": "self.version",
- "guzzle/common": "self.version",
- "guzzle/http": "self.version",
- "guzzle/inflection": "self.version",
- "guzzle/iterator": "self.version",
- "guzzle/log": "self.version",
- "guzzle/parser": "self.version",
- "guzzle/plugin": "self.version",
- "guzzle/plugin-async": "self.version",
- "guzzle/plugin-backoff": "self.version",
- "guzzle/plugin-cache": "self.version",
- "guzzle/plugin-cookie": "self.version",
- "guzzle/plugin-curlauth": "self.version",
- "guzzle/plugin-error-response": "self.version",
- "guzzle/plugin-history": "self.version",
- "guzzle/plugin-log": "self.version",
- "guzzle/plugin-md5": "self.version",
- "guzzle/plugin-mock": "self.version",
- "guzzle/plugin-oauth": "self.version",
- "guzzle/service": "self.version",
- "guzzle/stream": "self.version"
- },
- "require-dev": {
- "doctrine/cache": "~1.3",
- "monolog/monolog": "~1.0",
- "phpunit/phpunit": "3.7.*",
- "psr/log": "~1.0",
- "symfony/class-loader": "~2.1",
- "zendframework/zend-cache": "2.*,<2.3",
- "zendframework/zend-log": "2.*,<2.3"
- },
- "suggest": {
- "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated."
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.9-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Guzzle": "src/",
- "Guzzle\\Tests": "tests/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- },
- {
- "name": "Guzzle Community",
- "homepage": "https://github.com/guzzle/guzzle/contributors"
- }
- ],
- "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle",
- "homepage": "http://guzzlephp.org/",
- "keywords": [
- "client",
- "curl",
- "framework",
- "http",
- "http client",
- "rest",
- "web service"
- ],
- "time": "2015-03-18 18:23:50"
- },
- {
- "name": "guzzlehttp/guzzle",
- "version": "5.3.0",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/guzzle.git",
- "reference": "f3c8c22471cb55475105c14769644a49c3262b93"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f3c8c22471cb55475105c14769644a49c3262b93",
- "reference": "f3c8c22471cb55475105c14769644a49c3262b93",
- "shasum": ""
- },
- "require": {
- "guzzlehttp/ringphp": "^1.1",
- "php": ">=5.4.0"
- },
- "require-dev": {
- "ext-curl": "*",
- "phpunit/phpunit": "^4.0",
- "psr/log": "^1.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.0-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "GuzzleHttp\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- }
- ],
- "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients",
- "homepage": "http://guzzlephp.org/",
- "keywords": [
- "client",
- "curl",
- "framework",
- "http",
- "http client",
- "rest",
- "web service"
- ],
- "time": "2015-05-20 03:47:55"
- },
- {
- "name": "guzzlehttp/ringphp",
- "version": "1.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/RingPHP.git",
- "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/RingPHP/zipball/dbbb91d7f6c191e5e405e900e3102ac7f261bc0b",
- "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b",
- "shasum": ""
- },
- "require": {
- "guzzlehttp/streams": "~3.0",
- "php": ">=5.4.0",
- "react/promise": "~2.0"
- },
- "require-dev": {
- "ext-curl": "*",
- "phpunit/phpunit": "~4.0"
- },
- "suggest": {
- "ext-curl": "Guzzle will use specific adapters if cURL is present"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.1-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "GuzzleHttp\\Ring\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- }
- ],
- "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.",
- "time": "2015-05-20 03:37:09"
- },
- {
- "name": "guzzlehttp/streams",
- "version": "3.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/streams.git",
- "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
- "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5",
- "shasum": ""
- },
- "require": {
- "php": ">=5.4.0"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.0-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "GuzzleHttp\\Stream\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- }
- ],
- "description": "Provides a simple abstraction over streams of data",
- "homepage": "http://guzzlephp.org/",
- "keywords": [
- "Guzzle",
- "stream"
- ],
- "time": "2014-10-12 19:18:40"
- },
- {
"name": "michelf/php-markdown",
"version": "1.6.0",
"source": {
@@ -2282,50 +2231,6 @@
"time": "2013-03-08 08:21:40"
},
{
- "name": "react/promise",
- "version": "v2.2.1",
- "source": {
- "type": "git",
- "url": "https://github.com/reactphp/promise.git",
- "reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/reactphp/promise/zipball/3b6fca09c7d56321057fa8867c8dbe1abf648627",
- "reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627",
- "shasum": ""
- },
- "require": {
- "php": ">=5.4.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "React\\Promise\\": "src/"
- },
- "files": [
- "src/functions_include.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jan Sorgalla",
- "email": "jsorgalla@gmail.com"
- }
- ],
- "description": "A lightweight implementation of CommonJS Promises/A for PHP",
- "time": "2015-07-03 13:48:55"
- },
- {
"name": "sami/sami",
"version": "v1.4.1",
"source": {
diff --git a/phpBB/config/default/container/services_files.yml b/phpBB/config/default/container/services_files.yml
index 39277bcd9d..88414d89a9 100644
--- a/phpBB/config/default/container/services_files.yml
+++ b/phpBB/config/default/container/services_files.yml
@@ -49,6 +49,7 @@ services:
class: phpbb\files\types\remote
scope: prototype
arguments:
+ - '@config'
- '@files.factory'
- '@language'
- '@php_ini'
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index 26663d2a62..9d65c48bed 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -415,6 +415,7 @@ class acp_board
'browser_check' => array('lang' => 'BROWSER_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'forwarded_for_check' => array('lang' => 'FORWARDED_FOR_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'referer_validation' => array('lang' => 'REFERRER_VALID', 'validate' => 'int:0:3','type' => 'custom', 'method' => 'select_ref_check', 'explain' => true),
+ 'remote_upload_verify' => array('lang' => 'UPLOAD_CERT_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'check_dnsbl' => array('lang' => 'CHECK_DNSBL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'email_check_mx' => array('lang' => 'EMAIL_CHECK_MX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,),
diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql
index 6d3a199a5a..ede31e53e6 100644
--- a/phpBB/install/schemas/schema_data.sql
+++ b/phpBB/install/schemas/schema_data.sql
@@ -239,6 +239,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('queue_interval', '
INSERT INTO phpbb_config (config_name, config_value) VALUES ('ranks_path', 'images/ranks');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('read_notification_expire_days', '30');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('read_notification_gc', '86400');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('remote_upload_verify', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('require_activation', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('referer_validation', '1');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('script_path', '');
diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php
index ba51595dc3..462d66a04a 100644
--- a/phpBB/language/en/acp/board.php
+++ b/phpBB/language/en/acp/board.php
@@ -535,6 +535,8 @@ $lang = array_merge($lang, array(
'REFERRER_VALID_EXPLAIN' => 'If enabled, the referrer of POST requests will be checked against the host/script path settings. This may cause issues with boards using several domains and or external logins.',
'TPL_ALLOW_PHP' => 'Allow php in templates',
'TPL_ALLOW_PHP_EXPLAIN' => 'If this option is enabled, <code>PHP</code> and <code>INCLUDEPHP</code> statements will be recognised and parsed in templates.',
+ 'UPLOAD_CERT_VALID' => 'Validate upload certificate',
+ 'UPLOAD_CERT_VALID_EXPLAIN' => 'If enabled, certificates of remote uploads will be validated. This requires the CA bundle to be defined by the <samp>openssl.cafile</samp> or <samp>curl.cainfo</samp> setting in your php.ini.',
));
// Email Settings
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 @@
+<?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\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 d311face98..1fdba0ca32 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;
@@ -86,19 +92,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']);
@@ -106,108 +99,55 @@ 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();
- $errno = 0;
- $errstr = '';
+ $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);
- if (!($fsock = @fsockopen($hostname, $port, $errno, $errstr)))
+ try
{
- return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED'));
+ $response = $client->get($upload_url, $guzzle_options);
}
-
- // Make sure $path not beginning with /
- if (strpos($path, '/') === 0)
+ catch (\GuzzleHttp\Exception\ClientException $clientException)
{
- $path = substr($path, 1);
+ return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'URL_NOT_FOUND');
}
-
- 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))
+ catch (\GuzzleHttp\Exception\RequestException $requestException)
{
- if ($get_info)
+ if (strpos($requestException->getMessage(), 'cURL error 28') !== false || preg_match('/408|504/', $requestException->getCode()))
{
- 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;
+ return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT');
}
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');
- }
- }
+ 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'));
+ }
- $stream_meta_data = stream_get_meta_data($fsock);
+ $content_length = $response->getBody()->getSize();
+ if ($remote_max_filesize && $content_length > $remote_max_filesize)
+ {
+ $max_filesize = get_formatted_filesize($remote_max_filesize, false);
- // 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))
+ 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')))
diff --git a/tests/files/types_remote_test.php b/tests/files/types_remote_test.php
index caed5c9e05..476d8ed3ba 100644
--- a/tests/files/types_remote_test.php
+++ b/tests/files/types_remote_test.php
@@ -20,6 +20,9 @@ class phpbb_files_types_remote_test extends phpbb_test_case
private $filesystem;
+ /** @var \phpbb\config\config */
+ protected $config;
+
/** @var \Symfony\Component\DependencyInjection\ContainerInterface */
protected $container;
@@ -43,6 +46,8 @@ class phpbb_files_types_remote_test extends phpbb_test_case
global $config, $phpbb_root_path, $phpEx;
$config = new \phpbb\config\config(array());
+ $this->config = $config;
+ $this->config->set('remote_upload_verify', 0);
$this->request = $this->getMock('\phpbb\request\request');
$this->filesystem = new \phpbb\filesystem\filesystem();
@@ -67,7 +72,7 @@ class phpbb_files_types_remote_test extends phpbb_test_case
public function test_upload_fsock_fail()
{
- $type_remote = new \phpbb\files\types\remote($this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
+ $type_remote = new \phpbb\files\types\remote($this->config, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
$upload = new \phpbb\files\upload($this->filesystem, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
$upload->set_allowed_extensions(array('png'));
$type_remote->set_upload($upload);
@@ -102,7 +107,7 @@ class phpbb_files_types_remote_test extends phpbb_test_case
$php_ini->expects($this->any())
->method('getString')
->willReturn($max_file_size);
- $type_remote = new \phpbb\files\types\remote($this->factory, $this->language, $php_ini, $this->request, $this->phpbb_root_path);
+ $type_remote = new \phpbb\files\types\remote($this->config, $this->factory, $this->language, $php_ini, $this->request, $this->phpbb_root_path);
$upload = new \phpbb\files\upload($this->filesystem, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
$upload->set_allowed_extensions(array('png'));
$type_remote->set_upload($upload);
@@ -112,22 +117,9 @@ class phpbb_files_types_remote_test extends phpbb_test_case
$this->assertSame($expected, $file->error);
}
- public function test_upload_timeout()
- {
- $type_remote = new \phpbb\files\types\remote($this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
- $upload = new \phpbb\files\upload($this->filesystem, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
- $upload->set_allowed_extensions(array('png'));
- $type_remote->set_upload($upload);
- $upload->upload_timeout = -5;
-
- $file = $type_remote->upload('http://google.com/?.png');
-
- $this->assertSame(array('REMOTE_UPLOAD_TIMEOUT'), $file->error);
- }
-
public function test_upload_wrong_path()
{
- $type_remote = new \phpbb\files\types\foo($this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
+ $type_remote = new \phpbb\files\types\foo($this->config, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
$upload = new \phpbb\files\upload($this->filesystem, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
$upload->set_allowed_extensions(array('png'));
$type_remote->set_upload($upload);
diff --git a/tests/functional/fileupload_remote_test.php b/tests/functional/fileupload_remote_test.php
index 7e0f192b40..b70d49cddd 100644
--- a/tests/functional/fileupload_remote_test.php
+++ b/tests/functional/fileupload_remote_test.php
@@ -45,11 +45,12 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case
if (!is_array($config))
{
- $config = array();
+ $config = new \phpbb\config\config(array());
}
$config['rand_seed'] = '';
$config['rand_seed_last_update'] = time() + 600;
+ $config['remote_upload_verify'] = 0;
$this->filesystem = new \phpbb\filesystem\filesystem();
$this->language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx));
@@ -60,7 +61,7 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case
$container->set('files.filespec', new \phpbb\files\filespec($this->filesystem, $this->language, $this->php_ini, new \FastImageSize\FastImageSize(), $this->phpbb_root_path));
$this->factory = new \phpbb\files\factory($container);
$container->set('files.factory', $this->factory);
- $container->set('files.types.remote', new \phpbb\files\types\remote($this->factory, $this->language, $this->php_ini, $this->request, $phpbb_root_path));
+ $container->set('files.types.remote', new \phpbb\files\types\remote($config, $this->factory, $this->language, $this->php_ini, $this->request, $phpbb_root_path));
$this->phpbb_root_path = $phpbb_root_path;
}