You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
4.3 KiB
PHP

<?php
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
require __DIR__ . '/required.php';
require __DIR__ . '/apiconfig.php';
require __DIR__ . '/authenticator.php';
require __DIR__ . '/functions.php';
/*
* Gather request data in a variety of ways for maximum client flexibility
*/
// URL parameters and POST fields
$VARS = $_GET;
if ($_SERVER['REQUEST_METHOD'] != "GET") {
$VARS = array_merge($VARS, $_POST);
}
// Parse JSON request body
$requestbody = file_get_contents('php://input');
$requestjson = json_decode($requestbody, TRUE);
if (json_last_error() == JSON_ERROR_NONE) {
$VARS = array_merge($VARS, $requestjson);
}
// Get requested API endpoint
// Strip out urlbase
$pos = strpos($_SERVER['REQUEST_URI'], env("urlbase", "/"));
if ($pos !== false) {
$routestr = substr_replace($_SERVER['REQUEST_URI'], "", $pos, strlen(env("urlbase", "/")));
}
$route = explode("/", $routestr);
if ($route[0] == "") {
// The urlbase didn't have a trailing slash, so there's an empty zeroth element
array_shift($route);
}
$ENDPOINT = $VARS["endpoint"] ?? "";
if (count($route) >= 1) {
$ep = $route[0];
// Ignore URL parameters if present,
// otherwise requests like /endpoint?abc=123 will have the endpoint "endpoint?abc=123"
$ep = explode("?", $ep, 2)[0];
// Don't allow = in endpoint ID because it's confusing
if (strpos($ep, "=") === FALSE) {
$ENDPOINT = $ep;
}
}
$urlkeyvaluepairs = [];
if (count($route) >= 2 && strpos($route[1], "?") !== 0) {
for ($i = 1; $i < count($route); $i++) {
if (empty($route[$i])) {
continue;
}
if (strpos($route[$i], "=") === false) {
// Allow slashes in endpoint as long as no key/value pairs have
// been found yet
if (empty($urlkeyvaluepairs)) {
$ENDPOINT .= "/" . $route[$i];
}
continue;
}
$key = explode("=", $route[$i], 2)[0];
$val = explode("=", $route[$i], 2)[1];
$urlkeyvaluepairs[$key] = $val;
}
}
$VARS += $urlkeyvaluepairs;
// Make sure /endpoint/?key=val&key2=val2 works
if (count($route) > 0 && strpos($route[count($route) - 1], "?") === 0) {
$morevars = explode("&", substr($route[count($route) - 1], 1));
foreach ($morevars as $var) {
if (strpos($var, "=") === false) {
continue;
}
$key = explode("=", $var, 2)[0];
$val = explode("=", $var, 2)[1];
$VARS[$key] = $val;
}
}
if (empty($ENDPOINT)) {
if (file_exists(__DIR__ . "/publicsite/index.html")) {
http_response_code(200);
header("Content-Type: text/html");
exit(file_get_contents(__DIR__ . "/publicsite/index.html"));
} else {
http_response_code(404);
die("404 No endpoint specified.");
}
}
if (!isset($APIS[$ENDPOINT])) {
if (preg_match("/[a-zA-Z0-9_\-]+/", $ENDPOINT) === 1 && file_exists(__DIR__ . "/publicsite/$ENDPOINT.html")) {
http_response_code(200);
header("Content-Type: text/html");
exit(file_get_contents(__DIR__ . "/publicsite/$ENDPOINT.html"));
} else {
http_response_code(404);
die("404 Requested endpoint (" . htmlentities($ENDPOINT) . ") not known.");
}
}
// Deny access if authenticator returns false (add your logic to authenticator.php)
if (!authenticaterequest()) {
http_response_code(401);
die("401 Unauthorized: You need to supply valid credentials.");
}
$APIENDPOINTCONFIG = $APIS[$ENDPOINT];
if (!file_exists(__DIR__ . "/endpoints/" . $APIENDPOINTCONFIG["load"])) {
http_response_code(404);
die("404 Requested endpoint known but not found.");
}
// Check and validate arguments/data passed from client based on configured patterns
// This makes sure that all required variables are present and not malformed, reducing
// the amount of validation code in each endpoint
if (!empty($APIENDPOINTCONFIG["vars"])) {
checkVars($APIENDPOINTCONFIG["vars"]);
}
// cleanup variables that won't be needed in endpoints
unset($route, $ep, $key, $val, $urlkeyvaluepairs, $pos, $requestjson, $requestbody, $i, $routestr);
require_once __DIR__ . "/endpoints/" . $APIENDPOINTCONFIG["load"];