Files

102 lines
2.2 KiB
Plaintext

path = import("path.noja");
Request = import("request.noja").Request;
respond = import("response.noja").new;
Router = {table: Map, plug: Callable, solve: Callable};
fun loadFile(path: String) {
print("path=", path, "\n");
stream, error = files.openFile(path, files.READ);
if error != none:
return none, error;
text = "";
size = 512;
do {
size = 2 * size;
data = buffer.new(size);
num_bytes, error = files.read(stream, data);
if error != none:
return none, error;
text = string.cat(text, buffer.toString(data));
} while num_bytes == size;
#files.close(stream);
return text;
}
fun join(list: List, glue="") {
if count(list) == 0:
text = "";
else {
i = 1;
text = toString(list[0]);
while i < count(list): {
text = string.cat(text, glue, toString(list[i]));
i = i+1;
}
}
return text;
}
fun new() {
return {
table: {},
fun plug(router: Router, name: String, methods: Map)
router.table[name] = methods;
fun getRouteAllowedMethods(router: Router, route) {
method_table = router.table[route];
if method_table == none:
return none;
allowed = keysof(method_table);
if method_table.HEAD == none and method_table.GET != none:
append(allowed, "HEAD");
if method_table.OPTIONS == none:
append(allowed, "OPTIONS");
return allowed;
}
fun solve(router: Router, req: Request) {
endpoint = req.url.path;
method_table = router.table[endpoint];
if method_table == none:
return respond(404);
method_item = method_table[req.method];
if method_item == none: {
allowed = router->getRouteAllowedMethods(endpoint);
if req.method == "OPTIONS":
status = 204;
else
status = 405;
return respond(status, none, {"Allow": join(allowed, ", ")});
}
if isCallable(method_item):
res = method_item(req);
else {
csd = getCurrentScriptDirectory();
file = path.join(csd, method_item);
data, error = loadFile(file);
if error == none:
res = respond(200, data);
else
res = respond(500, error);
}
return res;
}
};
}
return {new: new, Router: Router};