From b40508e2241f4cc1edfc527ba5fb83ae377303a7 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Mon, 3 Jun 2024 14:01:57 +0200 Subject: [PATCH] handle not found in a single place --- cmd/httpd/main.ha | 64 +++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/cmd/httpd/main.ha b/cmd/httpd/main.ha index 1a98643..fb18942 100644 --- a/cmd/httpd/main.ha +++ b/cmd/httpd/main.ha @@ -19,6 +19,8 @@ use strings; use thread; use time; +type notfound = !void; + const usage: [_]getopt::help = [ "HTTP server", ('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(); 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; switch (request.method) { case "GET" => switch (request.target.path) { - case "/" => handle_index(&buf, serv_req); + case "/" => handle_index(buf, serv_req); case => - handle_file(&buf, serv_req); + handle_file(buf, serv_req)?; return; }; case "POST" => switch (request.target.path) { - case "/v1/exec" => handle_exec(&buf, serv_req); - case => - handle_notfound(&buf, serv_req); - return; + case "/v1/exec" => handle_exec(buf, serv_req)?; + case => return notfound; }; case "OPTIONS" => - handle_cors(&buf, serv_req); - return; - case => - handle_notfound(&buf, serv_req); + handle_cors(buf, serv_req); 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 pathbuf = strings::toutf8(request.target.path); if (bytes::contains(pathbuf[1..], '/')) { - fmt::printfln("additional slash. not handling that.")!; - handle_notfound(buf, serv_req); - return; + return notfound; }; let p = path::init(request.target.path)!; let ext = path::peek_ext(&p); if (ext is void) { - handle_notfound(buf, serv_req); - return; + return notfound; }; let content_type = switch (ext: str) { case "html" => yield "text/html; charset=utf-8"; case "css" => yield "text/css"; case "js" => yield "application/javascript; charset=utf-8"; - case => - handle_notfound(buf, serv_req); - return; + case => return notfound; }; 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); let fp = match (os::open(path)) { case let fp: io::file => yield fp; - case => - handle_notfound(buf, serv_req); - return; + case => return notfound; }; defer io::close(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 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) { case let obj: json::object => yield obj; - case => - handle_notfound(buf, serv_req); - return; + case => return notfound; }; let files = match (json::get(&payload, "files")) { - case void => - handle_notfound(buf, serv_req); - return; + case void => return notfound; case let j: *json::value => yield j; }; let files = match (*files) { case let o: json::object => yield o; - case => - handle_notfound(buf, serv_req); - return; + case => return notfound; }; let code = match (json::get(&files, "")) { - case void => - handle_notfound(buf, serv_req); - return; + case void => return notfound; case let j: *json::value => yield j; }; let code = match (*code) { case let c: str => yield c; - case => - handle_notfound(buf, serv_req); - return; + case => return notfound; }; let (stdout, stderr) = run_code(code);