1
1
Fork 0
mirror of https://code.mensbeam.com/MensBeam/Arsse.git synced 2024-12-22 21:22:40 +00:00

Fail gracefully when extensions are missing

This still needs tests
This commit is contained in:
J. King 2021-07-03 12:38:48 -04:00
parent c9a2393a4e
commit c49cb72528
4 changed files with 25 additions and 3 deletions

View file

@ -8,6 +8,15 @@ namespace JKingWeb\Arsse;
class Arsse { class Arsse {
public const VERSION = "0.9.2"; public const VERSION = "0.9.2";
public const REQUIRED_EXTENSIONS = [
"intl", // as this extension is required to prepare formatted messages, its absence will throw a distinct English-only exception
"dom",
"filter",
"json", // part of the PHP core since version 8.0
"hash", // part of the PHP core since version 7.4
"simplexml", // required by PicoFeed only
"iconv", // required by PicoFeed only
];
/** @var Factory */ /** @var Factory */
public static $obj; public static $obj;
@ -29,6 +38,7 @@ class Arsse {
static::$user = static::$user ?? new User; static::$user = static::$user ?? new User;
} }
/** Checks whether the specified extensions are loaded and throws an exception if any are not */
public static function checkExtensions(string ...$ext): void { public static function checkExtensions(string ...$ext): void {
$missing = []; $missing = [];
foreach ($ext as $e) { foreach ($ext as $e) {

View file

@ -80,11 +80,15 @@ USAGE_TEXT;
'help' => false, 'help' => false,
]); ]);
try { try {
// ensure the require extensions are loaded
Arsse::checkExtensions(...Arsse::REQUIRED_EXTENSIONS);
// reconstitute multi-token commands (e.g. user add) into a single string
$cmd = $this->command($args); $cmd = $this->command($args);
if ($cmd && !in_array($cmd, ["", "conf save-defaults", "daemon"])) { if ($cmd && !in_array($cmd, ["", "conf save-defaults", "daemon"])) {
// only certain commands don't require configuration to be loaded; daemon loads configuration after forking (if applicable) // only certain commands don't require configuration to be loaded; daemon loads configuration after forking (if applicable)
$this->loadConf(); $this->loadConf();
} }
// run the requested command
switch ($cmd) { switch ($cmd) {
case "": case "":
if ($args['--version']) { if ($args['--version']) {

View file

@ -80,10 +80,12 @@ class REST {
} }
public function dispatch(ServerRequestInterface $req = null): ResponseInterface { public function dispatch(ServerRequestInterface $req = null): ResponseInterface {
// create a request object if not provided
$req = $req ?? ServerRequestFactory::fromGlobals();
// find the API to handle
try { try {
// ensure the require extensions are loaded
Arsse::checkExtensions(...Arsse::REQUIRED_EXTENSIONS);
// create a request object if not provided
$req = $req ?? ServerRequestFactory::fromGlobals();
// find the API to handle
[$api, $target, $class] = $this->apiMatch($req->getRequestTarget(), $this->apis); [$api, $target, $class] = $this->apiMatch($req->getRequestTarget(), $this->apis);
// authenticate the request pre-emptively // authenticate the request pre-emptively
$req = $this->authenticateRequest($req); $req = $this->authenticateRequest($req);

View file

@ -7,9 +7,15 @@ declare(strict_types=1);
namespace JKingWeb\Arsse\Service; namespace JKingWeb\Arsse\Service;
use JKingWeb\Arsse\AbstractException; use JKingWeb\Arsse\AbstractException;
use JKingWeb\Arsse\Arsse;
class Daemon { class Daemon {
protected const PID_PATTERN = '/^([1-9]\d{0,77})?$/D'; // no more than 78 digits (256-bit unsigned integer), starting with a digit other than zero protected const PID_PATTERN = '/^([1-9]\d{0,77})?$/D'; // no more than 78 digits (256-bit unsigned integer), starting with a digit other than zero
protected const REQUIRED_EXTENSIONS = ["posix", "pcntl"];
public function __construct() {
Arsse::checkExtensions(...self::REQUIRED_EXTENSIONS);
}
/** Daemonizes the process via the traditional sysvinit double-fork procedure /** Daemonizes the process via the traditional sysvinit double-fork procedure
* *