Skip to content

Commit

Permalink
use build_info to determine if use system ca bundle
Browse files Browse the repository at this point in the history
  • Loading branch information
jiacai2050 committed Jan 21, 2024
1 parent cf7a049 commit 227c33e
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 103 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ clean:
rm -rf zig-cache zig-out

run:
zig build run-basic -freference-trace
zig build run-advanced -freference-trace
zig build run-basic -freference-trace -Dlink_vendor
zig build run-advanced -freference-trace -Dlink_vendor

test:
zig build test
zig build test -Dlink_vendor

docs:
zig build-lib -femit-docs src/root.zig
Expand Down
24 changes: 18 additions & 6 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,18 @@ pub fn build(b: *Build) void {
const optimize = b.standardOptimizeOption(.{});
const link_vendor = b.option(bool, "link_vendor", "Whether link with vendored libcurl");

const libcurl = buildLibcurl(b, target, optimize);
const build_info = b.addOptions();
build_info.addOption(bool, "link_vendor", link_vendor orelse false);
const module = b.addModule(MODULE_NAME, .{
.root_source_file = .{ .path = "src/root.zig" },
});
module.addOptions("build_info", build_info);

var libcurl: ?*Step.Compile = null;
if (link_vendor) |link| {
if (link) {
module.linkLibrary(libcurl);
libcurl = buildLibcurl(b, target, optimize);
module.linkLibrary(libcurl.?);
}
}

Expand All @@ -30,8 +35,11 @@ pub fn build(b: *Build) void {
.optimize = optimize,
});

main_tests.linkLibrary(libcurl);
main_tests.linkLibC();
if (libcurl) |lib| {
main_tests.linkLibrary(lib);
} else {
main_tests.linkSystemLibrary("curl");
}

