api.finnhub.io supports TLS 1.3 - curl fallback removed

This commit is contained in:
Emil Lerch 2026-03-10 14:09:31 -07:00
parent 543be9733e
commit a7448525ed
Signed by: lobo
GPG key ID: A7B62D657EF764F8
2 changed files with 2 additions and 71 deletions

View file

@ -70,13 +70,8 @@ pub const Client = struct {
.payload = body,
.extra_headers = extra_headers,
.response_writer = &aw.writer,
}) catch |err| {
}) catch {
aw.deinit();
// TLS 1.2-only hosts (e.g., finnhub.io) fail with Zig's TLS 1.3-only client.
// Fall back to system curl for these cases.
if (err == error.TlsInitializationFailed) {
return curlRequest(self.allocator, method, url, body, extra_headers);
}
return HttpError.RequestFailed;
};
@ -104,70 +99,6 @@ pub const Client = struct {
}
};
/// Fallback HTTP request using system curl for TLS 1.2 hosts.
fn curlRequest(
allocator: std.mem.Allocator,
method: std.http.Method,
url: []const u8,
body: ?[]const u8,
extra_headers: []const std.http.Header,
) HttpError!Response {
var argv: std.ArrayList([]const u8) = .empty;
defer argv.deinit(allocator);
// Heap-allocated strings that need freeing after Child.run
var to_free: std.ArrayList([]const u8) = .empty;
defer {
for (to_free.items) |s| allocator.free(s);
to_free.deinit(allocator);
}
argv.appendSlice(allocator, &.{ "curl", "-sS", "-f", "-L", "--max-time", "30" }) catch
return HttpError.OutOfMemory;
if (method != .GET) {
argv.appendSlice(allocator, &.{ "-X", @tagName(method) }) catch
return HttpError.OutOfMemory;
}
for (extra_headers) |hdr| {
const val = std.fmt.allocPrint(allocator, "{s}: {s}", .{ hdr.name, hdr.value }) catch
return HttpError.OutOfMemory;
to_free.append(allocator, val) catch return HttpError.OutOfMemory;
argv.appendSlice(allocator, &.{ "-H", val }) catch return HttpError.OutOfMemory;
}
if (body) |b| {
argv.appendSlice(allocator, &.{ "-d", b }) catch return HttpError.OutOfMemory;
}
argv.append(allocator, url) catch return HttpError.OutOfMemory;
const result = std.process.Child.run(.{
.allocator = allocator,
.argv = argv.items,
.max_output_bytes = 10 * 1024 * 1024,
}) catch return HttpError.RequestFailed;
allocator.free(result.stderr);
const success = switch (result.term) {
.Exited => |code| code == 0,
else => false,
};
if (!success) {
allocator.free(result.stdout);
return HttpError.RequestFailed;
}
return .{
.status = .ok,
.body = result.stdout,
.allocator = allocator,
};
}
/// Build a URL with query parameters.
pub fn buildUrl(
allocator: std.mem.Allocator,

View file

@ -16,7 +16,7 @@ const json_utils = @import("json_utils.zig");
const optFloat = json_utils.optFloat;
const jsonStr = json_utils.jsonStr;
const base_url = "https://finnhub.io/api/v1";
const base_url = "https://api.finnhub.io/api/v1";
pub const Finnhub = struct {
api_key: []const u8,