1
Fork 0

handle not found in a single place

This commit is contained in:
Jan-Erik Rediger 2024-06-03 14:01:57 +02:00
parent 92b4600afa
commit b40508e224

View file

@ -19,6 +19,8 @@ use strings;
use thread; use thread;
use time; use time;
type notfound = !void;
const usage: [_]getopt::help = [ const usage: [_]getopt::help = [
"HTTP server", "HTTP server",
('a', "address", "listened address (ex: 127.0.0.1:8080)"), ('a', "address", "listened address (ex: 127.0.0.1:8080)"),
@ -80,28 +82,31 @@ fn handle_req(arg: nullable *opaque) void = {
let buf = memio::dynamic(); let buf = memio::dynamic();
defer io::close(&buf)!; defer io::close(&buf)!;
match (route_request(&buf, serv_req)) {
case void => void;
case notfound => handle_notfound(&buf, serv_req);
};
};
fn route_request(buf: *io::stream, serv_req: *http::server_request) (void | notfound) = {
let request = &serv_req.request; let request = &serv_req.request;
switch (request.method) { switch (request.method) {
case "GET" => case "GET" =>
switch (request.target.path) { switch (request.target.path) {
case "/" => handle_index(&buf, serv_req); case "/" => handle_index(buf, serv_req);
case => case =>
handle_file(&buf, serv_req); handle_file(buf, serv_req)?;
return; return;
}; };
case "POST" => case "POST" =>
switch (request.target.path) { switch (request.target.path) {
case "/v1/exec" => handle_exec(&buf, serv_req); case "/v1/exec" => handle_exec(buf, serv_req)?;
case => case => return notfound;
handle_notfound(&buf, serv_req);
return;
}; };
case "OPTIONS" => case "OPTIONS" =>
handle_cors(&buf, serv_req); handle_cors(buf, serv_req);
return;
case =>
handle_notfound(&buf, serv_req);
return; return;
case => return notfound;
}; };
}; };
@ -125,31 +130,26 @@ fn handle_index(buf: *io::stream, serv_req: *http::server_request) void = {
)!; )!;
}; };
fn handle_file(buf: *memio::stream, serv_req: *http::server_request) void = { fn handle_file(buf: *io::stream, serv_req: *http::server_request) (void | notfound) = {
let request = &serv_req.request; let request = &serv_req.request;
let pathbuf = strings::toutf8(request.target.path); let pathbuf = strings::toutf8(request.target.path);
if (bytes::contains(pathbuf[1..], '/')) { if (bytes::contains(pathbuf[1..], '/')) {
fmt::printfln("additional slash. not handling that.")!; return notfound;
handle_notfound(buf, serv_req);
return;
}; };
let p = path::init(request.target.path)!; let p = path::init(request.target.path)!;
let ext = path::peek_ext(&p); let ext = path::peek_ext(&p);
if (ext is void) { if (ext is void) {
handle_notfound(buf, serv_req); return notfound;
return;
}; };
let content_type = switch (ext: str) { let content_type = switch (ext: str) {
case "html" => yield "text/html; charset=utf-8"; case "html" => yield "text/html; charset=utf-8";
case "css" => yield "text/css"; case "css" => yield "text/css";
case "js" => yield "application/javascript; charset=utf-8"; case "js" => yield "application/javascript; charset=utf-8";
case => case => return notfound;
handle_notfound(buf, serv_req);
return;
}; };
let filename = path::basename(request.target.path); let filename = path::basename(request.target.path);
@ -157,9 +157,7 @@ fn handle_file(buf: *memio::stream, serv_req: *http::server_request) void = {
defer free(path); defer free(path);
let fp = match (os::open(path)) { let fp = match (os::open(path)) {
case let fp: io::file => yield fp; case let fp: io::file => yield fp;
case => case => return notfound;
handle_notfound(buf, serv_req);
return;
}; };
defer io::close(fp)!; defer io::close(fp)!;
let filecontent = io::drain(fp)!; let filecontent = io::drain(fp)!;
@ -211,7 +209,7 @@ export fn handle_cors(buf: *io::stream, serv_req: *http::server_request) void =
)!; )!;
}; };
export fn handle_exec(buf: *io::stream, serv_req: *http::server_request) void = { fn handle_exec(buf: *io::stream, serv_req: *http::server_request) (void | notfound) = {
let request = serv_req.request; let request = serv_req.request;
let payload = match (request.body) { let payload = match (request.body) {
@ -233,37 +231,27 @@ export fn handle_exec(buf: *io::stream, serv_req: *http::server_request) void =
let payload = match (payload) { let payload = match (payload) {
case let obj: json::object => yield obj; case let obj: json::object => yield obj;
case => case => return notfound;
handle_notfound(buf, serv_req);
return;
}; };
let files = match (json::get(&payload, "files")) { let files = match (json::get(&payload, "files")) {
case void => case void => return notfound;
handle_notfound(buf, serv_req);
return;
case let j: *json::value => yield j; case let j: *json::value => yield j;
}; };
let files = match (*files) { let files = match (*files) {
case let o: json::object => yield o; case let o: json::object => yield o;
case => case => return notfound;
handle_notfound(buf, serv_req);
return;
}; };
let code = match (json::get(&files, "")) { let code = match (json::get(&files, "")) {
case void => case void => return notfound;
handle_notfound(buf, serv_req);
return;
case let j: *json::value => yield j; case let j: *json::value => yield j;
}; };
let code = match (*code) { let code = match (*code) {
case let c: str => yield c; case let c: str => yield c;
case => case => return notfound;
handle_notfound(buf, serv_req);
return;
}; };
let (stdout, stderr) = run_code(code); let (stdout, stderr) = run_code(code);