diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index b8a9a9aa86e..5627e9d4cd3 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -7,9 +7,11 @@ #include "nix/util/callback.hh" #include "nix/util/signals.hh" +#include "nix/util/util.hh" #include "store-config-private.hh" #include "nix/store/s3-url.hh" #include +#include #if NIX_WITH_AWS_AUTH # include "nix/store/aws-creds.hh" #endif @@ -177,7 +179,7 @@ struct curlFileTransfer : public FileTransfer #if NIX_WITH_AWS_AUTH if (!request.awsSigV4Provider) #endif - appendHeaders("Accept-Encoding: zstd, br, gzip, deflate, bzip2, xz"); + appendHeaders("Accept-Encoding: zstd, br, gzip, deflate, bzip2"); if (!request.expectedETag.empty()) appendHeaders("If-None-Match: " + request.expectedETag); if (!request.mimeType.empty()) @@ -275,6 +277,29 @@ struct curlFileTransfer : public FileTransfer result.urls.push_back(effectiveUriCStr); } + static std::string parseContentEncoding(std::string_view contentEncoding) + { + + if (contentEncoding.find(",") != std::string::npos) { + throw nix::Error("Stacked Content-Encoding is not supported: %s", contentEncoding); + } + + if (contentEncoding == "gzip" || contentEncoding == "x-gzip") + return "gzip"; + else if (contentEncoding == "compress" || contentEncoding == "x-compress") + return "compress"; + else if (contentEncoding == "br") + return "br"; + else if (contentEncoding == "zstd") + return "zstd"; + else if (contentEncoding == "bzip2") + return "bzip2"; + else if (contentEncoding == "identity") + return "identity"; + + throw nix::Error("Invalid content-encoding: %s", contentEncoding); + } + size_t headerCallback(void * contents, size_t size, size_t nmemb) noexcept try { size_t realSize = size * nmemb; @@ -311,8 +336,11 @@ struct curlFileTransfer : public FileTransfer } } + /* https://www.rfc-editor.org/rfc/rfc9110.html#name-content-codings + * All content codings are case-insensitive and ought to be + * registered within the "HTTP Content Coding Registry" */ else if (name == "content-encoding") - encoding = trim(line.substr(i + 1)); + encoding = parseContentEncoding(toLower(trim(line.substr(i + 1)))); else if (name == "accept-ranges" && toLower(trim(line.substr(i + 1))) == "bytes") acceptRanges = true;