summaryrefslogtreecommitdiff
path: root/src/mongo/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/client')
-rw-r--r--src/mongo/client/mongo_uri.cpp54
-rw-r--r--src/mongo/client/mongo_uri.h45
-rw-r--r--src/mongo/client/replica_set_monitor.cpp2
3 files changed, 98 insertions, 3 deletions
diff --git a/src/mongo/client/mongo_uri.cpp b/src/mongo/client/mongo_uri.cpp
index 597933712df..c8b76e776a8 100644
--- a/src/mongo/client/mongo_uri.cpp
+++ b/src/mongo/client/mongo_uri.cpp
@@ -40,6 +40,7 @@
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/find_iterator.hpp>
#include <boost/algorithm/string/predicate.hpp>
+#include <boost/range/algorithm/count.hpp>
#include "mongo/base/status_with.h"
#include "mongo/bson/bsonobjbuilder.h"
@@ -56,8 +57,6 @@ using namespace std::literals::string_literals;
namespace {
constexpr std::array<char, 16> hexits{
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
-const mongo::StringData kURIPrefix{"mongodb://"};
-const mongo::StringData kURISRVPrefix{"mongodb+srv://"};
// This vector must remain sorted. It is over pairs to facilitate a call to `std::includes` using
// a `std::map<std::string, std::string>` as the other parameter.
@@ -112,6 +111,10 @@ namespace mongo {
namespace {
+constexpr StringData kURIPrefix = "mongodb://"_sd;
+constexpr StringData kURISRVPrefix = "mongodb+srv://"_sd;
+constexpr StringData kDefaultMongoHost = "127.0.0.1:27017"_sd;
+
/**
* Helper Method for MongoURI::parse() to split a string into exactly 2 pieces by a char
* delimiter.
@@ -519,8 +522,53 @@ const boost::optional<std::string> MongoURI::getAppName() const {
const auto optIter = _options.find("appName");
if (optIter != end(_options)) {
return optIter->second;
+ }
+ return boost::none;
+}
+
+std::string MongoURI::canonicalizeURIAsString() const {
+ StringBuilder uri;
+ uri << kURIPrefix;
+ if (!_user.empty()) {
+ uri << uriEncode(_user);
+ if (!_password.empty()) {
+ uri << ":" << uriEncode(_password);
+ }
+ uri << "@";
+ }
+
+ const auto& servers = _connectString.getServers();
+ if (!servers.empty()) {
+ auto delimeter = "";
+ for (auto& hostAndPort : servers) {
+ if (boost::count(hostAndPort.host(), ':') > 1) {
+ uri << delimeter << "[" << uriEncode(hostAndPort.host()) << "]"
+ << ":" << uriEncode(std::to_string(hostAndPort.port()));
+ } else if (StringData(hostAndPort.host()).endsWith(".sock")) {
+ uri << delimeter << uriEncode(hostAndPort.host());
+ } else {
+ uri << delimeter << uriEncode(hostAndPort.host()) << ":"
+ << uriEncode(std::to_string(hostAndPort.port()));
+ }
+ delimeter = ",";
+ }
} else {
- return boost::none;
+ uri << kDefaultMongoHost;
+ }
+
+ uri << "/";
+ if (!_database.empty()) {
+ uri << uriEncode(_database);
+ }
+
+ if (!_options.empty()) {
+ auto delimeter = "";
+ uri << "?";
+ for (const auto& pair : _options) {
+ uri << delimeter << uriEncode(pair.first) << "=" << uriEncode(pair.second);
+ delimeter = "&";
+ }
}
+ return uri.str();
}
} // namespace mongo
diff --git a/src/mongo/client/mongo_uri.h b/src/mongo/client/mongo_uri.h
index 9b61dcaebd9..c121fa21801 100644
--- a/src/mongo/client/mongo_uri.h
+++ b/src/mongo/client/mongo_uri.h
@@ -130,22 +130,64 @@ public:
return _user;
}
+ void setUser(std::string newUsername) {
+ _user = std::move(newUsername);
+ }
+
const std::string& getPassword() const {
return _password;
}
+ void setPassword(std::string newPassword) {
+ _password = std::move(newPassword);
+ }
+
const OptionsMap& getOptions() const {
return _options;
}
+ void addOption(std::string newKey, std::string newValue) {
+ _options[std::move(newKey)] = std::move(newValue);
+ }
+
+ void setOptionIfNecessary(std::string uriParamKey, std::string value) {
+ const auto key = _options.find(uriParamKey);
+ if (key == end(_options) && !value.empty()) {
+ addOption(uriParamKey, value);
+ }
+ }
+
+ boost::optional<std::string> getOption(const std::string& key) const {
+ const auto optIter = _options.find(key);
+ if (optIter != end(_options)) {
+ return optIter->second;
+ }
+ return boost::none;
+ }
+
const std::string& getDatabase() const {
return _database;
}
+ std::string getAuthenticationDatabase() {
+ auto authDB = _options.find("authSource");
+ if (authDB != _options.end()) {
+ return authDB->second;
+ } else if (!_database.empty()) {
+ return _database;
+ } else {
+ return "admin";
+ }
+ }
+
bool isValid() const {
return _connectString.isValid();
}
+ const ConnectionString& connectionString() const {
+ return _connectString;
+ }
+
const std::string& toString() const {
return _connectString.toString();
}
@@ -161,6 +203,9 @@ public:
const boost::optional<std::string> getAppName() const;
+ std::string canonicalizeURIAsString() const;
+
+
boost::optional<bool> getRetryWrites() const {
return _retryWrites;
}
diff --git a/src/mongo/client/replica_set_monitor.cpp b/src/mongo/client/replica_set_monitor.cpp
index 769358dc9b0..0488b9100ec 100644
--- a/src/mongo/client/replica_set_monitor.cpp
+++ b/src/mongo/client/replica_set_monitor.cpp
@@ -854,6 +854,8 @@ HostAndPort Refresher::_refreshUntilMatches(const ReadPreferenceSetting* criteri
if (_set->setUri.isValid()) {
targetURI = _set->setUri.cloneURIForServer(ns.host);
+ targetURI.setUser("");
+ targetURI.setPassword("");
} else {
targetURI = MongoURI(ConnectionString(ns.host));
}