diff --git a/docs/docs/languages/zig.md b/docs/docs/languages/zig.md index c1a97ee..e084b0c 100644 --- a/docs/docs/languages/zig.md +++ b/docs/docs/languages/zig.md @@ -342,4 +342,4 @@ The Zig kit was originally authored by Christoph Voigt ([@voigt](https://github. | [K/V Store](../features/key-value.md) | [Environment Variables](../features/environment-variables.md) | [Dynamic Routes](../features/dynamic-routes.md) | [Folders](../features/mount-folders.md) | [HTTP Requests](../features/http-requests.md) | | --- | --- | --- | --- | --- | -| ✅ | ❌ | ✅ | ❓ | ❌ | +| ✅ | ❌ | ✅ | ✅ | ❌ | diff --git a/examples/zig-mount/src/mount.zig b/examples/zig-mount/src/mount.zig new file mode 100644 index 0000000..72a6496 --- /dev/null +++ b/examples/zig-mount/src/mount.zig @@ -0,0 +1,26 @@ +const std = @import("std"); +const worker = @import("worker"); + +var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); +const allocator = arena.allocator(); + +fn requestFn(resp: *worker.Response, r: *worker.Request) void { + _ = r; + + const file = std.fs.Dir.openFileWasi( + std.fs.cwd(), "zig.svg", .{ + .mode = std.fs.File.OpenMode.read_only, + .lock = std.fs.File.Lock.none, + }) catch unreachable; + defer file.close(); + + const mb = (1 << 10) << 10; + const file_contents = file.readToEndAlloc(allocator, mb) catch ""; + + _ = &resp.headers.append("x-generated-by", "wasm-workers-server"); + _ = &resp.writeAll(file_contents); +} + +pub fn main() !void { + worker.ServeFunc(requestFn); +} diff --git a/kits/zig/worker/src/worker.zig b/kits/zig/worker/src/worker.zig index 197e1be..0bfbfa1 100644 --- a/kits/zig/worker/src/worker.zig +++ b/kits/zig/worker/src/worker.zig @@ -18,6 +18,7 @@ pub const Request = struct { pub const Response = struct { body: []const u8, + base64: bool, headers: http.Headers, request: Request, @@ -25,6 +26,12 @@ pub const Response = struct { res.body = data; return res.body.len; } + + pub fn writeAllBase64(res: *Response, data: []const u8) !u32 { + res.body = base64Encode(data); + res.base64 = true; + return res.body.len; + } }; // Note: as Zig does not support multiple return types, we use this struct @@ -60,7 +67,7 @@ pub const Output = struct { .httpHeader = http.Headers.init(allocator), }; } - + pub fn header(self: *Self) http.Headers { if (self.httpHeader == undefined) { self.httpHeader = http.Headers.init(allocator); @@ -73,12 +80,12 @@ pub const Output = struct { self.status = statusCode; } - pub fn write(self: *Self, data: []const u8) !u32 { - if (std.unicode.utf8ValidateSlice(data)) { - self.data = data; + pub fn write(self: *Self, response: Response) !u32 { + self.base64 = response.base64; + if (response.base64) { + self.data = base64Encode(response.body); } else { - self.base64 = true; - self.data = base64Encode(data); + self.data = response.body; } if (self.status == 0) { @@ -90,7 +97,7 @@ pub const Output = struct { } // prepare writer for json - var out_buf: [1024]u8 = undefined; + var out_buf: [4096]u8 = undefined; var slice_stream = std.io.fixedBufferStream(&out_buf); const out = slice_stream.writer(); var w = std.json.writeStream(out, .{ .whitespace = .minified }); @@ -116,8 +123,6 @@ pub const Output = struct { try w.endObject(); const result = slice_stream.getWritten(); - // std.debug.print("\noutput json: {s}\n\n", .{ result }); - const stdout = std.io.getStdOut().writer(); try stdout.print("{s}", .{ result }); @@ -129,7 +134,7 @@ fn base64Encode(data: []const u8) []const u8 { // This initializing Base64Encoder throws weird error if not wrapped in function (maybe Zig bug?) var enc = std.base64.Base64Encoder.init(std.base64.standard_alphabet_chars, '='); var data_len = enc.calcSize(data.len); - var buf: [128]u8 = undefined; + var buf: [16384]u8 = undefined; return enc.encode(buf[0..data_len], data); } @@ -192,7 +197,7 @@ fn getInput(s: []const u8) !Input { while (paramsIterator.next()) |entry| { try params.put(entry.key_ptr.*, entry.value_ptr.*.string); } - + return input; } @@ -249,13 +254,13 @@ pub fn ServeFunc(requestFn: *const fn (*Response, *Request) void) void { var request = r.request; var output = r.output; - var response = Response{ .body = "", .headers = http.Headers.init(allocator), .request = request, }; - + var response = Response{ .body = "", .base64 = false, .headers = http.Headers.init(allocator), .request = request, }; + requestFn(&response, &request); output.httpHeader = response.headers; - _ = output.write(response.body) catch |err| { + _ = output.write(response) catch |err| { std.debug.print("error writing data: {!} \n", .{ err }); }; }