1
Fork 0

some early httpd code

This commit is contained in:
Jan-Erik Rediger 2024-05-28 20:28:52 +02:00
parent bcb3d9a56d
commit 41eef76c22
3 changed files with 68 additions and 6 deletions

3
.gitmodules vendored
View file

@ -1,3 +1,6 @@
[submodule "backend/vendor/hare-http"] [submodule "backend/vendor/hare-http"]
path = backend/vendor/hare-http path = backend/vendor/hare-http
url = https://git.sr.ht/~sircmpwn/hare-http url = https://git.sr.ht/~sircmpwn/hare-http
[submodule "backend/vendor/hare-logfmt"]
path = backend/vendor/hare-logfmt
url = https://git.sr.ht/~blainsmith/hare-logfmt

View file

@ -1,8 +1,10 @@
use getopt; use getopt;
use net; use net;
use net::ip; use net::ip;
use net::uri;
use net::http; use net::http;
use net::dial; use net::dial;
use net::tcp::{reuseaddr};
use os; use os;
use memio; use memio;
use io; use io;
@ -11,6 +13,8 @@ use bufio;
use strings; use strings;
use thread; use thread;
use time; use time;
use log::logfmt;
use log;
const usage: [_]getopt::help = [ const usage: [_]getopt::help = [
"HTTP server", "HTTP server",
@ -18,6 +22,9 @@ const usage: [_]getopt::help = [
]; ];
export fn main() void = { export fn main() void = {
let l = logfmt::new(os::stdout);
log::setlogger(&l);
const cmd = getopt::parse(os::args, usage...); const cmd = getopt::parse(os::args, usage...);
defer getopt::finish(&cmd); defer getopt::finish(&cmd);
@ -39,7 +46,7 @@ export fn main() void = {
}; };
}; };
const server = match (http::listen(ip_addr, port)) { const server = match (http::listen(ip_addr, port, reuseaddr)) {
case let this: *http::server => case let this: *http::server =>
yield this; yield this;
case net::error => abort("failure while listening"); case net::error => abort("failure while listening");
@ -53,6 +60,7 @@ export fn main() void = {
case net::error => abort("failure while serving"); case net::error => abort("failure while serving");
}; };
log::println("method", serv_req.request.method, "uri", uri::string(serv_req.request.target));
let tid = thread::spawn(&handle_req, serv_req)!; let tid = thread::spawn(&handle_req, serv_req)!;
thread::detach(tid)!; thread::detach(tid)!;
}; };
@ -61,11 +69,27 @@ export fn main() void = {
fn handle_req(arg: nullable *opaque) void = { fn handle_req(arg: nullable *opaque) void = {
let serv_req = arg: *http::server_request; let serv_req = arg: *http::server_request;
defer http::serve_finish(serv_req); defer http::serve_finish(serv_req);
fmt::printfln("got a request. serving now.")!;
let buf = memio::dynamic(); let buf = memio::dynamic();
defer io::close(&buf)!; defer io::close(&buf)!;
handlereq(&buf, &serv_req.request);
let request = &serv_req.request;
let route = (request.method, request.target.path);
switch (request.method) {
case "GET" =>
switch (request.target.path) {
case "/" => handle_index(&buf, &serv_req.request);
case =>
handle_notfound(&buf, serv_req);
return;
};
case "OPTIONS" =>
handle_cors(&buf, serv_req);
return;
case =>
handle_notfound(&buf, serv_req);
return;
};
http::response_write( http::response_write(
serv_req.socket, serv_req.socket,
@ -75,7 +99,43 @@ fn handle_req(arg: nullable *opaque) void = {
)!; )!;
}; };
export fn handlereq(buf: *io::stream, request: *http::request) void = { export fn handle_notfound(buf: *io::stream, request: *http::server_request) void = {
fmt::fprintfln(buf, "not found")!;
http::response_write(
request.socket,
http::STATUS_NOT_FOUND,
buf,
("Content-Type", "text/plain")
)!;
};
export fn handle_cors(buf: *io::stream, serv_req: *http::server_request) void = {
let request = serv_req.request;
if (request.target.path == "/v1/exec") {
http::response_write(
serv_req.socket,
http::STATUS_OK,
void,
("Content-Length", "0"),
("access-control-allow-origin", "*"),
("vary", "origin, access-control-request-method, access-control-request-headers"),
("access-control-allow-methods", "*"),
("access-control-allow-headers", "*"),
)!;
return;
};
http::response_write(
serv_req.socket,
http::STATUS_METHOD_NOT_ALLOWED,
void,
("Content-Length", "0")
)!;
};
export fn handle_index(buf: *io::stream, request: *http::request) void = {
fmt::fprintfln(buf, "Method: {}", request.method)!; fmt::fprintfln(buf, "Method: {}", request.method)!;
fmt::fprintfln(buf, "Path: {}", request.target.path)!; fmt::fprintfln(buf, "Path: {}", request.target.path)!;
fmt::fprintfln(buf, "Fragment: {}", request.target.fragment)!; fmt::fprintfln(buf, "Fragment: {}", request.target.fragment)!;
@ -84,8 +144,6 @@ export fn handlereq(buf: *io::stream, request: *http::request) void = {
http::write_header(buf, &request.header)!; http::write_header(buf, &request.header)!;
fmt::fprintfln(buf, "EOF")!; fmt::fprintfln(buf, "EOF")!;
time::sleep(5 * time::SECOND);
match (request.body) { match (request.body) {
case void => void; case void => void;
case let body: io::handle => case let body: io::handle =>

1
backend/vendor/hare-logfmt vendored Submodule

@ -0,0 +1 @@
Subproject commit 2b4a37459be54c83ac6ac6354cddec3e9fa796bf