sendHead
Sends HTTP headers without flushing.
Function parameters
Parameters
- r:*Request
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
fn sendHead(r: *Request) Writer.Error!void {
const uri = r.uri;
const connection = r.connection.?;
const w = connection.writer();
try w.writeAll(@tagName(r.method));
try w.writeByte(' ');
if (r.method == .CONNECT) {
try uri.writeToStream(w, .{ .authority = true });
} else {
try uri.writeToStream(w, .{
.scheme = connection.proxied,
.authentication = connection.proxied,
.authority = connection.proxied,
.path = true,
.query = true,
});
}
try w.writeByte(' ');
try w.writeAll(@tagName(r.version));
try w.writeAll("\r\n");
if (try emitOverridableHeader("host: ", r.headers.host, w)) {
try w.writeAll("host: ");
try uri.writeToStream(w, .{ .authority = true });
try w.writeAll("\r\n");
}
if (try emitOverridableHeader("authorization: ", r.headers.authorization, w)) {
if (uri.user != null or uri.password != null) {
try w.writeAll("authorization: ");
try basic_authorization.write(uri, w);
try w.writeAll("\r\n");
}
}
if (try emitOverridableHeader("user-agent: ", r.headers.user_agent, w)) {
try w.writeAll("user-agent: zig/");
try w.writeAll(builtin.zig_version_string);
try w.writeAll(" (std.http)\r\n");
}
if (try emitOverridableHeader("connection: ", r.headers.connection, w)) {
if (r.keep_alive) {
try w.writeAll("connection: keep-alive\r\n");
} else {
try w.writeAll("connection: close\r\n");
}
}
if (try emitOverridableHeader("accept-encoding: ", r.headers.accept_encoding, w)) {
try w.writeAll("accept-encoding: ");
for (r.accept_encoding, 0..) |enabled, i| {
if (!enabled) continue;
const tag: http.ContentEncoding = @enumFromInt(i);
if (tag == .identity) continue;
const tag_name = @tagName(tag);
try w.ensureUnusedCapacity(tag_name.len + 2);
try w.writeAll(tag_name);
try w.writeAll(", ");
}
w.undo(2);
try w.writeAll("\r\n");
}
switch (r.transfer_encoding) {
.chunked => try w.writeAll("transfer-encoding: chunked\r\n"),
.content_length => |len| try w.print("content-length: {d}\r\n", .{len}),
.none => {},
}
if (try emitOverridableHeader("content-type: ", r.headers.content_type, w)) {
// The default is to omit content-type if not provided because
// "application/octet-stream" is redundant.
}
for (r.extra_headers) |header| {
assert(header.name.len != 0);
try w.writeAll(header.name);
try w.writeAll(": ");
try w.writeAll(header.value);
try w.writeAll("\r\n");
}
if (connection.proxied) proxy: {
const proxy = switch (connection.protocol) {
.plain => r.client.http_proxy,
.tls => r.client.https_proxy,
} orelse break :proxy;
const authorization = proxy.authorization orelse break :proxy;
try w.writeAll("proxy-authorization: ");
try w.writeAll(authorization);
try w.writeAll("\r\n");
}
try w.writeAll("\r\n");
}