From 79ed3df8f84adf87b1db708d431e768b8fcc4c05 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 3 Jul 2024 14:14:20 +0200 Subject: [PATCH 1/3] Tarball fetcher: Fix handling of cached tarballs Fixes a regression introduced in 5a9e1c0d20e2332c79fb0fd7570315a5d93041f2 where downloading a cached file causes the error "Failed to open archive (Unrecognized archive format)". --- src/libutil/tarfile.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libutil/tarfile.cc b/src/libutil/tarfile.cc index f0e24e937..445968b57 100644 --- a/src/libutil/tarfile.cc +++ b/src/libutil/tarfile.cc @@ -81,6 +81,7 @@ TarArchive::TarArchive(Source & source, bool raw, std::optional com if (!raw) { archive_read_support_format_tar(archive); archive_read_support_format_zip(archive); + archive_read_support_format_empty(archive); } else { archive_read_support_format_raw(archive); archive_read_support_format_empty(archive); @@ -99,6 +100,7 @@ TarArchive::TarArchive(const Path & path) archive_read_support_filter_all(archive); archive_read_support_format_tar(archive); archive_read_support_format_zip(archive); + archive_read_support_format_empty(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"); } From 8bdd0ecd80cbe85a03abb3d8eaf67bc771e64703 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 3 Jul 2024 15:52:49 +0200 Subject: [PATCH 2/3] Add a test --- tests/nixos/tarball-flakes.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/nixos/tarball-flakes.nix b/tests/nixos/tarball-flakes.nix index 2e7f98b5e..e20b853f7 100644 --- a/tests/nixos/tarball-flakes.nix +++ b/tests/nixos/tarball-flakes.nix @@ -74,8 +74,10 @@ in assert info["revision"] == "${nixpkgs.rev}" assert info["revCount"] == 1234 - # Check that fetching with rev/revCount/narHash succeeds. + # Check that a 0-byte cached (304) 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"]) From e7e070d36b8f58cb48c95ae3ca6dabc0df7b79b9 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 5 Jul 2024 16:29:16 +0200 Subject: [PATCH 3/3] Document --- src/libutil/tarfile.cc | 23 +++++++++++++++-------- tests/nixos/tarball-flakes.nix | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/libutil/tarfile.cc b/src/libutil/tarfile.cc index 445968b57..d985e5c2a 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,11 +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); - archive_read_support_format_empty(archive); - } else { + if (!raw) + enableSupportedFormats(archive); + else { archive_read_support_format_raw(archive); archive_read_support_format_empty(archive); } @@ -98,9 +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); - archive_read_support_format_empty(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 e20b853f7..3945bd8b0 100644 --- a/tests/nixos/tarball-flakes.nix +++ b/tests/nixos/tarball-flakes.nix @@ -74,7 +74,7 @@ in assert info["revision"] == "${nixpkgs.rev}" assert info["revCount"] == 1234 - # Check that a 0-byte cached (304) result works. + # 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.