DoxigAlpha

create

Function parameters

Parameters

#
client:*Client
remote_host:[]const u8
port:u16
stream:net.Stream

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 create(
    client: *Client,
    remote_host: []const u8,
    port: u16,
    stream: net.Stream,
) error{ OutOfMemory, TlsInitializationFailed }!*Tls {
    const gpa = client.allocator;
    const alloc_len = allocLen(client, remote_host.len);
    const base = try gpa.alignedAlloc(u8, .of(Tls), alloc_len);
    errdefer gpa.free(base);
    const host_buffer = base[@sizeOf(Tls)..][0..remote_host.len];
    // The TLS client wants enough buffer for the max encrypted frame
    // size, and the HTTP body reader wants enough buffer for the
    // entire HTTP header. This means we need a combined upper bound.
    const tls_read_buffer_len = client.tls_buffer_size + client.read_buffer_size;
    const tls_read_buffer = host_buffer.ptr[host_buffer.len..][0..tls_read_buffer_len];
    const tls_write_buffer = tls_read_buffer.ptr[tls_read_buffer.len..][0..client.tls_buffer_size];
    const socket_write_buffer = tls_write_buffer.ptr[tls_write_buffer.len..][0..client.write_buffer_size];
    const socket_read_buffer = socket_write_buffer.ptr[socket_write_buffer.len..][0..client.tls_buffer_size];
    assert(base.ptr + alloc_len == socket_read_buffer.ptr + socket_read_buffer.len);
    @memcpy(host_buffer, remote_host);
    const tls: *Tls = @ptrCast(base);
    tls.* = .{
        .connection = .{
            .client = client,
            .stream_writer = stream.writer(tls_write_buffer),
            .stream_reader = stream.reader(socket_read_buffer),
            .pool_node = .{},
            .port = port,
            .host_len = @intCast(remote_host.len),
            .proxied = false,
            .closing = false,
            .protocol = .tls,
        },
        // TODO data race here on ca_bundle if the user sets next_https_rescan_certs to true
        .client = std.crypto.tls.Client.init(
            tls.connection.stream_reader.interface(),
            &tls.connection.stream_writer.interface,
            .{
                .host = .{ .explicit = remote_host },
                .ca = .{ .bundle = client.ca_bundle },
                .ssl_key_log = client.ssl_key_log,
                .read_buffer = tls_read_buffer,
                .write_buffer = socket_write_buffer,
                // This is appropriate for HTTPS because the HTTP headers contain
                // the content length which is used to detect truncation attacks.
                .allow_truncation_attacks = true,
            },
        ) catch return error.TlsInitializationFailed,
    };
    return tls;
}