aboutsummaryrefslogtreecommitdiff
path: root/p/api/misc.php
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2025-06-03 00:16:17 +0200
committerGravatar GitHub <noreply@github.com> 2025-06-03 00:16:17 +0200
commitcc35094bb261cb3185def89d745317fa756560ee (patch)
tree0d94bbd1dfe1013101dd96b8dbfa975d275ddf7b /p/api/misc.php
parent430d4e898e60ec1892d7191cf6e039aaf693822f (diff)
Add API endpoint for extensions (#7576)
* Add API endpoint for extensions Useful for https://github.com/FreshRSS/FreshRSS/issues/7572 * Support PATH_INFO Now also support being invoked like `/api/misc.php/Extension%20Name/` * More documentation
Diffstat (limited to 'p/api/misc.php')
-rw-r--r--p/api/misc.php68
1 files changed, 68 insertions, 0 deletions
diff --git a/p/api/misc.php b/p/api/misc.php
new file mode 100644
index 000000000..7724caa7a
--- /dev/null
+++ b/p/api/misc.php
@@ -0,0 +1,68 @@
+<?php
+declare(strict_types=1);
+/**
+ * API entry point for FreshRSS extensions on
+ * `/api/misc.php/Extension%20name/` or `/api/misc.php?ext=Extension%20name`
+ */
+
+require(__DIR__ . '/../../constants.php');
+require(LIB_PATH . '/lib_rss.php'); //Includes class autoloader
+
+function badRequest(): never {
+ header('HTTP/1.1 400 Bad Request');
+ header('Content-Type: text/plain; charset=UTF-8');
+ die('Bad Request!');
+}
+
+function serviceUnavailable(): never {
+ header('HTTP/1.1 503 Service Unavailable');
+ header('Content-Type: text/plain; charset=UTF-8');
+ die('Service Unavailable!');
+}
+
+$extensionName = is_string($_GET['ext'] ?? null) ? $_GET['ext'] : '';
+
+if ($extensionName === '') {
+ $pathInfo = '';
+ if (empty($_SERVER['PATH_INFO']) || !is_string($_SERVER['PATH_INFO'] ?? null)) {
+ if (!empty($_SERVER['ORIG_PATH_INFO']) && is_string($_SERVER['ORIG_PATH_INFO'])) {
+ // Compatibility https://php.net/reserved.variables.server
+ $pathInfo = $_SERVER['ORIG_PATH_INFO'];
+ }
+ } else {
+ $pathInfo = $_SERVER['PATH_INFO'];
+ }
+ $pathInfo = rawurldecode($pathInfo);
+ $pathInfo = preg_replace('%^(/api)?(/misc\.php)?%', '', $pathInfo); //Discard common errors
+ if ($pathInfo !== '' && is_string($pathInfo)) {
+ $pathInfos = explode('/', $pathInfo, limit: 3);
+ if (count($pathInfos) > 1) {
+ $extensionName = $pathInfos[1];
+ }
+ }
+}
+
+if ($extensionName === '') {
+ badRequest();
+}
+
+Minz_Session::init('FreshRSS', volatile: true);
+
+FreshRSS_Context::initSystem();
+if (
+ !FreshRSS_Context::hasSystemConf() ||
+ !FreshRSS_Context::systemConf()->api_enabled ||
+ empty(FreshRSS_Context::systemConf()->extensions_enabled[$extensionName])
+) {
+ serviceUnavailable();
+}
+
+// Only enable the extension that is being called
+FreshRSS_Context::systemConf()->extensions_enabled = [$extensionName => true];
+Minz_ExtensionManager::init();
+
+Minz_Translate::init();
+
+if (!Minz_ExtensionManager::callHookUnique('api_misc')) {
+ serviceUnavailable();
+}