diff options
author | Maxence Lange <maxence@artificial-owl.com> | 2025-04-28 19:57:56 -0100 |
---|---|---|
committer | Maxence Lange <maxence@artificial-owl.com> | 2025-04-28 19:58:06 -0100 |
commit | 6d272ff894fa969e5a526caf6a91d60eda115c53 (patch) | |
tree | df90f826a29f7169dd9b550f2e478a1b09d29e71 /core/Controller/AsyncProcessController.php | |
parent | 10a01423ecfc7e028960eee8058bd177ad28d484 (diff) | |
download | nextcloud-server-enh/noid/async-process-run.tar.gz nextcloud-server-enh/noid/async-process-run.zip |
feat(async): AsyncProcessenh/noid/async-process-run
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
Diffstat (limited to 'core/Controller/AsyncProcessController.php')
-rw-r--r-- | core/Controller/AsyncProcessController.php | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/core/Controller/AsyncProcessController.php b/core/Controller/AsyncProcessController.php new file mode 100644 index 00000000000..f644e3a7851 --- /dev/null +++ b/core/Controller/AsyncProcessController.php @@ -0,0 +1,77 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OC\Core\Controller; + +use OC\Async\Exceptions\BlockAlreadyRunningException; +use OC\Async\ForkManager; +use OC\Config\Lexicon\CoreConfigLexicon; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\Attribute\FrontpageRoute; +use OCP\AppFramework\Http\Attribute\NoAdminRequired; +use OCP\AppFramework\Http\Attribute\NoCSRFRequired; +use OCP\AppFramework\Http\Attribute\PublicPage; +use OCP\AppFramework\Http\DataResponse; +use OCP\Async\Enum\ProcessExecutionTime; +use OCP\IAppConfig; +use OCP\IRequest; + +class AsyncProcessController extends Controller { + public function __construct( + string $appName, + IRequest $request, + private IAppConfig $appConfig, + private ForkManager $forkManager, + ) { + parent::__construct($appName, $request); + } + + #[NoAdminRequired] + #[NoCSRFRequired] + #[PublicPage] + #[FrontpageRoute(verb: 'POST', url: '/core/asyncProcessFork')] + public function processFork(string $token): DataResponse { + $metadata = ['executionTime' => ProcessExecutionTime::NOW]; + + // remote might only need a confirmation that this is a valid loopback endpoint + if ($token === '__ping__') { + return new DataResponse(['ping' => $this->appConfig->getValueString('core', CoreConfigLexicon::ASYNC_LOOPBACK_PING)]); + } + + $this->async($token); + + try { + $this->forkManager->runSession($token, $metadata); + } catch (BlockAlreadyRunningException) { + // TODO: debug() ? + } + + exit(); + } + + private function async(string $result = ''): void { + if (ob_get_contents() !== false) { + ob_end_clean(); + } + + header('Connection: close'); + header('Content-Encoding: none'); + ignore_user_abort(); + $timeLimit = 100; + set_time_limit(max($timeLimit, 0)); + ob_start(); + + echo($result); + + $size = ob_get_length(); + header('Content-Length: ' . $size); + ob_end_flush(); + flush(); + } + +} |