diff --git a/src/http/Server.zig b/src/http/Server.zig index d8b611d..35ae7f1 100644 --- a/src/http/Server.zig +++ b/src/http/Server.zig @@ -12,7 +12,7 @@ allocator: std.mem.Allocator, httpz_server: httpz.Server(*Context), context: Context, -const Context = struct { +pub const Context = struct { options: handler.HandleWeatherOptions, rate_limiter: *RateLimiter, @@ -45,6 +45,7 @@ pub fn init( rate_limiter: *RateLimiter, ) !Server { const ctx = try allocator.create(Context); + errdefer allocator.destroy(ctx); ctx.* = .{ .options = options, .rate_limiter = rate_limiter, diff --git a/src/http/handler.zig b/src/http/handler.zig index 1f6202f..c1f7c9b 100644 --- a/src/http/handler.zig +++ b/src/http/handler.zig @@ -21,6 +21,9 @@ pub const HandleWeatherOptions = struct { geoip: *@import("../location/GeoIp.zig"), }; +/// Only used for shutdown route (/stop) in debug mode +pub var server_instance: ?*httpz.Server(*@import("Server.zig").Context) = null; + pub fn handleWeather( opts: *HandleWeatherOptions, req: *httpz.Request, @@ -42,6 +45,11 @@ pub fn handleWeather( break :blk loc; } else break :blk client_ip; // no location, just use client ip instead }; + if (server_instance) |s| + if (std.mem.eql(u8, location, "stop")) { + s.stop(); + return; + }; if (std.mem.eql(u8, "favicon.ico", location)) { res.header("Content-Type", "image/x-icon"); diff --git a/src/main.zig b/src/main.zig index e75ecc5..9b32bee 100644 --- a/src/main.zig +++ b/src/main.zig @@ -80,7 +80,11 @@ pub fn main() !u8 { .geoip = &geoip, }, &rate_limiter); + // Only set up the server instance in debug mode + if (@import("builtin").mode == .Debug) @import("http/handler.zig").server_instance = &server.httpz_server; + try server.listen(); + std.debug.print("shutting down\n", .{}); return 0; }