Skip to content

Commit

Permalink
Merge branch 'middlewares'
Browse files Browse the repository at this point in the history
  • Loading branch information
karlseguin committed Aug 20, 2024
2 parents 201da69 + 56e5c43 commit 9dd9b83
Show file tree
Hide file tree
Showing 12 changed files with 681 additions and 449 deletions.
2 changes: 1 addition & 1 deletion example/dispatcher.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub fn start(allocator: Allocator) !void {
defer server.deinit();

var router = server.router();
router.get("/increment", increment);
router.get("/increment", increment, .{});
return server.listen();
}

Expand Down
2 changes: 1 addition & 1 deletion example/global.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub fn start(allocator: Allocator) !void {
var server = try httpz.Server(*Handler).init(allocator, .{ .port = 5883 }, &handler);
defer server.deinit();
var router = server.router();
router.get("/increment", increment);
router.get("/increment", increment, .{});
return server.listen();
}

Expand Down
52 changes: 52 additions & 0 deletions example/middleware/Logger.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// This is a sample middleware

// Generally, using a custom Handler with a dispatch method provides the most
// flexibility and should be your first approach (see the dispatcher.zig example).

// Middleware provide an alternative way to manipulate the request/response and
// is well suited if you need different middleware (or middleware configurations)
// for different routes.

const std = @import("std");
const httpz = @import("httpz");

const Logger = @This();

query: bool,

// Must define an `init` method, which will accept your Config
// Alternatively, you can define a init(config: Config, mc: httpz.MiddlewareConfig)
// here mc will give you access to the server's allocator and arena
pub fn init(config: Config) !Logger {
return .{
.query = config.query,
};
}

// optionally you can define an "deinit" method
// pub fn deinit(self: *Logger) void {

// }

// Must define an `execute` method. `self` doesn't have to be `const`, but
// you're responsible for making your middleware thread-safe.
pub fn execute(self: *const Logger, req: *httpz.Request, res: *httpz.Response, executor: anytype) !void {
// Better to use an std.time.Timer to measure elapsed time
// but we need the "start" time for our log anyways, so while this might occasionally
// report wrong/strange "elapsed" time, it's simpler to do.
const start = std.time.microTimestamp();

defer {
const elapsed = std.time.microTimestamp() - start;
std.log.info("{d}\t{s}?{s}\t{d}\t{d}us", .{start, req.url.path, if (self.query) req.url.query else "", res.status, elapsed});
}

// If you don't call executor.next(), there will be no further processing of
// the request and we'll go straight to writing the response.
return executor.next();
}

// Must defined a pub config structure, even if it's empty
pub const Config = struct {
query: bool,
};
17 changes: 10 additions & 7 deletions example/simple.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const std = @import("std");
const httpz = @import("httpz");
const websocket = httpz.websocket;
const Allocator = std.mem.Allocator;
const Logger = @import("middleware/Logger.zig");

var index_file_contents: []u8 = undefined;

Expand All @@ -17,13 +18,15 @@ pub fn start(allocator: Allocator) !void {
index_file_contents = try index_file.readToEndAlloc(allocator, 100000);
defer allocator.free(index_file_contents);

router.get("/", index);
router.get("/hello", hello);
router.get("/json/hello/:name", json);
router.get("/writer/hello/:name", writer);
router.get("/static_file", staticFile);
router.get("/cached_static_file", cachedStaticFile);
router.get("/metrics", metrics);
const logger = try server.middleware(Logger, .{.query = true});

router.get("/", index, .{});
router.get("/hello", hello, .{});
router.get("/json/hello/:name", json, .{.middlewares = &.{logger}});
router.get("/writer/hello/:name", writer, .{});
router.get("/static_file", staticFile, .{});
router.get("/cached_static_file", cachedStaticFile, .{});
router.get("/metrics", metrics, .{});
try server.listen();
}

Expand Down
Loading

0 comments on commit 9dd9b83

Please sign in to comment.