forked from lix-project/lix
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 "callback.hh"
|
||||
|
||||
#include <regex>
|
||||
|
||||
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_,
|
||||
const Store::Params & extraParams)
|
||||
{
|
||||
|
@ -1099,7 +1129,10 @@ ref<Store> openStore(const std::string & uri_,
|
|||
auto parsedUri = parseURL(uri_);
|
||||
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) {
|
||||
if (implem.uriSchemes.count(parsedUri.scheme)) {
|
||||
|
|
|
@ -8,7 +8,8 @@ namespace nix {
|
|||
// URI stuff.
|
||||
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 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 subdelimsRegex = "(?:[!$&'\"()*+,;=])";
|
||||
const static std::string hostnameRegex = "(?:(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + ")*)";
|
||||
|
|
Loading…
Reference in a new issue