diff --git a/src/jetzig/http/Headers.zig b/src/jetzig/http/Headers.zig index e3510e7..864e166 100644 --- a/src/jetzig/http/Headers.zig +++ b/src/jetzig/http/Headers.zig @@ -18,10 +18,14 @@ pub fn deinit(self: *Self) void { self.headers.deinit(self.allocator); } -// Gets the first value for a given header identified by `name`. +// Gets the first value for a given header identified by `name`. Case-insensitive string comparison. pub fn getFirstValue(self: *Self, name: []const u8) ?[]const u8 { for (self.headers.items) |header| { - if (std.mem.eql(u8, header.name, name)) return header.value; + if (name.len != header.name.len) continue; + for (name, header.name) |expected, actual| { + if (std.ascii.toLower(expected) != std.ascii.toLower(actual)) continue; + } + return header.value; } return null; } @@ -78,6 +82,14 @@ test "append" { try std.testing.expectEqualStrings(headers.getFirstValue("foo").?, "bar"); } +test "case-insensitive matching" { + const allocator = std.testing.allocator; + var headers = Self.init(allocator); + defer headers.deinit(); + try headers.append("Content-Type", "bar"); + try std.testing.expectEqualStrings(headers.getFirstValue("content-type").?, "bar"); +} + test "iterator" { const allocator = std.testing.allocator; var headers = Self.init(allocator); diff --git a/src/jetzig/http/Request.zig b/src/jetzig/http/Request.zig index ab50e07..0bf76ab 100644 --- a/src/jetzig/http/Request.zig +++ b/src/jetzig/http/Request.zig @@ -151,7 +151,10 @@ pub fn render(self: *Self, status_code: jetzig.http.status_codes.StatusCode) jet } pub fn requestFormat(self: *Self) jetzig.http.Request.Format { - return self.extensionFormat() orelse self.acceptHeaderFormat() orelse .UNKNOWN; + return self.extensionFormat() orelse + self.acceptHeaderFormat() orelse + self.contentTypeHeaderFormat() orelse + .UNKNOWN; } pub fn getHeader(self: *Self, key: []const u8) ?[]const u8 { @@ -233,6 +236,17 @@ pub fn acceptHeaderFormat(self: *Self) ?jetzig.http.Request.Format { return null; } +pub fn contentTypeHeaderFormat(self: *Self) ?jetzig.http.Request.Format { + const acceptHeader = self.getHeader("content-type"); + + if (acceptHeader) |item| { + if (std.mem.eql(u8, item, "text/html")) return .HTML; + if (std.mem.eql(u8, item, "application/json")) return .JSON; + } + + return null; +} + pub fn hash(self: *Self) ![]const u8 { return try std.fmt.allocPrint( self.allocator,