aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/store-api.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/store-api.cc')
-rw-r--r--src/libstore/store-api.cc35
1 files changed, 34 insertions, 1 deletions
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 27be66cac..7bf9235b2 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -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)) {