diff --git a/examples/endpoint/endpoint.zig b/examples/endpoint/endpoint.zig index ac4b408..6fb16bd 100644 --- a/examples/endpoint/endpoint.zig +++ b/examples/endpoint/endpoint.zig @@ -25,6 +25,7 @@ pub fn init( .put = putUser, .patch = putUser, .delete = deleteUser, + .options = optionsUser, }), }; } @@ -141,3 +142,11 @@ fn deleteUser(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void { } } } + +fn optionsUser(e: *zap.SimpleEndpoint, r: zap.SimpleRequest) void { + _ = e; + r.setHeader("Access-Control-Allow-Origin", "*") catch return; + r.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS") catch return; + r.setStatus(zap.StatusCode.no_content); + r.markAsFinished(true); +} diff --git a/src/endpoint.zig b/src/endpoint.zig index 499dc57..a04f7f6 100644 --- a/src/endpoint.zig +++ b/src/endpoint.zig @@ -14,6 +14,7 @@ pub const SimpleEndpointSettings = struct { put: ?RequestFn = null, delete: ?RequestFn = null, patch: ?RequestFn = null, + options: ?RequestFn = null, /// only applicable to AuthenticatingEndpoint unauthorized: ?RequestFn = null, }; @@ -32,6 +33,7 @@ pub const SimpleEndpoint = struct { .put = s.put orelse &nop, .delete = s.delete orelse &nop, .patch = s.patch orelse &nop, + .options = s.options orelse &nop, .unauthorized = s.unauthorized orelse &nop, }, }; @@ -54,6 +56,8 @@ pub const SimpleEndpoint = struct { return self.settings.delete.?(self, r); if (std.mem.eql(u8, m, "PATCH")) return self.settings.patch.?(self, r); + if (std.mem.eql(u8, m, "OPTIONS")) + return self.settings.options.?(self, r); } } }; @@ -79,6 +83,7 @@ pub fn AuthenticatingEndpoint(comptime Authenticator: type) type { .put = if (e.settings.put != null) put else null, .delete = if (e.settings.delete != null) delete else null, .patch = if (e.settings.patch != null) patch else null, + .options = if (e.settings.options != null) options else null, .unauthorized = e.settings.unauthorized, }), }; @@ -185,6 +190,25 @@ pub fn AuthenticatingEndpoint(comptime Authenticator: type) type { .Handled => {}, } } + + /// here, the auth_endpoint will be passed in + pub fn options(e: *SimpleEndpoint, r: zap.SimpleRequest) void { + const authEp: *Self = @fieldParentPtr(Self, "auth_endpoint", e); + switch (authEp.authenticator.authenticateRequest(&r)) { + .AuthFailed => { + if (e.settings.unauthorized) |unauthorized| { + unauthorized(authEp.endpoint, r); + return; + } else { + r.setStatus(.unauthorized); + r.sendBody("UNAUTHORIZED") catch return; + return; + } + }, + .AuthOK => authEp.endpoint.settings.put.?(authEp.endpoint, r), + .Handled => {}, + } + } }; }