const run_main_tests = b.addRunArtifact(main_tests);
const test_step = b.step("test", "Run library tests");
Expand All @@ -53,7 +61,7 @@ fn addExample(
b: *Build,
comptime name: []const u8,
curl_module: *Module,
libcurl: *Step.Compile,
libcurl: ?*Step.Compile,
target: Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode,
) !void {
Expand All @@ -66,7 +74,11 @@ fn addExample(

b.installArtifact(exe);
exe.root_module.addImport(MODULE_NAME, curl_module);
exe.linkLibrary(libcurl);
if (libcurl) |lib| {
exe.linkLibrary(lib);
} else {
exe.linkSystemLibrary("curl");
}
exe.linkLibC();

const run_step = b.step(
Expand Down
3 changes: 0 additions & 3 deletions examples/advanced.zig
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,6 @@ fn put_with_custom_header(allocator: Allocator, easy: Easy) !void {
},
);

if (!curl.has_parse_header_support()) {
return;
}
// Get response header `date`.
const date_header = try resp.get_header("date");
if (date_header) |h| {
Expand Down
80 changes: 0 additions & 80 deletions src/c.zig

This file was deleted.

9 changes: 5 additions & 4 deletions src/easy.zig
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
const c = @import("c.zig").c;
const std = @import("std");
const errors = @import("errors.zig");
const util = @import("util.zig");
const c = util.c;

const mem = std.mem;
const fmt = std.fmt;
const Allocator = mem.Allocator;
const checkCode = errors.checkCode;

const has_parse_header_support = @import("c.zig").has_parse_header_support;
const has_parse_header_support = @import("util.zig").has_parse_header_support;

const Self = @This();

Expand Down Expand Up @@ -137,8 +137,9 @@ pub const MultiPart = struct {
/// Init options for Easy handle
pub const EasyOptions = struct {
/// Use zig's std.crypto.Certificate.Bundle for TLS instead of libcurl's default.
/// Note that the builtin libcurl is compiled with mbedtls and does not include a CA bundle.
use_std_crypto_ca_bundle: bool = true,
// Note that the builtin libcurl is compiled with mbedtls and does not include a CA bundle,
// so this defaults to true when link_vendor is enabled.
use_std_crypto_ca_bundle: bool = @import("build_info").link_vendor,
/// The maximum time in milliseconds that the entire transfer operation to take.
default_timeout_ms: usize = 30_000,
};
Expand Down
2 changes: 1 addition & 1 deletion src/errors.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const std = @import("std");
const c = @import("c.zig").c;
const assert = @import("std").debug.assert;
const c = @import("util.zig").c;

pub const HeaderError = error{
BadIndex,
Expand Down
11 changes: 6 additions & 5 deletions src/root.zig
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
const std = @import("std");
const c = @import("c.zig").c;
const util = @import("util.zig");
const checkCode = @import("errors.zig").checkCode;

pub const Easy = @import("easy.zig");
pub usingnamespace Easy;
pub usingnamespace @import("c.zig");
pub const print_libcurl_version = util.print_libcurl_version;
pub const url_encode = util.url_encode;
pub const libcurl = util.c;

/// This function sets up the program environment that libcurl needs.
/// Since this function is not thread safe before libcurl 7.84.0, this function
/// must be called before the program calls any other function in libcurl.
/// A common place is in the beginning of the program. More see:
/// https://curl.se/libcurl/c/curl_global_init.html
pub fn global_init() !void {
try checkCode(c.curl_global_init(c.CURL_GLOBAL_ALL));
try checkCode(libcurl.curl_global_init(libcurl.CURL_GLOBAL_ALL));
}

/// This function releases resources acquired by curl_global_init.
pub fn global_deinit() void {
c.curl_global_cleanup();
libcurl.curl_global_cleanup();
}

test {
Expand Down
80 changes: 79 additions & 1 deletion src/util.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const std = @import("std");
const c = @import("c.zig").c;
pub const c = @cImport({
@cInclude("curl/curl.h");
});
const Allocator = std.mem.Allocator;
const Encoder = std.base64.standard.Encoder;

Expand All @@ -9,3 +11,79 @@ pub fn encode_base64(allocator: Allocator, input: []const u8) ![]const u8 {

return Encoder.encode(dest, input);
}

pub fn print_libcurl_version() void {
const v = c.curl_version_info(c.CURLVERSION_NOW);
std.debug.print(
\\Libcurl build info
\\Host: {s}
\\Version: {s}
\\SSL version: {s}
\\Libz version: {s}
\\Protocols:
, .{
v.*.host,
v.*.version,
v.*.ssl_version,
v.*.libz_version,
});
var i: usize = 0;
while (v.*.protocols[i] != null) {
std.debug.print(" {s}", .{
v.*.protocols[i],
});
i += 1;
} else {
std.debug.print("\n", .{});
}

// feature_names is introduced in 7.87.0
if (@hasField(c.struct_curl_version_info_data, "feature_names")) {
std.debug.print("Features:", .{});
i = 0;
while (v.*.feature_names[i] != null) {
std.debug.print(" {s}", .{
v.*.feature_names[i],
});
i += 1;
} else {
std.debug.print("\n", .{});
}
}
}

pub fn has_parse_header_support() bool {
// `curl_header` is officially supported since 7.84.0.
// https://curl.se/libcurl/c/curl_easy_header.html
return c.CURL_AT_LEAST_VERSION(7, 84, 0);
}

comptime {
// `curl_easy_reset` is only available since 7.12.0
if (!c.CURL_AT_LEAST_VERSION(7, 12, 0)) {
@compileError("Libcurl version must at least 7.12.0");
}
}

pub fn url_encode(string: [:0]const u8) ?[]const u8 {
const r = c.curl_easy_escape(null, string.ptr, @intCast(string.len));
return std.mem.sliceTo(r.?, 0);
}

test "url encode" {
inline for (.{
.{
"https://github.com/",
"https%3A%2F%2Fgithub.com%2F",
},
.{
"https://httpbin.org/anything/你好",
"https%3A%2F%2Fhttpbin.org%2Fanything%2F%E4%BD%A0%E5%A5%BD",
},
}) |case| {
const input = case.@"0";
const expected = case.@"1";
const actual = url_encode(input);
try std.testing.expectEqualStrings(expected, actual.?);
}
}

0 comments on commit 227c33e

Please sign in to comment.