commit 4ea63b457e8a1e2ee9e96e354fa90da2c7aa88e7 from: Omar Polo date: Thu Dec 21 22:57:17 2023 UTC rename client -> connection use consistently `conn' as local variable name commit - 5b302645b69e633643b7810d0de85cec0b54973d commit + 4ea63b457e8a1e2ee9e96e354fa90da2c7aa88e7 blob - 23594b7dd753141b992b762e15e3d96e46f60a8f blob + 5dbdc740fb3a5ef07ae666039271cdd4501ccb2d --- http/http.ha +++ http/http.ha @@ -65,7 +65,7 @@ export type request = struct { export type routefn = *fn(*request, *reswriter) (void | io::error); -type client = struct { +type connection = struct { fp: io::file, in: bufio::scanner, first_line: bool, @@ -97,10 +97,10 @@ export fn handle(pattern: str, routefn: routefn) void // http::listen("unix:/run/foo.sock") export fn listen_sock(f: io::file) void = { - ev::add(f, ev::READ, &acceptclt, &global); + ev::add(f, ev::READ, &acceptconn, &global); }; -fn acceptclt(f: io::file, ev: ev::event, data: nullable *opaque) void = { +fn acceptconn(f: io::file, ev: ev::event, data: nullable *opaque) void = { let sock = match(net::accept(f, net::sockflag::NONBLOCK)) { case let err: net::error => log::printfln("accept: {}", net::strerror(err)); @@ -110,7 +110,7 @@ fn acceptclt(f: io::file, ev: ev::event, data: nullabl }; let mux = data: *mux; - let clt = alloc(client { + let conn = alloc(connection { fp = sock, mux = mux, in = bufio::newscanner(sock, types::SIZE_MAX), @@ -120,46 +120,49 @@ fn acceptclt(f: io::file, ev: ev::event, data: nullabl ... }); - ev::add(sock, ev::READ, &handleclt, clt); + ev::add(sock, ev::READ, &handleconn, conn); }; fn parse_req( - c: *client + conn: *connection ) (bool | badrequest | io::error | encoding::utf8::invalid) = { + let req = &conn.request; + let res = &conn.response; + for (true) { - let line = match(bufio::scan_string(&c.in, "\r\n")) { + let line = match(bufio::scan_string(&conn.in, "\r\n")) { case io::EOF => return badrequest; case let err: io::error => return err; case let line: const str => yield line; }; - if (c.first_line) { - c.first_line = false; + if (conn.first_line) { + conn.first_line = false; let (method, rest) = strings::cut(line, " "); switch (method) { - case "GET" => c.request.method = method::GET; - case "HEAD" => c.request.method = method::HEAD; - case "POST" => c.request.method = method::POST; - case "PUT" => c.request.method = method::PUT; - case "DELETE" => c.request.method = method::DELETE; - case "CONNECT" => c.request.method = method::CONNECT; - case "OPTIONS" => c.request.method = method::OPTIONS; - case "TRACE" => c.request.method = method::TRACE; - case "PATCH" => c.request.method = method::PATCH; + case "GET" => req.method = method::GET; + case "HEAD" => req.method = method::HEAD; + case "POST" => req.method = method::POST; + case "PUT" => req.method = method::PUT; + case "DELETE" => req.method = method::DELETE; + case "CONNECT" => req.method = method::CONNECT; + case "OPTIONS" => req.method = method::OPTIONS; + case "TRACE" => req.method = method::TRACE; + case "PATCH" => req.method = method::PATCH; case => return badrequest; }; let (path, version) = strings::cut(rest, " "); - c.request.path = strings::dup(path); + req.path = strings::dup(path); switch (version) { case "HTTP/1.0" => - c.request.version = version::HTTP_1_0; + req.version = version::HTTP_1_0; case "HTTP/1.1" => - c.request.version = version::HTTP_1_1; - c.response.chunked = true; + req.version = version::HTTP_1_1; + res.chunked = true; case => return badrequest; }; @@ -175,82 +178,82 @@ fn parse_req( }; }; -fn delclient(c: *client) void = { - ev::del(c.fp); +fn close_conn(conn: *connection) void = { + ev::del(conn.fp); - bufio::finish(&c.in); - match (io::close(c.fp)) { + bufio::finish(&conn.in); + match (io::close(conn.fp)) { case => yield; }; - match (io::close(&c.response)) { + match (io::close(&conn.response)) { case => yield; }; - free(c); + free(conn); }; -fn handleclt(f: io::file, ev: ev::event, data: nullable *opaque) void = { - let clt = data: *client; +fn handleconn(f: io::file, ev: ev::event, data: nullable *opaque) void = { + let conn = data: *connection; - match (respond(clt)) { + match (respond(conn)) { case let err: io::error => log::printfln("failure: {}", io::strerror(err)); - delclient(clt); + close_conn(conn); return; case => // XXX wait if there is still data pending. - if (clt.response.done) { - delclient(clt); + if (conn.response.done) { + close_conn(conn); return; }; - ev::add(clt.fp, ev::READ | ev::WRITE, &handleclt, clt); + ev::add(conn.fp, ev::READ | ev::WRITE, &handleconn, conn); }; }; -fn handle_request(clt: *client) (void | io::error) = { - match (parse_req(clt)) { +fn handle_request(conn: *connection) (void | io::error) = { + match (parse_req(conn)) { case let done: bool => if (!done) return; // try again later yield; case errors::again => return; // try again later case badrequest => - route_badrequest(&clt.request, &clt.response)?; - clt.response.done = true; - reswriter_flush(&clt.response)?; + route_badrequest(&conn.request, &conn.response)?; + conn.response.done = true; + reswriter_flush(&conn.response)?; return; case let err: io::error => log::printfln("parse_req: {}", io::strerror(err)); return; }; - let path = clt.request.path; + let path = conn.request.path; log::printfln("< GET {}", path); - for (let i = 0z; i < len(clt.mux); i += 1) { - if (fnmatch::fnmatch(clt.mux[i].pattern, path)) { - clt.routefn = clt.mux[i].routefn; + for (let i = 0z; i < len(conn.mux); i += 1) { + if (fnmatch::fnmatch(conn.mux[i].pattern, path)) { + conn.routefn = conn.mux[i].routefn; break; }; }; - clt.request_done = true; + conn.request_done = true; }; -fn respond(clt: *client) (void | io::error) = { - if (!clt.request_done) - handle_request(clt)?; - if (!clt.request_done) +fn respond(conn: *connection) (void | io::error) = { + if (!conn.request_done) + handle_request(conn)?; + if (!conn.request_done) return; - if (!clt.response.done) { - clt.response.done = true; - clt.routefn(&clt.request, &clt.response)?; + if (!conn.response.done) { + conn.response.done = true; + conn.routefn(&conn.request, &conn.response)?; }; - reswriter_flush(&clt.response)?; + reswriter_flush(&conn.response)?; }; fn route_notfound(req: *request, res: *reswriter) (void | io::error) = {