From d0c59ab008c281edc1b48919c3eda00690fd65f9 Mon Sep 17 00:00:00 2001 From: Rene Schallner Date: Mon, 1 May 2023 04:43:48 +0200 Subject: [PATCH] fixed AuthEndpoint callbacks, BasicAuth logging AuthEndpoint callbacks now provide pointers to the original SimpleEndpoint structs, so their fieldParentPtr calls work. Added extensive debug() logging to BasicAuth with .UserPassword. --- build.zig | 1 + build.zig.zon | 2 +- src/endpoint.zig | 16 ++++++++-------- src/http_auth.zig | 42 +++++++++++++++++++++++++++++++++++++++--- wrk/measure.sh | 7 +++++++ wrk/zigstd/main.zig | 34 ++++++++++++++++++++++++++++++++++ 6 files changed, 90 insertions(+), 12 deletions(-) create mode 100644 wrk/zigstd/main.zig diff --git a/build.zig b/build.zig index bd74f89..90dae19 100644 --- a/build.zig +++ b/build.zig @@ -47,6 +47,7 @@ pub fn build(b: *std.build.Builder) !void { .{ .name = "hello_json", .src = "examples/hello_json/hello_json.zig" }, .{ .name = "endpoint", .src = "examples/endpoint/main.zig" }, .{ .name = "wrk", .src = "wrk/zig/main.zig" }, + .{ .name = "wrk_zigstd", .src = "wrk/zigstd/main.zig" }, .{ .name = "mustache", .src = "examples/mustache/mustache.zig" }, .{ .name = "endpoint_auth", .src = "examples/endpoint_auth/endpoint_auth.zig" }, }) |excfg| { diff --git a/build.zig.zon b/build.zig.zon index 2e4e34b..2dadfb1 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,6 +1,6 @@ .{ .name = "zap", - .version = "0.0.11", + .version = "0.0.13", .dependencies = .{ .@"facil.io" = .{ diff --git a/src/endpoint.zig b/src/endpoint.zig index 3b19b6a..3a24431 100644 --- a/src/endpoint.zig +++ b/src/endpoint.zig @@ -91,7 +91,7 @@ pub fn AuthenticatingEndpoint(comptime Authenticator: type) type { const authEp: *Self = @fieldParentPtr(Self, "auth_endpoint", e); if (authEp.authenticator.authenticateRequest(&r) == false) { if (e.settings.unauthorized) |foo| { - foo(e, r); + foo(authEp.endpoint, r); return; } else { r.setStatus(.unauthorized); @@ -100,7 +100,7 @@ pub fn AuthenticatingEndpoint(comptime Authenticator: type) type { } } // auth successful - authEp.endpoint.settings.get.?(e, r); + authEp.endpoint.settings.get.?(authEp.endpoint, r); } /// here, the auth_endpoint will be passed in @@ -108,7 +108,7 @@ pub fn AuthenticatingEndpoint(comptime Authenticator: type) type { const authEp: *Self = @fieldParentPtr(Self, "auth_endpoint", e); if (authEp.authenticator.authenticateRequest(&r) == false) { if (e.settings.unauthorized) |foo| { - foo(e, r); + foo(authEp.endpoint, r); return; } else { r.setStatus(.unauthorized); @@ -117,7 +117,7 @@ pub fn AuthenticatingEndpoint(comptime Authenticator: type) type { } } // auth successful - authEp.endpoint.settings.post.?(e, r); + authEp.endpoint.settings.post.?(authEp.endpoint, r); } /// here, the auth_endpoint will be passed in @@ -125,7 +125,7 @@ pub fn AuthenticatingEndpoint(comptime Authenticator: type) type { const authEp: *Self = @fieldParentPtr(Self, "auth_endpoint", e); if (authEp.authenticator.authenticateRequest(&r) == false) { if (e.settings.unauthorized) |foo| { - foo(e, r); + foo(authEp.endpoint, r); return; } else { r.setStatus(.unauthorized); @@ -134,7 +134,7 @@ pub fn AuthenticatingEndpoint(comptime Authenticator: type) type { } } // auth successful - authEp.endpoint.settings.put.?(e, r); + authEp.endpoint.settings.put.?(authEp.endpoint, r); } /// here, the auth_endpoint will be passed in @@ -142,7 +142,7 @@ pub fn AuthenticatingEndpoint(comptime Authenticator: type) type { const authEp: *Self = @fieldParentPtr(Self, "auth_endpoint", e); if (authEp.authenticator.authenticateRequest(&r) == false) { if (e.settings.unauthorized) |foo| { - foo(e, r); + foo(authEp.endpoint, r); return; } else { r.setStatus(.unauthorized); @@ -151,7 +151,7 @@ pub fn AuthenticatingEndpoint(comptime Authenticator: type) type { } } // auth successful - authEp.endpoint.settings.delete.?(e, r); + authEp.endpoint.settings.delete.?(authEp.endpoint, r); } }; } diff --git a/src/http_auth.zig b/src/http_auth.zig index 7590329..8e8c82a 100644 --- a/src/http_auth.zig +++ b/src/http_auth.zig @@ -92,31 +92,63 @@ pub fn BasicAuth(comptime Lookup: type, comptime kind: BasicAuthStrategy) type { /// Use this to decode the auth_header into user:pass, lookup pass in lookup pub fn authenticateUserPass(self: *Self, auth_header: []const u8) bool { + zap.debug("AuthenticateUserPass\n", .{}); const encoded = auth_header[AuthScheme.Basic.str().len..]; const decoder = std.base64.standard.Decoder; var buffer: [0x100]u8 = undefined; if (decoder.calcSizeForSlice(encoded)) |decoded_size| { if (decoded_size >= buffer.len) { + zap.debug( + "ERROR: UserPassAuth: decoded_size {d} >= buffer.len {d}\n", + .{ decoded_size, buffer.len }, + ); return false; } var decoded = buffer[0..decoded_size]; - decoder.decode(decoded, encoded) catch return false; + decoder.decode(decoded, encoded) catch |err| { + zap.debug( + "ERROR: UserPassAuth: unable to decode `{s}`: {any}\n", + .{ encoded, err }, + ); + return false; + }; // we have decoded // we can split var it = std.mem.split(u8, decoded, ":"); const user = it.next(); const pass = it.next(); if (user == null or pass == null) { + zap.debug( + "ERROR: UserPassAuth: user {any} or pass {any} is null\n", + .{ user, pass }, + ); return false; } // now, do the lookup const actual_pw = self.lookup.*.get(user.?); if (actual_pw) |pw| { - return std.mem.eql(u8, pass.?, pw); + const ret = std.mem.eql(u8, pass.?, pw); + zap.debug( + "INFO: UserPassAuth for user `{s}`: `{s}` == pass `{s}` = {}\n", + .{ user.?, pw, pass.?, ret }, + ); + return ret; + } else { + zap.debug( + "ERROR: UserPassAuth: user `{s}` not found in map of size {d}!\n", + .{ user.?, self.lookup.*.count() }, + ); + return false; } - } else |_| { + } else |err| { // can't calc slice size --> fallthrough to return false + zap.debug( + "ERROR: UserPassAuth: cannot calc slize size for encoded `{s}`: {any} \n", + .{ encoded, err }, + ); + return false; } + zap.debug("UNREACHABLE\n", .{}); return false; } @@ -128,6 +160,7 @@ pub fn BasicAuth(comptime Lookup: type, comptime kind: BasicAuthStrategy) type { // dispatch based on kind pub fn authenticate(self: *Self, auth_header: []const u8) bool { + zap.debug("AUTHENTICATE\n", .{}); // switch (self.kind) { switch (kind) { .UserPass => return self.authenticateUserPass(auth_header), @@ -135,9 +168,12 @@ pub fn BasicAuth(comptime Lookup: type, comptime kind: BasicAuthStrategy) type { } } pub fn authenticateRequest(self: *Self, r: *const zap.SimpleRequest) bool { + zap.debug("AUTHENTICATE REQUEST\n", .{}); if (extractAuthHeader(.Basic, r)) |auth_header| { + zap.debug("Auth Header found!\n", .{}); return self.authenticate(auth_header); } + zap.debug("NO Auth Header found!\n", .{}); return false; } }; diff --git a/wrk/measure.sh b/wrk/measure.sh index 948b228..b712b57 100755 --- a/wrk/measure.sh +++ b/wrk/measure.sh @@ -18,6 +18,13 @@ if [ "$SUBJECT" = "zig" ] ; then URL=http://127.0.0.1:3000 fi +if [ "$SUBJECT" = "zigstd" ] ; then + zig build -Doptimize=ReleaseFast wrk_zigstd > /dev/null + ./zig-out/bin/wrk_zigstd & + PID=$! + URL=http://127.0.0.1:3000 +fi + if [ "$SUBJECT" = "go" ] ; then cd wrk/go && go build main.go ./main & diff --git a/wrk/zigstd/main.zig b/wrk/zigstd/main.zig new file mode 100644 index 0000000..41a3397 --- /dev/null +++ b/wrk/zigstd/main.zig @@ -0,0 +1,34 @@ +const std = @import("std"); + +pub fn main() !void { + const allocator = std.heap.page_allocator; + var server = std.http.Server.init(allocator, .{ + .reuse_address = true, + }); + defer server.deinit(); + const address = try std.net.Address.parseIp("127.0.0.1", 3000); + try server.listen(address); + const max_header_size = 8192; + + while (true) { + var res = try server.accept(.{ .dynamic = max_header_size }); + const start_time = std.time.nanoTimestamp(); + defer res.deinit(); + defer res.reset(); + try res.wait(); + + const server_body: []const u8 = "HI FROM ZIG STD!\n"; + res.transfer_encoding = .{ .content_length = server_body.len }; + try res.headers.append("content-type", "text/plain"); + try res.headers.append("connection", "close"); + try res.do(); + + var buf: [128]u8 = undefined; + _ = try res.readAll(&buf); + _ = try res.writer().writeAll(server_body); + try res.finish(); + const end_time = std.time.nanoTimestamp(); + const diff = end_time - start_time; + std.debug.print("{d}\n", .{diff}); + } +}