* Fix issues with brackets in directory names
* Update dependencies
This commit is contained in:
parent
49b4ec839c
commit
97cbdd15c9
|
@ -43,6 +43,7 @@ class ErrorManager
|
|||
*/
|
||||
const PRODUCTION = 1;
|
||||
const DEVELOPMENT = 2;
|
||||
const CLI_DEVELOPMENT = 4;
|
||||
|
||||
/**
|
||||
* Term colors
|
||||
|
@ -269,11 +270,22 @@ class ErrorManager
|
|||
|
||||
$html_report = null;
|
||||
|
||||
if (self::$enabled != self::PRODUCTION || self::$email_errors) {
|
||||
if (self::$enabled & self::DEVELOPMENT || self::$email_errors) {
|
||||
$html_report = self::htmlReport($report);
|
||||
}
|
||||
|
||||
if (PHP_SAPI == 'cli' || 0 === strpos($_SERVER['HTTP_USER_AGENT'] ?? '', 'curl/'))
|
||||
$is_curl = 0 === strpos($_SERVER['HTTP_USER_AGENT'] ?? '', 'curl/');
|
||||
$is_cli = PHP_SAPI == 'cli';
|
||||
|
||||
if (!$is_cli) {
|
||||
http_response_code(500);
|
||||
}
|
||||
|
||||
if ($is_curl && !headers_sent()) {
|
||||
header('Content-Type: text/plain; charset=utf-8', true);
|
||||
}
|
||||
|
||||
if (($is_cli || $is_curl) && (self::$enabled & self::DEVELOPMENT || self::$enabled & self::CLI_DEVELOPMENT))
|
||||
{
|
||||
foreach ($report->errors as $e)
|
||||
{
|
||||
|
@ -315,7 +327,11 @@ class ErrorManager
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (self::$enabled == self::PRODUCTION)
|
||||
else if (($is_cli || $is_curl) && self::$enabled & self::PRODUCTION) {
|
||||
self::termPrint(' /!\\ An internal server error occurred ', self::RED);
|
||||
self::termPrint(' Error reference was: ' . $report->context->id, self::YELLOW);
|
||||
}
|
||||
else if (self::$enabled & self::PRODUCTION)
|
||||
{
|
||||
self::htmlProduction($report);
|
||||
}
|
||||
|
@ -520,7 +536,7 @@ class ErrorManager
|
|||
'date' => date(DATE_ATOM),
|
||||
'os' => PHP_OS,
|
||||
'language' => 'PHP ' . PHP_VERSION,
|
||||
'environment' => self::$enabled == self::DEVELOPMENT ? 'development' : 'production:' . self::$enabled,
|
||||
'environment' => self::$enabled & self::DEVELOPMENT ? 'development' : 'production:' . self::$enabled,
|
||||
'php_sapi' => PHP_SAPI,
|
||||
'remote_ip' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : null,
|
||||
'http_method' => isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : null,
|
||||
|
@ -718,6 +734,8 @@ class ErrorManager
|
|||
/**
|
||||
* Enable error manager
|
||||
* @param integer $type Type of error management (ErrorManager::PRODUCTION or ErrorManager::DEVELOPMENT)
|
||||
* You can also use ErrorManager::PRODUCTION | ErrorManager::CLI_DEVELOPMENT to get error messages in CLI but still hide errors
|
||||
* on web front-end.
|
||||
* @return void
|
||||
*/
|
||||
static public function enable($type = self::DEVELOPMENT)
|
||||
|
@ -734,9 +752,9 @@ class ErrorManager
|
|||
ini_set('log_errors', false);
|
||||
ini_set('html_errors', false);
|
||||
ini_set('zend.exception_ignore_args', false); // We want to get the args in exceptions (since PHP 7.4)
|
||||
error_reporting($type == self::DEVELOPMENT ? -1 : E_ALL & ~E_DEPRECATED & ~E_STRICT);
|
||||
error_reporting($type & self::DEVELOPMENT ? -1 : E_ALL & ~E_DEPRECATED & ~E_STRICT);
|
||||
|
||||
if ($type == self::DEVELOPMENT && PHP_SAPI != 'cli')
|
||||
if ($type & self::DEVELOPMENT && PHP_SAPI != 'cli')
|
||||
{
|
||||
self::setHtmlHeader('<!DOCTYPE html><meta charset="utf-8" /><style type="text/css">
|
||||
body { font-family: sans-serif; } * { margin: 0; padding: 0; }
|
||||
|
@ -760,7 +778,7 @@ class ErrorManager
|
|||
|
||||
set_error_handler([__CLASS__, 'errorHandler']);
|
||||
|
||||
if ($type == self::DEVELOPMENT)
|
||||
if ($type & self::DEVELOPMENT)
|
||||
{
|
||||
self::startTimer('_global');
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ abstract class NextCloud
|
|||
self::PROP_NC_DDC,
|
||||
];
|
||||
|
||||
protected string $prefix = '';
|
||||
protected string $root_url;
|
||||
protected Server $server;
|
||||
protected AbstractStorage $storage;
|
||||
|
@ -326,6 +327,8 @@ abstract class NextCloud
|
|||
{
|
||||
$this->requireAuth();
|
||||
|
||||
$base_uri = null;
|
||||
|
||||
// Find out which route we are using and replace URI
|
||||
foreach (self::ROUTES as $route => $method) {
|
||||
if ($method != 'webdav') {
|
||||
|
@ -338,6 +341,10 @@ abstract class NextCloud
|
|||
}
|
||||
}
|
||||
|
||||
if (!$base_uri) {
|
||||
throw new Exception('Invalid WebDAV URL', 404);
|
||||
}
|
||||
|
||||
// Android app is using "/remote.php/dav/files/user//" as root
|
||||
// so let's alias that as well
|
||||
// ownCloud Android is requesting just /dav/files/
|
||||
|
@ -345,6 +352,8 @@ abstract class NextCloud
|
|||
$base_uri = $match[0];
|
||||
}
|
||||
|
||||
$this->server->prefix = $this->prefix;
|
||||
|
||||
$this->server->setBaseURI($base_uri);
|
||||
$this->server->route($uri);
|
||||
}
|
||||
|
|
|
@ -92,6 +92,11 @@ class Server
|
|||
*/
|
||||
public string $original_uri;
|
||||
|
||||
/**
|
||||
* Prefix, if you want to force some clients inside a path, eg. '/documents/'
|
||||
*/
|
||||
public string $prefix = '';
|
||||
|
||||
protected AbstractStorage $storage;
|
||||
|
||||
public function setStorage(AbstractStorage $storage)
|
||||
|
@ -109,6 +114,15 @@ class Server
|
|||
$this->base_uri = rtrim($uri, '/') . '/';
|
||||
}
|
||||
|
||||
protected function _prefix(string $uri): string
|
||||
{
|
||||
if (!$this->prefix) {
|
||||
return $uri;
|
||||
}
|
||||
|
||||
return rtrim(rtrim($this->prefix, '/') . '/' . ltrim($uri, '/'), '/');
|
||||
}
|
||||
|
||||
protected function html_directory(string $uri, iterable $list): ?string
|
||||
{
|
||||
// Not a file: let's serve a directory listing if you are browsing with a web browser
|
||||
|
@ -187,6 +201,8 @@ class Server
|
|||
throw new Exception('We can only delete to infinity', 400);
|
||||
}
|
||||
|
||||
$uri = $this->_prefix($uri);
|
||||
|
||||
$this->checkLock($uri);
|
||||
|
||||
$this->storage->delete($uri);
|
||||
|
@ -233,6 +249,8 @@ class Server
|
|||
$hash = bin2hex(base64_decode($_SERVER['HTTP_CONTENT_MD5']));
|
||||
}
|
||||
|
||||
$uri = $this->_prefix($uri);
|
||||
|
||||
$this->checkLock($uri);
|
||||
|
||||
if (!empty($_SERVER['HTTP_IF_MATCH'])) {
|
||||
|
@ -271,6 +289,8 @@ class Server
|
|||
|
||||
public function http_head(string $uri, array &$props = []): ?string
|
||||
{
|
||||
$uri = $this->_prefix($uri);
|
||||
|
||||
$requested_props = self::BASIC_PROPERTIES;
|
||||
$requested_props[] = 'DAV::getetag';
|
||||
|
||||
|
@ -325,6 +345,8 @@ class Server
|
|||
$props = [];
|
||||
$this->http_head($uri, $props);
|
||||
|
||||
$uri = $this->_prefix($uri);
|
||||
|
||||
$is_collection = !empty($props['DAV::resourcetype']) && $props['DAV::resourcetype'] == 'collection';
|
||||
$out = '';
|
||||
|
||||
|
@ -523,6 +545,8 @@ class Server
|
|||
|
||||
protected function _http_copymove(string $uri, string $method): ?string
|
||||
{
|
||||
$uri = $this->_prefix($uri);
|
||||
|
||||
$destination = $_SERVER['HTTP_DESTINATION'] ?? null;
|
||||
$depth = $_SERVER['HTTP_DEPTH'] ?? 1;
|
||||
|
||||
|
@ -581,6 +605,7 @@ class Server
|
|||
throw new Exception('Unsupported body for MKCOL', 415);
|
||||
}
|
||||
|
||||
$uri = $this->_prefix($uri);
|
||||
$this->storage->mkcol($uri);
|
||||
|
||||
http_response_code(201);
|
||||
|
@ -656,6 +681,7 @@ class Server
|
|||
// We only support depth of 0 and 1
|
||||
$depth = isset($_SERVER['HTTP_DEPTH']) && empty($_SERVER['HTTP_DEPTH']) ? 0 : 1;
|
||||
|
||||
$uri = $this->_prefix($uri);
|
||||
$body = file_get_contents('php://input');
|
||||
|
||||
if (false !== strpos($body, '<!DOCTYPE ')) {
|
||||
|
@ -756,7 +782,12 @@ class Server
|
|||
foreach ($items as $uri => $item) {
|
||||
$e = '<d:response>';
|
||||
|
||||
$path = '/' . str_replace('%2F', '/', rawurlencode(trim($this->base_uri . $uri, '/')));
|
||||
if ($this->prefix) {
|
||||
$uri = substr($uri, strlen($this->prefix));
|
||||
}
|
||||
|
||||
$uri = trim(rtrim($this->base_uri, '/') . '/' . ltrim($uri, '/'), '/');
|
||||
$path = '/' . str_replace('%2F', '/', rawurlencode($uri));
|
||||
|
||||
if (($item['DAV::resourcetype'] ?? null) == 'collection') {
|
||||
$path .= '/';
|
||||
|
@ -929,6 +960,7 @@ class Server
|
|||
|
||||
public function http_proppatch(string $uri): ?string
|
||||
{
|
||||
$uri = $this->_prefix($uri);
|
||||
$this->checkLock($uri);
|
||||
|
||||
$body = file_get_contents('php://input');
|
||||
|
@ -948,6 +980,7 @@ class Server
|
|||
|
||||
public function http_lock(string $uri): ?string
|
||||
{
|
||||
$uri = $this->_prefix($uri);
|
||||
// We don't use this currently, but maybe later?
|
||||
//$depth = !empty($this->_SERVER['HTTP_DEPTH']) ? 1 : 0;
|
||||
//$timeout = isset($_SERVER['HTTP_TIMEOUT']) ? explode(',', $_SERVER['HTTP_TIMEOUT']) : [];
|
||||
|
@ -1039,6 +1072,7 @@ class Server
|
|||
|
||||
public function http_unlock(string $uri): ?string
|
||||
{
|
||||
$uri = $this->_prefix($uri);
|
||||
$token = $this->getLockToken();
|
||||
|
||||
if (!$token) {
|
||||
|
@ -1169,6 +1203,7 @@ class Server
|
|||
}
|
||||
|
||||
$uri = substr($uri, strlen($this->base_uri));
|
||||
$uri = $this->_prefix($uri);
|
||||
return $uri;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,11 +51,11 @@ class Storage extends AbstractStorage
|
|||
|
||||
public function list(string $uri, ?array $properties): iterable
|
||||
{
|
||||
$dirs = glob($this->users->current()->path . $uri . '/*', \GLOB_ONLYDIR);
|
||||
$dirs = self::glob($this->users->current()->path . $uri, '/*', \GLOB_ONLYDIR);
|
||||
$dirs = array_map('basename', $dirs);
|
||||
natcasesort($dirs);
|
||||
|
||||
$files = glob($this->users->current()->path . $uri . '/*');
|
||||
$files = self::glob($this->users->current()->path . $uri, '/*');
|
||||
$files = array_map('basename', $files);
|
||||
$files = array_diff($files, $dirs);
|
||||
natcasesort($files);
|
||||
|
@ -291,7 +291,7 @@ class Storage extends AbstractStorage
|
|||
}
|
||||
|
||||
if (is_dir($target)) {
|
||||
foreach (glob($target . '/*') as $file) {
|
||||
foreach (self::glob($target, '/*') as $file) {
|
||||
$this->delete(substr($file, strlen($this->users->current()->path)));
|
||||
}
|
||||
|
||||
|
@ -421,12 +421,18 @@ class Storage extends AbstractStorage
|
|||
return;
|
||||
}
|
||||
|
||||
static protected function glob(string $path, string $pattern = '', int $flags = 0): array
|
||||
{
|
||||
$path = preg_replace('/[\*\?\[\]]/', '\\\\$0', $path);
|
||||
return glob($path . $pattern, $flags);
|
||||
}
|
||||
|
||||
static public function getDirectorySize(string $path): int
|
||||
{
|
||||
$total = 0;
|
||||
$path = rtrim($path, '/');
|
||||
|
||||
foreach (glob($path . '/*', GLOB_NOSORT) as $f) {
|
||||
foreach (self::glob($path, '/*', GLOB_NOSORT) as $f) {
|
||||
if (is_dir($f)) {
|
||||
$total += self::getDirectorySize($f);
|
||||
}
|
||||
|
@ -440,7 +446,7 @@ class Storage extends AbstractStorage
|
|||
|
||||
static public function deleteDirectory(string $path): void
|
||||
{
|
||||
foreach (glob($path . '/*', GLOB_NOSORT) as $f) {
|
||||
foreach (self::glob($path, '/*', GLOB_NOSORT) as $f) {
|
||||
if (is_dir($f)) {
|
||||
self::deleteDirectory($f);
|
||||
@rmdir($f);
|
||||
|
@ -458,7 +464,7 @@ class Storage extends AbstractStorage
|
|||
$last = 0;
|
||||
$path = rtrim($path, '/');
|
||||
|
||||
foreach (glob($path . '/*', GLOB_NOSORT) as $f) {
|
||||
foreach (self::glob($path, '/*', GLOB_NOSORT) as $f) {
|
||||
if (is_dir($f)) {
|
||||
$m = self::getDirectoryMTime($f);
|
||||
|
||||
|
|
Loading…
Reference in a new issue