Heyo,
so I sadly cant show the code as im trying to make a home automation “script” in zig and it involves a bit of private contact information.
Basically the program looks roughly as follows (-> main is pseudocode but the the two http functions are the original code):
fn main() !void {
var alloc_impl = std.heap.GeneralPurposeAllocator(.{}) = .{};
defer _ = alloc_impl.deinit();
const allocator = alloc_impl.allocator();
var client: std.http.Client = .{ .allocator = allocator };
defer client.deinit();
while (downloading) {
try download(&client, "my url", target_dir, "a struct with a function that generates the filename and verifies that the download is correct");
}
try sendSignalMessage(&client, "api uri", "my number", "recipient", "some message");
}
// this is not pseudocode but an exact copy
fn download(
client: *std.http.Client,
uri: std.Uri,
dir: std.fs.Dir,
generator: anytype,
) ![]const u8 {
var server_header_buffer: [16 * 1024]u8 = undefined;
var req = try client.open(.GET, uri, .{ .server_header_buffer = &server_header_buffer });
defer req.deinit();
try req.send();
try req.finish();
try req.wait();
switch (req.response.status.class()) {
.client_error, .server_error => return error.InvalidResponseStatus,
else => {},
}
const filename = try generator.generate(req.response.content_disposition);
const file = try dir.createFile(filename, .{});
defer file.close();
var fifo: std.fifo.LinearFifo(u8, .{ .Static = 4 * 1024 }) = .init();
try fifo.pump(req.reader(), file.writer());
return filename;
}
// also an exact copy of the original code
fn sendSignalMesage(
client: *std.http.Client,
uri: std.Uri,
host_number: []const u8,
message: []const u8,
recipients: []const []const u8,
) !void {
std.debug.assert(recipients.len == 1); // TODO
const fmt_str =
\\{{
\\ "message": "{s}",
\\ "number": "{s}",
\\ "recipients": [ "{s}" ]
\\}}
;
var server_header_buffer: [16 * 1024]u8 = undefined;
var req = try client.open(.POST, uri, .{
.server_header_buffer = &server_header_buffer,
.headers = .{
.accept_encoding = .{ .override = "application/json" },
.content_type = .{ .override = "application/json" },
},
});
defer req.deinit();
req.transfer_encoding = .{
.content_length = std.fmt.count(fmt_str, .{ message, host_number, recipients[0] }),
};
try req.send();
var bufwriter = std.io.bufferedWriter(req.writer());
try bufwriter.writer().print(fmt_str, .{ message, host_number, recipients[0] });
try bufwriter.flush();
try req.finish();
try req.wait();
switch (req.response.status.class()) {
.client_error, .server_error => return error.InvalidResponseStatus,
else => {},
}
}
Now the error I am getting is that the signal api claims that my request is malformed, but that only happens when I send the signal message AFTER having used the download method. So as far as I can tell, the http client is somehow being corrupted or im using the requests wrong. Interestingly, if I try to deinit and reinit the client manually right before calling sendSignalMessage
, it gives me an error claiming that a connection is still active. How can this be?