DoxigAlpha

serveTarFile

Function parameters

Parameters

#
ws:*WebServer
request:*http.Server.Request
paths:[]const Cache.Path

Type definitions in this namespace

Types

#

Thread-safe.

Functions

#
notifyUpdate
Thread-safe.

Source

Implementation

#
pub fn serveTarFile(
    ws: *WebServer,
    request: *http.Server.Request,
    paths: []const Cache.Path,
) !void {
    const gpa = ws.gpa;

    var send_buffer: [0x4000]u8 = undefined;
    var response = try request.respondStreaming(&send_buffer, .{
        .respond_options = .{
            .extra_headers = &.{
                .{ .name = "Content-Type", .value = "application/x-tar" },
                cache_control_header,
            },
        },
    });

    var cached_cwd_path: ?[]const u8 = null;
    defer if (cached_cwd_path) |p| gpa.free(p);

    var archiver: std.tar.Writer = .{ .underlying_writer = &response.writer };

    for (paths) |path| {
        var file = path.root_dir.handle.openFile(path.sub_path, .{}) catch |err| {
            log.err("failed to open '{f}': {s}", .{ path, @errorName(err) });
            continue;
        };
        defer file.close();
        const stat = try file.stat();
        var read_buffer: [1024]u8 = undefined;
        var file_reader: std.fs.File.Reader = .initSize(file, &read_buffer, stat.size);

        // TODO: this logic is completely bogus -- obviously so, because `path.root_dir.path` can
        // be cwd-relative. This is also related to why linkification doesn't work in the fuzzer UI:
        // it turns out the WASM treats the first path component as the module name, typically
        // resulting in modules named "" and "src". The compiler needs to tell the build system
        // about the module graph so that the build system can correctly encode this information in
        // the tar file.
        archiver.prefix = path.root_dir.path orelse cwd: {
            if (cached_cwd_path == null) cached_cwd_path = try std.process.getCwdAlloc(gpa);
            break :cwd cached_cwd_path.?;
        };
        try archiver.writeFile(path.sub_path, &file_reader, stat.mtime);
    }

    // intentionally not calling `archiver.finishPedantically`
    try response.end();
}