mirror of
https://github.com/NixOS/nix.git
synced 2025-11-12 21:46:01 +01:00
The problem with old code was that it used getUri for both the `diskCache` as well as logging. This is really bad because it mixes the textual human readable representation with the caching. Also using getUri for the cache key is really problematic for the S3 store, since it doesn't include the `endpoint` in the cache key, so it's totally broken. This starts separating the logging / cache concerns by introducing a `getHumanReadableURI` that should only be used for logging. The caching logic now instead uses `getReference().render(/*withParams=*/false)` exclusively. This would need to be fixed in follow-ups, because that's really fragile and broken for some store types (but it was already broken before).
116 lines
3.2 KiB
C++
116 lines
3.2 KiB
C++
#include <regex>
|
|
|
|
#include "nix/util/error.hh"
|
|
#include "nix/util/url.hh"
|
|
#include "nix/store/store-reference.hh"
|
|
#include "nix/util/file-system.hh"
|
|
#include "nix/util/util.hh"
|
|
|
|
namespace nix {
|
|
|
|
static bool isNonUriPath(const std::string & spec)
|
|
{
|
|
return
|
|
// is not a URL
|
|
spec.find("://") == std::string::npos
|
|
// Has at least one path separator, and so isn't a single word that
|
|
// might be special like "auto"
|
|
&& spec.find("/") != std::string::npos;
|
|
}
|
|
|
|
std::string StoreReference::render(bool withParams) const
|
|
{
|
|
std::string res;
|
|
|
|
std::visit(
|
|
overloaded{
|
|
[&](const StoreReference::Auto &) { res = "auto"; },
|
|
[&](const StoreReference::Specified & g) {
|
|
res = g.scheme;
|
|
res += "://";
|
|
res += g.authority;
|
|
},
|
|
},
|
|
variant);
|
|
|
|
if (withParams && !params.empty()) {
|
|
res += "?";
|
|
res += encodeQuery(params);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
StoreReference StoreReference::parse(const std::string & uri, const StoreReference::Params & extraParams)
|
|
{
|
|
auto params = extraParams;
|
|
try {
|
|
auto parsedUri = parseURL(uri);
|
|
params.insert(parsedUri.query.begin(), parsedUri.query.end());
|
|
|
|
auto baseURI = parsedUri.authority.value_or(ParsedURL::Authority{}).to_string() + parsedUri.path;
|
|
|
|
return {
|
|
.variant =
|
|
Specified{
|
|
.scheme = std::move(parsedUri.scheme),
|
|
.authority = std::move(baseURI),
|
|
},
|
|
.params = std::move(params),
|
|
};
|
|
} catch (BadURL &) {
|
|
auto [baseURI, uriParams] = splitUriAndParams(uri);
|
|
params.insert(uriParams.begin(), uriParams.end());
|
|
|
|
if (baseURI == "" || baseURI == "auto") {
|
|
return {
|
|
.variant = Auto{},
|
|
.params = std::move(params),
|
|
};
|
|
} else if (baseURI == "daemon") {
|
|
return {
|
|
.variant =
|
|
Specified{
|
|
.scheme = "unix",
|
|
.authority = "",
|
|
},
|
|
.params = std::move(params),
|
|
};
|
|
} else if (baseURI == "local") {
|
|
return {
|
|
.variant =
|
|
Specified{
|
|
.scheme = "local",
|
|
.authority = "",
|
|
},
|
|
.params = std::move(params),
|
|
};
|
|
} else if (isNonUriPath(baseURI)) {
|
|
return {
|
|
.variant =
|
|
Specified{
|
|
.scheme = "local",
|
|
.authority = absPath(baseURI),
|
|
},
|
|
.params = std::move(params),
|
|
};
|
|
}
|
|
}
|
|
|
|
throw UsageError("Cannot parse Nix store '%s'", uri);
|
|
}
|
|
|
|
/* Split URI into protocol+hierarchy part and its parameter set. */
|
|
std::pair<std::string, StoreReference::Params> splitUriAndParams(const std::string & uri_)
|
|
{
|
|
auto uri(uri_);
|
|
StoreReference::Params params;
|
|
auto q = uri.find('?');
|
|
if (q != std::string::npos) {
|
|
params = decodeQuery(uri.substr(q + 1));
|
|
uri = uri_.substr(0, q);
|
|
}
|
|
return {uri, params};
|
|
}
|
|
|
|
} // namespace nix
|