commit - 4ea63b457e8a1e2ee9e96e354fa90da2c7aa88e7
commit + ed8cff624698690721a3e0489c3ce3dd96e1657a
blob - 5dbdc740fb3a5ef07ae666039271cdd4501ccb2d
blob + c7ac521478186bb7bea8b5f7b1d11cc26867a89c
--- http/http.ha
+++ http/http.ha
use encoding::utf8;
use errors;
use fmt;
-use fnmatch;
use io;
use log;
use net;
mux: *mux,
};
-export type route = struct {
- pattern: str,
- routefn: routefn,
-};
-
-export type mux = []route;
-
-let global: mux = [];
-
-export fn handle(pattern: str, routefn: routefn) void = {
- append(global, route {
- pattern = pattern,
- routefn = routefn,
- });
-};
-
// XXX generic listen would be very handy!
// something like: http::listen("localhost:8080") or maybe even
// http::listen("unix:/run/foo.sock")
-export fn listen_sock(f: io::file) void = {
- ev::add(f, ev::READ, &acceptconn, &global);
+export fn listen_sock(f: io::file, mux: nullable *mux) void = {
+ ev::add(f, ev::READ, &acceptconn, match(mux) {
+ case null => yield &global;
+ case => yield mux;
+ });
};
fn acceptconn(f: io::file, ev: ev::event, data: nullable *opaque) void = {
return;
};
- let path = conn.request.path;
- log::printfln("< GET {}", path);
+ log::printfln("< GET {}", conn.request.path);
- 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;
- };
- };
-
+ conn.routefn = mux_match(conn.mux, &conn.request, &route_notfound);
conn.request_done = true;
};
blob - /dev/null
blob + 32f7f9b4e954a55b4fbc576137132c67b363086e (mode 644)
--- /dev/null
+++ http/mux.ha
+// This is free and unencumbered software released into the public domain.
+//
+// Anyone is free to copy, modify, publish, use, compile, sell, or
+// distribute this software, either in source code form or as a compiled
+// binary, for any purpose, commercial or non-commercial, and by any
+// means.
+//
+// In jurisdictions that recognize copyright laws, the author or authors
+// of this software dedicate any and all copyright interest in the
+// software to the public domain. We make this dedication for the benefit
+// of the public at large and to the detriment of our heirs and
+// successors. We intend this dedication to be an overt act of
+// relinquishment in perpetuity of all present and future rights to this
+// software under copyright law.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+use fnmatch;
+
+export type route = struct {
+ pattern: str,
+ routefn: routefn,
+};
+
+export type mux = []route;
+
+let global: mux = [];
+
+export fn newmux() mux = [];
+
+export fn handle(pattern: str, routefn: routefn) void = {
+ handle_mux(&global, pattern, routefn);
+};
+
+export fn handle_mux(mux: *mux, pattern: str, routefn: routefn) void = {
+ append(mux, route {
+ pattern = pattern,
+ routefn = routefn,
+ });
+};
+
+export fn mux_match(mux: *mux, req: *request, default: routefn) routefn = {
+ for (let i = 0z; i < len(mux); i += 1) {
+ if (fnmatch::fnmatch(mux[i].pattern, req.path)) {
+ return mux[i].routefn;
+ };
+ };
+
+ return default;
+};