Upgrade to 3.6.3

This commit is contained in:
Bastian Allgeier
2022-03-22 10:43:28 +01:00
parent 15da803094
commit f732a03566
275 changed files with 1961 additions and 1126 deletions

View File

@@ -11,7 +11,7 @@ use Kirby\Toolkit\Str;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Cookie

View File

@@ -8,7 +8,7 @@ namespace Kirby\Http\Exceptions;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class NextRouteException extends \Exception

View File

@@ -11,7 +11,7 @@ use Kirby\Filesystem\F;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Header

View File

@@ -10,7 +10,7 @@ use Kirby\Toolkit\Str;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Idn

View File

@@ -12,7 +12,7 @@ use Kirby\Toolkit\Str;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Params extends Query
@@ -69,10 +69,13 @@ class Params extends Query
}
$paramParts = Str::split($p, $separator);
$paramKey = $paramParts[0];
$paramKey = $paramParts[0] ?? null;
$paramValue = $paramParts[1] ?? null;
$params[$paramKey] = $paramValue;
if ($paramKey !== null) {
$params[$paramKey] = $paramValue;
}
unset($path[$index]);
}

View File

@@ -12,7 +12,7 @@ use Kirby\Toolkit\Str;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Path extends Collection

View File

@@ -12,7 +12,7 @@ use Kirby\Toolkit\Obj;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Query extends Obj

View File

