🌊
【Zig】TLS 1.2 対応の HTTPS クライアントをつくる
Zig 0.12 の std.crypto.tls
は TLS 1.2 のみしかサポートしない。TLS 1.2 をサポートする Zig-TLS12 を利用して HTTPS クライアントをつくってみた。Zig-TLS12
は依存パッケージ管理のための build.zig.zon
に対応しており、zig build
を実行するだけで自動的に依存パッケージはダウンロードされる
build.zig.zon
.{
.name = "http-client-project",
.version = "0.0.1",
.paths = .{
"hello.zig",
"build.zig",
"build.zig.zon"
},
.dependencies = .{
.tls12 = .{
.url = "https://github.com/melonedo/zig-tls12/archive/refs/tags/0.1.0-for-zig-0.12.tar.gz",
.hash = "1220bb536438e7f0f6b5bdb86039b7de33116ea52198eff0f1ac9f39ab10e487fbf6",
},
},
}
build.zig
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "http-client",
.root_source_file = .{ .path = "client.zig" },
.target = target,
.optimize = optimize
});
const tls12 = b.dependency("tls12", .{
.target = target,
.optimize = optimize
});
exe.root_module.addImport("tls12", tls12.module("zig-tls12"));
b.installArtifact(exe);
const run_exe = b.addRunArtifact(exe);
const run_step = b.step("run", "Run the application");
run_step.dependOn(&run_exe.step);
}
client.zig
const std = @import("std");
const HttpClient = @import("tls12");
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
var client = HttpClient{ .allocator = allocator };
defer client.deinit();
try client.initDefaultProxies(allocator);
const url = "https://httpbin.org/get";
const uri = try std.Uri.parse(url);
var server_header_buffer: [1024 * 1024]u8 = undefined;
var req = try HttpClient.open(&client, .GET, uri, .{
.server_header_buffer = &server_header_buffer,
.redirect_behavior = @enumFromInt(10),
});
defer req.deinit();
try req.send();
try req.wait();
const body = try req.reader().readAllAlloc(allocator, 16 * 1024 * 1024);
defer allocator.free(body);
std.debug.print("{s}: {s}\n", .{ url, body });
}
実行結果は次のとおり。リクエスト先の httpbin.org
は現時点で TLS 1.3 には対応していない
zig build run
https://httpbin.org/get: {
"args": {},
"headers": {
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "zig/0.12.0 (std.http)",
"X-Amzn-Trace-Id": "Root=1-6651e55e-0e911c7d0eecfa53324e8ad2"
},
"origin": "115.162.203.179",
"url": "https://httpbin.org/get"
}
Discussion