Perform a one-shot HTTP request with the provided options.
This function is threadsafe.
pub fn fetch(client: *Client, options: FetchOptions) FetchError!FetchResult
pub fn fetch(client: *Client, options: FetchOptions) FetchError!FetchResult {
const uri = switch (options.location) {
.url => |u| try Uri.parse(u),
.uri => |u| u,
};
const method: http.Method = options.method orelse
if (options.payload != null) .POST else .GET;
const redirect_behavior: Request.RedirectBehavior = options.redirect_behavior orelse
if (options.payload == null) @fromBackingInt(@intCast(3)) else .unhandled;
var req = try request(client, method, uri, .{
.redirect_behavior = redirect_behavior,
.headers = options.headers,
.extra_headers = options.extra_headers,
.privileged_headers = options.privileged_headers,
.keep_alive = options.keep_alive,
});
defer req.deinit();
if (options.payload) |payload| {
req.transfer_encoding = .{ .content_length = payload.len };
var body = try req.sendBodyUnflushed(&.{});
try body.writer.writeAll(payload);
try body.end();
try req.connection.?.flush();
} else {
try req.sendBodiless();
}
const redirect_buffer: []u8 = if (redirect_behavior == .unhandled) &.{} else options.redirect_buffer orelse
try client.allocator.alloc(u8, 8 * 1024);
defer if (options.redirect_buffer == null) client.allocator.free(redirect_buffer);
var response = try req.receiveHead(redirect_buffer);
const response_writer = options.response_writer orelse {
const reader = response.reader(&.{});
_ = reader.discardRemaining() catch |err| switch (err) {
error.ReadFailed => return response.bodyErr().?,
};
return .{ .status = response.head.status };
};
const decompress_buffer: []u8 = switch (response.head.content_encoding) {
.identity => &.{},
.zstd => options.decompress_buffer orelse try client.allocator.alloc(u8, std.compress.zstd.default_window_len),
.deflate, .gzip => options.decompress_buffer orelse try client.allocator.alloc(u8, std.compress.flate.max_window_len),
.compress => return error.UnsupportedCompressionMethod,
};
defer if (options.decompress_buffer == null) client.allocator.free(decompress_buffer);
var transfer_buffer: [64]u8 = undefined;
var decompress: http.Decompress = undefined;
const reader = response.readerDecompressing(&transfer_buffer, &decompress, decompress_buffer);
_ = reader.streamRemaining(response_writer) catch |err| switch (err) {
error.ReadFailed => return response.bodyErr().?,
else => |e| return e,
};
return .{ .status = response.head.status };
}