diff --git a/src/libutil/tarfile.cc b/src/libutil/tarfile.cc index c7faedd1e..f0df527b3 100644 --- a/src/libutil/tarfile.cc +++ b/src/libutil/tarfile.cc @@ -67,6 +67,17 @@ int getArchiveFilterCodeByName(const std::string & method) return code; } +static void enableSupportedFormats(struct archive * archive) +{ + archive_read_support_format_tar(archive); + archive_read_support_format_zip(archive); + + /* Enable support for empty files so we don't throw an exception + for empty HTTP 304 "Not modified" responses. See + downloadTarball(). */ + archive_read_support_format_empty(archive); +} + TarArchive::TarArchive(Source & source, bool raw, std::optional compression_method) : archive{archive_read_new()} , source{&source} @@ -78,10 +89,9 @@ TarArchive::TarArchive(Source & source, bool raw, std::optional com archive_read_support_filter_by_code(archive, getArchiveFilterCodeByName(*compression_method)); } - if (!raw) { - archive_read_support_format_tar(archive); - archive_read_support_format_zip(archive); - } else { + if (!raw) + enableSupportedFormats(archive); + else { archive_read_support_format_raw(archive); archive_read_support_format_empty(archive); } @@ -97,8 +107,7 @@ TarArchive::TarArchive(const Path & path) , buffer(defaultBufferSize) { archive_read_support_filter_all(archive); - archive_read_support_format_tar(archive); - archive_read_support_format_zip(archive); + enableSupportedFormats(archive); archive_read_set_option(archive, NULL, "mac-ext", NULL); check(archive_read_open_filename(archive, path.c_str(), 16384), "failed to open archive: %s"); } diff --git a/tests/nixos/tarball-flakes.nix b/tests/nixos/tarball-flakes.nix index bc0ddc3f6..84cf377ec 100644 --- a/tests/nixos/tarball-flakes.nix +++ b/tests/nixos/tarball-flakes.nix @@ -77,8 +77,10 @@ in assert info["revision"] == "${nixpkgs.rev}" assert info["revCount"] == 1234 - # Check that fetching with rev/revCount/narHash succeeds. + # Check that a 0-byte HTTP 304 "Not modified" result works. + machine.succeed("nix flake metadata --refresh --json http://localhost/tags/latest.tar.gz") + # Check that fetching with rev/revCount/narHash succeeds. machine.succeed("nix flake metadata --json http://localhost/tags/latest.tar.gz?rev=" + info["revision"]) machine.succeed("nix flake metadata --json http://localhost/tags/latest.tar.gz?revCount=" + str(info["revCount"])) machine.succeed("nix flake metadata --json http://localhost/tags/latest.tar.gz?narHash=" + info["locked"]["narHash"])