aboutsummaryrefslogtreecommitdiff
path: root/src/routes/handler-info.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/routes/handler-info.zig')
-rw-r--r--src/routes/handler-info.zig29
1 files changed, 20 insertions, 9 deletions
diff --git a/src/routes/handler-info.zig b/src/routes/handler-info.zig
index e8c9dfb..97eb9bd 100644
--- a/src/routes/handler-info.zig
+++ b/src/routes/handler-info.zig
@@ -12,7 +12,7 @@ const log = std.log.scoped(.handler_info);
const Self = @This();
-const Handler = *const fn (*Context) anyerror![]const u8;
+const Handler = *const fn (*Context) anyerror!memora.Stream;
get: ?Handler,
head: ?Handler,
@@ -95,7 +95,7 @@ pub fn handle(
}
}
- const response = handler(&context) catch |err| {
+ var stream = handler(&context) catch |err| {
const response, const status_code: std.http.Status = switch (err) {
error.BadRequest => .{ "{ \"error\": \"Bad Request\" }", .bad_request },
error.Unauthorized => .{ "{ \"error\": \"Unauthorized\" }", .unauthorized },
@@ -109,6 +109,7 @@ pub fn handle(
return request.respond(response, .{ .status = status_code });
};
+ defer stream.close();
var headers: std.ArrayList(std.http.Header) = .empty;
defer headers.deinit(allocator);
@@ -129,9 +130,19 @@ pub fn handle(
});
}
- try request.respond(response, .{
- .extra_headers = headers.items
+ var read_buffer: [1024]u8 = undefined;
+ var reader = stream.reader(&read_buffer);
+
+ var write_buffer: [1024]u8 = undefined;
+ var body_writer = try request.respondStreaming(&write_buffer, .{
+ .respond_options = .{
+ .extra_headers = headers.items,
+ .transfer_encoding = .chunked,
+ },
});
+
+ _ = try reader.streamRemaining(&body_writer.writer);
+ try body_writer.end();
}
fn HandlerWrapper(T: type, name: []const u8) type {
@@ -140,7 +151,7 @@ fn HandlerWrapper(T: type, name: []const u8) type {
const payload_type = @typeInfo(return_type).error_union.payload;
return struct {
- pub fn call(ctx: *Context) anyerror![]const u8 {
+ pub fn call(ctx: *Context) anyerror!memora.Stream {
const args = args: {
const tuple = std.meta.fields(std.meta.ArgsTuple(@TypeOf(@field(T, name))));
@@ -161,7 +172,7 @@ fn HandlerWrapper(T: type, name: []const u8) type {
Body,
ctx.allocator,
writer.written(),
- .{}
+ .{},
) catch return error.BadRequest;
break :args .{ ctx, body };
} else {
@@ -169,16 +180,16 @@ fn HandlerWrapper(T: type, name: []const u8) type {
}
};
- if (payload_type == []const u8) {
+ if (payload_type == memora.Stream) {
return @call(.auto, @field(T, name), args);
} else if (payload_type == void) {
try @call(.auto, @field(T, name), args);
- return "";
+ return memora.Stream.from_buffer("");
} else {
var writer = std.Io.Writer.Allocating.init(ctx.allocator);
var stringify = std.json.Stringify { .writer = &writer.writer };
try stringify.write(try @call(.auto, @field(T, name), args));
- return writer.written();
+ return memora.Stream.from_buffer(writer.written());
}
}
};