diff options
Diffstat (limited to 'src/routes')
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; - } - } -} |