diff --git a/src/db.zig b/src/db.zig index 0a0f106..684ff31 100644 --- a/src/db.zig +++ b/src/db.zig @@ -1,5 +1,8 @@ +const root = @import("root"); +const Uuid = root.Uuid; + pub const Actor = struct { - id: u128, + id: Uuid, display_name: ?[]const u8 = null, handle: []const u8, host: []const u8, @@ -9,13 +12,13 @@ pub const Actor = struct { const this_host = "localhost:8080"; const actor = Actor{ - .id = 1234, + .id = Uuid.parse("f75f5160-12d3-42c2-a81d-ad2245b7a74b") catch unreachable, .handle = "testacct", .host = this_host, }; -pub fn getActorById(id: u128) !?Actor { - if (id == actor.id) return actor; +pub fn getActorById(id: Uuid) !?Actor { + if (Uuid.eql(id, actor.id)) return actor; return null; } diff --git a/src/main.zig b/src/main.zig index 6ef975c..0871c15 100644 --- a/src/main.zig +++ b/src/main.zig @@ -6,6 +6,62 @@ pub const io_mode = .evented; const Reader = std.net.Stream.Reader; const Writer = std.net.Stream.Writer; +pub const Uuid = struct { + data: [16]u8, + + pub fn eql(lhs: Uuid, rhs: Uuid) bool { + return std.mem.eql(u8, &lhs.data, &rhs.data); + } + + pub fn format(value: Uuid, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void { + try std.fmt.format(writer, "{x:0>2}{x:0>2}{x:0>2}{x:0>2}-{x:0>2}{x:0>2}-{x:0>2}{x:0>2}-{x:0>2}{x:0>2}-{x:0>2}{x:0>2}{x:0>2}{x:0>2}{x:0>2}{x:0>2}", .{ + value.data[0], + value.data[1], + value.data[2], + value.data[3], + value.data[4], + value.data[5], + value.data[6], + value.data[7], + value.data[8], + value.data[9], + value.data[10], + value.data[11], + value.data[12], + value.data[13], + value.data[14], + value.data[15], + }); + } + + const ParseError = error{ + InvalidCharacter, + }; + pub fn parse(str: []const u8) ParseError!Uuid { + if (str.len < 36) return error.InvalidCharacter; + + var uuid: Uuid = undefined; + var str_i: usize = 0; + var i: usize = 0; + while (i < 16 and str_i < str.len) : ({ + i += 1; + str_i += 2; + }) { + uuid.data[i] = std.fmt.parseInt(u8, str[str_i .. str_i + 2], 16) catch |err| switch (err) { + error.InvalidCharacter => return error.InvalidCharacter, + else => unreachable, + }; + + if (i == 3 or i == 5 or i == 7 or i == 9) { + if (str[str_i + 2] != '-') return error.InvalidCharacter; + str_i += 1; + } + } + + return uuid; + } +}; + const ciutf8 = struct { const Hash = std.hash.Wyhash; const View = std.unicode.Utf8View; @@ -508,18 +564,19 @@ const this_host = "localhost:8080"; fn getUser(ctx: *Context) anyerror!void { const id_str = ctx.request.arg("id"); - const host = ctx.request.headers.get("host"); - if (host == null) { + const host = ctx.request.headers.get("host") orelse { try ctx.response.statusOnly(400); return; - } + }; + + const id = Uuid.parse(id_str) catch { + try ctx.response.statusOnly(400); + return; + }; - const id = try std.fmt.parseInt(u128, id_str, 10); const actor = try db.getActorById(id); - if (actor == null or - !std.mem.eql(u8, actor.?.host, ctx.request.headers.get("host").?)) - { + if (actor == null or !std.mem.eql(u8, actor.?.host, host)) { try ctx.response.statusOnly(404); return; } @@ -546,6 +603,9 @@ pub fn main() anyerror!void { var srv = std.net.StreamServer.init(.{ .reuse_address = true }); defer srv.deinit(); + const uuid = try Uuid.parse("f75f5160-12d3-42c2-a81d-ad2245b7a74b"); + std.log.debug("{}", .{uuid}); + try srv.listen(std.net.Address.parseIp("0.0.0.0", 8080) catch unreachable); while (true) {