aboutsummaryrefslogtreecommitdiff
path: root/src/routes
diff options
context:
space:
mode:
Diffstat (limited to 'src/routes')
-rw-r--r--src/routes/access.zig6
-rw-r--r--src/routes/api/auth/first-login.zig15
-rw-r--r--src/routes/api/auth/login.zig34
-rw-r--r--src/routes/api/auth/root.zig4
-rw-r--r--src/routes/api/image/list.zig42
-rw-r--r--src/routes/api/image/load.zig15
-rw-r--r--src/routes/api/image/query.zig0
-rw-r--r--src/routes/api/image/remove.zig14
-rw-r--r--src/routes/api/image/root.zig6
-rw-r--r--src/routes/api/image/upload.zig17
-rw-r--r--src/routes/api/profile/create.zig29
-rw-r--r--src/routes/api/profile/image/load.zig17
-rw-r--r--src/routes/api/profile/image/root.zig5
-rw-r--r--src/routes/api/profile/image/upload.zig19
-rw-r--r--src/routes/api/profile/list.zig17
-rw-r--r--src/routes/api/profile/root.zig8
-rw-r--r--src/routes/api/profile/set.zig26
-rw-r--r--src/routes/api/profile/update-password.zig37
-rw-r--r--src/routes/api/root.zig4
-rw-r--r--src/routes/api/session/current.zig27
-rw-r--r--src/routes/api/session/drop.zig9
-rw-r--r--src/routes/api/session/is-online.zig15
-rw-r--r--src/routes/api/session/is-valid.zig21
-rw-r--r--src/routes/api/session/renew.zig9
-rw-r--r--src/routes/api/session/root.zig7
-rw-r--r--src/routes/handler-info.zig225
-rw-r--r--src/routes/root.zig49
-rw-r--r--src/routes/static.zig35
28 files changed, 0 insertions, 712 deletions
diff --git a/src/routes/access.zig b/src/routes/access.zig
deleted file mode 100644
index 39872b8..0000000
--- a/src/routes/access.zig
+++ /dev/null
@@ -1,6 +0,0 @@
-
-pub const Access = enum {
- everyone,
- users,
- admins,
-};
diff --git a/src/routes/api/auth/first-login.zig b/src/routes/api/auth/first-login.zig
deleted file mode 100644
index 523fdf4..0000000
--- a/src/routes/api/auth/first-login.zig
+++ /dev/null
@@ -1,15 +0,0 @@
-const std = @import("std");
-
-const memora = @import("memora");
-const Context = memora.Context;
-
-pub const access = .everyone;
-
-const Result = struct {
- is_first: bool,
-};
-
-pub fn post(ctx: *Context) anyerror!Result {
- _ = ctx;
- return .{ .is_first = false };
-}
diff --git a/src/routes/api/auth/login.zig b/src/routes/api/auth/login.zig
deleted file mode 100644
index 8a33082..0000000
--- a/src/routes/api/auth/login.zig
+++ /dev/null
@@ -1,34 +0,0 @@
-const std = @import("std");
-
-const memora = @import("memora");
-const Context = memora.Context;
-const Storage = memora.Storage;
-
-const Body = struct {
- user: []const u8,
- password: []const u8,
-};
-
-const Result = struct {
- success: bool,
-};
-
-pub const access = .everyone;
-
-pub fn post(ctx: *Context, body: Body) anyerror!Result {
- var user = Storage.User.open(ctx.storage, body.user) catch return .{
- .success = false
- };
- defer user.deinit();
-
- const result = Result {
- .success = user.check_password(body.password)
- };
-
- if (result.success) {
- const session = try ctx.storage.sessions.add(ctx.storage, user.info);
- ctx.response.headers.fingerprint = session.fingerprint;
- }
-
- return result;
-}
diff --git a/src/routes/api/auth/root.zig b/src/routes/api/auth/root.zig
deleted file mode 100644
index 5f45891..0000000
--- a/src/routes/api/auth/root.zig
+++ /dev/null
@@ -1,4 +0,0 @@
-const HandlerInfo = @import("../../handler-info.zig");
-
-pub const login: HandlerInfo = .from_type(@import("login.zig"));
-pub const @"first-login": HandlerInfo = .from_type(@import("first-login.zig"));
diff --git a/src/routes/api/image/list.zig b/src/routes/api/image/list.zig
deleted file mode 100644
index 5d2eace..0000000
--- a/src/routes/api/image/list.zig
+++ /dev/null
@@ -1,42 +0,0 @@
-const std = @import("std");
-const memora = @import("memora");
-const Context = memora.Context;
-const Storage = memora.Storage;
-
-pub const access = .users;
-
-const ImageInfo = struct {
- id: []const u8,
- timestamp: ?i64,
-};
-
-const Result = struct {
- images: []ImageInfo,
-};
-
-pub fn get(ctx: *Context) !Result {
- var images: std.ArrayList(ImageInfo) = .empty;
-
- var images_list = ctx.storage.images.list();
- defer images_list.unlock();
-
- var locked = ctx.storage.images.first_by_timestamp();
- defer locked.unlock();
-
- var current = locked.value;
-
- while (current) |c| {
- const image = ctx.storage.images.items.items[c.index];
-
- try images.append(ctx.allocator, .{
- .id = try ctx.allocator.dupe(u8, image.id),
- .timestamp = image.timestamp,
- });
-
- current = c.next();
- }
-
- return .{
- .images = try images.toOwnedSlice(ctx.allocator),
- };
-}
diff --git a/src/routes/api/image/load.zig b/src/routes/api/image/load.zig
deleted file mode 100644
index 3ef25d6..0000000
--- a/src/routes/api/image/load.zig
+++ /dev/null
@@ -1,15 +0,0 @@
-const std = @import("std");
-
-const memora = @import("memora");
-const Context = memora.Context;
-const Storage = memora.Storage;
-const mime = @import("../../../mime.zig");
-
-pub const access = .users;
-
-pub fn get(ctx: *Context) !memora.Stream {
- const id = ctx.request.head.target["/api/image/load/".len..];
- var image = Storage.Image { .id = id, .timestamp = null };
- ctx.response.headers.content_type = comptime mime.content_types.get(".jpeg") orelse unreachable;
- return .from_file(try image.file(ctx.storage));
-}
diff --git a/src/routes/api/image/query.zig b/src/routes/api/image/query.zig
deleted file mode 100644
index e69de29..0000000
--- a/src/routes/api/image/query.zig
+++ /dev/null
diff --git a/src/routes/api/image/remove.zig b/src/routes/api/image/remove.zig
deleted file mode 100644
index d99cbb4..0000000
--- a/src/routes/api/image/remove.zig
+++ /dev/null
@@ -1,14 +0,0 @@
-const std = @import("std");
-
-const memora = @import("memora");
-const Context = memora.Context;
-
-pub const access = .users;
-
-const Body = struct {
- id: []const u8,
-};
-
-pub fn post(ctx: *Context, body: Body) anyerror!void {
- return ctx.storage.images.delete(ctx.storage, body.id);
-}
diff --git a/src/routes/api/image/root.zig b/src/routes/api/image/root.zig
deleted file mode 100644
index 931bb06..0000000
--- a/src/routes/api/image/root.zig
+++ /dev/null
@@ -1,6 +0,0 @@
-const HandlerInfo = @import("../../handler-info.zig");
-
-pub const upload: HandlerInfo = .from_type(@import("upload.zig"));
-pub const list: HandlerInfo = .from_type(@import("list.zig"));
-pub const load: HandlerInfo = .from_type(@import("load.zig"));
-pub const remove: HandlerInfo = .from_type(@import("remove.zig"));
diff --git a/src/routes/api/image/upload.zig b/src/routes/api/image/upload.zig
deleted file mode 100644
index 72c8a2d..0000000
--- a/src/routes/api/image/upload.zig
+++ /dev/null
@@ -1,17 +0,0 @@
-const std = @import("std");
-
-const memora = @import("memora");
-const Context = memora.Context;
-const Storage = memora.Storage;
-
-const log = std.log.scoped(.image_upload);
-
-pub const access = .users;
-
-pub fn post(ctx: *Context) !void {
- if (ctx.request.head.content_length) |length| {
- var buffer: [1024]u8 = undefined;
- const reader = try ctx.request.readerExpectContinue(&buffer);
- try ctx.storage.images.save(ctx.storage, reader, length);
- }
-}
diff --git a/src/routes/api/profile/create.zig b/src/routes/api/profile/create.zig
deleted file mode 100644
index 68f32ec..0000000
--- a/src/routes/api/profile/create.zig
+++ /dev/null
@@ -1,29 +0,0 @@
-const std = @import("std");
-
-const memora = @import("memora");
-const Context = memora.Context;
-const Storage = memora.Storage;
-
-pub const access = .admins;
-
-const Body = struct {
- name: []const u8,
- full_name: []const u8,
- birthday: []const u8,
- password: []const u8,
-};
-
-pub fn post(ctx: *Context, body: Body) !void {
- var user = try Storage.User.new(
- ctx.storage,
- body.name,
- body.full_name,
- body.birthday,
- body.password,
- true,
- ctx.storage.allocator,
- );
- defer user.deinit();
-
- try user.sync();
-}
diff --git a/src/routes/api/profile/image/load.zig b/src/routes/api/profile/image/load.zig
deleted file mode 100644
index 4b696ce..0000000
--- a/src/routes/api/profile/image/load.zig
+++ /dev/null
@@ -1,17 +0,0 @@
-const std = @import("std");
-
-const memora = @import("memora");
-const Context = memora.Context;
-const Storage = memora.Storage;
-
-pub const access = .users;
-
-pub fn get(ctx: *Context) !memora.Stream {
- const name = ctx.request.head.target["/api/profile/image/load/".len..];
- if (Storage.User.image(ctx.storage, name)) |file| {
- ctx.response.headers.content_type = "image/jpeg";
- return .from_file(file);
- }
-
- return error.NotFound;
-}
diff --git a/src/routes/api/profile/image/root.zig b/src/routes/api/profile/image/root.zig
deleted file mode 100644
index d6b77f2..0000000
--- a/src/routes/api/profile/image/root.zig
+++ /dev/null
@@ -1,5 +0,0 @@
-const memora = @import("memora");
-const HandlerInfo = memora.routes.HandlerInfo;
-
-pub const upload: HandlerInfo = .from_type(@import("upload.zig"));
-pub const load: HandlerInfo = .from_type(@import("load.zig"));
diff --git a/src/routes/api/profile/image/upload.zig b/src/routes/api/profile/image/upload.zig
deleted file mode 100644
index db140d4..0000000
--- a/src/routes/api/profile/image/upload.zig
+++ /dev/null
@@ -1,19 +0,0 @@
-const std = @import("std");
-
-const memora = @import("memora");
-const Context = memora.Context;
-const Storage = memora.Storage;
-
-pub const access = .users;
-
-pub fn post(ctx: *Context) !void {
- const name = ctx.request.head.target["/api/profile/image/upload/".len..];
- if (ctx.request.head.content_length) |length| {
- var buffer: [1024]u8 = undefined;
- const reader = try ctx.request.readerExpectContinue(&buffer);
-
- try Storage.User.set_image(ctx.storage, name, reader, length);
-
- ctx.response.headers.content_type = "image/jpeg";
- }
-}
diff --git a/src/routes/api/profile/list.zig b/src/routes/api/profile/list.zig
deleted file mode 100644
index 59d4684..0000000
--- a/src/routes/api/profile/list.zig
+++ /dev/null
@@ -1,17 +0,0 @@
-const std = @import("std");
-
-const memora = @import("memora");
-const Context = memora.Context;
-const Storage = memora.Storage;
-
-pub const access = .admins;
-
-const Response = struct {
- users: [][]const u8,
-};
-
-pub fn get(ctx: *Context) !Response {
- return .{
- .users = try Storage.User.list(ctx.storage, ctx.allocator)
- };
-}
diff --git a/src/routes/api/profile/root.zig b/src/routes/api/profile/root.zig
deleted file mode 100644
index 45dec8e..0000000
--- a/src/routes/api/profile/root.zig
+++ /dev/null
@@ -1,8 +0,0 @@
-const memora = @import("memora");
-const HandlerInfo = memora.routes.HandlerInfo;
-
-pub const image = @import("image/root.zig");
-pub const set: HandlerInfo = .from_type(@import("set.zig"));
-pub const @"update-password": HandlerInfo = .from_type(@import("update-password.zig"));
-pub const create: HandlerInfo = .from_type(@import("create.zig"));
-pub const list: HandlerInfo = .from_type(@import("list.zig"));
diff --git a/src/routes/api/profile/set.zig b/src/routes/api/profile/set.zig
deleted file mode 100644
index a007b23..0000000
--- a/src/routes/api/profile/set.zig
+++ /dev/null
@@ -1,26 +0,0 @@
-const std = @import("std");
-
-const memora = @import("memora");
-const Context = memora.Context;
-const Storage = memora.Storage;
-
-pub const access = .users;
-
-const Body = struct {
- full_name: []const u8,
- birthday: []const u8,
-};
-
-pub fn post(ctx: *Context, body: Body) !void {
- if (ctx.storage.sessions.get(ctx.storage, ctx.fingerprint)) |session| {
- var user = try Storage.User.open(ctx.storage, session.info.name);
- defer user.deinit();
-
- user.info.full_name = body.full_name;
- user.info.birthday = body.birthday;
-
- try user.sync();
- } else {
- return error.UnknownSession;
- }
-}
diff --git a/src/routes/api/profile/update-password.zig b/src/routes/api/profile/update-password.zig
deleted file mode 100644
index ac6ceed..0000000
--- a/src/routes/api/profile/update-password.zig
+++ /dev/null
@@ -1,37 +0,0 @@
-const std = @import("std");
-
-const memora = @import("memora");
-const Context = memora.Context;
-const Storage = memora.Storage;
-
-pub const access = .users;
-
-const Body = struct {
- current_password: []const u8,
- new_password: []const u8,
-};
-
-const Response = struct {
- success: bool,
-};
-
-pub fn post(ctx: *Context, body: Body) !Response {
- if (ctx.storage.sessions.get(ctx.storage, ctx.fingerprint)) |session| {
- var user = try Storage.User.open(ctx.storage, session.info.name);
- defer user.deinit();
-
- const result = Response {
- .success = user.check_password(body.current_password)
- };
-
- if (result.success) {
- try user.set_password(body.new_password);
- try user.sync();
- }
-
- return result;
-
- } else {
- return error.UnknownSession;
- }
-}
diff --git a/src/routes/api/root.zig b/src/routes/api/root.zig
deleted file mode 100644
index 5f731c3..0000000
--- a/src/routes/api/root.zig
+++ /dev/null
@@ -1,4 +0,0 @@
-pub const auth = @import("auth/root.zig");
-pub const session = @import("session/root.zig");
-pub const image = @import("image/root.zig");
-pub const profile = @import("profile/root.zig");
diff --git a/src/routes/api/session/current.zig b/src/routes/api/session/current.zig
deleted file mode 100644
index 897d01c..0000000
--- a/src/routes/api/session/current.zig
+++ /dev/null
@@ -1,27 +0,0 @@
-const std = @import("std");
-
-const memora = @import("memora");
-const Context = memora.Context;
-
-pub const access = .users;
-
-const Result = struct {
- name: []const u8,
- full_name: []const u8,
- birthday: []const u8,
- is_admin: bool,
-};
-
-pub fn get(ctx: *Context) !Result {
- const session = ctx.storage.sessions.get(
- ctx.storage,
- ctx.fingerprint,
- ) orelse return error.UserDoesNotExist;
-
- return .{
- .name = session.info.name,
- .full_name = session.info.full_name,
- .birthday = session.info.birthday,
- .is_admin = session.info.is_admin,
- };
-}
diff --git a/src/routes/api/session/drop.zig b/src/routes/api/session/drop.zig
deleted file mode 100644
index 4b193e0..0000000
--- a/src/routes/api/session/drop.zig
+++ /dev/null
@@ -1,9 +0,0 @@
-const memora = @import("memora");
-const Context = memora.Context;
-
-pub const access = .users;
-
-pub fn get(ctx: *Context) !void {
- ctx.storage.sessions.remove(ctx.storage, ctx.fingerprint);
- ctx.response.headers.fingerprint = "";
-}
diff --git a/src/routes/api/session/is-online.zig b/src/routes/api/session/is-online.zig
deleted file mode 100644
index f5ebaee..0000000
--- a/src/routes/api/session/is-online.zig
+++ /dev/null
@@ -1,15 +0,0 @@
-const std = @import("std");
-
-const memora = @import("memora");
-const Context = memora.Context;
-
-pub const access = .everyone;
-
-const Result = struct {
- is_online: bool,
-};
-
-pub fn get(ctx: *Context) !Result {
- _ = ctx;
- return .{ .is_online = true };
-}
diff --git a/src/routes/api/session/is-valid.zig b/src/routes/api/session/is-valid.zig
deleted file mode 100644
index 8cf6794..0000000
--- a/src/routes/api/session/is-valid.zig
+++ /dev/null
@@ -1,21 +0,0 @@
-const std = @import("std");
-const config = @import("config");
-
-const memora = @import("memora");
-const Context = memora.Context;
-
-pub const access = .everyone;
-
-const Result = struct {
- is_valid: bool
-};
-
-pub fn get(ctx: *Context) !Result {
- if (comptime config.disable_auth) {
- return .{ .is_valid = true };
- }
-
- return .{
- .is_valid = ctx.storage.sessions.get(ctx.storage, ctx.fingerprint) != null
- };
-}
diff --git a/src/routes/api/session/renew.zig b/src/routes/api/session/renew.zig
deleted file mode 100644
index c13e27e..0000000
--- a/src/routes/api/session/renew.zig
+++ /dev/null
@@ -1,9 +0,0 @@
-const memora = @import("memora");
-const Context = memora.Context;
-
-pub const access = .users;
-
-pub fn get(ctx: *Context) !void {
- const new = try ctx.storage.sessions.renew(ctx.storage, ctx.fingerprint);
- ctx.response.headers.fingerprint = new.fingerprint;
-}
diff --git a/src/routes/api/session/root.zig b/src/routes/api/session/root.zig
deleted file mode 100644
index a889869..0000000
--- a/src/routes/api/session/root.zig
+++ /dev/null
@@ -1,7 +0,0 @@
-const HandlerInfo = @import("../../handler-info.zig");
-
-pub const current: HandlerInfo = .from_type(@import("current.zig"));
-pub const drop: HandlerInfo = .from_type(@import("drop.zig"));
-pub const renew: HandlerInfo = .from_type(@import("renew.zig"));
-pub const @"is-valid": HandlerInfo = .from_type(@import("is-valid.zig"));
-pub const @"is-online": HandlerInfo = .from_type(@import("is-online.zig"));
diff --git a/src/routes/handler-info.zig b/src/routes/handler-info.zig
deleted file mode 100644
index ca4babd..0000000
--- a/src/routes/handler-info.zig
+++ /dev/null
@@ -1,225 +0,0 @@
-const std = @import("std");
-
-const memora = @import("memora");
-const Context = memora.Context;
-const Storage = memora.Storage;
-
-const config = @import("config");
-
-const Access = @import("access.zig").Access;
-
-const log = std.log.scoped(.handler_info);
-
-const Self = @This();
-
-const Handler = *const fn (*Context) anyerror!memora.Stream;
-
-get: ?Handler,
-head: ?Handler,
-post: ?Handler,
-put: ?Handler,
-delete: ?Handler,
-connect: ?Handler,
-options: ?Handler,
-trace: ?Handler,
-patch: ?Handler,
-access: Access,
-
-inline fn handler_from_method(self: *const Self, method: std.http.Method) ?Handler {
- return switch (method) {
- .GET => self.get,
- .HEAD => self.head,
- .POST => self.post,
- .PUT => self.put,
- .DELETE => self.delete,
- .CONNECT => self.connect,
- .OPTIONS => self.options,
- .TRACE => self.trace,
- .PATCH => self.patch,
- };
-}
-
-inline fn get_fingerprint(cookie: []const u8) []const u8 {
- const start = std.mem.indexOf(u8, cookie, "fingerprint=") orelse return "";
- const end = std.mem.indexOf(u8, cookie[start + 12..], " ") orelse return cookie[start + 12..];
- return cookie[start..end + 1];
-}
-
-pub fn handle(
- self: *const Self,
- request: *std.http.Server.Request,
- storage: *Storage,
- allocator: std.mem.Allocator,
-) !void {
- const target = try allocator.dupe(u8, request.head.target);
- defer allocator.free(target);
-
- const handler = self.handler_from_method(request.head.method) orelse return request.respond(
- "{ \"error\": \"Bad Request\" }",
- .{ .status = .bad_request }
- );
-
- const cookie = cookie: {
- var iterator = request.iterateHeaders();
- while (iterator.next()) |header| {
- if (std.ascii.eqlIgnoreCase(header.name, "cookie")) {
- break :cookie header.value;
- }
- }
- break :cookie "";
- };
-
- var arena = std.heap.ArenaAllocator.init(allocator);
- defer arena.deinit();
- var context: Context = .{
- .request = request,
- .storage = storage,
- .allocator = arena.allocator(),
- .fingerprint = get_fingerprint(cookie),
- };
-
- if (!comptime config.disable_auth) {
- const allowed = switch (self.access) {
- .everyone => true,
- .users => storage.sessions.get(storage, context.fingerprint) != null,
- .admins => admin: {
- if (storage.sessions.get(storage, context.fingerprint)) |session| {
- break :admin session.info.is_admin;
- }
- break :admin false;
- },
- };
-
- if (!allowed) {
- return request.respond(
- "{ \"error\": \"Forbidden\" }",
- .{ .status = .forbidden }
- );
- }
- }
-
- var stream = handler(&context) catch |err| {
- const response, const status_code: std.http.Status = switch (err) {
- error.BadRequest => .{ "{ \"error\": \"Bad Request\" }", .bad_request },
- error.Unauthorized => .{ "{ \"error\": \"Unauthorized\" }", .unauthorized },
- error.Forbidden => .{ "{ \"error\": \"Forbidden\" }", .forbidden },
- error.NotFound => .{ "{ \"error\": \"Not Found\" }", .not_found },
- else => blk: {
- log.err("handler for '{s}' returned {}", .{target, err});
- break :blk .{ "{ \"error\": \"Internal Server Error\" }", .internal_server_error };
- },
- };
-
- return request.respond(response, .{ .status = status_code });
- };
- defer stream.close();
-
- var headers: std.ArrayList(std.http.Header) = .empty;
- defer headers.deinit(allocator);
-
- try headers.append(allocator, .{
- .name = "Content-Type",
- .value = context.response.headers.content_type
- });
-
- try headers.append(allocator, .{
- .name = "Service-Worker-Allowed",
- .value = "/",
- });
-
- if (context.response.headers.fingerprint) |auth_token| {
- var value = std.Io.Writer.Allocating.init(arena.allocator());
-
- try value.writer.print("fingerprint={s}; Secure; Path=/; Max-Age={}", .{
- auth_token,
- storage.config.session_expires_after / std.time.ns_per_s,
- });
-
- try headers.append(allocator, .{
- .name = "Set-Cookie",
- .value = value.written(),
- });
- }
-
- var read_buffer: [1024]u8 = undefined;
- var reader = stream.reader(&read_buffer);
-
- var write_buffer: [1024]u8 = undefined;
- var body_writer = try request.respondStreaming(&write_buffer, .{
- .respond_options = .{
- .extra_headers = headers.items,
- .transfer_encoding = .chunked,
- },
- });
-
- _ = try reader.streamRemaining(&body_writer.writer);
- try body_writer.end();
-}
-
-fn HandlerWrapper(T: type, name: []const u8) type {
- const info = @typeInfo(@TypeOf(@field(T, name)));
- const return_type = info.@"fn".return_type orelse void;
- const payload_type = @typeInfo(return_type).error_union.payload;
-
- return struct {
- pub fn call(ctx: *Context) anyerror!memora.Stream {
- const args = args: {
- const tuple = std.meta.fields(std.meta.ArgsTuple(@TypeOf(@field(T, name))));
-
- if (tuple.len == 1) {
- break :args .{ ctx };
- } else if (tuple.len == 2) {
- const Body = tuple[1].@"type";
-
- var writer = std.Io.Writer.Allocating.init(ctx.allocator);
- const interface = &writer.writer;
-
- var buffer: [1024]u8 = undefined;
- const reader = try ctx.request.readerExpectContinue(&buffer);
-
- try reader.streamExact64(interface, ctx.request.head.content_length orelse 0);
-
- const body = std.json.parseFromSliceLeaky(
- Body,
- ctx.allocator,
- writer.written(),
- .{},
- ) catch |err| {
- log.warn("failed to parse JSON {}", .{err});
- return error.BadRequest;
- };
- break :args .{ ctx, body };
- } else {
- @compileError("invalid amount of arguments for request function");
- }
- };
-
- if (payload_type == memora.Stream) {
- return @call(.auto, @field(T, name), args);
- } else if (payload_type == void) {
- try @call(.auto, @field(T, name), args);
- return memora.Stream.from_buffer("{}");
- } else {
- var writer = std.Io.Writer.Allocating.init(ctx.allocator);
- var stringify = std.json.Stringify { .writer = &writer.writer };
- try stringify.write(try @call(.auto, @field(T, name), args));
- return memora.Stream.from_buffer(writer.written());
- }
- }
- };
-}
-
-pub fn from_type(T: type) @This() {
- return Self {
- .get = if (@hasDecl(T, "get")) HandlerWrapper(T, "get").call else null,
- .head = if (@hasDecl(T, "head")) HandlerWrapper(T, "head").call else null,
- .post = if (@hasDecl(T, "post")) HandlerWrapper(T, "post").call else null,
- .put = if (@hasDecl(T, "put")) HandlerWrapper(T, "put").call else null,
- .delete = if (@hasDecl(T, "delete")) HandlerWrapper(T, "delete").call else null,
- .connect = if (@hasDecl(T, "connect")) HandlerWrapper(T, "connect").call else null,
- .options = if (@hasDecl(T, "options")) HandlerWrapper(T, "options").call else null,
- .trace = if (@hasDecl(T, "trace")) HandlerWrapper(T, "trace").call else null,
- .patch = if (@hasDecl(T, "patch")) HandlerWrapper(T, "patch").call else null,
- .access = T.access,
- };
-}
diff --git a/src/routes/root.zig b/src/routes/root.zig
deleted file mode 100644
index c438893..0000000
--- a/src/routes/root.zig
+++ /dev/null
@@ -1,49 +0,0 @@
-const std = @import("std");
-
-pub const HandlerInfo = @import("handler-info.zig");
-
-pub const api = @import("api/root.zig");
-pub const static: HandlerInfo = .from_type(@import("static.zig"));
-
-const routes = (Routes {})
- .with("", static)
- .with_module("/api", api);
-
-pub const handlers = std.StaticStringMap(HandlerInfo).initComptime(routes.items);
-
-pub fn get(path: []const u8) HandlerInfo {
- return (handlers.getLongestPrefix(std.mem.trimEnd(u8, path, "/")) orelse unreachable).value;
-}
-
-const Routes = struct {
- const Self = @This();
-
- const Route = struct{ []const u8, HandlerInfo };
-
- items: []const Route = &[0]Route{},
-
- pub fn with(self: Self, comptime route: []const u8, handler: HandlerInfo) Self {
- var next = self;
- const tail: []const Route = &[1]Route { .{ route, handler } };
- next.items = self.items ++ tail;
- return next;
- }
-
- pub fn with_module(self: Self, comptime prefix: []const u8, module: type) Self {
- var next = self;
-
- if (@typeInfo(module) != .@"struct") return self;
-
- inline for (@typeInfo(module).@"struct".decls) |decl| {
- const field = @field(module, decl.name);
- const route = prefix ++ "/" ++ decl.name;
- switch (@TypeOf(field)) {
- type => next = next.with_module(route, field),
- HandlerInfo => next = next.with(route, field),
- else => {},
- }
- }
-
- return next;
- }
-};
diff --git a/src/routes/static.zig b/src/routes/static.zig
deleted file mode 100644
index f8f7a6c..0000000
--- a/src/routes/static.zig
+++ /dev/null
@@ -1,35 +0,0 @@
-const std = @import("std");
-const mime = @import("../mime.zig");
-const config = @import("config");
-
-const memora = @import("memora");
-const Context = memora.Context;
-
-const log = std.log.scoped(.fallback);
-
-pub const access = .everyone;
-
-pub fn get(ctx: *Context) anyerror!memora.Stream {
- var static = try std.fs.cwd().openDir(config.static_path, .{});
- defer static.close();
-
- if (static.openFile(ctx.request.head.target[1..], .{})) |file| {
- const mime_type = mime.get_type(ctx.request.head.target);
- ctx.response.headers.content_type = mime_type;
- return .from_file(file);
- } else |_| {
- var subdir = if (ctx.request.head.target.len == 1) static
- else (static.openDir(ctx.request.head.target[1..], .{}) catch {
- return error.NotFound;
- });
- defer if (ctx.request.head.target.len > 1) subdir.close();
-
- if (subdir.openFile("index.html", .{})) |file| {
- ctx.response.headers.content_type = "text/html";
- return .from_file(file);
- } else |_| {
- log.warn("File '{s}' Not Found", .{ ctx.request.head.target });
- return error.NotFound;
- }
- }
-}