simplify structure

This commit is contained in:
Emil Lerch 2025-12-18 17:58:15 -08:00
parent 7d06d281e0
commit 60cede5a8b
Signed by: lobo
GPG key ID: A7B62D657EF764F8
3 changed files with 28 additions and 47 deletions

View file

@ -2,7 +2,6 @@ const std = @import("std");
const httpz = @import("httpz"); const httpz = @import("httpz");
const handler = @import("handler.zig"); const handler = @import("handler.zig");
const RateLimiter = @import("RateLimiter.zig"); const RateLimiter = @import("RateLimiter.zig");
const middleware = @import("middleware.zig");
const Server = @This(); const Server = @This();
@ -36,8 +35,8 @@ pub fn init(
// We won't use actual middleware for rate limiting here because we only have // We won't use actual middleware for rate limiting here because we only have
// a couple routes to protect with rate limiting // a couple routes to protect with rate limiting
var router = try httpz_server.router(.{}); var router = try httpz_server.router(.{});
router.get("/", handleWeatherRoot, .{}); router.get("/", handleWeather, .{});
router.get("/:location", handleWeatherLocation, .{}); router.get("/:location", handleWeather, .{});
return Server{ return Server{
.allocator = allocator, .allocator = allocator,
@ -46,16 +45,20 @@ pub fn init(
}; };
} }
fn handleWeatherRoot(ctx: *Context, req: *httpz.Request, res: *httpz.Response) !void { fn handleWeather(ctx: *Context, req: *httpz.Request, res: *httpz.Response) !void {
try middleware.rateLimitMiddleware(ctx.rate_limiter, req, res); try rateLimitMiddleware(ctx.rate_limiter, req, res);
if (res.status == 429) return; if (res.status == 429) return;
try handler.handleWeather(&ctx.options, req, res); try handler.handleWeather(&ctx.options, req, res);
} }
fn handleWeatherLocation(ctx: *Context, req: *httpz.Request, res: *httpz.Response) !void { fn rateLimitMiddleware(limiter: *RateLimiter, req: *httpz.Request, res: *httpz.Response) !void {
try middleware.rateLimitMiddleware(ctx.rate_limiter, req, res); var ip_buf: [45]u8 = undefined;
if (res.status == 429) return; const ip_str = try std.fmt.bufPrint(&ip_buf, "{f}", .{req.address});
try handler.handleWeatherLocation(&ctx.options, req, res);
if (!limiter.shouldAcceptRequest(ip_str)) {
res.status = 429;
res.body = "Too Many Requests";
}
} }
pub fn listen(self: *Server) !void { pub fn listen(self: *Server) !void {

View file

@ -24,7 +24,9 @@ pub fn handleWeather(
req: *httpz.Request, req: *httpz.Request,
res: *httpz.Response, res: *httpz.Response,
) !void { ) !void {
// Check for location query parameter first // Get location from path parameter or query string
const location = req.param("location") orelse blk: {
// Check query string for location parameter
const query_string = req.url.query; const query_string = req.url.query;
const params = try QueryParams.parse(req.arena, query_string); const params = try QueryParams.parse(req.arena, query_string);
defer { defer {
@ -32,22 +34,15 @@ pub fn handleWeather(
if (params.lang) |l| req.arena.free(l); if (params.lang) |l| req.arena.free(l);
} }
const location = if (params.location) |loc| loc else blk: { if (params.location) |loc| {
break :blk loc;
} else {
// Fall back to IP-based detection // Fall back to IP-based detection
const client_ip = getClientIP(req); const client_ip = getClientIP(req);
break :blk client_ip; break :blk client_ip;
}
}; };
try handleWeatherInternal(opts, req, res, location);
}
pub fn handleWeatherLocation(
opts: *HandleWeatherOptions,
req: *httpz.Request,
res: *httpz.Response,
) !void {
const location = req.param("location") orelse "London";
// Handle special endpoints // Handle special endpoints
if (std.mem.startsWith(u8, location, ":")) { if (std.mem.startsWith(u8, location, ":")) {
if (std.mem.eql(u8, location, ":help")) { if (std.mem.eql(u8, location, ":help")) {

View file

@ -1,17 +0,0 @@
const std = @import("std");
const httpz = @import("httpz");
const RateLimiter = @import("RateLimiter.zig");
pub fn rateLimitMiddleware(limiter: *RateLimiter, req: *httpz.Request, res: *httpz.Response) !void {
var ip_buf: [45]u8 = undefined; // https://stackoverflow.com/a/166157
const ip_str = try std.fmt.bufPrint(
&ip_buf,
"{f}",
.{req.address},
);
if (!limiter.shouldAcceptRequest(ip_str)) {
res.status = 429;
res.body = "Too Many Requests";
}
}