diff --git a/Caddyfile b/Caddyfile index 919c0bfd3fc21..f4c0ff26a7391 100644 --- a/Caddyfile +++ b/Caddyfile @@ -8,6 +8,7 @@ frankenphp { max_threads auto max_requests 100 + php_ini memory_limit 512M worker { num 2 @@ -19,7 +20,7 @@ watch core/**/*.php watch 3rdparty/**/*.php watch *.php - + match /index.php/* max_consecutive_failures -1 } @@ -55,7 +56,6 @@ {$SERVER_NAME:localhost} { php_server { - } log { diff --git a/lib/OC.php b/lib/OC.php index 725e945219d47..3404cf982c1ef 100644 --- a/lib/OC.php +++ b/lib/OC.php @@ -779,7 +779,14 @@ public static function initForRequest(): void { self::handleAuthHeaders(); // setup the basic server - self::$server = new \OC\Server(\OC::$WEBROOT, self::$config); + /** @psalm-suppress RedundantPropertyInitializationCheck The server is first initialized here */ + if (!isset(self::$server)) { + self::$server = new \OC\Server(\OC::$WEBROOT, self::$config); + } else { + set_exception_handler(null); + set_error_handler(null); + self::$server->reset(); + } self::$server->boot(); self::oneTimeChecks(); @@ -825,7 +832,7 @@ public static function initForRequest(): void { } else { set_error_handler([$errorHandler, 'onError']); } - register_shutdown_function([$errorHandler, 'onShutdown']); + self::$server->registerShutdownFunction($errorHandler->onShutdown(...)); set_exception_handler($exceptionHandler); } @@ -924,11 +931,8 @@ public static function initForRequest(): void { $appManager->loadApp('settings'); } - //make sure temporary files are cleaned up - $tmpManager = Server::get(\OCP\ITempManager::class); - register_shutdown_function([$tmpManager, 'clean']); $lockProvider = Server::get(\OCP\Lock\ILockingProvider::class); - register_shutdown_function([$lockProvider, 'releaseAll']); + self::$server->registerShutdownFunction($lockProvider->releaseAll(...)); $host = $request->getInsecureServerHost(); /** @@ -974,11 +978,11 @@ public static function initForRequest(): void { $eventLogger->log('init', 'OC::init', $loaderStart, microtime(true)); $eventLogger->start('runtime', 'Runtime'); $eventLogger->start('request', 'Full request after boot'); - register_shutdown_function(function () use ($eventLogger) { + self::$server->registerShutdownFunction(static function () use ($eventLogger) { $eventLogger->end('request'); }); - register_shutdown_function(function () use ($config) { + self::$server->registerShutdownFunction(static function () use ($config) { $memoryPeak = memory_get_peak_usage(); $debugModeEnabled = $config->getSystemValueBool('debug', false); $memoryLimit = null; diff --git a/lib/private/Server.php b/lib/private/Server.php index 9d6dde25f4220..f6187e28e58d4 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -306,12 +306,28 @@ * TODO: hookup all manager classes */ class Server extends ServerContainer { + private array $shutdownFunctions = []; + public function __construct( private string $webRoot, - Config $config, + private Config $config, ) { parent::__construct(); + $this->runInitialRegistrations(); + + register_shutdown_function($this->shutdown(...)); + } + + /** + * Empty container and re-run initial registration + */ + public function reset(): void { + $this->shutdown(); + parent::__construct(); + $this->runInitialRegistrations(); + } + public function runInitialRegistrations(): void { // To find out if we are running from CLI or not $this->registerParameter('isCLI', \OC::$CLI); $this->registerParameter('serverRoot', \OC::$SERVERROOT); @@ -472,7 +488,7 @@ public function __construct( $this->registerAlias(IConfig::class, AllConfig::class); - $this->registerService(SystemConfig::class, static fn ($c) => new SystemConfig($config)); + $this->registerService(SystemConfig::class, fn ($c) => new SystemConfig($this->config)); $this->registerAlias(IAppConfig::class, \OC\AppConfig::class); $this->registerAlias(IUserConfig::class, UserConfig::class); @@ -1145,4 +1161,15 @@ public function setSession(ISession $session): void { public function getWebRoot(): string { return $this->webRoot; } + + public function registerShutdownFunction(callable $function): void { + $this->shutdownFunctions[] = $function; + } + + public function shutdown(): void { + foreach ($this->shutdownFunctions as $shutdownFunction) { + $shutdownFunction(); + } + $this->shutdownFunctions = []; + } } diff --git a/lib/private/TempManager.php b/lib/private/TempManager.php index fa7f891ca9272..c2d0da9a3d027 100644 --- a/lib/private/TempManager.php +++ b/lib/private/TempManager.php @@ -33,6 +33,10 @@ public function __construct( $this->tmpBaseDir = $this->getTempBaseDir(); } + public function __destruct() { + $this->clean(); + } + private function generateTemporaryPath(string $postFix): string { $secureRandom = Server::get(ISecureRandom::class); $absolutePath = $this->tmpBaseDir . '/' . self::TMP_PREFIX . $secureRandom->generate(32, ISecureRandom::CHAR_ALPHANUMERIC); @@ -93,6 +97,7 @@ public function getTemporaryFolder($postFix = ''): string|false { #[\Override] public function clean() { $this->cleanFiles($this->current); + $this->current = []; } /** diff --git a/tests/lib/TempManagerTest.php b/tests/lib/TempManagerTest.php index 06a43930e919f..2d5748217b17d 100644 --- a/tests/lib/TempManagerTest.php +++ b/tests/lib/TempManagerTest.php @@ -173,7 +173,8 @@ public function testGenerateTemporaryPathTraversal(): void { } public function testGetTempBaseDirFromConfig(): void { - $dir = $this->getManager()->getTemporaryFolder(); + $manager1 = $this->getManager(); + $dir = $manager1->getTemporaryFolder(); $config = $this->createMock(IConfig::class); $config->expects($this->once())