1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-08 19:46:02 +01:00
This commit is contained in:
Bernardo Meurer 2025-11-08 14:35:48 +03:00 committed by GitHub
commit 0bf18d949b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 46 additions and 1 deletions

View file

@ -74,6 +74,30 @@ TEST(decompress, decompressInvalidInputThrowsCompressionError)
ASSERT_THROW(decompress(method, str), CompressionError);
}
/* ----------------------------------------------------------------------------
* legacy HTTP Content-Encoding names (RFC 9110)
* --------------------------------------------------------------------------*/
TEST(decompress, decompressXGzipCompressed)
{
// Test that x-gzip (legacy HTTP Content-Encoding) works like gzip
auto str = "slfja;sljfklsa;jfklsjfkl;sdjfkl;sadjfkl;sdjf;lsdfjsadlf";
auto compressedData = compress("gzip", str);
auto o = decompress("x-gzip", compressedData);
ASSERT_EQ(o, str);
}
TEST(decompress, decompressXBzip2Compressed)
{
// Test that x-bzip2 (legacy HTTP Content-Encoding) works like bzip2
auto str = "slfja;sljfklsa;jfklsjfkl;sdjfkl;sadjfkl;sdjf;lsdfjsadlf";
auto compressedData = compress("bzip2", str);
auto o = decompress("x-bzip2", compressedData);
ASSERT_EQ(o, str);
}
/* ----------------------------------------------------------------------------
* compression sinks
* --------------------------------------------------------------------------*/

View file

@ -51,6 +51,26 @@ void TarArchive::check(int err, const std::string & reason)
checkLibArchive(archive, err, reason);
}
/// @brief Normalize compression method names from legacy HTTP Content-Encoding values.
///
/// Per RFC 9110 Section 8.4.1.3, HTTP recipients should treat legacy "x-*" compression
/// names as equivalent to their standard counterparts:
/// - "x-gzip" is equivalent to "gzip"
/// - "x-compress" is equivalent to "compress"
///
/// This function maps these legacy names to their libarchive-compatible equivalents.
static std::string normalizeCompressionMethod(const std::string & method)
{
if (method == "x-gzip")
return "gzip";
else if (method == "x-compress")
return "compress";
else if (method == "x-bzip2")
return "bzip2";
else
return method;
}
/// @brief Get filter_code from its name.
///
/// libarchive does not provide a convenience function like archive_write_add_filter_by_name but for reading.
@ -59,9 +79,10 @@ void TarArchive::check(int err, const std::string & reason)
/// hand-rolling the equivalent function that is better implemented in libarchive.
int getArchiveFilterCodeByName(const std::string & method)
{
auto normalizedMethod = normalizeCompressionMethod(method);
auto * ar = archive_write_new();
auto cleanup = Finally{[&ar]() { checkLibArchive(ar, archive_write_close(ar), "failed to close archive: %s"); }};
auto err = archive_write_add_filter_by_name(ar, method.c_str());
auto err = archive_write_add_filter_by_name(ar, normalizedMethod.c_str());
checkLibArchive(ar, err, "failed to get libarchive filter by name: %s");
auto code = archive_filter_code(ar, 0);
return code;