Add cURL support to HTTP Client
- Add HTTP_PROXY_EXCLUDE option when cURL is used - Show HTTP client backend in about page - Fallback to legacy Stream Contexts if cURL extension is not available
This commit is contained in:
@@ -12,7 +12,7 @@ RUN apk update && \
|
|||||||
apk add openssl unzip nginx bash ca-certificates s6 curl ssmtp mailx php7 php7-phar php7-curl \
|
apk add openssl unzip nginx bash ca-certificates s6 curl ssmtp mailx php7 php7-phar php7-curl \
|
||||||
php7-fpm php7-json php7-zlib php7-xml php7-dom php7-ctype php7-opcache php7-zip php7-iconv \
|
php7-fpm php7-json php7-zlib php7-xml php7-dom php7-ctype php7-opcache php7-zip php7-iconv \
|
||||||
php7-pdo php7-pdo_mysql php7-pdo_sqlite php7-pdo_pgsql php7-mbstring php7-session php7-bcmath \
|
php7-pdo php7-pdo_mysql php7-pdo_sqlite php7-pdo_pgsql php7-mbstring php7-session php7-bcmath \
|
||||||
php7-gd php7-mcrypt php7-openssl php7-sockets php7-posix php7-ldap php7-simplexml && \
|
php7-gd php7-mcrypt php7-openssl php7-sockets php7-posix php7-ldap php7-simplexml php7-curl && \
|
||||||
rm -rf /var/cache/apk/* && \
|
rm -rf /var/cache/apk/* && \
|
||||||
rm -rf /var/www/localhost && \
|
rm -rf /var/www/localhost && \
|
||||||
rm -f /etc/php7/php-fpm.d/www.conf
|
rm -f /etc/php7/php-fpm.d/www.conf
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ RUN apk update && \
|
|||||||
apk add openssl unzip nginx bash ca-certificates s6 curl ssmtp mailx php7 php7-phar php7-curl \
|
apk add openssl unzip nginx bash ca-certificates s6 curl ssmtp mailx php7 php7-phar php7-curl \
|
||||||
php7-fpm php7-json php7-zlib php7-xml php7-dom php7-ctype php7-opcache php7-zip php7-iconv \
|
php7-fpm php7-json php7-zlib php7-xml php7-dom php7-ctype php7-opcache php7-zip php7-iconv \
|
||||||
php7-pdo php7-pdo_mysql php7-pdo_sqlite php7-pdo_pgsql php7-mbstring php7-session php7-bcmath \
|
php7-pdo php7-pdo_mysql php7-pdo_sqlite php7-pdo_pgsql php7-mbstring php7-session php7-bcmath \
|
||||||
php7-gd php7-mcrypt php7-openssl php7-sockets php7-posix php7-ldap php7-simplexml && \
|
php7-gd php7-mcrypt php7-openssl php7-sockets php7-posix php7-ldap php7-simplexml php7-curl && \
|
||||||
rm -rf /var/cache/apk/* && \
|
rm -rf /var/cache/apk/* && \
|
||||||
rm -rf /var/www/localhost && \
|
rm -rf /var/www/localhost && \
|
||||||
rm -f /etc/php7/php-fpm.d/www.conf
|
rm -f /etc/php7/php-fpm.d/www.conf
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ RUN apk update && \
|
|||||||
apk add openssl unzip nginx bash ca-certificates s6 curl ssmtp mailx php7 php7-phar php7-curl \
|
apk add openssl unzip nginx bash ca-certificates s6 curl ssmtp mailx php7 php7-phar php7-curl \
|
||||||
php7-fpm php7-json php7-zlib php7-xml php7-dom php7-ctype php7-opcache php7-zip php7-iconv \
|
php7-fpm php7-json php7-zlib php7-xml php7-dom php7-ctype php7-opcache php7-zip php7-iconv \
|
||||||
php7-pdo php7-pdo_mysql php7-pdo_sqlite php7-pdo_pgsql php7-mbstring php7-session php7-bcmath \
|
php7-pdo php7-pdo_mysql php7-pdo_sqlite php7-pdo_pgsql php7-mbstring php7-session php7-bcmath \
|
||||||
php7-gd php7-mcrypt php7-openssl php7-sockets php7-posix php7-ldap php7-simplexml && \
|
php7-gd php7-mcrypt php7-openssl php7-sockets php7-posix php7-ldap php7-simplexml php7-curl && \
|
||||||
rm -rf /var/cache/apk/* && \
|
rm -rf /var/cache/apk/* && \
|
||||||
rm -rf /var/www/localhost && \
|
rm -rf /var/www/localhost && \
|
||||||
rm -f /etc/php7/php-fpm.d/www.conf
|
rm -f /etc/php7/php-fpm.d/www.conf
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ RUN apk update && \
|
|||||||
apk add openssl unzip nginx bash ca-certificates s6 curl ssmtp mailx php7 php7-phar php7-curl \
|
apk add openssl unzip nginx bash ca-certificates s6 curl ssmtp mailx php7 php7-phar php7-curl \
|
||||||
php7-fpm php7-json php7-zlib php7-xml php7-dom php7-ctype php7-opcache php7-zip php7-iconv \
|
php7-fpm php7-json php7-zlib php7-xml php7-dom php7-ctype php7-opcache php7-zip php7-iconv \
|
||||||
php7-pdo php7-pdo_mysql php7-pdo_sqlite php7-pdo_pgsql php7-mbstring php7-session php7-bcmath \
|
php7-pdo php7-pdo_mysql php7-pdo_sqlite php7-pdo_pgsql php7-mbstring php7-session php7-bcmath \
|
||||||
php7-gd php7-mcrypt php7-openssl php7-sockets php7-posix php7-ldap php7-simplexml && \
|
php7-gd php7-mcrypt php7-openssl php7-sockets php7-posix php7-ldap php7-simplexml php7-curl && \
|
||||||
rm -rf /var/cache/apk/* && \
|
rm -rf /var/cache/apk/* && \
|
||||||
rm -rf /var/www/localhost && \
|
rm -rf /var/www/localhost && \
|
||||||
rm -f /etc/php7/php-fpm.d/www.conf
|
rm -f /etc/php7/php-fpm.d/www.conf
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ class Client extends Base
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the HTTP request
|
* Make the HTTP request with cURL if detected, socket otherwise
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $method
|
* @param string $method
|
||||||
@@ -144,10 +144,38 @@ class Client extends Base
|
|||||||
*/
|
*/
|
||||||
public function doRequest($method, $url, $content, array $headers, $raiseForErrors = false)
|
public function doRequest($method, $url, $content, array $headers, $raiseForErrors = false)
|
||||||
{
|
{
|
||||||
if (empty($url)) {
|
$requestBody = '';
|
||||||
return '';
|
|
||||||
|
if (! empty($url)) {
|
||||||
|
if (function_exists('curl_version')) {
|
||||||
|
if (DEBUG) {
|
||||||
|
$this->logger->debug('HttpClient::doRequest: cURL detected');
|
||||||
|
}
|
||||||
|
$requestBody = $this->doRequestWithCurl($method, $url, $content, $headers, $raiseForErrors);
|
||||||
|
} else {
|
||||||
|
if (DEBUG) {
|
||||||
|
$this->logger->debug('HttpClient::doRequest: using socket');
|
||||||
|
}
|
||||||
|
$requestBody = $this->doRequestWithSocket($method, $url, $content, $headers, $raiseForErrors);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $requestBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the HTTP request with socket
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param string $method
|
||||||
|
* @param string $url
|
||||||
|
* @param string $content
|
||||||
|
* @param string[] $headers
|
||||||
|
* @param bool $raiseForErrors
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function doRequestWithSocket($method, $url, $content, array $headers, $raiseForErrors = false)
|
||||||
|
{
|
||||||
$startTime = microtime(true);
|
$startTime = microtime(true);
|
||||||
$stream = @fopen(trim($url), 'r', false, stream_context_create($this->getContext($method, $content, $headers, $raiseForErrors)));
|
$stream = @fopen(trim($url), 'r', false, stream_context_create($this->getContext($method, $content, $headers, $raiseForErrors)));
|
||||||
|
|
||||||
@@ -184,6 +212,91 @@ class Client extends Base
|
|||||||
return $body;
|
return $body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the HTTP request with cURL
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param string $method
|
||||||
|
* @param string $url
|
||||||
|
* @param string $content
|
||||||
|
* @param string[] $headers
|
||||||
|
* @param bool $raiseForErrors
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function doRequestWithCurl($method, $url, $content, array $headers, $raiseForErrors = false)
|
||||||
|
{
|
||||||
|
$startTime = microtime(true);
|
||||||
|
$curlSession = @curl_init();
|
||||||
|
|
||||||
|
curl_setopt($curlSession, CURLOPT_URL, trim($url));
|
||||||
|
curl_setopt($curlSession, CURLOPT_USERAGENT, self::HTTP_USER_AGENT);
|
||||||
|
curl_setopt($curlSession, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
|
||||||
|
curl_setopt($curlSession, CURLOPT_TIMEOUT, HTTP_TIMEOUT);
|
||||||
|
curl_setopt($curlSession, CURLOPT_FORBID_REUSE, true);
|
||||||
|
curl_setopt($curlSession, CURLOPT_MAXREDIRS, HTTP_MAX_REDIRECTS);
|
||||||
|
curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($curlSession, CURLOPT_FOLLOWLOCATION, true);
|
||||||
|
|
||||||
|
if ('POST' === $method) {
|
||||||
|
curl_setopt($curlSession, CURLOPT_POST, true);
|
||||||
|
curl_setopt($curlSession, CURLOPT_POSTFIELDS, $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! empty($headers)) {
|
||||||
|
curl_setopt($curlSession, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HTTP_VERIFY_SSL_CERTIFICATE === false) {
|
||||||
|
curl_setopt($curlSession, CURLOPT_SSL_VERIFYHOST, 0);
|
||||||
|
curl_setopt($curlSession, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HTTP_PROXY_HOSTNAME) {
|
||||||
|
curl_setopt($curlSession, CURLOPT_PROXY, HTTP_PROXY_HOSTNAME);
|
||||||
|
curl_setopt($curlSession, CURLOPT_PROXYPORT, HTTP_PROXY_PORT);
|
||||||
|
curl_setopt($curlSession, CURLOPT_NOPROXY, HTTP_PROXY_EXCLUDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HTTP_PROXY_USERNAME) {
|
||||||
|
curl_setopt($curlSession, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
|
||||||
|
curl_setopt($curlSession, CURLOPT_PROXYUSERPWD, HTTP_PROXY_USERNAME.':'.HTTP_PROXY_PASSWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = curl_exec($curlSession);
|
||||||
|
|
||||||
|
if (! $body) {
|
||||||
|
$this->logger->error('HttpClient: request failed ('.$url.')');
|
||||||
|
|
||||||
|
if ($raiseForErrors) {
|
||||||
|
throw new ClientException('Unreachable URL: '.$url);
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_close($curlSession);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($raiseForErrors) {
|
||||||
|
$statusCode = curl_getinfo($curlSession, CURLINFO_RESPONSE_CODE);
|
||||||
|
|
||||||
|
if ($statusCode >= 400) {
|
||||||
|
throw new InvalidStatusException('Request failed with status code '.$statusCode, $statusCode, $body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
$this->logger->debug('HttpClient: url='.$url);
|
||||||
|
$this->logger->debug('HttpClient: headers='.var_export($headers, true));
|
||||||
|
$this->logger->debug('HttpClient: payload='.$content);
|
||||||
|
$this->logger->debug('HttpClient: metadata='.var_export(curl_getinfo($curlSession), true));
|
||||||
|
$this->logger->debug('HttpClient: body='.$body);
|
||||||
|
$this->logger->debug('HttpClient: executionTime='.(microtime(true) - $startTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_close($curlSession);
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get stream context
|
* Get stream context
|
||||||
*
|
*
|
||||||
@@ -247,4 +360,15 @@ class Client extends Base
|
|||||||
|
|
||||||
return $status;
|
return $status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get backend used for making HTTP connections
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function backend()
|
||||||
|
{
|
||||||
|
return function_exists('curl_version') ? 'cURL' : 'socket';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,10 @@
|
|||||||
<?= t('PHP SAPI:') ?>
|
<?= t('PHP SAPI:') ?>
|
||||||
<strong><?= PHP_SAPI ?></strong>
|
<strong><?= PHP_SAPI ?></strong>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<?= t('HTTP Client:') ?>
|
||||||
|
<strong><?= Kanboard\Core\Http\Client::backend() ?></strong>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<?= t('OS version:') ?>
|
<?= t('OS version:') ?>
|
||||||
<strong><?= @php_uname('s').' '.@php_uname('r') ?></strong>
|
<strong><?= @php_uname('s').' '.@php_uname('r') ?></strong>
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ defined('HTTP_PROXY_HOSTNAME') or define('HTTP_PROXY_HOSTNAME', '');
|
|||||||
defined('HTTP_PROXY_PORT') or define('HTTP_PROXY_PORT', '3128');
|
defined('HTTP_PROXY_PORT') or define('HTTP_PROXY_PORT', '3128');
|
||||||
defined('HTTP_PROXY_USERNAME') or define('HTTP_PROXY_USERNAME', '');
|
defined('HTTP_PROXY_USERNAME') or define('HTTP_PROXY_USERNAME', '');
|
||||||
defined('HTTP_PROXY_PASSWORD') or define('HTTP_PROXY_PASSWORD', '');
|
defined('HTTP_PROXY_PASSWORD') or define('HTTP_PROXY_PASSWORD', '');
|
||||||
|
defined('HTTP_PROXY_EXCLUDE') or define('HTTP_PROXY_EXCLUDE', 'localhost');
|
||||||
defined('HTTP_VERIFY_SSL_CERTIFICATE') or define('HTTP_VERIFY_SSL_CERTIFICATE', true);
|
defined('HTTP_VERIFY_SSL_CERTIFICATE') or define('HTTP_VERIFY_SSL_CERTIFICATE', true);
|
||||||
|
|
||||||
defined('TOTP_ISSUER') or define('TOTP_ISSUER', 'Kanboard');
|
defined('TOTP_ISSUER') or define('TOTP_ISSUER', 'Kanboard');
|
||||||
|
|||||||
@@ -241,6 +241,7 @@ define('HTTP_PROXY_HOSTNAME', '');
|
|||||||
define('HTTP_PROXY_PORT', '3128');
|
define('HTTP_PROXY_PORT', '3128');
|
||||||
define('HTTP_PROXY_USERNAME', '');
|
define('HTTP_PROXY_USERNAME', '');
|
||||||
define('HTTP_PROXY_PASSWORD', '');
|
define('HTTP_PROXY_PASSWORD', '');
|
||||||
|
define('HTTP_PROXY_EXCLUDE', 'localhost');
|
||||||
|
|
||||||
// Set to false to allow self-signed certificates
|
// Set to false to allow self-signed certificates
|
||||||
define('HTTP_VERIFY_SSL_CERTIFICATE', true);
|
define('HTTP_VERIFY_SSL_CERTIFICATE', true);
|
||||||
|
|||||||
Reference in New Issue
Block a user