diff --git a/src/_h5ai/client/js/inc/boot.js b/src/_h5ai/client/js/inc/boot.js index 70f595d7..4efaf837 100644 --- a/src/_h5ai/client/js/inc/boot.js +++ b/src/_h5ai/client/js/inc/boot.js @@ -11,7 +11,7 @@ modulejs.define('boot', ['$'], function ($) { if (module === 'index') { href = '.'; } else if (module === 'info') { - data.updatecmds = true; + data.updateCachedSetup = true; href = 'server/php/index.php'; } else { return; diff --git a/src/_h5ai/client/js/inc/main/info.js b/src/_h5ai/client/js/inc/main/info.js index 9850eda9..77257722 100644 --- a/src/_h5ai/client/js/inc/main/info.js +++ b/src/_h5ai/client/js/inc/main/info.js @@ -62,7 +62,7 @@ modulejs.define('main/info', ['$', 'config'], function ($, config) { addTest( 'PHP version', 'PHP version >= ' + setup.MIN_PHP_VERSION, - setup.HAS_MIN_PHP_VERSION, setup.PHP_VERSION + true, setup.PHP_VERSION ); addTest( diff --git a/src/_h5ai/server/php/config.php b/src/_h5ai/server/php/config.php index 11267288..ac02526f 100644 --- a/src/_h5ai/server/php/config.php +++ b/src/_h5ai/server/php/config.php @@ -1,8 +1,7 @@ basepath = $basepath; + $this->classpaths = ["/inc", "/inc/core", "/inc/ext"]; } public function run() { spl_autoload_register([$this, "autoload"]); + putenv("LANG=en_US.UTF-8"); + setlocale(LC_CTYPE, "en_US.UTF-8"); + date_default_timezone_set(@date_default_timezone_get()); + session_start(); + + $request_method = getenv("REQUEST_METHOD"); + $request_uri = getenv("REQUEST_URI"); + $script_name = getenv("SCRIPT_NAME"); + $server_software = getenv("SERVER_SOFTWARE"); $this->once("config"); - $this->setup_php(); - $this->setup_app(); - $this->setup_admin(); - $this->setup_server(); - $this->setup_paths(); - $this->setup_cache(); - $this->setup_cmds(); - $app = new App(); - if (Util::is_post_request()) { - $api = new Api($app); - $api->apply(); + $request = new Request($_REQUEST); + $setup = new Setup($request->query_boolean("updateCachedSetup", false), $_ENV); + $app = new App($request, $setup); + + if (strtolower(getenv("REQUEST_METHOD")) === "post") { + (new Api($app))->apply(); } else { - $fallback = new Fallback($app); - define("FALLBACK", $fallback->get_html()); + // (new Page($app))->apply(); + // define("PAGE_APP_HREF", $setup->get("APP_HREF")); + // define("PAGE_FALLBACK", (new Fallback($app))->get_html()); + define("APP_HREF", $setup->get("APP_HREF")); + define("FALLBACK", (new Fallback($app))->get_html()); $this->once("inc/page"); } } @@ -39,8 +46,8 @@ class Bootstrap { $filename = "class-" . strtolower($class_name) . ".php"; - foreach (Bootstrap::$classpaths as $path) { - $file = $this->basepath . $path . "/" . $filename; + foreach ($this->classpaths as $classpath) { + $file = $this->basepath . $classpath . "/" . $filename; if (file_exists($file)) { require_once($file); return true; @@ -52,101 +59,4 @@ class Bootstrap { require_once($this->basepath . "/" . $lib . ".php"); } - - private function setup_php() { - - putenv("LANG=en_US.UTF-8"); - setlocale(LC_CTYPE, "en_US.UTF-8"); - date_default_timezone_set(@date_default_timezone_get()); - - define("HAS_PHP_EXIF", function_exists("exif_thumbnail")); - $has_php_jpeg = false; - if (function_exists("gd_info")) { - $infos = gd_info(); - $has_php_jpeg = array_key_exists("JPEG Support", $infos) && $infos["JPEG Support"]; - } - define("HAS_PHP_JPEG", $has_php_jpeg); - } - - private function setup_app() { - - define("NAME", "{{pkg.name}}"); - define("VERSION", "{{pkg.version}}"); - define("FILE_PREFIX", "_{{pkg.name}}"); - } - - private function setup_admin() { - - session_start(); - define("AS_ADMIN_SESSION_KEY", "__H5AI_AS_ADMIN__"); - define("AS_ADMIN", isset($_SESSION[AS_ADMIN_SESSION_KEY]) && $_SESSION[AS_ADMIN_SESSION_KEY] === true); - define("HAS_CUSTOM_PASSHASH", strcasecmp(PASSHASH, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e") !== 0); - } - - private function setup_server() { - - $server_name = null; - $server_version = null; - $server_software = getenv("SERVER_SOFTWARE"); - if ($server_software && preg_match("#^(.*?)(?:/(.*?))?(?: |$)#", strtolower($server_software), $matches)) { - $server_name = $matches[1]; - $server_version = count($matches) > 2 ? $matches[2] : ''; - } - define("SERVER_NAME", $server_name); - define("SERVER_VERSION", $server_version); - define("HAS_SERVER", in_array($server_name, ["apache", "lighttpd", "nginx", "cherokee"])); - } - - private function setup_paths() { - - $script_name = getenv("SCRIPT_NAME"); - if (SERVER_NAME === "lighttpd") { - $script_name = preg_replace("#^.*?//#", "/", $script_name); - } - define("APP_HREF", Util::normalize_path(dirname(dirname(dirname($script_name))), true)); - define("APP_PATH", Util::normalize_path(dirname(dirname(dirname(dirname(__FILE__)))), false)); - - define("ROOT_HREF", Util::normalize_path(dirname(APP_HREF), true)); - define("ROOT_PATH", Util::normalize_path(dirname(APP_PATH), false)); - - $index_href = null; - if (@is_readable(Util::normalize_path(APP_PATH . "/server/php/index.php", false))) { - $index_href = Util::normalize_path(APP_HREF . "/server/php/index.php", false); - } - define("INDEX_HREF", $index_href); - } - - private function setup_cache() { - - define("CACHE_HREF", Util::normalize_path(APP_HREF . "/cache", true)); - define("CACHE_PATH", Util::normalize_path(APP_PATH . "/cache", false)); - define("HAS_WRITABLE_CACHE", @is_writable(CACHE_PATH)); - } - - private function setup_cmds() { - - define("CMDS_PATH", Util::normalize_path(CACHE_PATH . "/cmds.json", false)); - - $cmds = Util::load_commented_json(CMDS_PATH); - if (sizeof($cmds) === 0 || Util::query_boolean_request_param("updatecmds", false)) { - $cmds["command"] = Util::exec_0("command -v command"); - $cmds["which"] = Util::exec_0("which which"); - - $cmd = false; - if ($cmds["command"]) { - $cmd = "command -v"; - } else if ($cmds["which"]) { - $cmd = "which"; - } - - foreach (["avconv", "convert", "du", "ffmpeg", "tar", "zip"] as $c) { - $cmds[$c] = ($cmd !== false) && Util::exec_0($cmd . " " . $c); - } - - Util::save_json(CMDS_PATH, $cmds); - } - foreach ($cmds as $c => $has) { - define("HAS_CMD_" . strtoupper($c), $has); - } - } } diff --git a/src/_h5ai/server/php/inc/core/class-api.php b/src/_h5ai/server/php/inc/core/class-api.php index fb635398..69d320b8 100644 --- a/src/_h5ai/server/php/inc/core/class-api.php +++ b/src/_h5ai/server/php/inc/core/class-api.php @@ -2,18 +2,20 @@ class Api { + private $request; + private $setup; private $app; - public function __construct($app) { + $this->request = $app->get_request(); + $this->setup = $app->get_setup(); $this->app = $app; } - public function apply() { - $action = Util::query_request_param("action"); + $action = $this->request->query("action"); $supported = ["download", "get", "login", "logout"]; Util::json_fail(Util::ERR_UNSUPPORTED, "unsupported action", !in_array($action, $supported)); @@ -21,15 +23,14 @@ class Api { $this->$methodname(); } - private function on_download() { Util::json_fail(Util::ERR_DISABLED, "download disabled", !$this->app->query_option("download.enabled", false)); - $as = Util::query_request_param("as"); - $type = Util::query_request_param("type"); - $base_href = Util::query_request_param("baseHref"); - $hrefs = Util::query_request_param("hrefs"); + $as = $this->request->query("as"); + $type = $this->request->query("type"); + $base_href = $this->request->query("baseHref"); + $hrefs = $this->request->query("hrefs"); $archive = new Archive($this->app); @@ -43,66 +44,70 @@ class Api { exit; } - private function on_get() { $response = []; - foreach (["langs", "options", "setup", "types"] as $name) { - if (Util::query_boolean_request_param($name, false)) { + foreach (["langs", "options", "types"] as $name) { + if ($this->request->query_boolean($name, false)) { $methodname = "get_${name}"; $response[$name] = $this->app->$methodname(); } } - if (Util::query_boolean_request_param("theme", false)) { + if ($this->request->query_boolean("setup", false)) { + + $response["setup"] = $this->setup->to_jsono(); + } + + if ($this->request->query_boolean("theme", false)) { $theme = new Theme($this->app); $response["theme"] = $theme->get_icons(); } - if (Util::query_request_param("items", false)) { + if ($this->request->query("items", false)) { - $href = Util::query_request_param("items.href"); - $what = Util::query_numeric_request_param("items.what"); + $href = $this->request->query("items.href"); + $what = $this->request->query_numeric("items.what"); $response["items"] = $this->app->get_items($href, $what); } - if (Util::query_request_param("custom", false)) { + if ($this->request->query("custom", false)) { Util::json_fail(Util::ERR_DISABLED, "custom disabled", !$this->app->query_option("custom.enabled", false)); - $href = Util::query_request_param("custom"); + $href = $this->request->query("custom"); $custom = new Custom($this->app); $response["custom"] = $custom->get_customizations($href); } - if (Util::query_request_param("l10n", false)) { + if ($this->request->query("l10n", false)) { Util::json_fail(Util::ERR_DISABLED, "l10n disabled", !$this->app->query_option("l10n.enabled", false)); - $iso_codes = Util::query_array_request_param("l10n"); + $iso_codes = $this->request->query_array("l10n"); $iso_codes = array_filter($iso_codes); $response["l10n"] = $this->app->get_l10n($iso_codes); } - if (Util::query_request_param("search", false)) { + if ($this->request->query("search", false)) { Util::json_fail(Util::ERR_DISABLED, "search disabled", !$this->app->query_option("search.enabled", false)); - $href = Util::query_request_param("search.href"); - $pattern = Util::query_request_param("search.pattern"); + $href = $this->request->query("search.href"); + $pattern = $this->request->query("search.pattern"); $search = new Search($this->app); $response["search"] = $search->get_items($href, $pattern); } - if (Util::query_request_param("thumbs", false)) { + if ($this->request->query("thumbs", false)) { Util::json_fail(Util::ERR_DISABLED, "thumbnails disabled", !$this->app->query_option("thumbnails.enabled", false)); - Util::json_fail(Util::ERR_UNSUPPORTED, "thumbnails not supported", !HAS_PHP_JPEG); - $thumbs = Util::query_array_request_param("thumbs"); + Util::json_fail(Util::ERR_UNSUPPORTED, "thumbnails not supported", !$this->setup->get("HAS_PHP_JPEG")); + $thumbs = $this->request->query_array("thumbs"); $response["thumbs"] = $this->app->get_thumbs($thumbs); } @@ -110,18 +115,14 @@ class Api { Util::json_exit($response); } - private function on_login() { - $pass = Util::query_request_param("pass"); - $_SESSION[AS_ADMIN_SESSION_KEY] = strcasecmp(hash("sha512", $pass), PASSHASH) === 0; - Util::json_exit(["asAdmin" => $_SESSION[AS_ADMIN_SESSION_KEY]]); + $pass = $this->request->query("pass"); + Util::json_exit(["asAdmin" => $this->app->login_admin($pass)]); } - private function on_logout() { - $_SESSION[AS_ADMIN_SESSION_KEY] = false; - Util::json_exit(["asAdmin" => $_SESSION[AS_ADMIN_SESSION_KEY]]); + Util::json_exit(["asAdmin" => $this->app->logout_admin()]); } } diff --git a/src/_h5ai/server/php/inc/core/class-app.php b/src/_h5ai/server/php/inc/core/class-app.php index 015a6d9d..e007fc1f 100644 --- a/src/_h5ai/server/php/inc/core/class-app.php +++ b/src/_h5ai/server/php/inc/core/class-app.php @@ -2,80 +2,62 @@ class App { + private $request; + private $setup; private $options; + public function __construct($request, $setup) { - public function __construct() { - - $this->options = Util::load_commented_json(APP_PATH . "/conf/options.json"); + $this->request = $request; + $this->setup = $setup; + $this->options = Util::load_commented_json($this->setup->get("APP_PATH") . "/conf/options.json"); } + public function get_request() { + + return $this->request; + } + + public function get_setup() { + + return $this->setup; + } public function get_options() { return $this->options; } - public function query_option($keypath = "", $default = null) { return Util::array_query($this->options, $keypath, $default); } - - public function get_setup() { - - $keys = [ - "APP_HREF", - "ROOT_HREF", - "VERSION", - - "AS_ADMIN", - "HAS_CUSTOM_PASSHASH" - ]; - - if (AS_ADMIN) { - $keys = array_merge($keys, [ - "PHP_VERSION", - "MIN_PHP_VERSION", - "HAS_MIN_PHP_VERSION", - "HAS_PHP_EXIF", - "HAS_PHP_JPEG", - - "SERVER_NAME", - "SERVER_VERSION", - "HAS_SERVER", - - "INDEX_HREF", - - "HAS_WRITABLE_CACHE", - - "HAS_CMD_AVCONV", - "HAS_CMD_CONVERT", - "HAS_CMD_DU", - "HAS_CMD_FFMPEG", - "HAS_CMD_TAR", - "HAS_CMD_ZIP" - ]); - } - - $setup = []; - foreach ($keys as $key) { - $setup[$key] = constant($key); - } - return $setup; - } - - public function get_types() { - return Util::load_commented_json(APP_PATH . "/conf/types.json"); + return Util::load_commented_json($this->setup->get("APP_PATH") . "/conf/types.json"); } + public function login_admin($pass) { + + $key = $this->setup->get("AS_ADMIN_SESSION_KEY"); + $hash = $this->setup->get("PASSHASH"); + + $_SESSION[$key] = strcasecmp(hash("sha512", $pass), $hash) === 0; + return $_SESSION[$key]; + } + + public function logout_admin() { + + $key = $this->setup->get("AS_ADMIN_SESSION_KEY"); + + $_SESSION[$key] = false; + return $_SESSION[$key]; + } public function to_href($path, $trailing_slash = true) { - $rel_path = substr($path, strlen(ROOT_PATH)); + $rel_path = substr($path, strlen($this->setup->get("ROOT_PATH"))); $parts = explode("/", $rel_path); $encoded_parts = []; foreach ($parts as $part) { @@ -84,17 +66,15 @@ class App { } } - return Util::normalize_path(ROOT_HREF . implode("/", $encoded_parts), $trailing_slash); + return Util::normalize_path($this->setup->get("ROOT_HREF") . implode("/", $encoded_parts), $trailing_slash); } - public function to_path($href) { - $rel_href = substr($href, strlen(ROOT_HREF)); - return Util::normalize_path(ROOT_PATH . "/" . rawurldecode($rel_href)); + $rel_href = substr($href, strlen($this->setup->get("ROOT_HREF"))); + return Util::normalize_path($this->setup->get("ROOT_PATH") . "/" . rawurldecode($rel_href)); } - public function is_hidden($name) { // always hide @@ -112,7 +92,6 @@ class App { return false; } - public function read_dir($path) { $names = []; @@ -131,20 +110,18 @@ class App { return $names; } - public function is_managed_href($href) { return $this->is_managed_path($this->to_path($href)); } - public function is_managed_path($path) { if (!is_dir($path) || strpos($path, '../') !== false || strpos($path, '/..') !== false || $path === '..') { return false; } - if ($path === APP_PATH || strpos($path, APP_PATH . '/') === 0) { + if ($path === $this->setup->get("APP_PATH") || strpos($path, $this->setup->get("APP_PATH") . '/') === 0) { return false; } @@ -154,7 +131,7 @@ class App { } } - while ($path !== ROOT_PATH) { + while ($path !== $this->setup->get("ROOT_PATH")) { if (@is_dir($path . "/_h5ai/server")) { return false; } @@ -167,7 +144,6 @@ class App { return true; } - public function get_items($href, $what) { if (!$this->is_managed_href($href)) { @@ -200,11 +176,10 @@ class App { return $result; } - public function get_langs() { $langs = []; - $l10n_path = APP_PATH . "/conf/l10n"; + $l10n_path = $this->setup->get("APP_PATH") . "/conf/l10n"; if (is_dir($l10n_path)) { if ($dir = opendir($l10n_path)) { while (($file = readdir($dir)) !== false) { @@ -220,13 +195,12 @@ class App { return $langs; } - public function get_l10n($iso_codes) { $results = []; foreach ($iso_codes as $iso_code) { - $file = APP_PATH . "/conf/l10n/" . $iso_code . ".json"; + $file = $this->setup->get("APP_PATH") . "/conf/l10n/" . $iso_code . ".json"; $results[$iso_code] = Util::load_commented_json($file); $results[$iso_code]["isoCode"] = $iso_code; } @@ -234,7 +208,6 @@ class App { return $results; } - public function get_thumbs($requests) { $hrefs = []; diff --git a/src/_h5ai/server/php/inc/core/class-fallback.php b/src/_h5ai/server/php/inc/core/class-fallback.php index 45287194..cdd30355 100644 --- a/src/_h5ai/server/php/inc/core/class-fallback.php +++ b/src/_h5ai/server/php/inc/core/class-fallback.php @@ -26,6 +26,8 @@ class Fallback { $path = $this->get_current_path(); } + $app_href = $this->app->get_setup()->get("APP_HREF"); + $cache = []; $folder = Item::get($this->app, $path, $cache); $items = $folder->get_content($cache); @@ -42,7 +44,7 @@ class Fallback { if ($folder->get_parent($cache)) { $html .= "