Skip to content
This repository was archived by the owner on Mar 15, 2026. It is now read-only.
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions zig-code/samples/curl.zig
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
// compile with `zig build-exe zig-curl-test.zig --library curl --library c $(pkg-config --cflags libcurl)`
//compile with `zig build-exe curl.zig -lcurl -lc $(pkg-config --cflags libcurl)`
const std = @import("std");
const cURL = @cImport({
@cInclude("curl/curl.h");
});

const ResponseContext = struct {
buffer: std.ArrayList(u8),
allocator: std.mem.Allocator,
};

pub fn main() !void {
var arena_state = std.heap.ArenaAllocator.init(std.heap.c_allocator);
defer arena_state.deinit();
Expand All @@ -19,11 +24,14 @@ pub fn main() !void {
const handle = cURL.curl_easy_init() orelse return error.CURLHandleInitFailed;
defer cURL.curl_easy_cleanup(handle);

var response_buffer = std.ArrayList(u8).init(allocator);
var response_ctx = ResponseContext{
.buffer = std.ArrayList(u8).empty,
.allocator = allocator,
};

// superfluous when using an arena allocator, but
// important if the allocator implementation changes
defer response_buffer.deinit();
// defer response_ctx.buffer.deinit(allocator);

// setup curl options
if (cURL.curl_easy_setopt(handle, cURL.CURLOPT_URL, "https://ziglang.org") != cURL.CURLE_OK)
Expand All @@ -32,21 +40,26 @@ pub fn main() !void {
// set write function callbacks
if (cURL.curl_easy_setopt(handle, cURL.CURLOPT_WRITEFUNCTION, writeToArrayListCallback) != cURL.CURLE_OK)
return error.CouldNotSetWriteCallback;
if (cURL.curl_easy_setopt(handle, cURL.CURLOPT_WRITEDATA, &response_buffer) != cURL.CURLE_OK)
if (cURL.curl_easy_setopt(handle, cURL.CURLOPT_WRITEDATA, &response_ctx) != cURL.CURLE_OK)
return error.CouldNotSetWriteCallback;

// perform
if (cURL.curl_easy_perform(handle) != cURL.CURLE_OK)
return error.FailedToPerformRequest;

std.log.info("Got response of {d} bytes", .{response_buffer.items.len});
std.debug.print("{s}\n", .{response_buffer.items});
std.log.info("Got response of {d} bytes", .{response_ctx.buffer.items.len});
std.debug.print("{s}\n", .{response_ctx.buffer.items});
}

fn writeToArrayListCallback(data: *anyopaque, size: c_uint, nmemb: c_uint, user_data: *anyopaque) callconv(.C) c_uint {
var buffer: *std.ArrayList(u8) = @alignCast(@ptrCast(user_data));
fn writeToArrayListCallback(
data: *anyopaque,
size: usize,
nmemb: usize,
user_data: *anyopaque,
) callconv(.c) usize {
var ctx: *ResponseContext = @ptrCast(@alignCast(user_data));
var typed_data: [*]u8 = @ptrCast(data);
buffer.appendSlice(typed_data[0 .. nmemb * size]) catch return 0;
ctx.buffer.appendSlice(ctx.allocator, typed_data[0 .. nmemb * size]) catch return 0;
return nmemb * size;
}

Expand Down