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
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"];
|