Lindenii Project Forge
Warning: Due to various recent migrations, viewing non-HEAD refs may be broken.
/cmd/httpserv/main.ha (raw)
use errors;
use ev;
use ev::server;
use fmt;
use io;
use log;
use memio;
use net::http;
use net::ip;
use net::tcp;
use net;
use os;
use unix::signal;
type state = struct {
loop: *ev::loop,
exit: int,
};
export fn main() void = {
const loop = ev::newloop()!;
defer ev::finish(&loop);
const sock = match (ev::listen_tcp(&loop, ip::LOCAL_V4, 8080, tcp::reuseaddr)) {
case let err: net::error =>
log::fatalf("Error: listen: {}", net::strerror(err));
case let err: errors::error =>
log::fatalf("Error: listen: {}", errors::strerror(err));
case let sock: *ev::file =>
yield sock;
};
defer ev::close(sock);
let state = state {
loop = &loop,
...
};
const server = server::http_serve(sock, &http_serve, &state)!;
defer server::server_finish(server);
const sig = ev::signal(&loop, &signal, signal::sig::INT, signal::sig::TERM)!;
defer ev::close(sig);
ev::setuser(sig, &state);
log::println("Listening on 127.0.0.1:8080");
for (ev::dispatch(&loop, -1)!) void;
os::exit(state.exit);
};
fn signal(file: *ev::file, sig: signal::sig) (void | nomem) = {
log::printfln("Exiting due to {}", signal::signame(sig));
const state = ev::getuser(file): *state;
ev::stop(state.loop);
};
fn http_serve(
user: nullable *opaque,
req: http::request,
rw: http::response_writer
) void = {
const state = user: *state;
const (ip, port) = http::peeraddr(&rw);
log::printfln("Serving from {}:{}", ip::string(ip), port);
const buf = memio::dynamic();
defer io::close(&buf)!;
fmt::fprintfln(&buf, "Method: {}", req.method)!;
fmt::fprintfln(&buf, "Path: {}", req.target.path)!;
fmt::fprintfln(&buf, "Fragment: {}", req.target.fragment)!;
fmt::fprintfln(&buf, "Query: {}", req.target.query)!;
fmt::fprintfln(&buf, "Headers:")!;
http::write_header(&buf, &req.header)!;
fmt::fprintln(&buf)!;
io::copy(&buf, req.body)!;
io::seek(&buf, 0, io::whence::SET)!;
http::response_add_header(&rw, "Content-Type", "text/plain")!;
http::response_set_body(&rw, &buf);
http::response_write(&rw)!;
};