1
0
Fork 0
mirror of https://github.com/zigzap/zap.git synced 2025-10-20 15:14:08 +00:00

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.
This commit is contained in:
Rene Schallner 2023-05-01 04:43:48 +02:00
parent 828dc16668
commit d0c59ab008
6 changed files with 90 additions and 12 deletions

View file

@ -47,6 +47,7 @@ pub fn build(b: *std.build.Builder) !void {
.{ .name = "hello_json", .src = "examples/hello_json/hello_json.zig" }, .{ .name = "hello_json", .src = "examples/hello_json/hello_json.zig" },
.{ .name = "endpoint", .src = "examples/endpoint/main.zig" }, .{ .name = "endpoint", .src = "examples/endpoint/main.zig" },
.{ .name = "wrk", .src = "wrk/zig/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 = "mustache", .src = "examples/mustache/mustache.zig" },
.{ .name = "endpoint_auth", .src = "examples/endpoint_auth/endpoint_auth.zig" }, .{ .name = "endpoint_auth", .src = "examples/endpoint_auth/endpoint_auth.zig" },
}) |excfg| { }) |excfg| {

View file

@ -1,6 +1,6 @@
.{ .{
.name = "zap", .name = "zap",
.version = "0.0.11", .version = "0.0.13",
.dependencies = .{ .dependencies = .{
.@"facil.io" = .{ .@"facil.io" = .{

View file

@ -91,7 +91,7 @@ pub fn AuthenticatingEndpoint(comptime Authenticator: type) type {
const authEp: *Self = @fieldParentPtr(Self, "auth_endpoint", e); const authEp: *Self = @fieldParentPtr(Self, "auth_endpoint", e);
if (authEp.authenticator.authenticateRequest(&r) == false) { if (authEp.authenticator.authenticateRequest(&r) == false) {
if (e.settings.unauthorized) |foo| { if (e.settings.unauthorized) |foo| {
foo(e, r); foo(authEp.endpoint, r);
return; return;
} else { } else {
r.setStatus(.unauthorized); r.setStatus(.unauthorized);
@ -100,7 +100,7 @@ pub fn AuthenticatingEndpoint(comptime Authenticator: type) type {
} }
} }
// auth successful // auth successful
authEp.endpoint.settings.get.?(e, r); authEp.endpoint.settings.get.?(authEp.endpoint, r);
} }
/// here, the auth_endpoint will be passed in /// 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); const authEp: *Self = @fieldParentPtr(Self, "auth_endpoint", e);
if (authEp.authenticator.authenticateRequest(&r) == false) { if (authEp.authenticator.authenticateRequest(&r) == false) {
if (e.settings.unauthorized) |foo| { if (e.settings.unauthorized) |foo| {
foo(e, r); foo(authEp.endpoint, r);
return; return;
} else { } else {
r.setStatus(.unauthorized); r.setStatus(.unauthorized);
@ -117,7 +117,7 @@ pub fn AuthenticatingEndpoint(comptime Authenticator: type) type {
} }
} }
// auth successful // auth successful
authEp.endpoint.settings.post.?(e, r); authEp.endpoint.settings.post.?(authEp.endpoint, r);
} }
/// here, the auth_endpoint will be passed in /// 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); const authEp: *Self = @fieldParentPtr(Self, "auth_endpoint", e);
if (authEp.authenticator.authenticateRequest(&r) == false) { if (authEp.authenticator.authenticateRequest(&r) == false) {
if (e.settings.unauthorized) |foo| { if (e.settings.unauthorized) |foo| {
foo(e, r); foo(authEp.endpoint, r);
return; return;
} else { } else {
r.setStatus(.unauthorized); r.setStatus(.unauthorized);
@ -134,7 +134,7 @@ pub fn AuthenticatingEndpoint(comptime Authenticator: type) type {
} }
} }
// auth successful // auth successful
authEp.endpoint.settings.put.?(e, r); authEp.endpoint.settings.put.?(authEp.endpoint, r);
} }
/// here, the auth_endpoint will be passed in /// 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); const authEp: *Self = @fieldParentPtr(Self, "auth_endpoint", e);
if (authEp.authenticator.authenticateRequest(&r) == false) { if (authEp.authenticator.authenticateRequest(&r) == false) {
if (e.settings.unauthorized) |foo| { if (e.settings.unauthorized) |foo| {
foo(e, r); foo(authEp.endpoint, r);
return; return;
} else { } else {
r.setStatus(.unauthorized); r.setStatus(.unauthorized);
@ -151,7 +151,7 @@ pub fn AuthenticatingEndpoint(comptime Authenticator: type) type {
} }
} }
// auth successful // auth successful
authEp.endpoint.settings.delete.?(e, r); authEp.endpoint.settings.delete.?(authEp.endpoint, r);
} }
}; };
} }

