DoxigAlpha

request

Open a connection to the host specified by uri and prepare to send a HTTP request.

The caller is responsible for calling deinit() on the Request. This function is threadsafe.

Asserts that "\r\n" does not occur in any header name or value.

Function parameters

Parameters

#
client:*Client
method:http.Method

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 request(
    client: *Client,
    method: http.Method,
    uri: Uri,
    options: RequestOptions,
) RequestError!Request {
    if (std.debug.runtime_safety) {
        for (options.extra_headers) |header| {
            assert(header.name.len != 0);
            assert(std.mem.indexOfScalar(u8, header.name, ':') == null);
            assert(std.mem.indexOfPosLinear(u8, header.name, 0, "\r\n") == null);
            assert(std.mem.indexOfPosLinear(u8, header.value, 0, "\r\n") == null);
        }
        for (options.privileged_headers) |header| {
            assert(header.name.len != 0);
            assert(std.mem.indexOfPosLinear(u8, header.name, 0, "\r\n") == null);
            assert(std.mem.indexOfPosLinear(u8, header.value, 0, "\r\n") == null);
        }
    }

    const protocol = Protocol.fromUri(uri) orelse return error.UnsupportedUriScheme;

    if (protocol == .tls) {
        if (disable_tls) unreachable;
        if (@atomicLoad(bool, &client.next_https_rescan_certs, .acquire)) {
            client.ca_bundle_mutex.lock();
            defer client.ca_bundle_mutex.unlock();

            if (client.next_https_rescan_certs) {
                client.ca_bundle.rescan(client.allocator) catch
                    return error.CertificateBundleLoadFailure;
                @atomicStore(bool, &client.next_https_rescan_certs, false, .release);
            }
        }
    }

    const connection = options.connection orelse c: {
        var host_name_buffer: [Uri.host_name_max]u8 = undefined;
        const host_name = try uri.getHost(&host_name_buffer);
        break :c try client.connect(host_name, uriPort(uri, protocol), protocol);
    };

    return .{
        .uri = uri,
        .client = client,
        .connection = connection,
        .reader = .{
            .in = connection.reader(),
            .state = .ready,
            // Populated when `http.Reader.bodyReader` is called.
            .interface = undefined,
            .max_head_len = client.read_buffer_size,
        },
        .keep_alive = options.keep_alive,
        .method = method,
        .version = options.version,
        .transfer_encoding = .none,
        .redirect_behavior = options.redirect_behavior,
        .handle_continue = options.handle_continue,
        .headers = options.headers,
        .extra_headers = options.extra_headers,
        .privileged_headers = options.privileged_headers,
    };
}