diff --git a/src/flexilib.zig b/src/flexilib.zig index 39215f3..3d211e3 100644 --- a/src/flexilib.zig +++ b/src/flexilib.zig @@ -62,23 +62,11 @@ export fn handle_request(request: *interface.Request) callconv(.C) ?*interface.R fn handleRequest(allocator: std.mem.Allocator, request: interface.ZigRequest, response: interface.ZigResponse) !void { // setup var response_writer = response.body.writer(); - try response_writer.writeAll(try client_handler.handler(allocator, request.content, .{})); - // real work - for (request.headers) |h| { - const header = interface.toZigHeader(h); - // std.debug.print("\n{s}: {s}\n", .{ header.name, header.value }); - if (std.ascii.eqlIgnoreCase(header.name, "host") and std.mem.startsWith(u8, header.value, "iam")) { - try response_writer.print("iam response", .{}); - return; - } - if (std.ascii.eqlIgnoreCase(header.name, "x-slow")) { - std.time.sleep(std.time.ns_per_ms * (std.fmt.parseInt(usize, header.value, 10) catch 1000)); - try response_writer.print("i am slow\n\n", .{}); - return; - } - } - try response.headers.put("X-custom-foo", "bar"); - log.info("handlerequest header count {d}", .{response.headers.count()}); + // dispatch to our actual handler + try response_writer.writeAll(try client_handler.handler(allocator, request.content, .{ .flexilib = .{ + .request = request, + .response = response, + } })); } // Need to figure out how tests would work test "handle_request" { diff --git a/src/lambda.zig b/src/lambda.zig index c877203..d269ce7 100644 --- a/src/lambda.zig +++ b/src/lambda.zig @@ -67,7 +67,10 @@ pub fn run(allocator: ?std.mem.Allocator, event_handler: HandlerFn) !void { // T // reasonable to report back const event = ev.?; defer ev.?.deinit(); - const event_response = event_handler(req_allocator, event.event_data, .{}) catch |err| { + // Lambda does not have context, just environment variables. API Gateway + // might be configured to pass in lots of context, but this comes through + // event data, not context. + const event_response = event_handler(req_allocator, event.event_data, .{ .none = {} }) catch |err| { event.reportError(@errorReturnTrace(), err, lambda_runtime_uri) catch unreachable; continue; }; diff --git a/src/universal_lambda.zig b/src/universal_lambda.zig index d884346..99f1ac4 100644 --- a/src/universal_lambda.zig +++ b/src/universal_lambda.zig @@ -1,12 +1,19 @@ const std = @import("std"); const build_options = @import("build_options"); - +const flexilib = @import("flexilib-interface.zig"); // TODO: pull in flexilib directly pub const HandlerFn = *const fn (std.mem.Allocator, []const u8, Context) anyerror![]const u8; const log = std.log.scoped(.universal_lambda); // TODO: Should this be union? -pub const Context = struct {}; +pub const Context = union(enum) { + web_request: *std.http.Server.Response, + flexilib: struct { + request: flexilib.Request, + response: flexilib.Response, + }, + none: void, +}; const runFn = blk: { switch (build_options.build_type) { @@ -37,11 +44,12 @@ fn runExe(allocator: ?std.mem.Allocator, event_handler: HandlerFn) !void { const aa = arena.allocator(); + const data = try std.io.getStdIn().reader().readAllAlloc(aa, std.math.maxInt(usize)); // We're setting up an arena allocator. While we could use a gpa and get // some additional safety, this is now "production" runtime, and those // things are better handled by unit tests const writer = std.io.getStdOut().writer(); - try writer.writeAll(try event_handler(aa, "", .{})); + try writer.writeAll(try event_handler(aa, data, .{ .none = {} })); try writer.writeAll("\n"); } @@ -105,7 +113,7 @@ fn processRequest(aa: std.mem.Allocator, server: *std.http.Server, event_handler try aa.dupe(u8, ""); // no need to free - will be handled by arena - response_bytes = event_handler(aa, body, .{}) catch |e| brk: { + response_bytes = event_handler(aa, body, .{ .web_request = &res }) catch |e| brk: { res.status = .internal_server_error; // TODO: more about this particular request log.err("Unexpected error from executor processing request: {any}", .{e});