diff options
Diffstat (limited to 'src/mongo/client')
-rw-r--r-- | src/mongo/client/mongo_uri.cpp | 54 | ||||
-rw-r--r-- | src/mongo/client/mongo_uri.h | 45 | ||||
-rw-r--r-- | src/mongo/client/replica_set_monitor.cpp | 2 |
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)); } |