zig 0.12.0: upgrade console.zig/refactor headers

This commit is contained in:
Emil Lerch 2024-05-06 12:16:06 -07:00
parent a962e05d82
commit decb2d34af
Signed by: lobo
GPG Key ID: A7B62D657EF764F8

View File

@ -31,7 +31,7 @@ pub fn run(allocator: ?std.mem.Allocator, event_handler: interface.HandlerFn) !u
defer response.deinit(); defer response.deinit();
var headers = try findHeaders(aa); var headers = try findHeaders(aa);
defer headers.deinit(); defer headers.deinit();
response.request.headers = headers.http_headers.*; response.request.headers = headers.http_headers;
response.request.headers_owned = false; response.request.headers_owned = false;
response.request.target = try findTarget(aa); response.request.target = try findTarget(aa);
response.request.method = try findMethod(aa); response.request.method = try findMethod(aa);
@ -107,7 +107,7 @@ fn findTarget(allocator: std.mem.Allocator) ![]const u8 {
return error.CommandLineError; return error.CommandLineError;
if (is_target_option) if (is_target_option)
return arg; return arg;
return (try std.Uri.parse(arg)).path; return (try std.Uri.parse(arg)).path.raw;
} }
if (std.mem.startsWith(u8, arg, "-" ++ target_option.short) or if (std.mem.startsWith(u8, arg, "-" ++ target_option.short) or
std.mem.startsWith(u8, arg, "--" ++ target_option.long)) std.mem.startsWith(u8, arg, "--" ++ target_option.long))
@ -126,7 +126,7 @@ fn findTarget(allocator: std.mem.Allocator) ![]const u8 {
var split = std.mem.splitSequence(u8, arg, "="); var split = std.mem.splitSequence(u8, arg, "=");
_ = split.next(); _ = split.next();
const rest = split.rest(); const rest = split.rest();
if (split.next()) |_| return (try std.Uri.parse(rest)).path; // found it if (split.next()) |_| return (try std.Uri.parse(rest)).path.raw; // found it
is_url_option = true; is_url_option = true;
} }
} }
@ -134,13 +134,13 @@ fn findTarget(allocator: std.mem.Allocator) ![]const u8 {
} }
pub const Headers = struct { pub const Headers = struct {
http_headers: *std.http.Headers, http_headers: []std.http.Header,
owned: bool, owned: bool,
allocator: std.mem.Allocator, allocator: std.mem.Allocator,
const Self = @This(); const Self = @This();
pub fn init(allocator: std.mem.Allocator, headers: *std.http.Headers, owned: bool) Self { pub fn init(allocator: std.mem.Allocator, headers: []std.http.Header, owned: bool) Self {
return .{ return .{
.http_headers = headers, .http_headers = headers,
.owned = owned, .owned = owned,
@ -150,8 +150,7 @@ pub const Headers = struct {
pub fn deinit(self: *Self) void { pub fn deinit(self: *Self) void {
if (self.owned) { if (self.owned) {
self.http_headers.deinit(); self.allocator.free(self.http_headers);
self.allocator.destroy(self.http_headers);
self.http_headers = undefined; self.http_headers = undefined;
} }
} }
@ -160,13 +159,8 @@ pub const Headers = struct {
// Get headers from request. Headers will be gathered from the command line // Get headers from request. Headers will be gathered from the command line
// and include all environment variables // and include all environment variables
pub fn findHeaders(allocator: std.mem.Allocator) !Headers { pub fn findHeaders(allocator: std.mem.Allocator) !Headers {
var headers = try allocator.create(std.http.Headers); var headers = std.ArrayList(std.http.Header).init(allocator);
errdefer allocator.destroy(headers); defer headers.deinit();
headers.allocator = allocator;
headers.list = .{};
headers.index = .{};
headers.owned = true;
errdefer headers.deinit();
// without context, we have environment variables // without context, we have environment variables
// possibly event data (API Gateway does this if so configured), // possibly event data (API Gateway does this if so configured),
@ -185,7 +179,7 @@ pub fn findHeaders(allocator: std.mem.Allocator) !Headers {
is_header_option = false; is_header_option = false;
var split = std.mem.splitSequence(u8, arg, "="); var split = std.mem.splitSequence(u8, arg, "=");
const name = split.next().?; const name = split.next().?;
try headers.append(name, split.rest()); try headers.append(.{ .name = name, .value = split.rest() });
} }
if (std.mem.startsWith(u8, arg, "-" ++ header_option.short) or if (std.mem.startsWith(u8, arg, "-" ++ header_option.short) or
std.mem.startsWith(u8, arg, "--" ++ header_option.long)) std.mem.startsWith(u8, arg, "--" ++ header_option.long))
@ -196,21 +190,30 @@ pub fn findHeaders(allocator: std.mem.Allocator) !Headers {
is_header_option = true; is_header_option = true;
} }
} }
if (is_test) return Headers.init(allocator, headers, true); if (is_test) return Headers.init(allocator, try headers.toOwnedSlice(), true);
// not found on command line. Let's check environment // not found on command line. Let's check environment
// TODO: Get this under test - fake an environment map with deterministic values
var map = try std.process.getEnvMap(allocator); var map = try std.process.getEnvMap(allocator);
defer map.deinit(); defer map.deinit();
var it = map.iterator(); var it = map.iterator();
while (it.next()) |kvp| { while (it.next()) |kvp| {
// Do not allow environment variables to interfere with command line // Do not allow environment variables to interfere with command line
if (headers.getFirstValue(kvp.key_ptr.*) == null) var found = false;
try headers.append( const key = kvp.key_ptr.*;
kvp.key_ptr.*, for (headers.items) |h| {
kvp.value_ptr.*, if (std.ascii.eqlIgnoreCase(h.name, key)) {
); found = true;
break;
} }
return Headers.init(allocator, headers, true); }
if (!found)
try headers.append(.{
.name = try allocator.dupe(u8, key),
.value = try allocator.dupe(u8, kvp.value_ptr.*),
});
}
return Headers.init(allocator, try headers.toOwnedSlice(), true);
} }
test { test {
@ -233,13 +236,13 @@ test "can get headers" {
try test_args.append(allocator, "X-Foo=Bar"); try test_args.append(allocator, "X-Foo=Bar");
var headers = try findHeaders(allocator); var headers = try findHeaders(allocator);
defer headers.deinit(); defer headers.deinit();
try std.testing.expectEqual(@as(usize, 1), headers.http_headers.list.items.len); try std.testing.expectEqual(@as(usize, 1), headers.http_headers.len);
} }
fn testHandler(allocator: std.mem.Allocator, event_data: []const u8, context: interface.Context) ![]const u8 { fn testHandler(allocator: std.mem.Allocator, event_data: []const u8, context: interface.Context) ![]const u8 {
try context.headers.append("X-custom-foo", "bar"); context.headers = &.{.{ .name = "X-custom-foo", .value = "bar" }};
try context.writeAll(event_data); try context.writeAll(event_data);
return std.fmt.allocPrint(allocator, "{d}", .{context.request.headers.list.items.len}); return std.fmt.allocPrint(allocator, "{d}", .{context.request.headers.len});
} }
var test_args: std.SegmentedList([]const u8, 8) = undefined; var test_args: std.SegmentedList([]const u8, 8) = undefined;
@ -249,7 +252,7 @@ var test_output: std.ArrayList(u8) = undefined;
test "handle_request" { test "handle_request" {
var arena = std.heap.ArenaAllocator.init(std.testing.allocator); var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit(); defer arena.deinit();
var aa = arena.allocator(); const aa = arena.allocator();
test_args = .{}; test_args = .{};
defer test_args.deinit(aa); defer test_args.deinit(aa);
try test_args.append(aa, "mainexe"); try test_args.append(aa, "mainexe");