summaryrefslogtreecommitdiffstats
path: root/modules-available/dozmod/api.inc.php
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available/dozmod/api.inc.php')
-rw-r--r--modules-available/dozmod/api.inc.php107
1 files changed, 70 insertions, 37 deletions
diff --git a/modules-available/dozmod/api.inc.php b/modules-available/dozmod/api.inc.php
index d9f7354c..b5030cc5 100644
--- a/modules-available/dozmod/api.inc.php
+++ b/modules-available/dozmod/api.inc.php
@@ -10,6 +10,8 @@
**/
+use JetBrains\PhpStorm\NoReturn;
+
if (!Module::isAvailable('locations')) {
die('require locations module');
}
@@ -17,27 +19,30 @@ if (!Module::isAvailable('locations')) {
define('LIST_URL', CONFIG_DOZMOD_URL . '/vmchooser/list');
define('VMX_URL', CONFIG_DOZMOD_URL . '/vmchooser/lecture');
-$availableRessources = ['list', 'vmx', 'netrules', 'runscript', 'metadata', 'netshares'];
+$availableRessources = ['list', 'netrules', 'metadata', 'imagemeta'];
/* BEGIN: A simple caching mechanism ---------------------------- */
-function cache_hash($obj)
+function cache_hash($obj): string
{
return md5(serialize($obj));
}
-function cache_key_to_filename($key)
+function cache_key_to_filename(string $key): string
{
return "/tmp/bwlp-slxadmin-cache-$key";
}
-function cache_put($key, $value)
+function cache_put(string $key, string $value): void
{
$filename = cache_key_to_filename($key);
- file_put_contents($filename, $value);
+ // Try to avoid another client concurrently accessing the cache seeing an empty file
+ $tmp = $filename . '-' . mt_rand();
+ file_put_contents($tmp, $value);
+ rename($tmp, $filename);
}
-function cache_has($key)
+function cache_has(string $key): bool
{
$filename = cache_key_to_filename($key);
$mtime = @filemtime($filename);
@@ -46,21 +51,18 @@ function cache_has($key)
return false; // cache miss
}
$now = time();
- if ($now < $mtime || $now - $mtime > CONFIG_DOZMOD_EXPIRE) {
- return false;
- } else {
- return true;
- }
+ return $now >= $mtime && $now - $mtime <= CONFIG_DOZMOD_EXPIRE;
}
-function cache_get($key)
+function cache_get(string $key): string
{
$filename = cache_key_to_filename($key);
return file_get_contents($filename);
}
/* good for large binary files */
-function cache_get_passthru($key)
+#[NoReturn]
+function cache_get_passthru(string $key): void
{
$filename = cache_key_to_filename($key);
$fp = fopen($filename, "r");
@@ -68,7 +70,7 @@ function cache_get_passthru($key)
fpassthru($fp);
exit;
}
- error_log('Cannot passthrough cache file ' . $filename);
+ error_log('DMSD-cache: Cannot passthrough cache file ' . $filename);
}
/* END: Cache ---------------------------------------------------- */
@@ -76,7 +78,7 @@ function cache_get_passthru($key)
/* this script requires 2 (3 with implicit client ip) parameters
*
-* resource = vmx,...
+* resource = list,metadata,...
* lecture_uuid = client can choose
**/
@@ -85,11 +87,16 @@ function cache_get_passthru($key)
* Takes raw lecture list xml, returns array of uuids.
*
* @param string $responseXML XML from dozmod server
- * @return array list of UUIDs, false on error
+ * @return array list of UUIDs
*/
-function xmlToLectureIds($responseXML)
+function xmlToLectureIds(string $responseXML): array
{
- $xml = new SimpleXMLElement($responseXML);
+ try {
+ $xml = new SimpleXMLElement($responseXML);
+ } catch (Exception $e) {
+ EventLog::warning('Error parsing XML response data from DMSD: ' . $e->getMessage(), $responseXML);
+ return [];
+ }
if (!isset($xml->eintrag))
return [];
@@ -102,7 +109,8 @@ function xmlToLectureIds($responseXML)
return $uuids;
}
-function sendExamModeMismatch()
+#[NoReturn]
+function sendExamModeMismatch(): void
{
Header('Content-Type: text/xml; charset=utf-8');
echo
@@ -112,8 +120,8 @@ function sendExamModeMismatch()
<image_name param="null"/>
<priority param="100"/>
<creator param="Ernie Esslingen"/>
- <short_description param="Klausurmodus geändert, bitte PC neustarten"/>
- <long_description param="Der Klausurmodus wurde ein- oder ausgeschaltet, bitte starten Sie den PC neu"/>
+ <short_description param="Prüfungsmodus geändert, bitte PC neustarten"/>
+ <long_description param="Der Prüfungsmodus wurde ein- oder ausgeschaltet, bitte starten Sie den PC neu"/>
<uuid param="exam-mode-warning"/>
<virtualmachine param="exam-mode-warning"/>
<os param="debian8"/>
@@ -142,7 +150,7 @@ BLA;
}
/** Caching wrapper around _getLecturesForLocations() */
-function getListForLocations($locationIds, $raw)
+function getListForLocations(array $locationIds, bool $raw)
{
/* if in any of the locations there is an exam active, consider the client
to be in "exam-mode" and only offer him exams (no lectures) */
@@ -179,7 +187,12 @@ function getListForLocations($locationIds, $raw)
if ($examMode) {
$url .= '&exams';
}
+ $t = microtime(true);
$value = Download::asString($url, 60, $code);
+ $t = microtime(true) - $t;
+ if ($t > 5) {
+ error_log("DMSD-cache: Download of lecture list took $t ($code)");
+ }
if ($value === false || $code < 200 || $code > 299)
return false;
cache_put($rawKey, $value);
@@ -191,30 +204,37 @@ function getListForLocations($locationIds, $raw)
return $list;
}
-function getLectureUuidsForLocations($locationIds)
+function getLectureUuidsForLocations(array $locationIds)
{
return getListForLocations($locationIds, false);
}
-function outputLectureXmlForLocation($locationIds)
+function outputLectureXmlForLocation(array $locationIds)
{
return getListForLocations($locationIds, true);
}
-function _getVmData($lecture_uuid, $subResource = false)
+function _getVmData(string $lecture_uuid, string $subResource = null)
{
$url = VMX_URL . '/' . $lecture_uuid;
- if ($subResource !== false) {
+ if ($subResource !== null) {
$url .= '/' . $subResource;
}
+ $t = microtime(true);
$response = Download::asString($url, 60, $code);
- if ($code < 200 || $code > 299)
+ $t = microtime(true) - $t;
+ if ($t > 5) {
+ error_log("DMSD-cache: Download of $subResource took $t ($code)");
+ }
+ if ($code < 200 || $code > 299) {
+ error_log("DMSD-cache: Return code $code, payload len " . strlen($response));
return (int)$code;
+ }
return $response;
}
/** Caching wrapper around _getVmData() **/
-function outputResource($lecture_uuid, $resource)
+function outputResource(string $lecture_uuid, string $resource): void
{
if ($resource === 'metadata') {
// HACK: config.tgz is compressed, don't use gzip output handler
@@ -235,7 +255,7 @@ function outputResource($lecture_uuid, $resource)
} else {
$value = _getVmData($lecture_uuid, $resource);
if ($value === false)
- return false;
+ return;
if (is_int($value)) {
http_response_code($value);
exit;
@@ -243,16 +263,16 @@ function outputResource($lecture_uuid, $resource)
cache_put($key, $value);
die($value);
}
- return false;
}
+#[NoReturn]
function fatalDozmodUnreachable()
{
Header('HTTP/1.1 504 Gateway Timeout');
die('DMSD currently not available');
}
-function readLectureParam($locationIds)
+function readLectureParam(array $locationIds): string
{
$lecture = Request::get('lecture', false, 'string');
if ($lecture === false) {
@@ -272,12 +292,26 @@ function readLectureParam($locationIds)
}
+// in this context the lecture param is an image id (container),
+// just read and check if valid.
+// TODO do we need to check if this is allowed?
+function readImageParam(): string
+{
+ $image = Request::get('lecture', false, 'string');
+
+ if ($image === false) {
+ Header('HTTP/1.1 400 Bad Request');
+ die('Missing IMAGE UUID');
+ }
+ return $image;
+}
+
// -----------------------------------------------------------------------------//
/* request data, don't trust */
$resource = Request::get('resource', false, 'string');
if ($resource === false) {
- Util::traceError("you have to specify the 'resource' parameter");
+ ErrorHandler::traceError("you have to specify the 'resource' parameter");
}
if (!in_array($resource, $availableRessources)) {
@@ -298,12 +332,11 @@ $location_ids = Location::getLocationRootChain($location_ids);
if ($resource === 'list') {
outputLectureXmlForLocation($location_ids);
// Won't return on success...
- fatalDozmodUnreachable();
+} elseif ($resource === 'imagemeta') {
+ $image = readImageParam();
+ outputResource($image, $resource);
} else {
$lecture = readLectureParam($location_ids);
outputResource($lecture, $resource);
- fatalDozmodUnreachable();
}
-
-Header('HTTP/1.1 400 Bad Request');
-die("I don't know how to give you that resource");
+fatalDozmodUnreachable();