TLS Custom CA Certificate ​
Demonstrates TLS with self-signed certificates for development and testing, using httpx.tls.Listener with PEM identity material.
Features Demonstrated ​
- Self-signed certificate PEM blocks
httpx.tls.ListenerwithdefaultIdentity- Development-only verification bypass via
.tls = .{ .verify = .none }
Demo Program ​
zig
const std = @import("std");
const httpx = @import("httpx");
fn handler(_: httpx.tls.Request) anyerror!httpx.tls.Response {
return .{ .status = 200, .body = "Served with custom CA cert" };
}
pub fn main() !void {
var gpa: std.heap.DebugAllocator(.{}) = .init;
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const io = std.Io.Threaded.global_single_threaded.io();
// Start a local TLS listener with a self-signed identity.
var listener = try httpx.tls.Listener.init(allocator, io, .{
.port = 0,
.defaultIdentity = .{
.certChainPem = @embedFile("cert.pem"),
.privateKeyPem = @embedFile("key.pem"),
},
});
defer listener.deinit();
const port = listener.localPort();
// Development-only client bypass for the self-signed chain.
var client = httpx.Client.init(allocator, io, .{});
defer client.deinit();
var urlBuf: [64]u8 = undefined;
const url = try std.fmt.bufPrint(&urlBuf, "https://127.0.0.1:{d}/secure", .{port});
var res = try client.get(url, .{ .tls = .{ .verify = .none } });
defer res.deinit();
std.debug.print("Response: {d} bytes\n", .{res.body.len});
}Run ​
bash
zig build run-tls-mtlsProduction CA Workflow ​
- Generate CA:
openssl req -x509 -newkey rsa:2048 -nodes -keyout ca.key -out ca.crt -days 365 -subj '/CN=MyCA' - Embed in Zig:
const ca_pem = @embedFile("ca.crt"); - Serve via
httpx.tls.ListenerwithdefaultIdentity, and verify with a populated CA bundle (never.verify = .nonein production).
