aboutsummaryrefslogtreecommitdiff
path: root/req.ha
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--req.ha44
1 files changed, 39 insertions, 5 deletions
diff --git a/req.ha b/req.ha
index 2efa842..59f6438 100644
--- a/req.ha
+++ b/req.ha
@@ -2,15 +2,28 @@
// SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org>
use fmt;
+use fs;
use htmpl;
use io;
+use mime;
use net::http;
use net::uri;
use strconv;
use strings;
-fn handlereq(conn: io::handle, request: *http::request) (void | io::error | nomem | uri::invalid) = {
- let segments = segments_from_path(request.target.raw_path)?;
+fn handlereq(conn: io::handle, request: *http::request) (void | io::error | nomem | fs::error) = {
+ let segments = match(segments_from_path(request.target.raw_path)) {
+ case let s: []str =>
+ yield s;
+ case uri::invalid =>
+ start_response(conn, 400, "text/plain")?;
+ fmt::fprintln(conn, "Invalid URI")?;
+ return void;
+ case nomem =>
+ return nomem;
+ case =>
+ abort("unreachable");
+ };
defer strings::freeall(segments);
let trailing_slash: bool = false;
@@ -23,7 +36,7 @@ fn handlereq(conn: io::handle, request: *http::request) (void | io::error | nome
if (len(segments) == 0) {
start_response(conn, 200, "text/html")?;
- return tp_index(conn, segments);
+ return tp_index(conn);
};
if (segments[0] == ":") {
@@ -40,6 +53,7 @@ fn handlereq(conn: io::handle, request: *http::request) (void | io::error | nome
fmt::fprintln(conn, "Error: Blank static endpoint")?;
return;
};
+
let fs_segments = segments[2 ..];
for (let fs_segment .. fs_segments) {
if (strings::contains(fs_segment, "/")) {
@@ -48,8 +62,28 @@ fn handlereq(conn: io::handle, request: *http::request) (void | io::error | nome
return;
};
};
- start_response(conn, 501, "text/plain")?;
- fmt::fprintln(conn, "Not implemented yet")?;
+ let fs_segment_path = strings::join("/", fs_segments...)?;
+ defer free(fs_segment_path);
+
+ let file = match (fs::open(static_fs as *fs::fs, fs_segment_path)) {
+ case let f: io::handle => yield f;
+ case fs::error =>
+ start_response(conn, 500, "text/plain")?;
+ fmt::fprintln(conn, "Filesystem error")?;
+ return;
+ };
+ defer io::close(file)!;
+
+ let ext = strings::rcut(fs_segments[len(fs_segments) - 1], ".").1;
+
+ let mimetype = match (mime::lookup_ext(ext)) {
+ case let m: *mime::mimetype => yield m.mime;
+ case null => yield "application/octet-stream";
+ };
+
+ start_response(conn, 200, mimetype)?;
+ io::copy(conn, file)?;
+
case =>
start_response(conn, 404, "text/plain")?;
fmt::fprintln(conn, "Error: Unknown system endpoint")?;