Merge pull request #4319 from Ma27/store-v6-addr
libstore/openStore: fix stores with IPv6 addresses
This commit is contained in:
commit
eb458ad1b2
|
@ -10,6 +10,8 @@
|
||||||
#include "archive.hh"
|
#include "archive.hh"
|
||||||
#include "callback.hh"
|
#include "callback.hh"
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
|
@ -1091,6 +1093,34 @@ std::shared_ptr<Store> openFromNonUri(const std::string & uri, const Store::Para
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The `parseURL` function supports both IPv6 URIs as defined in
|
||||||
|
// RFC2732, but also pure addresses. The latter one is needed here to
|
||||||
|
// connect to a remote store via SSH (it's possible to do e.g. `ssh root@::1`).
|
||||||
|
//
|
||||||
|
// This function now ensures that a usable connection string is available:
|
||||||
|
// * If the store to be opened is not an SSH store, nothing will be done.
|
||||||
|
// * If the URL looks like `root@[::1]` (which is allowed by the URL parser and probably
|
||||||
|
// needed to pass further flags), it
|
||||||
|
// will be transformed into `root@::1` for SSH (same for `[::1]` -> `::1`).
|
||||||
|
// * If the URL looks like `root@::1` it will be left as-is.
|
||||||
|
// * In any other case, the string will be left as-is.
|
||||||
|
static std::string extractConnStr(const std::string &proto, const std::string &connStr)
|
||||||
|
{
|
||||||
|
if (proto.rfind("ssh") != std::string::npos) {
|
||||||
|
std::smatch result;
|
||||||
|
std::regex v6AddrRegex("^((.*)@)?\\[(.*)\\]$");
|
||||||
|
|
||||||
|
if (std::regex_match(connStr, result, v6AddrRegex)) {
|
||||||
|
if (result[1].matched) {
|
||||||
|
return result.str(1) + result.str(3);
|
||||||
|
}
|
||||||
|
return result.str(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return connStr;
|
||||||
|
}
|
||||||
|
|
||||||
ref<Store> openStore(const std::string & uri_,
|
ref<Store> openStore(const std::string & uri_,
|
||||||
const Store::Params & extraParams)
|
const Store::Params & extraParams)
|
||||||
{
|
{
|
||||||
|
@ -1099,7 +1129,10 @@ ref<Store> openStore(const std::string & uri_,
|
||||||
auto parsedUri = parseURL(uri_);
|
auto parsedUri = parseURL(uri_);
|
||||||
params.insert(parsedUri.query.begin(), parsedUri.query.end());
|
params.insert(parsedUri.query.begin(), parsedUri.query.end());
|
||||||
|
|
||||||
auto baseURI = parsedUri.authority.value_or("") + parsedUri.path;
|
auto baseURI = extractConnStr(
|
||||||
|
parsedUri.scheme,
|
||||||
|
parsedUri.authority.value_or("") + parsedUri.path
|
||||||
|
);
|
||||||
|
|
||||||
for (auto implem : *Implementations::registered) {
|
for (auto implem : *Implementations::registered) {
|
||||||
if (implem.uriSchemes.count(parsedUri.scheme)) {
|
if (implem.uriSchemes.count(parsedUri.scheme)) {
|
||||||
|
|
|
@ -8,7 +8,8 @@ namespace nix {
|
||||||
// URI stuff.
|
// URI stuff.
|
||||||
const static std::string pctEncoded = "(?:%[0-9a-fA-F][0-9a-fA-F])";
|
const static std::string pctEncoded = "(?:%[0-9a-fA-F][0-9a-fA-F])";
|
||||||
const static std::string schemeRegex = "(?:[a-z][a-z0-9+.-]*)";
|
const static std::string schemeRegex = "(?:[a-z][a-z0-9+.-]*)";
|
||||||
const static std::string ipv6AddressRegex = "(?:\\[[0-9a-fA-F:]+\\])";
|
const static std::string ipv6AddressSegmentRegex = "[0-9a-fA-F:]+";
|
||||||
|
const static std::string ipv6AddressRegex = "(?:\\[" + ipv6AddressSegmentRegex + "\\]|" + ipv6AddressSegmentRegex + ")";
|
||||||
const static std::string unreservedRegex = "(?:[a-zA-Z0-9-._~])";
|
const static std::string unreservedRegex = "(?:[a-zA-Z0-9-._~])";
|
||||||
const static std::string subdelimsRegex = "(?:[!$&'\"()*+,;=])";
|
const static std::string subdelimsRegex = "(?:[!$&'\"()*+,;=])";
|
||||||
const static std::string hostnameRegex = "(?:(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + ")*)";
|
const static std::string hostnameRegex = "(?:(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + ")*)";
|
||||||
|
|
Loading…
Reference in a new issue