View file

@ -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 /// Use this to decode the auth_header into user:pass, lookup pass in lookup
pub fn authenticateUserPass(self: *Self, auth_header: []const u8) bool { pub fn authenticateUserPass(self: *Self, auth_header: []const u8) bool {
zap.debug("AuthenticateUserPass\n", .{});
const encoded = auth_header[AuthScheme.Basic.str().len..]; const encoded = auth_header[AuthScheme.Basic.str().len..];
const decoder = std.base64.standard.Decoder; const decoder = std.base64.standard.Decoder;
var buffer: [0x100]u8 = undefined; var buffer: [0x100]u8 = undefined;
if (decoder.calcSizeForSlice(encoded)) |decoded_size| { if (decoder.calcSizeForSlice(encoded)) |decoded_size| {
if (decoded_size >= buffer.len) { if (decoded_size >= buffer.len) {
zap.debug(
"ERROR: UserPassAuth: decoded_size {d} >= buffer.len {d}\n",
.{ decoded_size, buffer.len },
);
return false; return false;
} }
var decoded = buffer[0..decoded_size]; 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 have decoded
// we can split // we can split
var it = std.mem.split(u8, decoded, ":"); var it = std.mem.split(u8, decoded, ":");
const user = it.next(); const user = it.next();
const pass = it.next(); const pass = it.next();
if (user == null or pass == null) { if (user == null or pass == null) {
zap.debug(
"ERROR: UserPassAuth: user {any} or pass {any} is null\n",
.{ user, pass },
);
return false; return false;
} }
// now, do the lookup // now, do the lookup
const actual_pw = self.lookup.*.get(user.?); const actual_pw = self.lookup.*.get(user.?);
if (actual_pw) |pw| { 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 // 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; return false;
} }
@ -128,6 +160,7 @@ pub fn BasicAuth(comptime Lookup: type, comptime kind: BasicAuthStrategy) type {
// dispatch based on kind // dispatch based on kind
pub fn authenticate(self: *Self, auth_header: []const u8) bool { pub fn authenticate(self: *Self, auth_header: []const u8) bool {
zap.debug("AUTHENTICATE\n", .{});
// switch (self.kind) { // switch (self.kind) {
switch (kind) { switch (kind) {
.UserPass => return self.authenticateUserPass(auth_header), .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 { pub fn authenticateRequest(self: *Self, r: *const zap.SimpleRequest) bool {
zap.debug("AUTHENTICATE REQUEST\n", .{});
if (extractAuthHeader(.Basic, r)) |auth_header| { if (extractAuthHeader(.Basic, r)) |auth_header| {
zap.debug("Auth Header found!\n", .{});
return self.authenticate(auth_header); return self.authenticate(auth_header);
} }
zap.debug("NO Auth Header found!\n", .{});
return false; return false;
} }
}; };

View file

@ -18,6 +18,13 @@ if [ "$SUBJECT" = "zig" ] ; then
URL=http://127.0.0.1:3000 URL=http://127.0.0.1:3000
fi 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 if [ "$SUBJECT" = "go" ] ; then
cd wrk/go && go build main.go cd wrk/go && go build main.go
./main & ./main &

34
wrk/zigstd/main.zig Normal file
View file

@ -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});
}
}