Merge pull request #18 from jetzig-framework/format-from-content-type

Use content-type header if present to detect format
This commit is contained in:
bobf 2024-03-10 11:39:55 +00:00 committed by GitHub
commit edbf433a81
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 3 deletions

View File

@ -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);

View File

@ -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,