👏

【Zig】std.http.Client を利用して HTTP/1 リクエストを送信する

2024/04/17に公開

Zig 0.12 では std.http は HTTP/1 のみ、デフォルトで SSL/TLS に自動対応し、std.crypto.tls は TLS 1.3 のみをサポートする。次のコードは std.http.Client.fetch を使ったコードの例である

// https://github.com/ziglang/zig/issues/19878

const std = @import("std");
const print = std.debug.print;

pub fn main() !void {
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();
    const allocator = arena.allocator();

    var client = std.http.Client{ .allocator = allocator };
    defer client.deinit();

    var response = std.ArrayList(u8).init(allocator);
    defer response.deinit();

    const result = try client.fetch(.{
        .method = .GET,
        .location = .{ .url = "https://httpbun.com/get" },
        .response_storage = .{ .dynamic = &response },
    });

    print("Result: {}\n", .{result.status});
    print("Response: {s}\n", .{response.items});
}

std.http.Client の初期化において SSL/TLS 通信のための .next_https_rescan_certs の値はデフォルトで true となっている

httpbin.org は TLS 1.3 をサポートしないのでテストサイトとしては使わなかった。次のコードは client.open を使った例である

const std = @import("std");
const print = std.debug.print;

pub fn main() !void {
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();
    const allocator = arena.allocator();

    var client: std.http.Client = .{ .allocator = allocator };
    defer client.deinit();

    const uri = std.Uri.parse("https://httpbun.com/get") catch unreachable;

    var server_header_buffer: [1024]u8 = undefined;
    var req = try client.open(.GET, uri, .{
        .server_header_buffer = &server_header_buffer,
    });
    defer req.deinit();

    try req.send();
    try req.wait();

    const body = req.reader().readAllAlloc(allocator, 10 * 1024 * 1024) catch unreachable;
    defer allocator.free(body);

    print("{s}\n", .{ body });
}

Discussion