aboutsummaryrefslogtreecommitdiffstats
path: root/core/Controller/AsyncProcessController.php
diff options
context:
space:
mode:
Diffstat (limited to 'core/Controller/AsyncProcessController.php')
-rw-r--r--core/Controller/AsyncProcessController.php77
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();
+ }
+
+}