@@ -15,13 +15,13 @@ use Kirby\Toolkit\Str;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Remote
{
const CA_INTERNAL = 1;
const CA_SYSTEM = 2;
public const CA_INTERNAL = 1;
public const CA_SYSTEM = 2;
/**
* @var array

View File

@@ -18,7 +18,7 @@ use Kirby\Toolkit\Str;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Request

View File

@@ -11,7 +11,7 @@ namespace Kirby\Http\Request;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Body

View File

@@ -13,7 +13,7 @@ namespace Kirby\Http\Request;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
trait Data

View File

@@ -12,7 +12,7 @@ namespace Kirby\Http\Request;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Files

View File

@@ -10,7 +10,7 @@ namespace Kirby\Http\Request;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Query

View File

@@ -14,7 +14,7 @@ use Throwable;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Response

View File

@@ -8,7 +8,7 @@ use Closure;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Route

View File

@@ -11,7 +11,7 @@ use Kirby\Toolkit\A;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Router

View File

@@ -2,6 +2,8 @@
namespace Kirby\Http;
use Kirby\Toolkit\A;
/**
* A set of methods that make it more convenient to get variables
* from the global server array
@@ -9,11 +11,15 @@ namespace Kirby\Http;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Server
{
public const HOST_FROM_SERVER = 1;
public const HOST_FROM_HEADER = 2;
public const HOST_ALLOW_EMPTY = 4;
/**
* Cache for the cli status
*
@@ -21,6 +27,13 @@ class Server
*/
public static $cli;
/**
* List of trusted hosts
*
* @var array
*/
public static $hosts = [];
/**
* Returns the server's IP address
*
@@ -28,7 +41,7 @@ class Server
*/
public static function address(): string
{
return static::get('SERVER_ADDR');
return static::get('SERVER_ADDR', '');
}
/**
@@ -84,59 +97,66 @@ class Server
}
/**
* Help to sanitize some _SERVER keys
* Returns the correct host
*
* @param string $key
* @param mixed $value
* @return mixed
* @param bool $forwarded Deprecated. Todo: remove in 3.7.0
* @return string
*/
public static function sanitize(string $key, $value)
public static function host(bool $forwarded = false): string
{
// make sure $value is not null
$value ??= '';
$hosts[] = static::get('SERVER_NAME');
$hosts[] = static::get('SERVER_ADDR');
switch ($key) {
case 'SERVER_ADDR':
case 'SERVER_NAME':
case 'HTTP_HOST':
case 'HTTP_X_FORWARDED_HOST':
$value = strip_tags($value);
$value = preg_replace('![^\w.:-]+!iu', '', $value);
$value = trim($value, '-');
$value = htmlspecialchars($value, ENT_COMPAT);
break;
case 'SERVER_PORT':
case 'HTTP_X_FORWARDED_PORT':
$value = (int)(preg_replace('![^0-9]+!', '', $value));
break;
// insecure host parameters are only allowed when hosts
// are validated against set of host patterns
if (empty(static::$hosts) === false) {
$hosts[] = static::get('HTTP_HOST');
$hosts[] = static::get('HTTP_X_FORWARDED_HOST');
}
return $value;
}
// remove empty hosts
$hosts = array_filter($hosts);
/**
* Returns the correct port number
*
* @param bool $forwarded
* @return int
*/
public static function port(bool $forwarded = false): int
{
// based on forwarded port
if ($forwarded === true) {
if ($port = static::get('HTTP_X_FORWARDED_PORT')) {
return $port;
foreach ($hosts as $host) {
if (static::isAllowedHost($host) === true) {
return explode(':', $host)[0];
}
}
// based on HTTP host
$host = static::get('HTTP_HOST');
if ($pos = strpos($host, ':')) {
return (int)substr($host, $pos + 1);
return '';
}
/**
* Setter and getter for the the static $hosts property
*
* $hosts = null -> return all defined hosts
* $hosts = Server::HOST_FROM_SERVER -> []
* $hosts = Server::HOST_FROM_HEADER -> ['*']
* $hosts = array -> [array of trusted hosts]
* $hosts = string -> [single trusted host]
*
* @param string|array|int|null $hosts
* @return array
*/
public static function hosts($hosts = null): array
{
if ($hosts === null) {
return static::$hosts;
}
// based on server port
return static::get('SERVER_PORT');
if (is_int($hosts) && $hosts & static::HOST_FROM_SERVER) {
return static::$hosts = [];
}
if (is_int($hosts) && $hosts & static::HOST_FROM_HEADER) {
return static::$hosts = ['*'];
}
// make sure hosts are always an array
$hosts = A::wrap($hosts);
// return unique hosts
return static::$hosts = array_unique($hosts);
}
/**
@@ -146,35 +166,183 @@ class Server
*/
public static function https(): bool
{
if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
$https = $_SERVER['HTTPS'] ?? null;
$off = ['off', null, '', 0, '0', false, 'false', -1, '-1'];
// check for various options to send a negative HTTPS header
if (in_array($https, $off, true) === false) {
return true;
} elseif (static::port() === 443) {
return true;
} elseif (in_array(static::get('HTTP_X_FORWARDED_PROTO'), ['https', 'https, http'])) {
return true;
} else {
return false;
}
// check for the port
if (static::port() === 443) {
return true;
}
return false;
}
/**
* Returns the correct host
* Checks for allowed host names
*
* @param string $host
* @return bool
*/
public static function isAllowedHost(string $host): bool
{
if (empty(static::$hosts) === true) {
return true;
}
foreach (static::$hosts as $pattern) {
if (empty($pattern) === true) {
continue;
}
if (fnmatch($pattern, $host) === true) {
return true;
}
}
return false;
}
/**
* Checks if the server is behind a
* proxy server.
*
* @return bool
*/
public static function isBehindProxy(): bool
{
return empty($_SERVER['HTTP_X_FORWARDED_HOST']) === false;
}
/**
* Returns the correct port number
*
* @param bool $forwarded Deprecated. Todo: remove in 3.7.0
* @return int
*/
public static function port(bool $forwarded = false): int
{
$port = null;
// handle reverse proxy setups
if (static::isBehindProxy() === true) {
// based on forwarded port
$port = static::get('HTTP_X_FORWARDED_PORT');
// based on the forwarded host
if (empty($port) === true) {
$port = (int)parse_url(static::get('HTTP_X_FORWARDED_HOST'), PHP_URL_PORT);
}
// based on the forwarded proto
if (empty($port) === true) {
if (in_array($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? null, ['https', 'https, http']) === true) {
$port = 443;
}
}
}
// based on the host
if (empty($port) === true) {
$port = (int)parse_url(static::get('HTTP_HOST'), PHP_URL_PORT);
}
// based on server port
if (empty($port) === true) {
$port = static::get('SERVER_PORT');
}
return $port ?? 0;
}
/**
* Returns an array with path and query
* from the REQUEST_URI
*
* @return array
*/
public static function requestUri(): array
{
$uri = static::get('REQUEST_URI', '');
$uri = parse_url($uri);
return [
'path' => $uri['path'] ?? null,
'query' => $uri['query'] ?? null,
];
}
/**
* Help to sanitize some _SERVER keys
*
* @param string $key
* @param mixed $value
* @return mixed
*/
public static function sanitize(string $key, $value)
{
switch ($key) {
case 'SERVER_ADDR':
case 'SERVER_NAME':
case 'HTTP_HOST':
case 'HTTP_X_FORWARDED_HOST':
$value ??= '';
$value = strtolower($value);
$value = strip_tags($value);
$value = basename($value);
$value = preg_replace('![^\w.:-]+!iu', '', $value);
$value = htmlspecialchars($value, ENT_COMPAT);
$value = trim($value, '-');
$value = trim($value, '.');
break;
case 'SERVER_PORT':
case 'HTTP_X_FORWARDED_PORT':
$value ??= '';
$value = (int)(preg_replace('![^0-9]+!', '', $value));
break;
}
return $value;
}
/**
* Returns the path to the php script
* within the document root without the
* filename of the script.
*
* i.e. /subfolder/index.php -> subfolder
*
* This can be used to build the base url
* for subfolder installations
*
* @param bool $forwarded
* @return string
*/
public static function host(bool $forwarded = false): string
public static function scriptPath(): string
{
$host = $forwarded === true ? static::get('HTTP_X_FORWARDED_HOST') : null;
if (empty($host) === true) {
$host = static::get('SERVER_NAME');
if (static::cli() === true) {
return '';
}
if (empty($host) === true) {
$host = static::get('SERVER_ADDR');
$path = $_SERVER['SCRIPT_NAME'] ?? '';
// replace Windows backslashes
$path = str_replace('\\', '/', $path);
// remove the script
$path = dirname($path);
// replace those fucking backslashes again
$path = str_replace('\\', '/', $path);
// remove the leading and trailing slashes
$path = trim($path, '/');
// top-level scripts don't have a path
// and dirname() will return '.'
if ($path === '.') {
$path = '';
}
return explode(':', $host)[0];
return $path;
}
}

View File

@@ -12,7 +12,7 @@ use Throwable;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Uri
@@ -237,7 +237,7 @@ class Uri
/**
* @param array $props
* @param bool $forwarded
* @param bool $forwarded Deprecated! Todo: remove in 3.7.0
* @return static
*/
public static function current(array $props = [], bool $forwarded = false)
@@ -246,20 +246,13 @@ class Uri
return static::$current;
}
$uri = Server::get('REQUEST_URI') ?? '';
$uri = preg_replace(
'!^(http|https)\:\/\/' . Server::get('HTTP_HOST') . '!',
'',
$uri
);
$uri = parse_url('http://getkirby.com' . $uri);
$uri = Server::requestUri();
$url = new static(array_merge([
'scheme' => Server::https() === true ? 'https' : 'http',
'host' => Server::host($forwarded),
'port' => Server::port($forwarded),
'path' => $uri['path'] ?? null,
'query' => $uri['query'] ?? null,
'host' => Server::host(),
'port' => Server::port(),
'path' => $uri['path'],
'query' => $uri['query'],
], $props));
return $url;
@@ -335,34 +328,16 @@ class Uri
* or any other executed script.
*
* @param array $props
* @param bool $forwarded
* @param bool $forwarded Deprecated! Todo: remove in 3.7.0
* @return string
*/
public static function index(array $props = [], bool $forwarded = false)
{
if (Server::cli() === true) {
$path = null;
} else {
$path = Server::get('SCRIPT_NAME');
// replace Windows backslashes
$path = str_replace('\\', '/', $path);
// remove the script
$path = dirname($path);
// replace those fucking backslashes again
$path = str_replace('\\', '/', $path);
// remove the leading and trailing slashes
$path = trim($path, '/');
}
if ($path === '.') {
$path = null;
}
return static::current(array_merge($props, [
'path' => $path,
'path' => Server::scriptPath(),
'query' => null,
'fragment' => null,
]), $forwarded);
]));
}

View File

@@ -10,7 +10,7 @@ use Kirby\Toolkit\Str;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Url
@@ -100,12 +100,12 @@ class Url
* Returns the url to the executed script
*
* @param array $props
* @param bool $forwarded
* @param bool $forwarded Deprecated! Todo: remove in 3.7.0
* @return string
*/
public static function index(array $props = [], bool $forwarded = false): string
{
return Uri::index($props, $forwarded)->toString();
return Uri::index($props)->toString();
}
/**

View File

@@ -15,7 +15,7 @@ use Kirby\Toolkit\Str;
* @package Kirby Http
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @copyright Bastian Allgeier
* @license https://opensource.org/licenses/MIT
*/
class Visitor