Compare commits
No commits in common. "54740a7022d8d7bd47c13f422c8d3a77ba705f26" and "fc0f9a0c7636a6e4ae2e31a63ab718a9ea3cacf8" have entirely different histories.
54740a7022
...
fc0f9a0c76
|
@ -19,7 +19,7 @@ pub fn build(b: *std.Build) !void {
|
||||||
.name = "universal-lambda-zig",
|
.name = "universal-lambda-zig",
|
||||||
// In this case the main source file is merely a path, however, in more
|
// In this case the main source file is merely a path, however, in more
|
||||||
// complicated build scripts, this could be a generated file.
|
// complicated build scripts, this could be a generated file.
|
||||||
.root_source_file = .{ .path = "src/universal_lambda_build.zig" },
|
.root_source_file = .{ .path = "src/main.zig" },
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,9 +17,6 @@ pub const Response = extern struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Request = extern struct {
|
pub const Request = extern struct {
|
||||||
target: [*]const u8,
|
|
||||||
target_len: usize,
|
|
||||||
|
|
||||||
method: [*:0]u8,
|
method: [*:0]u8,
|
||||||
method_len: usize,
|
method_len: usize,
|
||||||
|
|
||||||
|
@ -36,7 +33,6 @@ threadlocal var allocator: ?*std.mem.Allocator = null;
|
||||||
const log = std.log.scoped(.interface);
|
const log = std.log.scoped(.interface);
|
||||||
|
|
||||||
pub const ZigRequest = struct {
|
pub const ZigRequest = struct {
|
||||||
target: []const u8,
|
|
||||||
method: [:0]u8,
|
method: [:0]u8,
|
||||||
content: []u8,
|
content: []u8,
|
||||||
headers: []Header,
|
headers: []Header,
|
||||||
|
@ -108,7 +104,6 @@ pub fn handleRequest(request: *Request, zigRequestHandler: ZigRequestHandler) ?*
|
||||||
zigRequestHandler(
|
zigRequestHandler(
|
||||||
alloc,
|
alloc,
|
||||||
.{
|
.{
|
||||||
.target = request.target[0..request.target_len],
|
|
||||||
.method = request.method[0..request.method_len :0],
|
.method = request.method[0..request.method_len :0],
|
||||||
.content = request.content[0..request.content_len],
|
.content = request.content[0..request.content_len],
|
||||||
.headers = request.headers[0..request.headers_len],
|
.headers = request.headers[0..request.headers_len],
|
||||||
|
|
|
@ -62,11 +62,23 @@ export fn handle_request(request: *interface.Request) callconv(.C) ?*interface.R
|
||||||
fn handleRequest(allocator: std.mem.Allocator, request: interface.ZigRequest, response: interface.ZigResponse) !void {
|
fn handleRequest(allocator: std.mem.Allocator, request: interface.ZigRequest, response: interface.ZigResponse) !void {
|
||||||
// setup
|
// setup
|
||||||
var response_writer = response.body.writer();
|
var response_writer = response.body.writer();
|
||||||
// dispatch to our actual handler
|
try response_writer.writeAll(try client_handler.handler(allocator, request.content, .{}));
|
||||||
try response_writer.writeAll(try client_handler.handler(allocator, request.content, .{ .flexilib = .{
|
// real work
|
||||||
.request = request,
|
for (request.headers) |h| {
|
||||||
.response = response,
|
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()});
|
||||||
}
|
}
|
||||||
// Need to figure out how tests would work
|
// Need to figure out how tests would work
|
||||||
test "handle_request" {
|
test "handle_request" {
|
||||||
|
|
|
@ -67,10 +67,7 @@ pub fn run(allocator: ?std.mem.Allocator, event_handler: HandlerFn) !void { // T
|
||||||
// reasonable to report back
|
// reasonable to report back
|
||||||
const event = ev.?;
|
const event = ev.?;
|
||||||
defer ev.?.deinit();
|
defer ev.?.deinit();
|
||||||
// Lambda does not have context, just environment variables. API Gateway
|
const event_response = event_handler(req_allocator, event.event_data, .{}) catch |err| {
|
||||||
// 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;
|
event.reportError(@errorReturnTrace(), err, lambda_runtime_uri) catch unreachable;
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,19 +1,12 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const build_options = @import("build_options");
|
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;
|
pub const HandlerFn = *const fn (std.mem.Allocator, []const u8, Context) anyerror![]const u8;
|
||||||
|
|
||||||
const log = std.log.scoped(.universal_lambda);
|
const log = std.log.scoped(.universal_lambda);
|
||||||
|
|
||||||
// TODO: Should this be union?
|
// TODO: Should this be union?
|
||||||
pub const Context = union(enum) {
|
pub const Context = struct {};
|
||||||
web_request: *std.http.Server.Response,
|
|
||||||
flexilib: struct {
|
|
||||||
request: flexilib.Request,
|
|
||||||
response: flexilib.Response,
|
|
||||||
},
|
|
||||||
none: void,
|
|
||||||
};
|
|
||||||
|
|
||||||
const runFn = blk: {
|
const runFn = blk: {
|
||||||
switch (build_options.build_type) {
|
switch (build_options.build_type) {
|
||||||
|
@ -44,12 +37,11 @@ fn runExe(allocator: ?std.mem.Allocator, event_handler: HandlerFn) !void {
|
||||||
|
|
||||||
const aa = arena.allocator();
|
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
|
// 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
|
// some additional safety, this is now "production" runtime, and those
|
||||||
// things are better handled by unit tests
|
// things are better handled by unit tests
|
||||||
const writer = std.io.getStdOut().writer();
|
const writer = std.io.getStdOut().writer();
|
||||||
try writer.writeAll(try event_handler(aa, data, .{ .none = {} }));
|
try writer.writeAll(try event_handler(aa, "", .{}));
|
||||||
try writer.writeAll("\n");
|
try writer.writeAll("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +105,7 @@ fn processRequest(aa: std.mem.Allocator, server: *std.http.Server, event_handler
|
||||||
try aa.dupe(u8, "");
|
try aa.dupe(u8, "");
|
||||||
// no need to free - will be handled by arena
|
// no need to free - will be handled by arena
|
||||||
|
|
||||||
response_bytes = event_handler(aa, body, .{ .web_request = &res }) catch |e| brk: {
|
response_bytes = event_handler(aa, body, .{}) catch |e| brk: {
|
||||||
res.status = .internal_server_error;
|
res.status = .internal_server_error;
|
||||||
// TODO: more about this particular request
|
// TODO: more about this particular request
|
||||||
log.err("Unexpected error from executor processing request: {any}", .{e});
|
log.err("Unexpected error from executor processing request: {any}", .{e});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user