srctree

Jeremy Hertel parent bea1f183 0f4127db
add basic content type detection based on file extension

src/content-type.zig added: 44, removed: 3, total 41
@@ -228,6 +228,35 @@ fn wrap(comptime kind: type, val: anytype) !ContentType {
};
}
 
pub fn fromFileExtension(extension: []const u8) ContentType {
var ext = extension;
if (ext[0] == '.') {
ext = ext[1..];
}
 
if (eql(u8, ext, "html") or eql(u8, extension, "htm")) {
return .{ .base = .{ .text = .html } };
}
 
if (eql(u8, ext, "css")) {
return .{ .base = .{ .text = .css } };
}
 
if (eql(u8, ext, "js")) {
return .{ .base = .{ .text = .javascript } };
}
 
if (eql(u8, ext, "png")) {
return .{ .base = .{ .image = .png } };
}
 
if (eql(u8, ext, "jpg") or eql(u8, extension, "jpeg")) {
return .{ .base = .{ .image = .jpeg } };
}
 
return default;
}
 
test ContentType {
std.testing.refAllDecls(@This());
}
@@ -235,3 +264,4 @@ test ContentType {
const std = @import("std");
const startsWith = std.mem.startsWith;
const indexOf = std.mem.indexOf;
const eql = std.mem.eql;
 
src/static-file.zig added: 44, removed: 3, total 41
@@ -1,6 +1,7 @@
const std = @import("std");
const Frame = @import("frame.zig");
const Route = @import("router.zig");
const ContentType = @import("content-type.zig");
 
pub fn fileOnDisk(frame: *Frame) Route.Error!void {
_ = frame.uri.next(); // clear /static
@@ -15,9 +16,19 @@ pub fn fileOnDisk(frame: *Frame) Route.Error!void {
const static = std.fs.cwd().openDir("static", .{}) catch return error.Unrouteable;
const fdata = static.readFileAlloc(frame.alloc, fname, 0xFFFFFF) catch return error.Unknown;
 
var content_type = ContentType.default;
const period_index = std.mem.indexOf(u8, fname, ".");
if (period_index) |index| {
content_type = ContentType.fromFileExtension(fname[index..]);
}
 
frame.status = .ok;
frame.content_type = content_type;
 
frame.sendHeaders() catch |err| switch (err) {
error.BrokenPipe, error.IOWriteFailure => |e| return e,
else => unreachable,
};
try frame.sendHTML(.ok, fdata);
try frame.sendRawSlice("\r\n");
try frame.sendRawSlice(fdata);
}