fetch
Perform a one-shot HTTP request with the provided options.
This function is threadsafe.
Function parameters
Parameters
- client:*Client
A Least-Recently-Used cache of open connections to be reused.
Types
- ConnectionPool
- A Least-Recently-Used cache of open connections to be reused.
Release all associated resources with the client.
Functions
- deinit
- Release all associated resources with the client.
- initDefaultProxies
- Populates `http_proxy` and `https_proxy` via standard proxy environment variables.
- connectTcp
- Reuses a `Connection` if one matching `host` and `port` is already open.
- connectUnix
- Connect to `path` as a unix domain socket.
- connectProxied
- Connect to `proxied_host:proxied_port` using the specified proxy with HTTP
- connect
- Connect to `host:port` using the specified protocol.
- request
- Open a connection to the host specified by `uri` and prepare to send a HTTP request.
- fetch
- Perform a one-shot HTTP request with the provided options.
Error sets in this namespace
Error Sets
= std.options.http_disable_tls
Values
- disable_tls
- = std.options.http_disable_tls
Source
Implementation
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 };
}