|
| 1 | +const std = @import("std"); |
| 2 | + |
| 3 | +const zzz = @import("zzz"); |
| 4 | +const http = zzz.HTTP; |
| 5 | + |
| 6 | +const tardy = zzz.tardy; |
| 7 | +const Tardy = tardy.Tardy(.auto); |
| 8 | +const Runtime = tardy.Runtime; |
| 9 | +const Socket = tardy.Socket; |
| 10 | + |
| 11 | +const Server = http.Server; |
| 12 | +const Router = http.Router; |
| 13 | +const Context = http.Context; |
| 14 | +const Route = http.Route; |
| 15 | +const Respond = http.Respond; |
| 16 | + |
| 17 | +const Message = struct { message: []const u8 }; |
| 18 | +var date: [29]u8 = undefined; |
| 19 | + |
| 20 | +pub fn main() !void { |
| 21 | + const host: []const u8 = "0.0.0.0"; |
| 22 | + const port: u16 = 8080; |
| 23 | + |
| 24 | + const date_thread = try std.Thread.spawn(.{}, struct { |
| 25 | + fn a() !void { |
| 26 | + while (true) { |
| 27 | + var d = http.Date.init(std.time.timestamp()); |
| 28 | + const http_date = d.to_http_date(); |
| 29 | + _ = try http_date.into_buf(date[0..]); |
| 30 | + std.time.sleep(std.time.ns_per_ms * 985); |
| 31 | + } |
| 32 | + } |
| 33 | + }.a, .{}); |
| 34 | + |
| 35 | + date_thread.detach(); |
| 36 | + |
| 37 | + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; |
| 38 | + defer if (gpa.deinit() == .leak) { |
| 39 | + @panic("Memory leak has occurred!"); |
| 40 | + }; |
| 41 | + |
| 42 | + const allocator = gpa.allocator(); |
| 43 | + |
| 44 | + var t = try Tardy.init(allocator, .{ |
| 45 | + .threading = .all, |
| 46 | + }); |
| 47 | + defer t.deinit(); |
| 48 | + |
| 49 | + var router = try Router.init(allocator, &.{ |
| 50 | + Route.init("/plaintext").get({}, home_handler).layer(), |
| 51 | + Route.init("/json").get({}, json_handler).layer(), |
| 52 | + }, .{}); |
| 53 | + defer router.deinit(allocator); |
| 54 | + |
| 55 | + var socket = try Socket.init(.{ .tcp = .{ .host = host, .port = port } }); |
| 56 | + defer socket.close_blocking(); |
| 57 | + try socket.bind(); |
| 58 | + try socket.listen(4096); |
| 59 | + |
| 60 | + const EntryParams = struct { |
| 61 | + router: *const Router, |
| 62 | + socket: Socket, |
| 63 | + }; |
| 64 | + |
| 65 | + try t.entry( |
| 66 | + EntryParams{ .router = &router, .socket = socket }, |
| 67 | + struct { |
| 68 | + fn entry(rt: *Runtime, p: EntryParams) !void { |
| 69 | + var server = Server.init(.{ |
| 70 | + .capture_count_max = 0, |
| 71 | + }); |
| 72 | + try server.serve(rt, p.router, .{ .normal = p.socket }); |
| 73 | + } |
| 74 | + }.entry, |
| 75 | + ); |
| 76 | +} |
| 77 | + |
| 78 | +pub fn home_handler(ctx: *const Context, _: void) !Respond { |
| 79 | + try ctx.response.headers.put("Date", try ctx.allocator.dupe(u8, date[0..])); |
| 80 | + return ctx.response.apply(.{ |
| 81 | + .mime = http.Mime.TEXT, |
| 82 | + .body = "Hello, World!", |
| 83 | + .status = .OK, |
| 84 | + }); |
| 85 | +} |
| 86 | + |
| 87 | +pub fn json_handler(ctx: *const Context, _: void) !Respond { |
| 88 | + try ctx.response.headers.put("Date", try ctx.allocator.dupe(u8, date[0..])); |
| 89 | + return ctx.response.apply(.{ |
| 90 | + .mime = http.Mime.JSON, |
| 91 | + .body = try std.json.stringifyAlloc(ctx.allocator, Message{ .message = "Hello, World!" }, .{}), |
| 92 | + .status = .OK, |
| 93 | + }); |
| 94 | +} |
0 commit comments