Skip to content
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
30 changes: 30 additions & 0 deletions src/unbundle/download.zig
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ pub const DownloadError = error{
NoHashInUrl,
NetworkError,
FileError,
InvalidProxyUrl,
} || unbundle.UnbundleError || std.mem.Allocator.Error;

pub const Version = base.url.Version;
Expand Down Expand Up @@ -189,10 +190,18 @@ fn downloadToFile(
filename_prefix: []const u8,
filename_out: []u8,
) DownloadError![]const u8 {
// Proxy configuration must outlive the client, so its arena is declared first.
var proxy_arena = std.heap.ArenaAllocator.init(allocator.*);
defer proxy_arena.deinit();

// Create HTTP client
var client = std.http.Client{ .allocator = allocator.*, .io = io };
defer client.deinit();

// Honor the standard proxy environment variables so downloads work in
// proxied/network-restricted environments (same variables `zig fetch` uses).
try initProxiesFromEnv(&client, proxy_arena.allocator());

// Parse the URL
const uri = std.Uri.parse(url) catch return error.InvalidUrl;

Expand Down Expand Up @@ -262,6 +271,27 @@ fn downloadToFile(
return error.FileError;
}

/// Populate the client's proxy configuration from the standard proxy
/// environment variables (http_proxy/HTTP_PROXY, https_proxy/HTTPS_PROXY,
/// all_proxy/ALL_PROXY). `arena` owns the proxy allocations and must outlive
/// `client`.
fn initProxiesFromEnv(client: *std.http.Client, arena: Allocator) DownloadError!void {
var environ_map = std.process.Environ.Map.init(arena);
const proxy_env_vars = [_][:0]const u8{
"http_proxy", "HTTP_PROXY", "https_proxy", "HTTPS_PROXY", "all_proxy", "ALL_PROXY",
};
for (proxy_env_vars) |name| {
const value = std.c.getenv(name.ptr) orelse continue;
const value_slice = std.mem.span(value);
if (value_slice.len == 0) continue;
environ_map.put(name, value_slice) catch return error.OutOfMemory;
}
client.initDefaultProxies(arena, &environ_map) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
else => return error.InvalidProxyUrl,
};
}

/// Download and extract a bundled tar.zst file to memory buffers.
///
/// Returns a BufferExtractWriter containing all extracted files and directories.
Expand Down