Function fetch [src]
Perform a one-shot HTTP request with the provided options.
This function is threadsafe.
Prototype
pub fn fetch(client: *Client, options: FetchOptions) FetchError!FetchResult Parameters
client: *Clientoptions: FetchOptions Possible Errors
The client sent 0 bytes of headers before closing the stream. This happens when a keep-alive connection is finally closed.
Server sent headers that did not conform to the HTTP protocol.
To find out more detailed diagnostics, http.Reader.head_buffer can be
passed directly to Request.Head.parse.
Too many bytes of HTTP headers.
The HTTP specification suggests to respond with a 431 status code before closing the connection.
Partial HTTP request was received but the connection was closed before fully receiving the headers.
Transitive error occurred reading from in.
This can be avoided by calling receiveHead before sending the
request body.
Sending the request failed. Error code can be found on the
Connection object.
Source
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) @enumFromInt(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 };
}