Add `std.io.Writer` and `std.io.Reader` support for `zap.SimpleRequest`
Currently the only (exposed) way to send response is to create buffer where you write whole response and you send that. However it would be way more useful to have support for std.io.Writer (and potentially std.io.Reader for reading body of the request) as it would allow developer to use std.fmt functions. This however requires changes upstream as calling http_send_body repeatedly sets incorrect content-length header (it will be set to length of last chunk instead of length of the whole written data).
That would be a nice addition if facilio supported it. Can you verify everything works well when you set the content-length after the final write?
My hunch is that after sending the connection is in an invalid state internally.
Another thing to consider is who owns the memory with writer support.
You can always use an arraylist's writer and write into that; then call send on the arraylist's items. That's what I would do and is only 2 lines of code or so. That's why I am not yet convinced of the added value.
Plus, wrapping facil.io, we'd need to somehow keep a reference to the underlying Reader / Writer context and in the case of Writer: buffer / ArrayList. The easiest way would be to wrap this functionality in a separate struct that you pass the Request:
const reader = zap.Reader(request); var writer = zap.Writer(request);
// use writer
// send the buffer: writer.flush(); // ? // or writer.send(); // ?
// or r.sendBody(writer.buffer);
Since you're already playing with it, consider submitting a PR ;-)
I have written my wrapper around zap.SimpleRequest where I have:
pub const Writer = std.io.Writer(*const Self, zap.HttpError, sendBodyChunk);
pub fn writer(self: *const Self) Writer {
return .{ .context = self };
}
pub fn sendBodyChunk(self: *const Self, chunk: []const u8) zap.HttpError!usize {
const ret = zap.http_send_body(self.req.h, @as(
*anyopaque,
@ptrFromInt(@intFromPtr(chunk.ptr)),
), chunk.len);
if (ret == -1) return error.HttpSendBody;
return chunk.len;
}
~~And it seems to work quite ok.~~ My bad, that doesn't really work.
Yeah, I figured. But nothing stops you from wriing into an ArrayList, then passing its items to zap.
That would be a nice addition if facilio supported it. Can you verify everything works well when you set the
content-lengthafter the final write?My hunch is that after sending the connection is in an invalid state internally.
Another thing to consider is who owns the memory with writer support.
You can always use an arraylist's writer and write into that; then call send on the arraylist's items. That's what I would do and is only 2 lines of code or so. That's why I am not yet convinced of the added value.
Plus, wrapping facil.io, we'd need to somehow keep a reference to the underlying Reader / Writer context and in the case of Writer: buffer / ArrayList. The easiest way would be to wrap this functionality in a separate struct that you pass the Request:
const reader = zap.Reader(request); var writer = zap.Writer(request);
// use writer
// send the buffer: writer.flush(); // ? // or writer.send(); // ?
// or r.sendBody(writer.buffer);
Since you're already playing with it, consider submitting a PR ;-)
Since facil.io doesn't support chunked responses, the above is what I'd implement. For later reference when I have time.