diff options
author | Andrew Morrow <acm@mongodb.com> | 2017-04-27 14:26:11 -0400 |
---|---|---|
committer | Andrew Morrow <acm@mongodb.com> | 2017-04-27 19:55:38 -0400 |
commit | 2fac57f28272d900e7926bed481e42b01cc45d00 (patch) | |
tree | 422c7c3a2b7e7a8777c4a47c22d249eaec160365 /src | |
parent | b3b32ae51349a66670f2ef17dc88f43b3ab9b90f (diff) | |
download | mongo-2fac57f28272d900e7926bed481e42b01cc45d00.tar.gz |
SERVER-29000 Remove the miniwebserver and derivatives
Diffstat (limited to 'src')
25 files changed, 2 insertions, 2619 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript index abf34365dbb..8020440e2c5 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -287,7 +287,6 @@ mongodLibDeps = [ 'db/mongod_options', 'db/mongodandmongos', 'db/op_observer_d', - 'db/mongodwebserver', 'db/repl/repl_set_commands', 'db/repair_database', 'db/repl/storage_interface_impl', diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index cef9ffea77c..05c31829d07 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -385,7 +385,6 @@ env.CppUnitTest( env.Library( target="mongodandmongos", source=[ - "dbwebserver.cpp", "initialize_server_global_state.cpp", "server_extra_log_context.cpp", "server_options_init.cpp", @@ -397,35 +396,12 @@ env.Library( "$BUILD_DIR/mongo/rpc/command_reply", "$BUILD_DIR/mongo/rpc/command_request", "$BUILD_DIR/mongo/rpc/metadata", - "$BUILD_DIR/mongo/util/net/miniwebserver", "$BUILD_DIR/mongo/util/processinfo", "$BUILD_DIR/mongo/util/signal_handlers", "auth/authorization_manager_global", ], ) -env.Library( - target="mongodwebserver", - source=[ - "clientlistplugin.cpp", - "restapi.cpp", - "stats/snapshots_webplugins.cpp", - "repl/repl_set_web_handler.cpp", - ], - LIBDEPS=[ - '$BUILD_DIR/mongo/db/background', - "$BUILD_DIR/mongo/db/curop", - '$BUILD_DIR/mongo/db/clientcursor', - "$BUILD_DIR/mongo/db/dbdirectclient", - '$BUILD_DIR/mongo/db/stats/fill_locker_info', - '$BUILD_DIR/mongo/db/stats/serveronly', - "$BUILD_DIR/mongo/util/net/miniwebserver", - "mongodandmongos", - 'repl/repl_coordinator_global', - 'repl/serveronly', - ], -) - # mongod options env.Library( target="mongod_options", diff --git a/src/mongo/db/clientlistplugin.cpp b/src/mongo/db/clientlistplugin.cpp deleted file mode 100644 index 73fb06865d3..00000000000 --- a/src/mongo/db/clientlistplugin.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/** -* Copyright (C) 2009 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -* -* As a special exception, the copyright holders give permission to link the -* code of portions of this program with the OpenSSL library under certain -* conditions as described in each individual source file and distribute -* linked combinations including the program with the OpenSSL library. You -* must comply with the GNU Affero General Public License in all respects for -* all of the code used other than as permitted herein. If you modify file(s) -* with this exception, you may extend this exception to your version of the -* file(s), but you are not obligated to do so. If you do not wish to do so, -* delete this exception statement from your version. If you delete this -* exception statement from all source files in the program, then also delete -* it in the license file. -*/ - -#include "mongo/platform/basic.h" - -#include "mongo/bson/bsonobjbuilder.h" -#include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_session.h" -#include "mongo/db/client.h" -#include "mongo/db/commands.h" -#include "mongo/db/curop.h" -#include "mongo/db/dbwebserver.h" -#include "mongo/db/matcher/expression_parser.h" -#include "mongo/db/matcher/extensions_callback_disallow_extensions.h" -#include "mongo/db/operation_context.h" -#include "mongo/db/service_context.h" -#include "mongo/db/stats/fill_locker_info.h" -#include "mongo/rpc/metadata/client_metadata.h" -#include "mongo/rpc/metadata/client_metadata_ismaster.h" -#include "mongo/util/mongoutils/html.h" -#include "mongo/util/stringutils.h" - -namespace mongo { - -using std::unique_ptr; -using std::string; - -namespace { - -class ClientListPlugin : public WebStatusPlugin { -public: - ClientListPlugin() : WebStatusPlugin("clients", 20) {} - virtual void init() {} - - virtual void run(OperationContext* opCtx, std::stringstream& ss) { - using namespace html; - - ss << "\n<table border=1 cellpadding=2 cellspacing=0>"; - ss << "<tr align='left'>" - << th(a("", "Connections to the database, both internal and external.", "Client")) - << th(a("http://dochub.mongodb.org/core/viewingandterminatingcurrentoperation", - "", - "OpId")) - << "<th>Locking</th>" - << "<th>Waiting</th>" - << "<th>SecsRunning</th>" - << "<th>Op</th>" - << th(a("http://dochub.mongodb.org/core/whatisanamespace", "", "Namespace")) - << "<th>Query</th>" - << "<th>client</th>" - << "<th>msg</th>" - << "<th>progress</th>" - - << "</tr>\n"; - - _processAllClients(opCtx->getClient()->getServiceContext(), ss); - - ss << "</table>\n"; - } - -private: - static void _processAllClients(ServiceContext* service, std::stringstream& ss) { - using namespace html; - - for (ServiceContext::LockedClientsCursor cursor(service); Client* client = cursor.next();) { - invariant(client); - - // Make the client stable - stdx::lock_guard<Client> lk(*client); - const OperationContext* opCtx = client->getOperationContext(); - if (!opCtx) - continue; - - CurOp* curOp = CurOp::get(opCtx); - if (!curOp) - continue; - - ss << "<tr><td>" << client->desc() << "</td>"; - - tablecell(ss, opCtx->getOpID()); - tablecell(ss, true); - - // LockState - { - Locker::LockerInfo lockerInfo; - opCtx->lockState()->getLockerInfo(&lockerInfo); - - BSONObjBuilder lockerInfoBuilder; - fillLockerInfo(lockerInfo, lockerInfoBuilder); - - tablecell(ss, lockerInfoBuilder.obj()); - } - - tablecell(ss, curOp->elapsedSeconds()); - - tablecell(ss, curOp->getNetworkOp()); - tablecell(ss, html::escape(curOp->getNS())); - - if (curOp->haveQuery()) { - tablecell(ss, html::escape(curOp->query().toString())); - } else { - tablecell(ss, ""); - } - - tablecell(ss, client->clientAddress(true /*includePort*/)); - - tablecell(ss, curOp->getMessage()); - tablecell(ss, curOp->getProgressMeter().toString()); - - ss << "</tr>\n"; - } - } - -} clientListPlugin; - -} // namespace -} // namespace mongo diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index 4bf339e49b1..c363aafc1dc 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -63,7 +63,6 @@ #include "mongo/db/dbdirectclient.h" #include "mongo/db/dbhelpers.h" #include "mongo/db/dbmessage.h" -#include "mongo/db/dbwebserver.h" #include "mongo/db/diag_log.h" #include "mongo/db/exec/working_set_common.h" #include "mongo/db/ftdc/ftdc_mongod.h" @@ -89,7 +88,6 @@ #include "mongo/db/repl/replication_coordinator_impl.h" #include "mongo/db/repl/storage_interface_impl.h" #include "mongo/db/repl/topology_coordinator_impl.h" -#include "mongo/db/restapi.h" #include "mongo/db/s/balancer/balancer.h" #include "mongo/db/s/sharding_initialization_mongod.h" #include "mongo/db/s/sharding_state.h" @@ -102,7 +100,6 @@ #include "mongo/db/service_entry_point_mongod.h" #include "mongo/db/startup_warnings_mongod.h" #include "mongo/db/stats/counters.h" -#include "mongo/db/stats/snapshots.h" #include "mongo/db/storage/encryption_hooks.h" #include "mongo/db/storage/mmap_v1/mmap_v1_options.h" #include "mongo/db/storage/storage_engine.h" @@ -123,6 +120,7 @@ #include "mongo/stdx/thread.h" #include "mongo/transport/transport_layer_legacy.h" #include "mongo/util/assert_util.h" +#include "mongo/util/background.h" #include "mongo/util/cmdline_utils/censor_cmdline.h" #include "mongo/util/concurrency/idle_thread_block.h" #include "mongo/util/concurrency/thread_name.h" @@ -488,18 +486,6 @@ ExitCode _initAndListen(int listenPort) { return EXIT_NET_ERROR; } - std::shared_ptr<DbWebServer> dbWebServer; - if (serverGlobalParams.isHttpInterfaceEnabled) { - dbWebServer.reset(new DbWebServer(serverGlobalParams.bind_ip, - serverGlobalParams.port + 1000, - globalServiceContext, - new RestAdminAccess())); - if (!dbWebServer->setupSockets()) { - error() << "Failed to set up sockets for HTTP interface during startup."; - return EXIT_NET_ERROR; - } - } - globalServiceContext->initializeGlobalStorageEngine(); #ifdef MONGO_CONFIG_WIREDTIGER_ENABLED @@ -592,16 +578,6 @@ ExitCode _initAndListen(int listenPort) { /* this is for security on certain platforms (nonce generation) */ srand((unsigned)(curTimeMicros64() ^ startupSrandTimer.micros())); - // The snapshot thread provides historical collection level and lock statistics for use - // by the web interface. Only needed when HTTP is enabled. - if (serverGlobalParams.isHttpInterfaceEnabled) { - statsSnapshotThread.go(); - - invariant(dbWebServer); - stdx::thread web(stdx::bind(&webServerListenThread, dbWebServer)); - web.detach(); - } - AuthorizationManager* globalAuthzManager = getGlobalAuthorizationManager(); if (globalAuthzManager->shouldValidateAuthSchemaOnStartup()) { Status status = authindex::verifySystemIndexes(startupOpCtx.get()); diff --git a/src/mongo/db/dbwebserver.cpp b/src/mongo/db/dbwebserver.cpp deleted file mode 100644 index 361c51ca05f..00000000000 --- a/src/mongo/db/dbwebserver.cpp +++ /dev/null @@ -1,658 +0,0 @@ -/* dbwebserver.cpp - - This is the administrative web page displayed on port 28017. -*/ - -/** -* Copyright (C) 2008 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -* -* As a special exception, the copyright holders give permission to link the -* code of portions of this program with the OpenSSL library under certain -* conditions as described in each individual source file and distribute -* linked combinations including the program with the OpenSSL library. You -* must comply with the GNU Affero General Public License in all respects for -* all of the code used other than as permitted herein. If you modify file(s) -* with this exception, you may extend this exception to your version of the -* file(s), but you are not obligated to do so. If you do not wish to do so, -* delete this exception statement from your version. If you delete this -* exception statement from all source files in the program, then also delete -* it in the license file. -*/ - -#include "mongo/platform/basic.h" - -#include "mongo/db/dbwebserver.h" - -#include <pcrecpp.h> - -#include "mongo/base/init.h" -#include "mongo/db/auth/authorization_manager.h" -#include "mongo/db/auth/authorization_manager_global.h" -#include "mongo/db/auth/authorization_session.h" -#include "mongo/db/auth/privilege.h" -#include "mongo/db/auth/user.h" -#include "mongo/db/auth/user_name.h" -#include "mongo/db/background.h" -#include "mongo/db/commands.h" -#include "mongo/db/db.h" -#include "mongo/db/operation_context.h" -#include "mongo/db/service_context.h" -#include "mongo/db/stats/snapshots.h" -#include "mongo/rpc/command_reply.h" -#include "mongo/rpc/command_reply_builder.h" -#include "mongo/rpc/command_request.h" -#include "mongo/rpc/command_request_builder.h" -#include "mongo/rpc/metadata.h" -#include "mongo/util/admin_access.h" -#include "mongo/util/md5.hpp" -#include "mongo/util/mongoutils/html.h" -#include "mongo/util/ramlog.h" -#include "mongo/util/version.h" - -namespace mongo { - -using std::map; -using std::stringstream; -using std::vector; - -using namespace html; - -namespace { - -void doUnlockedStuff(stringstream& ss) { - // This is in the header already ss << "port: " << port << '\n' - auto&& vii = VersionInfoInterface::instance(); - ss << "<pre>"; - ss << mongodVersion(vii) << '\n'; - ss << "git hash: " << vii.gitVersion() << '\n'; - ss << vii.openSSLVersion("OpenSSL version: ", "\n"); - ss << "uptime: " << time(0) - serverGlobalParams.started << " seconds\n"; - ss << "</pre>"; -} - -bool prisort(const Prioritizable* a, const Prioritizable* b) { - return a->priority() < b->priority(); -} - -void htmlHelp(Command* command, stringstream& ss) { - string helpStr; - { - stringstream h; - command->help(h); - helpStr = h.str(); - } - - ss << "\n<tr><td>"; - if (command->isWebUI()) - ss << "<a href=\"/" << command->getName() << "?text=1\">"; - ss << command->getName(); - if (command->isWebUI()) - ss << "</a>"; - ss << "</td>\n"; - ss << "<td>"; - ss << "UNUSED "; - if (command->slaveOk()) - ss << "S "; - if (command->adminOnly()) - ss << "A"; - ss << "</td>"; - ss << "<td>"; - if (helpStr != "no help defined") { - const char* p = helpStr.c_str(); - while (*p) { - if (*p == '<') { - ss << "<"; - p++; - continue; - } else if (*p == '{') - ss << "<code>"; - else if (*p == '}') { - ss << "}</code>"; - p++; - continue; - } - if (strncmp(p, "http:", 5) == 0) { - ss << "<a href=\""; - const char* q = p; - while (*q && *q != ' ' && *q != '\n') - ss << *q++; - ss << "\">"; - q = p; - if (str::startsWith(q, "http://www.mongodb.org/display/")) - q += 31; - while (*q && *q != ' ' && *q != '\n') { - ss << (*q == '+' ? ' ' : *q); - q++; - if (*q == '#') - while (*q && *q != ' ' && *q != '\n') - q++; - } - ss << "</a>"; - p = q; - continue; - } - if (*p == '\n') - ss << "<br>"; - else - ss << *p; - p++; - } - } - ss << "</td>"; - ss << "</tr>\n"; -} - -class LogPlugin : public WebStatusPlugin { -public: - LogPlugin() : WebStatusPlugin("Log", 100), _log(0) { - _log = RamLog::get("global"); - } - - virtual void init() {} - - virtual void run(OperationContext* opCtx, stringstream& ss) { - _log->toHTML(ss); - } - RamLog* _log; -}; - -class FavIconHandler : public DbWebHandler { -public: - FavIconHandler() : DbWebHandler("favicon.ico", 0, false) {} - - virtual void handle(OperationContext* opCtx, - const char* rq, - const std::string& url, - BSONObj params, - string& responseMsg, - int& responseCode, - vector<string>& headers, - const SockAddr& from) { - responseCode = 404; - headers.push_back("Content-Type: text/plain;charset=utf-8"); - responseMsg = "no favicon\n"; - } - -} faviconHandler; - -class StatusHandler : public DbWebHandler { -public: - StatusHandler() : DbWebHandler("_status", 1, false) {} - - virtual void handle(OperationContext* opCtx, - const char* rq, - const std::string& url, - BSONObj params, - string& responseMsg, - int& responseCode, - vector<string>& headers, - const SockAddr& from) { - headers.push_back("Content-Type: application/json;charset=utf-8"); - responseCode = 200; - - static vector<string> commands; - if (commands.size() == 0) { - commands.push_back("serverStatus"); - commands.push_back("buildinfo"); - } - - BSONObjBuilder buf(1024); - - for (unsigned i = 0; i < commands.size(); i++) { - string cmd = commands[i]; - - Command* c = Command::findCommand(cmd); - verify(c); - - BSONObj co; - { - BSONObjBuilder b; - b.append(cmd, 1); - - if (cmd == "serverStatus" && params["repl"].type()) { - b.append("repl", atoi(params["repl"].valuestr())); - } - - co = b.obj(); - } - - string errmsg; - - BSONObjBuilder sub; - if (!c->run(opCtx, "admin.$cmd", co, errmsg, sub)) - buf.append(cmd, errmsg); - else - buf.append(cmd, sub.obj()); - } - - responseMsg = buf.obj().jsonString(); - } - -} statusHandler; - -class CommandListHandler : public DbWebHandler { -public: - CommandListHandler() : DbWebHandler("_commands", 1, true) {} - - virtual void handle(OperationContext* opCtx, - const char* rq, - const std::string& url, - BSONObj params, - string& responseMsg, - int& responseCode, - vector<string>& headers, - const SockAddr& from) { - headers.push_back("Content-Type: text/html;charset=utf-8"); - responseCode = 200; - - stringstream ss; - ss << start("Commands List"); - ss << p(a("/", "back", "Home")); - ss << p( - "<b>MongoDB List of " - "<a href=\"http://dochub.mongodb.org/core/commands\">Commands</a>" - "</b>\n"); - - const Command::CommandMap* m = Command::commandsByBestName(); - ss << "S:slave-ok R:read-lock W:write-lock A:admin-only<br>\n"; - ss << table(); - ss << "<tr><th>Command</th><th>Attributes</th><th>Help</th></tr>\n"; - for (Command::CommandMap::const_iterator i = m->begin(); i != m->end(); ++i) { - htmlHelp(i->second, ss); - } - ss << _table() << _end(); - - responseMsg = ss.str(); - } -} commandListHandler; - -class CommandsHandler : public DbWebHandler { -public: - CommandsHandler() : DbWebHandler("DUMMY COMMANDS", 2, true) {} - - bool _cmd(const string& url, string& cmd, bool& text, bo params) const { - cmd = str::after(url, '/'); - text = params["text"].boolean(); - return true; - } - - Command* _cmd(const string& cmdName) const { - Command* cmd = Command::findCommand(cmdName); - if (cmd && cmd->isWebUI()) { - return cmd; - } - - return nullptr; - } - - virtual bool handles(const string& url) const { - string cmd; - bool text; - if (!_cmd(url, cmd, text, bo())) - return false; - return _cmd(cmd) != 0; - } - - virtual void handle(OperationContext* opCtx, - const char* rq, - const std::string& url, - BSONObj params, - string& responseMsg, - int& responseCode, - vector<string>& headers, - const SockAddr& from) { - string cmd; - bool text = false; - verify(_cmd(url, cmd, text, params)); - Command* c = _cmd(cmd); - verify(c); - - BSONObj cmdObj = BSON(cmd << 1); - - rpc::CommandRequestBuilder requestBuilder{}; - - requestBuilder.setDatabase("admin").setCommandName(cmd).setCommandArgs(cmdObj).setMetadata( - rpc::makeEmptyMetadata()); - - auto cmdRequestMsg = requestBuilder.done(); - rpc::CommandRequest cmdRequest{&cmdRequestMsg}; - rpc::CommandReplyBuilder cmdReplyBuilder{}; - - Command::execCommand(opCtx, c, cmdRequest, &cmdReplyBuilder); - - auto cmdReplyMsg = cmdReplyBuilder.done(); - rpc::CommandReply cmdReply{&cmdReplyMsg}; - - responseCode = 200; - - string j = cmdReply.getCommandReply().jsonString(Strict, text); - responseMsg = j; - - if (text) { - headers.push_back("Content-Type: text/plain;charset=utf-8"); - responseMsg += '\n'; - } else { - headers.push_back("Content-Type: application/json;charset=utf-8"); - } - } - -} commandsHandler; - - -MONGO_INITIALIZER(WebStatusLogPlugin)(InitializerContext*) { - if (serverGlobalParams.isHttpInterfaceEnabled) { - new LogPlugin; - } - return Status::OK(); -} - -} // namespace - - -DbWebServer::DbWebServer(const string& ip, int port, ServiceContext* ctx, AdminAccess* webUsers) - : MiniWebServer("admin web console", ip, port, ctx), _webUsers(webUsers) { - WebStatusPlugin::initAll(); -} - -void DbWebServer::doRequest(const char* rq, - string url, - string& responseMsg, - int& responseCode, - vector<string>& headers, - const SockAddr& from) { - Client* client = &cc(); - auto opCtx = client->makeOperationContext(); - - if (url.size() > 1) { - if (!_allowed(opCtx.get(), rq, headers, from)) { - responseCode = 401; - headers.push_back("Content-Type: text/plain;charset=utf-8"); - responseMsg = "not allowed\n"; - return; - } - - { - BSONObj params; - const size_t pos = url.find("?"); - if (pos != string::npos) { - MiniWebServer::parseParams(params, url.substr(pos + 1)); - url = url.substr(0, pos); - } - - DbWebHandler* handler = DbWebHandler::findHandler(url); - if (handler) { - if (handler->requiresREST(url) && !serverGlobalParams.rest) { - _rejectREST(responseMsg, responseCode, headers); - } else { - const string callback = params.getStringField("jsonp"); - - uassert(13453, - "server not started with --jsonp", - callback.empty() || serverGlobalParams.jsonp); - - handler->handle( - opCtx.get(), rq, url, params, responseMsg, responseCode, headers, from); - - if (responseCode == 200 && !callback.empty()) { - responseMsg = callback + '(' + responseMsg + ')'; - } - } - - return; - } - } - - if (!serverGlobalParams.rest) { - _rejectREST(responseMsg, responseCode, headers); - return; - } - - responseCode = 404; - headers.push_back("Content-Type: text/html;charset=utf-8"); - responseMsg = "<html><body>unknown url</body></html>\n"; - return; - } - - // generate home page - - if (!_allowed(opCtx.get(), rq, headers, from)) { - responseCode = 401; - headers.push_back("Content-Type: text/plain;charset=utf-8"); - responseMsg = "not allowed\n"; - return; - } - - responseCode = 200; - stringstream ss; - string dbname; - { - stringstream z; - z << serverGlobalParams.binaryName << ' ' << prettyHostName(); - dbname = z.str(); - } - - ss << start(dbname) << h2(dbname); - ss << "<p><a href=\"/_commands\">List all commands</a> | \n"; - ss << "<a href=\"/_replSet\">Replica set status</a></p>\n"; - - ss << a("", - "These read-only context-less commands can be executed from the web " - "interface. Results are json format, unless ?text=1 is appended in which " - "case the result is output as text for easier human viewing", - "Commands") - << ": "; - - auto m = Command::commandsByBestName(); - - for (Command::CommandMap::const_iterator i = m->begin(); i != m->end(); ++i) { - if (!i->second->isWebUI()) - continue; - - stringstream h; - i->second->help(h); - - const string help = h.str(); - ss << "<a href=\"/" << i->first << "?text=1\""; - if (help != "no help defined") { - ss << " title=\"" << help << '"'; - } - - ss << ">" << i->first << "</a> "; - } - - ss << '\n'; - - doUnlockedStuff(ss); - - WebStatusPlugin::runAll(opCtx.get(), ss); - - ss << "</body></html>\n"; - responseMsg = ss.str(); - headers.push_back("Content-Type: text/html;charset=utf-8"); -} - -bool DbWebServer::_allowed(OperationContext* opCtx, - const char* rq, - vector<string>& headers, - const SockAddr& from) { - AuthorizationSession* authSess = AuthorizationSession::get(opCtx->getClient()); - if (!authSess->getAuthorizationManager().isAuthEnabled()) { - return true; - } - - if (from.isLocalHost() && !_webUsers->haveAdminUsers(opCtx)) { - authSess->grantInternalAuthorization(); - return true; - } - - string auth = getHeader(rq, "Authorization"); - - if (auth.size() > 0 && auth.find("Digest ") == 0) { - auth = auth.substr(7) + ", "; - - map<string, string> parms; - pcrecpp::StringPiece input(auth); - - string name, val; - pcrecpp::RE re("(\\w+)=\"?(.*?)\"?,\\s*"); - while (re.Consume(&input, &name, &val)) { - parms[name] = val; - } - - // Only users in the admin DB are visible by the webserver - UserName userName(parms["username"], "admin"); - User* user; - AuthorizationManager& authzManager = authSess->getAuthorizationManager(); - Status status = authzManager.acquireUser(opCtx, userName, &user); - if (!status.isOK()) { - if (status.code() != ErrorCodes::UserNotFound) { - uasserted(17051, status.reason()); - } - } else { - uassert( - 17090, "External users don't have a password", !user->getCredentials().isExternal); - - string ha1 = user->getCredentials().password; - authzManager.releaseUser(user); - if (ha1.empty()) { - return false; - } - - const string ha2 = md5simpledigest((string) "GET" + ":" + parms["uri"]); - - stringstream r; - r << ha1 << ':' << parms["nonce"]; - if (parms["nc"].size() && parms["cnonce"].size() && parms["qop"].size()) { - r << ':'; - r << parms["nc"]; - r << ':'; - r << parms["cnonce"]; - r << ':'; - r << parms["qop"]; - } - r << ':'; - r << ha2; - - const string r1 = md5simpledigest(r.str()); - - if (r1 == parms["response"]) { - Status status = authSess->addAndAuthorizeUser(opCtx, userName); - uassertStatusOK(status); - return true; - } - } - } - - stringstream authHeader; - authHeader << "WWW-Authenticate: " - << "Digest realm=\"mongo\", " - << "nonce=\"abc\", " - << "algorithm=MD5, qop=\"auth\" "; - - headers.push_back(authHeader.str()); - return 0; -} - -void DbWebServer::_rejectREST(string& responseMsg, int& responseCode, vector<string>& headers) { - responseCode = 403; - stringstream ss; - ss << "REST is not enabled. use --rest to turn on.\n"; - ss << "check that port " << _port << " is secured for the network too.\n"; - responseMsg = ss.str(); - headers.push_back("Content-Type: text/plain;charset=utf-8"); -} - - -// -- status framework --- -WebStatusPlugin::WebStatusPlugin(const string& secionName, double priority, const string& subheader) - : Prioritizable(priority), _name(secionName), _subHeading(subheader) { - if (!_plugins) - _plugins = new vector<WebStatusPlugin*>(); - _plugins->push_back(this); -} - -void WebStatusPlugin::initAll() { - if (!_plugins) - return; - - sort(_plugins->begin(), _plugins->end(), prisort); - - for (unsigned i = 0; i < _plugins->size(); i++) - (*_plugins)[i]->init(); -} - -void WebStatusPlugin::runAll(OperationContext* opCtx, stringstream& ss) { - if (!_plugins) - return; - - for (unsigned i = 0; i < _plugins->size(); i++) { - WebStatusPlugin* p = (*_plugins)[i]; - ss << "<hr>\n" - << "<b>" << p->_name << "</b>"; - - ss << " " << p->_subHeading; - - ss << "<br>\n"; - - p->run(opCtx, ss); - } -} - -vector<WebStatusPlugin*>* WebStatusPlugin::_plugins = 0; - - -DbWebHandler::DbWebHandler(const string& name, double priority, bool requiresREST) - : Prioritizable(priority), _name(name), _requiresREST(requiresREST) { - { - // setup strings - _defaultUrl = "/"; - _defaultUrl += name; - - stringstream ss; - ss << name << " priority: " << priority << " rest: " << requiresREST; - _toString = ss.str(); - } - - { - // add to handler list - if (!_handlers) - _handlers = new vector<DbWebHandler*>(); - _handlers->push_back(this); - sort(_handlers->begin(), _handlers->end(), prisort); - } -} - -DbWebHandler* DbWebHandler::findHandler(const string& url) { - if (!_handlers) - return 0; - - for (unsigned i = 0; i < _handlers->size(); i++) { - DbWebHandler* h = (*_handlers)[i]; - if (h->handles(url)) - return h; - } - - return 0; -} - -vector<DbWebHandler*>* DbWebHandler::_handlers = 0; - -void webServerListenThread(std::shared_ptr<DbWebServer> dbWebServer) { - Client::initThread("websvr"); - - dbWebServer->initAndListen(); -} - -} // namespace mongo diff --git a/src/mongo/db/dbwebserver.h b/src/mongo/db/dbwebserver.h deleted file mode 100644 index 05de60f21e1..00000000000 --- a/src/mongo/db/dbwebserver.h +++ /dev/null @@ -1,149 +0,0 @@ -/** @file dbwebserver.h - */ - -/** -* Copyright (C) 2008 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -* -* As a special exception, the copyright holders give permission to link the -* code of portions of this program with the OpenSSL library under certain -* conditions as described in each individual source file and distribute -* linked combinations including the program with the OpenSSL library. You -* must comply with the GNU Affero General Public License in all respects for -* all of the code used other than as permitted herein. If you modify file(s) -* with this exception, you may extend this exception to your version of the -* file(s), but you are not obligated to do so. If you do not wish to do so, -* delete this exception statement from your version. If you delete this -* exception statement from all source files in the program, then also delete -* it in the license file. -*/ - -#pragma once - -#include <string> -#include <vector> - -#include "mongo/base/disallow_copying.h" -#include "mongo/util/net/miniwebserver.h" -#include "mongo/util/net/sockaddr.h" - -namespace mongo { - -class AdminAccess; -class DbWebServer; -class OperationContext; -class ServiceContext; - -class Prioritizable { -public: - Prioritizable(double p) : _priority(p) {} - double priority() const { - return _priority; - } - -private: - double _priority; -}; - -class DbWebHandler : public Prioritizable { - MONGO_DISALLOW_COPYING(DbWebHandler); - -public: - DbWebHandler(const std::string& name, double priority, bool requiresREST); - virtual ~DbWebHandler() {} - - virtual bool handles(const std::string& url) const { - return url == _defaultUrl; - } - - virtual bool requiresREST(const std::string& url) const { - return _requiresREST; - } - - virtual void handle(OperationContext* opCtx, - const char* rq, // the full request - const std::string& url, - BSONObj params, - // set these and return them: - std::string& responseMsg, - int& responseCode, - std::vector<std::string>& - headers, // if completely empty, content-type: text/html will be added - const SockAddr& from) = 0; - - std::string toString() const { - return _toString; - } - static DbWebHandler* findHandler(const std::string& url); - -private: - std::string _name; - bool _requiresREST; - - std::string _defaultUrl; - std::string _toString; - - static std::vector<DbWebHandler*>* _handlers; -}; - - -class WebStatusPlugin : public Prioritizable { -public: - WebStatusPlugin(const std::string& secionName, - double priority, - const std::string& subheader = ""); - virtual ~WebStatusPlugin() {} - - virtual void run(OperationContext* opCtx, std::stringstream& ss) = 0; - /** called when web server stats up */ - virtual void init() = 0; - - static void initAll(); - static void runAll(OperationContext* opCtx, std::stringstream& ss); - -private: - std::string _name; - std::string _subHeading; - static std::vector<WebStatusPlugin*>* _plugins; -}; - -class DbWebServer : public MiniWebServer { -public: - DbWebServer(const std::string& ip, int port, ServiceContext* ctx, AdminAccess* webUsers); - -private: - virtual void doRequest(const char* rq, - std::string url, - std::string& responseMsg, - int& responseCode, - std::vector<std::string>& headers, - const SockAddr& from); - - bool _allowed(OperationContext* opCtx, - const char* rq, - std::vector<std::string>& headers, - const SockAddr& from); - - void _rejectREST(std::string& responseMsg, - int& responseCode, - std::vector<std::string>& headers); - - - const std::unique_ptr<AdminAccess> _webUsers; -}; - -void webServerListenThread(std::shared_ptr<DbWebServer> dbWebServer); - -std::string prettyHostName(); -}; diff --git a/src/mongo/db/mongod_options.cpp b/src/mongo/db/mongod_options.cpp index ab9f370f7b7..f679f71b303 100644 --- a/src/mongo/db/mongod_options.cpp +++ b/src/mongo/db/mongod_options.cpp @@ -120,17 +120,6 @@ Status addMongodOptions(moe::OptionSection* options) { general_options.addOptionChaining("security.enableLocalhostAuthBypass", "", moe::String, "TODO") .setSources(moe::SourceYAMLConfig); - - // Network Options - - general_options.addOptionChaining("net.http.JSONPEnabled", - "jsonp", - moe::Switch, - "allow JSONP access via http (has security implications)"); - - general_options.addOptionChaining( - "net.http.RESTInterfaceEnabled", "rest", moe::Switch, "turn on simple rest api"); - // Diagnostic Options general_options @@ -637,33 +626,6 @@ Status validateMongodOptions(const moe::Environment& params) { "Can't specify both --journal and --nojournal options."); } - // SERVER-10019 Enabling rest/jsonp without --httpinterface should break in all cases in the - // future - if (params.count("net.http.RESTInterfaceEnabled") && - params["net.http.RESTInterfaceEnabled"].as<bool>() == true) { - // If we are explicitly setting httpinterface to false in the config file (the source of - // "net.http.enabled") and not overriding it on the command line (the source of - // "httpinterface"), then we can fail with an error message without breaking backwards - // compatibility. - if (!params.count("httpinterface") && params.count("net.http.enabled") && - params["net.http.enabled"].as<bool>() == false) { - return Status(ErrorCodes::BadValue, - "httpinterface must be enabled to use the rest api"); - } - } - - if (params.count("net.http.JSONPEnabled") && - params["net.http.JSONPEnabled"].as<bool>() == true) { - // If we are explicitly setting httpinterface to false in the config file (the source of - // "net.http.enabled") and not overriding it on the command line (the source of - // "httpinterface"), then we can fail with an error message without breaking backwards - // compatibility. - if (!params.count("httpinterface") && params.count("net.http.enabled") && - params["net.http.enabled"].as<bool>() == false) { - return Status(ErrorCodes::BadValue, "httpinterface must be enabled to use jsonp"); - } - } - #ifdef _WIN32 if (params.count("install") || params.count("reinstall")) { if (params.count("storage.dbPath") && @@ -713,48 +675,6 @@ Status validateMongodOptions(const moe::Environment& params) { } Status canonicalizeMongodOptions(moe::Environment* params) { - // Need to handle this before canonicalizing the general "server options", since - // httpinterface and nohttpinterface are shared between mongos and mongod, but mongod has - // extra validation required. - if (params->count("net.http.RESTInterfaceEnabled") && - (*params)["net.http.RESTInterfaceEnabled"].as<bool>() == true) { - bool httpEnabled = false; - if (params->count("net.http.enabled")) { - Status ret = params->get("net.http.enabled", &httpEnabled); - if (!ret.isOK()) { - return ret; - } - } - if (params->count("nohttpinterface")) { - log() << "** WARNING: Should not specify both --rest and --nohttpinterface" - << startupWarningsLog; - } else if (!(params->count("httpinterface") || - (params->count("net.http.enabled") && httpEnabled == true))) { - log() << "** WARNING: --rest is specified without --httpinterface," - << startupWarningsLog; - log() << "** enabling http interface" << startupWarningsLog; - Status ret = params->set("httpinterface", moe::Value(true)); - if (!ret.isOK()) { - return ret; - } - } - } - - if (params->count("net.http.JSONPEnabled") && - (*params)["net.http.JSONPEnabled"].as<bool>() == true) { - if (params->count("nohttpinterface")) { - log() << "** WARNING: Should not specify both --jsonp and --nohttpinterface" - << startupWarningsLog; - } else if (!params->count("httpinterface")) { - log() << "** WARNING --jsonp is specified without --httpinterface," - << startupWarningsLog; - log() << "** enabling http interface" << startupWarningsLog; - Status ret = params->set("httpinterface", moe::Value(true)); - if (!ret.isOK()) { - return ret; - } - } - } Status ret = canonicalizeServerOptions(params); if (!ret.isOK()) { @@ -1121,12 +1041,6 @@ Status storeMongodOptions(const moe::Environment& params) { mmapv1GlobalOptions.preallocj = !params["storage.mmapv1.journal.nopreallocj"].as<bool>(); } - if (params.count("net.http.RESTInterfaceEnabled")) { - serverGlobalParams.rest = params["net.http.RESTInterfaceEnabled"].as<bool>(); - } - if (params.count("net.http.JSONPEnabled")) { - serverGlobalParams.jsonp = params["net.http.JSONPEnabled"].as<bool>(); - } if (params.count("security.javascriptEnabled")) { mongodGlobalParams.scriptingEnabled = params["security.javascriptEnabled"].as<bool>(); } diff --git a/src/mongo/db/repl/repl_set_web_handler.cpp b/src/mongo/db/repl/repl_set_web_handler.cpp deleted file mode 100644 index 404dc659ae7..00000000000 --- a/src/mongo/db/repl/repl_set_web_handler.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/** -* Copyright (C) 2015 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -* -* As a special exception, the copyright holders give permission to link the -* code of portions of this program with the OpenSSL library under certain -* conditions as described in each individual source file and distribute -* linked combinations including the program with the OpenSSL library. You -* must comply with the GNU Affero General Public License in all respects for -* all of the code used other than as permitted herein. If you modify file(s) -* with this exception, you may extend this exception to your version of the -* file(s), but you are not obligated to do so. If you do not wish to do so, -* delete this exception statement from your version. If you delete this -* exception statement from all source files in the program, then also delete -* it in the license file. -*/ - -#include "mongo/platform/basic.h" - -#include <sstream> - -#include "mongo/db/dbwebserver.h" -#include "mongo/db/jsobj.h" -#include "mongo/db/repl/repl_set_html_summary.h" -#include "mongo/db/repl/replication_coordinator_global.h" -#include "mongo/db/repl/rslog.h" -#include "mongo/util/mongoutils/html.h" -#include "mongo/util/mongoutils/str.h" - -namespace mongo { -namespace repl { - -using namespace html; - -class ReplSetHandler : public DbWebHandler { -public: - ReplSetHandler() : DbWebHandler("_replSet", 1, false) {} - - virtual bool handles(const std::string& url) const { - return str::startsWith(url, "/_replSet"); - } - - virtual void handle(OperationContext* opCtx, - const char* rq, - const std::string& url, - BSONObj params, - std::string& responseMsg, - int& responseCode, - std::vector<std::string>& headers, - const SockAddr& from) { - responseMsg = _replSet(opCtx); - responseCode = 200; - } - - /* /_replSet show replica set status in html format */ - std::string _replSet(OperationContext* opCtx) { - std::stringstream s; - s << start("Replica Set Status " + prettyHostName()); - s << p(a("/", "back", "Home") + " | " + - a("/local/system.replset/?html=1", "", "View Replset Config") + " | " + - a("/replSetGetStatus?text=1", "", "replSetGetStatus") + " | " + - a("http://dochub.mongodb.org/core/replicasets", "", "Docs")); - - ReplicationCoordinator* replCoord = getGlobalReplicationCoordinator(); - if (replCoord->getReplicationMode() != ReplicationCoordinator::modeReplSet) { - s << p("Not using --replSet"); - s << _end(); - return s.str(); - } - - ReplSetHtmlSummary summary; - replCoord->summarizeAsHtml(&summary); - s << summary.toHtmlString(); - - s << p("Recent replset log activity:"); - fillRsLog(&s); - s << _end(); - return s.str(); - } - -} replSetHandler; - -} // namespace repl -} // namespace mongo diff --git a/src/mongo/db/restapi.cpp b/src/mongo/db/restapi.cpp deleted file mode 100644 index 393a6085529..00000000000 --- a/src/mongo/db/restapi.cpp +++ /dev/null @@ -1,315 +0,0 @@ -/** @file resetapi.cpp - web rest api -*/ -/** -* Copyright (C) 2008 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -* -* As a special exception, the copyright holders give permission to link the -* code of portions of this program with the OpenSSL library under certain -* conditions as described in each individual source file and distribute -* linked combinations including the program with the OpenSSL library. You -* must comply with the GNU Affero General Public License in all respects for -* all of the code used other than as permitted herein. If you modify file(s) -* with this exception, you may extend this exception to your version of the -* file(s), but you are not obligated to do so. If you do not wish to do so, -* delete this exception statement from your version. If you delete this -* exception statement from all source files in the program, then also delete -* it in the license file. -*/ - -#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kNetwork - -#include "mongo/platform/basic.h" - -#include "mongo/db/restapi.h" - -#include "mongo/db/auth/authorization_manager.h" -#include "mongo/db/auth/authorization_session.h" -#include "mongo/db/auth/user_name.h" -#include "mongo/db/background.h" -#include "mongo/db/clientcursor.h" -#include "mongo/db/concurrency/d_concurrency.h" -#include "mongo/db/dbdirectclient.h" -#include "mongo/db/dbwebserver.h" -#include "mongo/db/repl/master_slave.h" -#include "mongo/db/repl/replication_coordinator_global.h" -#include "mongo/util/log.h" -#include "mongo/util/md5.hpp" -#include "mongo/util/mongoutils/html.h" -#include "mongo/util/net/miniwebserver.h" - -namespace mongo { - -using std::unique_ptr; -using std::string; -using std::stringstream; -using std::vector; - -using namespace html; - -class RESTHandler : public DbWebHandler { -public: - RESTHandler() : DbWebHandler("DUMMY REST", 1000, true) {} - - virtual bool handles(const string& url) const { - return url[0] == '/' && url.find_last_of('/') > 0; - } - - virtual void handle(OperationContext* opCtx, - const char* rq, - const std::string& url, - BSONObj params, - string& responseMsg, - int& responseCode, - vector<string>& headers, - const SockAddr& from) { - DBDirectClient db(opCtx); - - string::size_type first = url.find("/", 1); - if (first == string::npos) { - responseCode = 400; - return; - } - - string method = MiniWebServer::parseMethod(rq); - string dbname = url.substr(1, first - 1); - string coll = url.substr(first + 1); - string action = ""; - - string::size_type last = coll.find_last_of("/"); - if (last == string::npos) { - action = coll; - coll = "_defaultCollection"; - } else { - action = coll.substr(last + 1); - coll = coll.substr(0, last); - } - - for (string::size_type i = 0; i < coll.size(); i++) - if (coll[i] == '/') - coll[i] = '.'; - - string fullns = MiniWebServer::urlDecode(dbname + "." + coll); - - headers.push_back((string) "x-action: " + action); - headers.push_back((string) "x-ns: " + fullns); - - bool html = false; - - stringstream ss; - - if (method == "GET") { - responseCode = 200; - html = handleRESTQuery(opCtx, fullns, action, params, responseCode, ss); - } else if (method == "POST") { - responseCode = 201; - handlePost(opCtx, fullns, MiniWebServer::body(rq), params, responseCode, ss); - } else { - responseCode = 400; - headers.push_back("X_err: bad request"); - ss << "don't know how to handle a [" << method << "]"; - log() << "don't know how to handle a [" << method << "]"; - } - - if (html) - headers.push_back("Content-Type: text/html;charset=utf-8"); - else - headers.push_back("Content-Type: text/plain;charset=utf-8"); - - responseMsg = ss.str(); - } - - bool handleRESTQuery(OperationContext* opCtx, - const std::string& ns, - const std::string& action, - BSONObj& params, - int& responseCode, - stringstream& out) { - Timer t; - - int html = _getOption(params["html"], 0); - int skip = _getOption(params["skip"], 0); - int num = _getOption(params["limit"], - _getOption(params["count"], 1000)); // count is old, limit is new - - int one = 0; - if (params["one"].type() == String && tolower(params["one"].valuestr()[0]) == 't') { - num = 1; - one = 1; - } - - BSONObjBuilder queryBuilder; - - BSONObjIterator i(params); - while (i.more()) { - BSONElement e = i.next(); - string name = e.fieldName(); - if (name.find("filter_") != 0) - continue; - - string field = name.substr(7); - const char* val = e.valuestr(); - - char* temp; - - // TODO: this is how i guess if something is a number. pretty lame right now - double number = strtod(val, &temp); - if (temp != val) - queryBuilder.append(field, number); - else - queryBuilder.append(field, val); - } - - BSONObj query = queryBuilder.obj(); - - DBDirectClient db(opCtx); - unique_ptr<DBClientCursor> cursor = db.query(ns.c_str(), query, num, skip); - uassert(13085, "query failed for dbwebserver", cursor.get()); - - if (one) { - if (cursor->more()) { - BSONObj obj = cursor->next(); - out << obj.jsonString(Strict, html ? 1 : 0) << '\n'; - } else { - responseCode = 404; - } - return html != 0; - } - - if (html) { - string title = string("query ") + ns; - out << start(title) << p(title) << "<pre>"; - } else { - out << "{\n"; - out << " \"offset\" : " << skip << ",\n"; - out << " \"rows\": [\n"; - } - - int howMany = 0; - while (cursor->more()) { - if (howMany++ && html == 0) - out << " ,\n"; - BSONObj obj = cursor->next(); - if (html) { - if (out.tellp() > 4 * 1024 * 1024) { - out << "Stopping output: more than 4MB returned and in html mode\n"; - break; - } - out << obj.jsonString(Strict, html ? 1 : 0) << "\n\n"; - } else { - if (out.tellp() > 50 * 1024 * 1024) // 50MB limit - we are using ram - break; - out << " " << obj.jsonString(); - } - } - - if (html) { - out << "</pre>\n"; - if (howMany == 0) - out << p("Collection is empty"); - out << _end(); - } else { - out << "\n ],\n\n"; - out << " \"total_rows\" : " << howMany << " ,\n"; - out << " \"query\" : " << query.jsonString() << " ,\n"; - out << " \"millis\" : " << t.millis() << '\n'; - out << "}\n"; - } - - return html != 0; - } - - // TODO Generate id and revision per couch POST spec - void handlePost(OperationContext* opCtx, - const std::string& ns, - const char* body, - BSONObj& params, - int& responseCode, - stringstream& out) { - try { - BSONObj obj = fromjson(body); - - DBDirectClient db(opCtx); - db.insert(ns.c_str(), obj); - } catch (...) { - responseCode = 400; // Bad Request. Seems reasonable for now. - out << "{ \"ok\" : false }"; - return; - } - - responseCode = 201; - out << "{ \"ok\" : true }"; - } - - int _getOption(BSONElement e, int def) { - if (e.isNumber()) - return e.numberInt(); - if (e.type() == String) - return atoi(e.valuestr()); - return def; - } -} restHandler; - -bool RestAdminAccess::haveAdminUsers(OperationContext* opCtx) const { - AuthorizationSession* authzSession = AuthorizationSession::get(opCtx->getClient()); - return authzSession->getAuthorizationManager().hasAnyPrivilegeDocuments(opCtx); -} - -class LowLevelMongodStatus : public WebStatusPlugin { -public: - LowLevelMongodStatus() - : WebStatusPlugin("overview", 5, "(only reported if can acquire read lock quickly)") {} - - virtual void init() {} - - void _gotLock(int millis, stringstream& ss) { - const repl::ReplSettings& replSettings = - repl::getGlobalReplicationCoordinator()->getSettings(); - ss << "<pre>\n"; - ss << "time to get readlock: " << millis << "ms\n"; - ss << "# Cursors: " << ClientCursor::totalOpen() << '\n'; - ss << "replication: "; - if (*repl::replInfo) - ss << "\nreplInfo: " << repl::replInfo << "\n\n"; - if (repl::getGlobalReplicationCoordinator()->getReplicationMode() == - repl::ReplicationCoordinator::modeReplSet) { - ss << a("", "see replSetGetStatus link top of page") << "--replSet </a>" - << replSettings.getReplSetString(); - } - // TODO(dannenberg) replAllDead is bad and should be removed when masterslave is removed - if (repl::replAllDead) - ss << "\n<b>replication replAllDead=" << repl::replAllDead << "</b>\n"; - else { - ss << "\nmaster: " << replSettings.isMaster() << '\n'; - ss << "slave: " << replSettings.isSlave() << '\n'; - ss << '\n'; - } - - BackgroundOperation::dump(ss); - ss << "</pre>\n"; - } - - virtual void run(OperationContext* opCtx, stringstream& ss) { - Timer t; - Lock::GlobalLock globalSLock(opCtx, MODE_S, 300); - if (globalSLock.isLocked()) { - _gotLock(t.millis(), ss); - } else { - ss << "\n<b>timed out getting lock</b>\n"; - } - } - -} lowLevelMongodStatus; -} diff --git a/src/mongo/db/restapi.h b/src/mongo/db/restapi.h deleted file mode 100644 index 39f5e0a93aa..00000000000 --- a/src/mongo/db/restapi.h +++ /dev/null @@ -1,49 +0,0 @@ -/** @file restapi.h - */ - -/** -* Copyright (C) 2010 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -* -* As a special exception, the copyright holders give permission to link the -* code of portions of this program with the OpenSSL library under certain -* conditions as described in each individual source file and distribute -* linked combinations including the program with the OpenSSL library. You -* must comply with the GNU Affero General Public License in all respects for -* all of the code used other than as permitted herein. If you modify file(s) -* with this exception, you may extend this exception to your version of the -* file(s), but you are not obligated to do so. If you do not wish to do so, -* delete this exception statement from your version. If you delete this -* exception statement from all source files in the program, then also delete -* it in the license file. -*/ - -#pragma once - -#include <string> - -#include "mongo/db/auth/user_name.h" -#include "mongo/db/jsobj.h" -#include "mongo/util/admin_access.h" - -namespace mongo { - -class RestAdminAccess : public AdminAccess { -public: - virtual ~RestAdminAccess() {} - - virtual bool haveAdminUsers(OperationContext* opCtx) const; -}; - -} // namespace mongo diff --git a/src/mongo/db/server_options.h b/src/mongo/db/server_options.h index 95bd873740c..3341d88df20 100644 --- a/src/mongo/db/server_options.h +++ b/src/mongo/db/server_options.h @@ -51,7 +51,6 @@ struct ServerGlobalParams { std::string bind_ip; // --bind_ip bool rest = false; // --rest - bool jsonp = false; // --jsonp bool indexBuildRetry = true; // --noIndexBuildRetry @@ -86,8 +85,6 @@ struct ServerGlobalParams { bool logWithSyslog = false; // True if logging to syslog; must not be set if logpath is set. int syslogFacility; // Facility used when appending messages to the syslog. - bool isHttpInterfaceEnabled = false; // True if the dbwebserver should be enabled. - #ifndef _WIN32 ProcessId parentProc; // --fork pid of initial process ProcessId leaderProc; // --fork pid of leader process diff --git a/src/mongo/db/server_options_helpers.cpp b/src/mongo/db/server_options_helpers.cpp index 37412636992..cd08324cfa2 100644 --- a/src/mongo/db/server_options_helpers.cpp +++ b/src/mongo/db/server_options_helpers.cpp @@ -284,19 +284,6 @@ Status addGeneralServerOptions(moe::OptionSection* options) { .composing(); options - ->addOptionChaining("httpinterface", "httpinterface", moe::Switch, "enable http interface") - .setSources(moe::SourceAllLegacy) - .incompatibleWith("nohttpinterface"); - - options->addOptionChaining("net.http.enabled", "", moe::Bool, "enable http interface") - .setSources(moe::SourceYAMLConfig); - - options - ->addOptionChaining( - "net.http.port", "", moe::Switch, "port to listen on for http interface") - .setSources(moe::SourceYAMLConfig); - - options ->addOptionChaining( "security.transitionToAuth", "transitionToAuth", @@ -348,14 +335,6 @@ Status addGeneralServerOptions(moe::OptionSection* options) { .setSources(moe::SourceAllLegacy); } - // Extra hidden options - options - ->addOptionChaining( - "nohttpinterface", "nohttpinterface", moe::Switch, "disable http interface") - .hidden() - .setSources(moe::SourceAllLegacy) - .incompatibleWith("httpinterface"); - options ->addOptionChaining("objcheck", "objcheck", @@ -631,31 +610,6 @@ Status canonicalizeServerOptions(moe::Environment* params) { } } - // "net.http.enabled" comes from the config file, so override it if "nohttpinterface" or - // "httpinterface" are set since those come from the command line. - if (params->count("nohttpinterface")) { - Status ret = - params->set("net.http.enabled", moe::Value(!(*params)["nohttpinterface"].as<bool>())); - if (!ret.isOK()) { - return ret; - } - ret = params->remove("nohttpinterface"); - if (!ret.isOK()) { - return ret; - } - } - if (params->count("httpinterface")) { - Status ret = - params->set("net.http.enabled", moe::Value((*params)["httpinterface"].as<bool>())); - if (!ret.isOK()) { - return ret; - } - ret = params->remove("httpinterface"); - if (!ret.isOK()) { - return ret; - } - } - // "net.unixDomainSocket.enabled" comes from the config file, so override it if // "nounixsocket" is set since that comes from the command line. if (params->count("nounixsocket")) { @@ -783,11 +737,6 @@ Status storeServerOptions(const moe::Environment& params) { return ret; } - // Check options that are not yet supported - if (params.count("net.http.port")) { - return Status(ErrorCodes::BadValue, "The net.http.port option is not currently supported"); - } - if (params.count("systemLog.verbosity")) { int verbosity = params["systemLog.verbosity"].as<int>(); if (verbosity < 0) { @@ -834,10 +783,6 @@ Status storeServerOptions(const moe::Environment& params) { enableIPv6(); } - if (params.count("net.http.enabled")) { - serverGlobalParams.isHttpInterfaceEnabled = params["net.http.enabled"].as<bool>(); - } - if (params.count("security.transitionToAuth")) { serverGlobalParams.transitionToAuth = params["security.transitionToAuth"].as<bool>(); } diff --git a/src/mongo/db/startup_warnings_common.cpp b/src/mongo/db/startup_warnings_common.cpp index 9c444410b51..510de06ca04 100644 --- a/src/mongo/db/startup_warnings_common.cpp +++ b/src/mongo/db/startup_warnings_common.cpp @@ -61,19 +61,6 @@ void logCommonStartupWarnings(const ServerGlobalParams& serverParams) { } } - if (serverParams.authState == ServerGlobalParams::AuthState::kEnabled && - (serverParams.rest || serverParams.isHttpInterfaceEnabled || serverParams.jsonp)) { - log() << startupWarningsLog; - log() - << "** WARNING: The server is started with the web server interface and access control." - << startupWarningsLog; - log() << "** The web interfaces (rest, httpinterface and/or jsonp) are insecure " - << startupWarningsLog; - log() << "** and should be disabled unless required for backward compatibility." - << startupWarningsLog; - warned = true; - } - if (serverParams.authState == ServerGlobalParams::AuthState::kUndefined) { log() << startupWarningsLog; log() << "** WARNING: Access control is not enabled for the database." diff --git a/src/mongo/db/stats/SConscript b/src/mongo/db/stats/SConscript index 270cadafe80..2bc9b1c1775 100644 --- a/src/mongo/db/stats/SConscript +++ b/src/mongo/db/stats/SConscript @@ -93,7 +93,6 @@ env.Library( source=[ "latency_server_status_section.cpp", "lock_server_status_section.cpp", - "snapshots.cpp", 'storage_stats.cpp', ], LIBDEPS=[ diff --git a/src/mongo/db/stats/snapshots.cpp b/src/mongo/db/stats/snapshots.cpp deleted file mode 100644 index c5ab5832534..00000000000 --- a/src/mongo/db/stats/snapshots.cpp +++ /dev/null @@ -1,124 +0,0 @@ -// snapshots.cpp - -/** -* Copyright (C) 2008 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -* -* As a special exception, the copyright holders give permission to link the -* code of portions of this program with the OpenSSL library under certain -* conditions as described in each individual source file and distribute -* linked combinations including the program with the OpenSSL library. You -* must comply with the GNU Affero General Public License in all respects for -* all of the code used other than as permitted herein. If you modify file(s) -* with this exception, you may extend this exception to your version of the -* file(s), but you are not obligated to do so. If you do not wish to do so, -* delete this exception statement from your version. If you delete this -* exception statement from all source files in the program, then also delete -* it in the license file. -*/ - -#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault - -#include "mongo/platform/basic.h" - -#include "mongo/db/stats/snapshots.h" - -#include "mongo/base/static_assert.h" -#include "mongo/db/client.h" -#include "mongo/db/clientcursor.h" -#include "mongo/db/service_context.h" -#include "mongo/util/concurrency/idle_thread_block.h" -#include "mongo/util/exit.h" -#include "mongo/util/log.h" - -/** - handles snapshotting performance metrics and other such things - */ -namespace mongo { - -using std::unique_ptr; -using std::endl; - -void SnapshotData::takeSnapshot() { - _created = curTimeMicros64(); - Top::get(getGlobalServiceContext()).cloneMap(_usage); -} - -SnapshotDelta::SnapshotDelta(const SnapshotData& older, const SnapshotData& newer) - : _older(older), _newer(newer) { - verify(_newer._created > _older._created); - _elapsed = _newer._created - _older._created; -} - -Top::UsageMap SnapshotDelta::collectionUsageDiff() { - verify(_newer._created > _older._created); - Top::UsageMap u; - - for (Top::UsageMap::const_iterator i = _newer._usage.begin(); i != _newer._usage.end(); ++i) { - Top::UsageMap::const_iterator j = _older._usage.find(i->first); - if (j != _older._usage.end()) - u[i->first] = Top::CollectionData(j->second, i->second); - else - u[i->first] = i->second; - } - return u; -} - -Snapshots::Snapshots() : _loc(0), _stored(0) {} - -const SnapshotData* Snapshots::takeSnapshot() { - stdx::lock_guard<stdx::mutex> lk(_lock); - _loc = (_loc + 1) % kNumSnapshots; - _snapshots[_loc].takeSnapshot(); - if (_stored < kNumSnapshots) - _stored++; - return &_snapshots[_loc]; -} - -StatusWith<SnapshotDiff> Snapshots::computeDelta() { - stdx::lock_guard<stdx::mutex> lk(_lock); - - // We need 2 snapshots to calculate a delta - if (_stored < 2) { - return StatusWith<SnapshotDiff>(ErrorCodes::BadValue, "Less than 2 snapshots exist"); - } - - // The following logic depends on there being exactly 2 stored snapshots - MONGO_STATIC_ASSERT(kNumSnapshots == 2); - - // Current and previous napshot alternates between indexes 0 and 1 - int currIdx = _loc; - int prevIdx = _loc > 0 ? 0 : 1; - SnapshotDelta delta(_snapshots[prevIdx], _snapshots[currIdx]); - - return SnapshotDiff(delta.collectionUsageDiff(), delta.elapsed()); -} - -void StatsSnapshotThread::run() { - Client::initThread("statsSnapshot"); - while (!globalInShutdownDeprecated()) { - try { - statsSnapshots.takeSnapshot(); - } catch (std::exception& e) { - log() << "ERROR in SnapshotThread: " << redact(e.what()) << endl; - } - - MONGO_IDLE_THREAD_BLOCK; - sleepsecs(4); - } -} - -Snapshots statsSnapshots; -StatsSnapshotThread statsSnapshotThread; -} diff --git a/src/mongo/db/stats/snapshots.h b/src/mongo/db/stats/snapshots.h deleted file mode 100644 index 5013275265b..00000000000 --- a/src/mongo/db/stats/snapshots.h +++ /dev/null @@ -1,116 +0,0 @@ -// snapshots.h - -/** -* Copyright (C) 2008 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -* -* As a special exception, the copyright holders give permission to link the -* code of portions of this program with the OpenSSL library under certain -* conditions as described in each individual source file and distribute -* linked combinations including the program with the OpenSSL library. You -* must comply with the GNU Affero General Public License in all respects for -* all of the code used other than as permitted herein. If you modify file(s) -* with this exception, you may extend this exception to your version of the -* file(s), but you are not obligated to do so. If you do not wish to do so, -* delete this exception statement from your version. If you delete this -* exception statement from all source files in the program, then also delete -* it in the license file. -*/ - -#pragma once - -#include "mongo/base/status_with.h" -#include "mongo/db/jsobj.h" -#include "mongo/db/stats/top.h" -#include "mongo/stdx/mutex.h" -#include "mongo/util/background.h" - -/** - handles snapshotting performance metrics and other such things - */ -namespace mongo { - -class StatsSnapshotThread; - -/** - * stores a point in time snapshot - * i.e. all counters at a given time - */ -class SnapshotData { - void takeSnapshot(); - - unsigned long long _created; - Top::UsageMap _usage; - - friend class StatsSnapshotThread; - friend class SnapshotDelta; - friend class Snapshots; -}; - -/** - * contains performance information for a time period - */ -class SnapshotDelta { -public: - SnapshotDelta(const SnapshotData& older, const SnapshotData& newer); - - unsigned long long elapsed() const { - return _elapsed; - } - - Top::UsageMap collectionUsageDiff(); - -private: - const SnapshotData& _older; - const SnapshotData& _newer; - - unsigned long long _elapsed; -}; - -struct SnapshotDiff { - Top::UsageMap usageDiff; - unsigned long long timeElapsed; - - SnapshotDiff() = default; - SnapshotDiff(Top::UsageMap map, unsigned long long elapsed) - : usageDiff(std::move(map)), timeElapsed(elapsed) {} -}; - -class Snapshots { -public: - Snapshots(); - - const SnapshotData* takeSnapshot(); - - StatusWith<SnapshotDiff> computeDelta(); - -private: - stdx::mutex _lock; - static const int kNumSnapshots = 2; - SnapshotData _snapshots[kNumSnapshots]; - int _loc; - int _stored; -}; - -class StatsSnapshotThread : public BackgroundJob { -public: - virtual std::string name() const { - return "statsSnapshot"; - } - void run(); -}; - -extern Snapshots statsSnapshots; -extern StatsSnapshotThread statsSnapshotThread; -} diff --git a/src/mongo/db/stats/snapshots_webplugins.cpp b/src/mongo/db/stats/snapshots_webplugins.cpp deleted file mode 100644 index c45d827ebf3..00000000000 --- a/src/mongo/db/stats/snapshots_webplugins.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/** -* Copyright (C) 2008 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -* -* As a special exception, the copyright holders give permission to link the -* code of portions of this program with the OpenSSL library under certain -* conditions as described in each individual source file and distribute -* linked combinations including the program with the OpenSSL library. You -* must comply with the GNU Affero General Public License in all respects for -* all of the code used other than as permitted herein. If you modify file(s) -* with this exception, you may extend this exception to your version of the -* file(s), but you are not obligated to do so. If you do not wish to do so, -* delete this exception statement from your version. If you delete this -* exception statement from all source files in the program, then also delete -* it in the license file. -*/ - -#include "mongo/platform/basic.h" - -#include "mongo/db/dbwebserver.h" -#include "mongo/db/operation_context.h" -#include "mongo/db/stats/snapshots.h" -#include "mongo/util/mongoutils/html.h" - -namespace mongo { -namespace { - -using namespace html; - -using std::fixed; -using std::setprecision; -using std::string; -using std::stringstream; - -class DBTopStatus : public WebStatusPlugin { -public: - DBTopStatus() : WebStatusPlugin("dbtop", 50, "(occurrences|percent of elapsed)") {} - - void display(stringstream& ss, double elapsed, const Top::UsageData& usage) { - ss << "<td>"; - ss << usage.count; - ss << "</td><td>"; - double per = 100 * ((double)usage.time) / elapsed; - if (per == (int)per) - ss << (int)per; - else { - const auto precision = ss.precision(); - const auto flags = ss.flags(); - ss << setprecision(1) << fixed << per; - ss.flags(flags); - ss.precision(precision); - } - ss << '%'; - ss << "</td>"; - } - - void display(stringstream& ss, - double elapsed, - const string& ns, - const Top::CollectionData& data) { - if (ns != "TOTAL" && data.total.count == 0) - return; - ss << "<tr><th>" << html::escape(ns) << "</th>"; - - display(ss, elapsed, data.total); - - display(ss, elapsed, data.readLock); - display(ss, elapsed, data.writeLock); - - display(ss, elapsed, data.queries); - display(ss, elapsed, data.getmore); - display(ss, elapsed, data.insert); - display(ss, elapsed, data.update); - display(ss, elapsed, data.remove); - - ss << "</tr>\n"; - } - - void run(OperationContext* opCtx, stringstream& ss) { - StatusWith<SnapshotDiff> diff = statsSnapshots.computeDelta(); - - if (!diff.isOK()) - return; - - ss << "<table border=1 cellpadding=2 cellspacing=0>"; - ss << "<tr align='left'><th>"; - ss << a("http://dochub.mongodb.org/core/whatisanamespace", "namespace") - << "NS</a></th>" - "<th colspan=2>total</th>" - "<th colspan=2>Reads</th>" - "<th colspan=2>Writes</th>" - "<th colspan=2>Queries</th>" - "<th colspan=2>GetMores</th>" - "<th colspan=2>Inserts</th>" - "<th colspan=2>Updates</th>" - "<th colspan=2>Removes</th>"; - ss << "</tr>\n"; - - const Top::UsageMap& usage = diff.getValue().usageDiff; - unsigned long long elapsed = diff.getValue().timeElapsed; - for (Top::UsageMap::const_iterator i = usage.begin(); i != usage.end(); ++i) { - display(ss, (double)elapsed, i->first, i->second); - } - - ss << "</table>"; - } - - virtual void init() {} -} dbtopStatus; - -} // namespace -} // namespace mongo diff --git a/src/mongo/s/mongos_options.cpp b/src/mongo/s/mongos_options.cpp index b1a49fae4e9..a98cb444fc3 100644 --- a/src/mongo/s/mongos_options.cpp +++ b/src/mongo/s/mongos_options.cpp @@ -99,13 +99,6 @@ Status addMongosOptions(moe::OptionSection* options) { .setSources(moe::SourceAllLegacy); sharding_options - .addOptionChaining("net.http.JSONPEnabled", - "jsonp", - moe::Switch, - "allow JSONP access via http (has security implications)") - .setSources(moe::SourceAllLegacy); - - sharding_options .addOptionChaining("noscripting", "noscripting", moe::Switch, "disable scripting engine") .setSources(moe::SourceAllLegacy); @@ -192,10 +185,6 @@ Status storeMongosOptions(const moe::Environment& params) { params["replication.localPingThresholdMs"].as<int>(); } - if (params.count("net.http.JSONPEnabled")) { - serverGlobalParams.jsonp = params["net.http.JSONPEnabled"].as<bool>(); - } - if (params.count("noscripting")) { // This option currently has no effect for mongos } diff --git a/src/mongo/s/server.cpp b/src/mongo/s/server.cpp index 5609edf2d99..a88d123e535 100644 --- a/src/mongo/s/server.cpp +++ b/src/mongo/s/server.cpp @@ -50,7 +50,6 @@ #include "mongo/db/auth/authz_manager_external_state_s.h" #include "mongo/db/auth/user_cache_invalidator_job.h" #include "mongo/db/client.h" -#include "mongo/db/dbwebserver.h" #include "mongo/db/initialize_server_global_state.h" #include "mongo/db/lasterror.h" #include "mongo/db/log_process_details.h" @@ -306,17 +305,6 @@ static ExitCode runMongosServer() { Grid::get(opCtx.get())->getBalancerConfiguration()->refreshAndCheck(opCtx.get()); } - if (serverGlobalParams.isHttpInterfaceEnabled) { - std::shared_ptr<DbWebServer> dbWebServer(new DbWebServer(serverGlobalParams.bind_ip, - serverGlobalParams.port + 1000, - getGlobalServiceContext(), - new NoAdminAccess())); - dbWebServer->setupSockets(); - - stdx::thread web(stdx::bind(&webServerListenThread, dbWebServer)); - web.detach(); - } - Status status = getGlobalAuthorizationManager()->initialize(NULL); if (!status.isOK()) { error() << "Initializing authorization data failed: " << status; diff --git a/src/mongo/shell/servers_misc.js b/src/mongo/shell/servers_misc.js index b2a31ac1a88..c79b7055e09 100644 --- a/src/mongo/shell/servers_misc.js +++ b/src/mongo/shell/servers_misc.js @@ -17,7 +17,6 @@ ToolTest.prototype.startDB = function(coll) { var options = { port: this.port, dbpath: this.dbpath, - nohttpinterface: "", noprealloc: "", smallfiles: "", bind_ip: "127.0.0.1" @@ -101,7 +100,7 @@ ReplTest.prototype.getOptions = function(master, extra, putBinaryFirst, norepl) var a = []; if (putBinaryFirst) a.push("mongod"); - a.push("--nohttpinterface", "--noprealloc", "--bind_ip", "127.0.0.1", "--smallfiles"); + a.push("--noprealloc", "--bind_ip", "127.0.0.1", "--smallfiles"); a.push("--port"); a.push(this.getPort(master)); diff --git a/src/mongo/util/net/SConscript b/src/mongo/util/net/SConscript index c712e477255..7d7dd572dad 100644 --- a/src/mongo/util/net/SConscript +++ b/src/mongo/util/net/SConscript @@ -36,7 +36,6 @@ networkEnv.Library( "asio_message_port.cpp", "asio_ssl_context.cpp", "hostname_canonicalization.cpp", - "httpclient.cpp", "listen.cpp", "message.cpp", "message_port.cpp", @@ -85,13 +84,3 @@ env.CppUnitTest( 'network', ], ) - -env.Library( - target='miniwebserver', - source=[ - 'miniwebserver.cpp', - ], - LIBDEPS=[ - 'network', - ], -) diff --git a/src/mongo/util/net/httpclient.cpp b/src/mongo/util/net/httpclient.cpp deleted file mode 100644 index 2cd94c0635f..00000000000 --- a/src/mongo/util/net/httpclient.cpp +++ /dev/null @@ -1,196 +0,0 @@ -// httpclient.cpp - -/* Copyright 2009 10gen Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects - * for all of the code used other than as permitted herein. If you modify - * file(s) with this exception, you may extend this exception to your - * version of the file(s), but you are not obligated to do so. If you do not - * wish to do so, delete this exception statement from your version. If you - * delete this exception statement from all source files in the program, - * then also delete it in the license file. - */ - -#include "mongo/platform/basic.h" - -#include "mongo/util/net/httpclient.h" - -#include "mongo/bson/util/builder.h" -#include "mongo/config.h" -#include "mongo/util/mongoutils/str.h" -#include "mongo/util/net/message.h" -#include "mongo/util/net/sock.h" -#include "mongo/util/net/socket_exception.h" -#include "mongo/util/net/ssl_manager.h" - -namespace mongo { - -using std::string; -using std::stringstream; - -//#define HD(x) cout << x << endl; -#define HD(x) - - -int HttpClient::get(const std::string& url, Result* result) { - return _go("GET", url, 0, result); -} - -int HttpClient::post(const std::string& url, const std::string& data, Result* result) { - return _go("POST", url, data.c_str(), result); -} - -int HttpClient::_go(const char* command, string url, const char* body, Result* result) { - bool ssl = false; - if (url.find("https://") == 0) { - ssl = true; - url = url.substr(8); - } else { - uassert(10271, "invalid url", url.find("http://") == 0); - url = url.substr(7); - } - - string host, path; - if (url.find("/") == string::npos) { - host = url; - path = "/"; - } else { - host = url.substr(0, url.find("/")); - path = url.substr(url.find("/")); - } - - - HD("host [" << host << "]"); - HD("path [" << path << "]"); - - string server = host; - int port = ssl ? 443 : 80; - - string::size_type idx = host.find(":"); - if (idx != string::npos) { - server = host.substr(0, idx); - string t = host.substr(idx + 1); - port = atoi(t.c_str()); - } - - HD("server [" << server << "]"); - HD("port [" << port << "]"); - - string req; - { - stringstream ss; - ss << command << " " << path << " HTTP/1.1\r\n"; - ss << "Host: " << host << "\r\n"; - ss << "Connection: Close\r\n"; - ss << "User-Agent: mongodb http client\r\n"; - if (body) { - ss << "Content-Length: " << strlen(body) << "\r\n"; - } - ss << "\r\n"; - if (body) { - ss << body; - } - - req = ss.str(); - } - - SockAddr addr(server.c_str(), port); - uassert(15000, "server socket addr is invalid", addr.isValid()); - HD("addr: " << addr.toString()); - - Socket sock; - if (!sock.connect(addr)) - return -1; - - if (ssl) { -#ifdef MONGO_CONFIG_SSL - // pointer to global singleton instance - SSLManagerInterface* mgr = getSSLManager(); - - sock.secure(mgr, ""); -#else - uasserted(15862, "no ssl support"); -#endif - } - - { - const char* out = req.c_str(); - int toSend = req.size(); - sock.send(out, toSend, "_go"); - } - - char buf[4097]; - int got = sock.unsafe_recv(buf, 4096); - buf[got] = 0; - - int rc; - char version[32]; - verify(sscanf(buf, "%s %d", version, &rc) == 2); - HD("rc: " << rc); - - StringBuilder sb; - if (result) - sb << buf; - - // SERVER-8864, unsafe_recv will throw when recv returns 0 indicating closed socket. - try { - while ((got = sock.unsafe_recv(buf, 4096)) > 0) { - buf[got] = 0; - if (result) - sb << buf; - } - } catch (const SocketException&) { - } - - - if (result) { - result->_init(rc, sb.str()); - } - - return rc; -} - -void HttpClient::Result::_init(int code, string entire) { - _code = code; - _entireResponse = entire; - - while (true) { - size_t i = entire.find('\n'); - if (i == string::npos) { - // invalid - break; - } - - string h = entire.substr(0, i); - entire = entire.substr(i + 1); - - if (h.size() && h[h.size() - 1] == '\r') - h = h.substr(0, h.size() - 1); - - if (h.size() == 0) - break; - - i = h.find(':'); - if (i != string::npos) - _headers[h.substr(0, i)] = str::ltrim(h.substr(i + 1)); - } - - _body = entire; -} -} diff --git a/src/mongo/util/net/httpclient.h b/src/mongo/util/net/httpclient.h deleted file mode 100644 index 8c7c1af8ce6..00000000000 --- a/src/mongo/util/net/httpclient.h +++ /dev/null @@ -1,87 +0,0 @@ -// httpclient.h - -/* Copyright 2009 10gen Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects - * for all of the code used other than as permitted herein. If you modify - * file(s) with this exception, you may extend this exception to your - * version of the file(s), but you are not obligated to do so. If you do not - * wish to do so, delete this exception statement from your version. If you - * delete this exception statement from all source files in the program, - * then also delete it in the license file. - */ - -#pragma once - -#include "mongo/base/disallow_copying.h" -#include "mongo/platform/basic.h" - -#include <map> -#include <string> - -namespace mongo { - -class HttpClient { - MONGO_DISALLOW_COPYING(HttpClient); - -public: - typedef std::map<std::string, std::string> Headers; - - class Result { - public: - Result() {} - - const std::string& getEntireResponse() const { - return _entireResponse; - } - - Headers getHeaders() const { - return _headers; - } - - const std::string& getBody() const { - return _body; - } - - private: - void _init(int code, std::string entire); - - int _code; - std::string _entireResponse; - - Headers _headers; - std::string _body; - - friend class HttpClient; - }; - - /** - * @return response code - */ - int get(const std::string& url, Result* result = 0); - - /** - * @return response code - */ - int post(const std::string& url, const std::string& body, Result* result = 0); - -private: - int _go(const char* command, std::string url, const char* body, Result* result); -}; -} diff --git a/src/mongo/util/net/miniwebserver.cpp b/src/mongo/util/net/miniwebserver.cpp deleted file mode 100644 index 5f4165d42f4..00000000000 --- a/src/mongo/util/net/miniwebserver.cpp +++ /dev/null @@ -1,242 +0,0 @@ -// miniwebserver.cpp - -/* Copyright 2009 10gen Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects - * for all of the code used other than as permitted herein. If you modify - * file(s) with this exception, you may extend this exception to your - * version of the file(s), but you are not obligated to do so. If you do not - * wish to do so, delete this exception statement from your version. If you - * delete this exception statement from all source files in the program, - * then also delete it in the license file. - */ - -#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kNetwork - -#include "mongo/platform/basic.h" - -#include "mongo/util/net/miniwebserver.h" - -#include <pcrecpp.h> - -#include "mongo/config.h" -#include "mongo/db/service_context.h" -#include "mongo/util/assert_util.h" -#include "mongo/util/hex.h" -#include "mongo/util/log.h" -#include "mongo/util/net/socket_exception.h" - -namespace mongo { - -using std::shared_ptr; -using std::stringstream; -using std::vector; - -MiniWebServer::MiniWebServer(const string& name, const string& ip, int port, ServiceContext* ctx) - : Listener(name, ip, port, ctx, false, false) {} - -string MiniWebServer::parseURL(const char* buf) { - const char* urlStart = strchr(buf, ' '); - if (!urlStart) - return "/"; - - urlStart++; - - const char* end = strchr(urlStart, ' '); - if (!end) { - end = strchr(urlStart, '\r'); - if (!end) { - end = strchr(urlStart, '\n'); - } - } - - if (!end) - return "/"; - - int diff = (int)(end - urlStart); - if (diff < 0 || diff > 255) - return "/"; - - return string(urlStart, (int)(end - urlStart)); -} - -void MiniWebServer::parseParams(BSONObj& params, string query) { - if (query.size() == 0) - return; - - BSONObjBuilder b; - while (query.size()) { - string::size_type amp = query.find("&"); - - string cur; - if (amp == string::npos) { - cur = query; - query = ""; - } else { - cur = query.substr(0, amp); - query = query.substr(amp + 1); - } - - string::size_type eq = cur.find("="); - if (eq == string::npos) - continue; - - b.append(urlDecode(cur.substr(0, eq)), urlDecode(cur.substr(eq + 1))); - } - - params = b.obj(); -} - -string MiniWebServer::parseMethod(const char* headers) { - const char* end = strchr(headers, ' '); - if (!end) - return "GET"; - return string(headers, (int)(end - headers)); -} - -const char* MiniWebServer::body(const char* buf) { - const char* ret = strstr(buf, "\r\n\r\n"); - return ret ? ret + 4 : ret; -} - -bool MiniWebServer::fullReceive(const char* buf) { - const char* bod = body(buf); - if (!bod) - return false; - const char* lenString = "Content-Length:"; - const char* lengthLoc = strstr(buf, lenString); - if (!lengthLoc) - return true; - lengthLoc += strlen(lenString); - long len = strtol(lengthLoc, 0, 10); - if (long(strlen(bod)) == len) - return true; - return false; -} - -void MiniWebServer::_accepted(const std::shared_ptr<Socket>& psock, long long connectionId) { - char buf[4096]; - int len = 0; - try { -#ifdef MONGO_CONFIG_SSL - psock->doSSLHandshake(); -#endif - psock->setTimeout(8); - while (1) { - int left = sizeof(buf) - 1 - len; - if (left == 0) - break; - int x; - try { - x = psock->unsafe_recv(buf + len, left); - } catch (const SocketException&) { - psock->close(); - return; - } - len += x; - buf[len] = 0; - if (fullReceive(buf)) { - break; - } - } - } catch (const SocketException& e) { - LOG(1) << "couldn't recv data via http client: " << e; - return; - } - buf[len] = 0; - - string responseMsg; - int responseCode = 599; - vector<string> headers; - - try { - doRequest(buf, parseURL(buf), responseMsg, responseCode, headers, psock->remoteAddr()); - } catch (std::exception& e) { - responseCode = 500; - responseMsg = "error loading page: "; - responseMsg += e.what(); - } catch (...) { - responseCode = 500; - responseMsg = "unknown error loading page"; - } - - stringstream ss; - ss << "HTTP/1.0 " << responseCode; - if (responseCode == 200) - ss << " OK"; - ss << "\r\n"; - if (headers.empty()) { - ss << "Content-Type: text/html\r\n"; - } else { - for (vector<string>::iterator i = headers.begin(); i != headers.end(); i++) { - verify(strncmp("Content-Length", i->c_str(), 14)); - ss << *i << "\r\n"; - } - } - ss << "Connection: close\r\n"; - ss << "Content-Length: " << responseMsg.size() << "\r\n"; - ss << "\r\n"; - ss << responseMsg; - string response = ss.str(); - - try { - psock->send(response.c_str(), response.size(), "http response"); - psock->close(); - } catch (SocketException& e) { - LOG(1) << "couldn't send data to http client: " << e; - } -} - -void MiniWebServer::accepted(std::unique_ptr<AbstractMessagingPort> mp) { - MONGO_UNREACHABLE; -} - -string MiniWebServer::getHeader(const char* req, const std::string& wanted) { - const char* headers = strchr(req, '\n'); - if (!headers) - return ""; - pcrecpp::StringPiece input(headers + 1); - - string name; - string val; - pcrecpp::RE re("([\\w\\-]+): (.*?)\r?\n"); - while (re.Consume(&input, &name, &val)) { - if (name == wanted) - return val; - } - return ""; -} - -string MiniWebServer::urlDecode(const char* s) { - stringstream out; - while (*s) { - if (*s == '+') { - out << ' '; - } else if (*s == '%') { - out << fromHex(s + 1); - s += 2; - } else { - out << *s; - } - s++; - } - return out.str(); -} - -} // namespace mongo diff --git a/src/mongo/util/net/miniwebserver.h b/src/mongo/util/net/miniwebserver.h deleted file mode 100644 index 122281555fc..00000000000 --- a/src/mongo/util/net/miniwebserver.h +++ /dev/null @@ -1,79 +0,0 @@ -// miniwebserver.h - -/* Copyright 2009 10gen Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects - * for all of the code used other than as permitted herein. If you modify - * file(s) with this exception, you may extend this exception to your - * version of the file(s), but you are not obligated to do so. If you do not - * wish to do so, delete this exception statement from your version. If you - * delete this exception statement from all source files in the program, - * then also delete it in the license file. - */ - -#pragma once - -#include "mongo/platform/basic.h" - - -#include "mongo/db/jsobj.h" -#include "mongo/util/net/listen.h" -#include "mongo/util/net/message.h" - -namespace mongo { - -class ServiceContext; - -class MiniWebServer : public Listener { -public: - MiniWebServer(const std::string& name, const std::string& ip, int _port, ServiceContext* ctx); - virtual ~MiniWebServer() {} - - virtual void doRequest(const char* rq, // the full request - std::string url, - // set these and return them: - std::string& responseMsg, - int& responseCode, - std::vector<std::string>& headers, // if completely empty, content-type: - // text/html will be added - const SockAddr& from) = 0; - - // --- static helpers ---- - - static void parseParams(BSONObj& params, std::string query); - - static std::string parseURL(const char* buf); - static std::string parseMethod(const char* headers); - static std::string getHeader(const char* headers, const std::string& name); - static const char* body(const char* buf); - - static std::string urlDecode(const char* s); - static std::string urlDecode(const std::string& s) { - return urlDecode(s.c_str()); - } - - // This is not currently used for the MiniWebServer. See SERVER-24200 - void accepted(std::unique_ptr<AbstractMessagingPort> mp) override; - -private: - void _accepted(const std::shared_ptr<Socket>& psocket, long long connectionId) override; - static bool fullReceive(const char* buf); -}; - -} // namespace mongo |