diff --git a/CMakeLists.txt b/CMakeLists.txt index f1eeeeef4..c95132587 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -205,15 +205,17 @@ endif() if (WITH_HTTPD) set(HTTPD_SOURCES - src/api/Api.h - src/api/interfaces/IApiRequest.h - src/api/requests/ApiRequest.h - src/api/requests/ApiRequest.cpp - src/api/requests/HttpApiRequest.h - src/api/Httpd.h src/api/Api.cpp - src/api/requests/HttpApiRequest.cpp + src/api/Api.h src/api/Httpd.cpp + src/api/Httpd.h + src/api/interfaces/IApiRequest.h + src/api/requests/ApiRequest.cpp + src/api/requests/ApiRequest.h + src/api/requests/HttpApiRequest.cpp + src/api/requests/HttpApiRequest.h + src/api/v1/ApiRouter.cpp + src/api/v1/ApiRouter.h ) else() set(HTTPD_SOURCES "") diff --git a/src/api/Api.cpp b/src/api/Api.cpp index 527565ede..f6b5ba013 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -30,6 +30,7 @@ #include "api/Api.h" #include "api/interfaces/IApiListener.h" #include "api/requests/HttpApiRequest.h" +#include "api/v1/ApiRouter.h" #include "base/tools/Buffer.h" #include "common/crypto/keccak.h" #include "core/config/Config.h" @@ -51,11 +52,16 @@ xmrig::Api::Api(Controller *controller) : controller->addListener(this); genId(m_controller->config()->apiId()); + + m_v1 = new ApiRouter(controller); + addListener(m_v1); } xmrig::Api::~Api() { + delete m_v1; + # ifdef XMRIG_FEATURE_HTTP delete m_httpd; # endif @@ -103,10 +109,12 @@ void xmrig::Api::onConfigChanged(Config *config, Config *previousConfig) void xmrig::Api::exec(IApiRequest &request) { - if (request.method() == IApiRequest::METHOD_GET && request.url() == "/1/summary") { + using namespace rapidjson; + + if (request.method() == IApiRequest::METHOD_GET && (request.url() == "/1/summary" || request.url() == "/api.json")) { request.accept(); - request.reply().AddMember("id", rapidjson::StringRef(m_id), request.doc().GetAllocator()); - request.reply().AddMember("worker_id", rapidjson::StringRef(m_workerId), request.doc().GetAllocator());; + request.reply().AddMember("id", StringRef(m_id), request.doc().GetAllocator()); + request.reply().AddMember("worker_id", StringRef(m_workerId), request.doc().GetAllocator());; } for (IApiListener *listener : m_listeners) { diff --git a/src/api/Api.h b/src/api/Api.h index dc4e8e212..d76e3105e 100644 --- a/src/api/Api.h +++ b/src/api/Api.h @@ -35,6 +35,7 @@ namespace xmrig { +class ApiRouter; class Controller; class Httpd; class HttpRequest; @@ -65,6 +66,7 @@ private: void genId(const String &id); void genWorkerId(const String &id); + ApiRouter *m_v1; char m_id[32]; char m_workerId[128]; Controller *m_controller; diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp deleted file mode 100644 index 30597f46c..000000000 --- a/src/api/ApiRouter.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - -#if _WIN32 -# include "winsock2.h" -#else -# include "unistd.h" -#endif - - -#include "api/ApiRouter.h" -#include "base/tools/Buffer.h" -#include "common/api/HttpReply.h" -#include "common/api/HttpRequest.h" -#include "common/cpu/Cpu.h" -#include "common/crypto/keccak.h" -#include "common/Platform.h" -#include "core/Config.h" -#include "core/Controller.h" -#include "interfaces/IThread.h" -#include "rapidjson/document.h" -#include "rapidjson/prettywriter.h" -#include "rapidjson/stringbuffer.h" -#include "version.h" -#include "workers/Hashrate.h" -#include "workers/Workers.h" - - -static inline double normalize(double d) -{ - if (!isnormal(d)) { - return 0.0; - } - - return floor(d * 100.0) / 100.0; -} - - -ApiRouter::ApiRouter(xmrig::Controller *controller) : - m_controller(controller) -{ - memset(m_workerId, 0, sizeof(m_workerId)); - - setWorkerId(controller->config()->apiWorkerId()); - genId(controller->config()->apiId()); -} - - -ApiRouter::~ApiRouter() -{ -} - - -void ApiRouter::ApiRouter::get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const -{ - rapidjson::Document doc; - - if (req.match("/1/config")) { - if (req.isRestricted()) { - reply.status = 403; - return; - } - - m_controller->config()->getJSON(doc); - - return finalize(reply, doc); - } - - if (req.match("/1/threads")) { - getThreads(doc); - - return finalize(reply, doc); - } - - doc.SetObject(); - - getIdentify(doc); - getMiner(doc); - getHashrate(doc); - - return finalize(reply, doc); -} - - -void ApiRouter::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) -{ - if (req.method() == xmrig::HttpRequest::Put && req.match("/1/config")) { - m_controller->config()->reload(req.body()); - return; - } - - reply.status = 404; -} - - -void ApiRouter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) -{ - updateWorkerId(config->apiWorkerId(), previousConfig->apiWorkerId()); -} - - -void ApiRouter::finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const -{ - rapidjson::StringBuffer buffer(nullptr, 4096); - rapidjson::PrettyWriter writer(buffer); - writer.SetMaxDecimalPlaces(10); - doc.Accept(writer); - - reply.status = 200; - reply.buf = strdup(buffer.GetString()); - reply.size = buffer.GetSize(); -} - - -void ApiRouter::genId(const char *id) -{ - memset(m_id, 0, sizeof(m_id)); - - if (id && strlen(id) > 0) { - strncpy(m_id, id, sizeof(m_id) - 1); - return; - } - - uv_interface_address_t *interfaces; - int count = 0; - - if (uv_interface_addresses(&interfaces, &count) < 0) { - return; - } - - for (int i = 0; i < count; i++) { - if (!interfaces[i].is_internal && interfaces[i].address.address4.sin_family == AF_INET) { - uint8_t hash[200]; - const size_t addrSize = sizeof(interfaces[i].phys_addr); - const size_t inSize = strlen(APP_KIND) + addrSize + sizeof(uint16_t); - const uint16_t port = static_cast(m_controller->config()->http().port()); - - uint8_t *input = new uint8_t[inSize](); - memcpy(input, &port, sizeof(uint16_t)); - memcpy(input + sizeof(uint16_t), interfaces[i].phys_addr, addrSize); - memcpy(input + sizeof(uint16_t) + addrSize, APP_KIND, strlen(APP_KIND)); - - xmrig::keccak(input, inSize, hash); - xmrig::Buffer::toHex(hash, 8, m_id); - - delete [] input; - break; - } - } - - uv_free_interface_addresses(interfaces, count); -} - - -void ApiRouter::getHashrate(rapidjson::Document &doc) const -{ - auto &allocator = doc.GetAllocator(); - - rapidjson::Value hashrate(rapidjson::kObjectType); - rapidjson::Value total(rapidjson::kArrayType); - rapidjson::Value threads(rapidjson::kArrayType); - - const Hashrate *hr = Workers::hashrate(); - - total.PushBack(normalize(hr->calc(Hashrate::ShortInterval)), allocator); - total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator); - total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator); - - for (size_t i = 0; i < Workers::threads(); i++) { - rapidjson::Value thread(rapidjson::kArrayType); - thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); - thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); - thread.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); - - threads.PushBack(thread, allocator); - } - - hashrate.AddMember("total", total, allocator); - hashrate.AddMember("highest", normalize(hr->highest()), allocator); - hashrate.AddMember("threads", threads, allocator); - doc.AddMember("hashrate", hashrate, allocator); -} - - -void ApiRouter::getIdentify(rapidjson::Document &doc) const -{ - doc.AddMember("id", rapidjson::StringRef(m_id), doc.GetAllocator()); - doc.AddMember("worker_id", rapidjson::StringRef(m_workerId), doc.GetAllocator()); -} - - -void ApiRouter::getMiner(rapidjson::Document &doc) const -{ - using namespace xmrig; - auto &allocator = doc.GetAllocator(); - - rapidjson::Value cpu(rapidjson::kObjectType); - cpu.AddMember("brand", rapidjson::StringRef(Cpu::info()->brand()), allocator); - cpu.AddMember("aes", Cpu::info()->hasAES(), allocator); - cpu.AddMember("x64", Cpu::info()->isX64(), allocator); - cpu.AddMember("sockets", Cpu::info()->sockets(), allocator); - - doc.AddMember("version", APP_VERSION, allocator); - doc.AddMember("kind", APP_KIND, allocator); - doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator); - doc.AddMember("cpu", cpu, allocator); - doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algorithm().name()), allocator); - doc.AddMember("hugepages", Workers::hugePages() > 0, allocator); - doc.AddMember("donate_level", m_controller->config()->pools().donateLevel(), allocator); -} - - -void ApiRouter::getThreads(rapidjson::Document &doc) const -{ - doc.SetObject(); - auto &allocator = doc.GetAllocator(); - const Hashrate *hr = Workers::hashrate(); - - Workers::threadsSummary(doc); - - const std::vector &threads = m_controller->config()->threads(); - rapidjson::Value list(rapidjson::kArrayType); - - size_t i = 0; - for (const xmrig::IThread *thread : threads) { - rapidjson::Value value = thread->toAPI(doc); - - rapidjson::Value hashrate(rapidjson::kArrayType); - hashrate.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); - hashrate.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); - hashrate.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); - - i++; - - value.AddMember("hashrate", hashrate, allocator); - list.PushBack(value, allocator); - } - - doc.AddMember("threads", list, allocator); -} - - -void ApiRouter::setWorkerId(const char *id) -{ - memset(m_workerId, 0, sizeof(m_workerId)); - - if (id && strlen(id) > 0) { - strncpy(m_workerId, id, sizeof(m_workerId) - 1); - } - else { - gethostname(m_workerId, sizeof(m_workerId) - 1); - } -} - - -void ApiRouter::updateWorkerId(const char *id, const char *previousId) -{ - if (id == previousId) { - return; - } - - if (id != nullptr && previousId != nullptr && strcmp(id, previousId) == 0) { - return; - } - - setWorkerId(id); -} diff --git a/src/api/requests/HttpApiRequest.cpp b/src/api/requests/HttpApiRequest.cpp index fac69f51c..a61dde8d1 100644 --- a/src/api/requests/HttpApiRequest.cpp +++ b/src/api/requests/HttpApiRequest.cpp @@ -25,10 +25,12 @@ #include "api/requests/HttpApiRequest.h" #include "base/net/http/HttpRequest.h" +#include "rapidjson/error/en.h" xmrig::HttpApiRequest::HttpApiRequest(const HttpRequest &req, bool restricted) : ApiRequest(SOURCE_HTTP, restricted), + m_parsed(false), m_req(req), m_res(req.id()), m_url(req.url.c_str()) @@ -36,20 +38,39 @@ xmrig::HttpApiRequest::HttpApiRequest(const HttpRequest &req, bool restricted) : } +const rapidjson::Value &xmrig::HttpApiRequest::json() const +{ + return m_body; +} + + xmrig::IApiRequest::Method xmrig::HttpApiRequest::method() const { return static_cast(m_req.method); } +void xmrig::HttpApiRequest::accept() +{ + using namespace rapidjson; + + ApiRequest::accept(); + + if (!m_parsed && !m_req.body.empty()) { + m_parsed = true; + m_body.Parse(m_req.body.c_str()); + + if (m_body.HasParseError()) { + reply().AddMember("error", StringRef(GetParseError_En(m_body.GetParseError())), doc().GetAllocator());; + } + } +} + + void xmrig::HttpApiRequest::done(int status) { ApiRequest::done(status); - if (status >= 400) { - reply().AddMember("status", status, doc().GetAllocator()); - } - m_res.setStatus(status); m_res.end(); } diff --git a/src/api/requests/HttpApiRequest.h b/src/api/requests/HttpApiRequest.h index dbe640ef3..26f26f393 100644 --- a/src/api/requests/HttpApiRequest.h +++ b/src/api/requests/HttpApiRequest.h @@ -44,15 +44,17 @@ public: HttpApiRequest(const HttpRequest &req, bool restricted); protected: - inline const rapidjson::Value &json() const override { return m_body; } inline rapidjson::Document &doc() override { return m_res.doc(); } inline rapidjson::Value &reply() override { return m_res.doc(); } inline const String &url() const override { return m_url; } + const rapidjson::Value &json() const override; Method method() const override; + void accept() override; void done(int status) override; private: + bool m_parsed; const HttpRequest &m_req; HttpApiResponse m_res; rapidjson::Document m_body; diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp new file mode 100644 index 000000000..2914b7552 --- /dev/null +++ b/src/api/v1/ApiRouter.cpp @@ -0,0 +1,179 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + + +#include "api/interfaces/IApiRequest.h" +#include "api/v1/ApiRouter.h" +#include "common/cpu/Cpu.h" +#include "common/Platform.h" +#include "core/config/Config.h" +#include "core/Controller.h" +#include "interfaces/IThread.h" +#include "rapidjson/document.h" +#include "version.h" +#include "workers/Hashrate.h" +#include "workers/Workers.h" + + +static inline double normalize(double d) +{ + if (!isnormal(d)) { + return 0.0; + } + + return floor(d * 100.0) / 100.0; +} + + +xmrig::ApiRouter::ApiRouter(xmrig::Controller *controller) : + m_controller(controller) +{ +} + + +xmrig::ApiRouter::~ApiRouter() +{ +} + + +void xmrig::ApiRouter::onRequest(IApiRequest &request) +{ + printf("xmrig::ApiRouter::onRequest\n %d", request.method()); + + if (request.method() == IApiRequest::METHOD_GET) { + if (request.url() == "/1/summary" || request.url() == "/api.json") { + request.accept(); + getMiner(request.reply(), request.doc()); + getHashrate(request.reply(), request.doc()); + } + else if (request.url() == "/1/threads") { + request.accept(); + getThreads(request.reply(), request.doc()); + } + else if (request.url() == "/1/config") { + if (request.isRestricted()) { + return request.done(403); + } + + m_controller->config()->getJSON(request.doc()); + } + } + else if (request.method() == IApiRequest::METHOD_PUT || request.method() == IApiRequest::METHOD_POST) { + if (request.url() == "/1/config") { + request.accept(); + + if (!m_controller->config()->reload(request.json())) { + return request.done(400); + } + + request.done(204); + } + } +} + + +void xmrig::ApiRouter::getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + Value hashrate(kObjectType); + Value total(kArrayType); + Value threads(kArrayType); + + const Hashrate *hr = Workers::hashrate(); + + total.PushBack(normalize(hr->calc(Hashrate::ShortInterval)), allocator); + total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator); + total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator); + + for (size_t i = 0; i < Workers::threads(); i++) { + Value thread(kArrayType); + thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); + thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); + thread.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); + + threads.PushBack(thread, allocator); + } + + hashrate.AddMember("total", total, allocator); + hashrate.AddMember("highest", normalize(hr->highest()), allocator); + hashrate.AddMember("threads", threads, allocator); + reply.AddMember("hashrate", hashrate, allocator); +} + + +void xmrig::ApiRouter::getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + Value cpu(kObjectType); + cpu.AddMember("brand", StringRef(Cpu::info()->brand()), allocator); + cpu.AddMember("aes", Cpu::info()->hasAES(), allocator); + cpu.AddMember("x64", Cpu::info()->isX64(), allocator); + cpu.AddMember("sockets", Cpu::info()->sockets(), allocator); + + reply.AddMember("version", APP_VERSION, allocator); + reply.AddMember("kind", APP_KIND, allocator); + reply.AddMember("ua", StringRef(Platform::userAgent()), allocator); + reply.AddMember("cpu", cpu, allocator); + reply.AddMember("algo", StringRef(m_controller->config()->algorithm().name()), allocator); + reply.AddMember("hugepages", Workers::hugePages() > 0, allocator); + reply.AddMember("donate_level", m_controller->config()->pools().donateLevel(), allocator); +} + + +void xmrig::ApiRouter::getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + const Hashrate *hr = Workers::hashrate(); + + Workers::threadsSummary(doc); + + const std::vector &threads = m_controller->config()->threads(); + Value list(kArrayType); + + size_t i = 0; + for (const xmrig::IThread *thread : threads) { + Value value = thread->toAPI(doc); + + Value hashrate(kArrayType); + hashrate.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); + hashrate.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); + hashrate.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); + + i++; + + value.AddMember("hashrate", hashrate, allocator); + list.PushBack(value, allocator); + } + + reply.AddMember("threads", list, allocator); +} diff --git a/src/api/ApiRouter.h b/src/api/v1/ApiRouter.h similarity index 63% rename from src/api/ApiRouter.h rename to src/api/v1/ApiRouter.h index cbdc04b80..02be91e2b 100644 --- a/src/api/ApiRouter.h +++ b/src/api/v1/ApiRouter.h @@ -27,7 +27,7 @@ #include "net/NetworkState.h" -#include "base/kernel/interfaces/IControllerListener.h" +#include "api/interfaces/IApiListener.h" #include "rapidjson/fwd.h" @@ -35,37 +35,30 @@ class Hashrate; namespace xmrig { - class Controller; - class HttpReply; - class HttpRequest; -} -class ApiRouter : public xmrig::IControllerListener +class Controller; + + +class ApiRouter : public xmrig::IApiListener { public: ApiRouter(xmrig::Controller *controller); ~ApiRouter() override; - void get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const; - void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply); - protected: - void onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) override; + void onRequest(IApiRequest &request) override; private: - void finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const; - void genId(const char *id); - void getHashrate(rapidjson::Document &doc) const; - void getIdentify(rapidjson::Document &doc) const; - void getMiner(rapidjson::Document &doc) const; - void getThreads(rapidjson::Document &doc) const; - void setWorkerId(const char *id); - void updateWorkerId(const char *id, const char *previousId); + void getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const; + void getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const; + void getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const; - char m_id[32]; - char m_workerId[128]; - xmrig::Controller *m_controller; + Controller *m_controller; }; + +} // namespace xmrig + + #endif /* XMRIG_APIROUTER_H */ diff --git a/src/common/config/CommonConfig.cpp b/src/common/config/CommonConfig.cpp index b7ad520f1..55bb0a49a 100644 --- a/src/common/config/CommonConfig.cpp +++ b/src/common/config/CommonConfig.cpp @@ -343,21 +343,21 @@ bool xmrig::CommonConfig::parseUint64(int key, uint64_t arg) } -void xmrig::CommonConfig::parseJSON(const rapidjson::Document &doc) +void xmrig::CommonConfig::parseJSON(const rapidjson::Value &json) { - const rapidjson::Value &pools = doc["pools"]; + const rapidjson::Value &pools = json["pools"]; if (pools.IsArray()) { m_pools.load(pools); } # ifdef XMRIG_DEPRECATED - const rapidjson::Value &api = doc["api"]; + const rapidjson::Value &api = json["api"]; if (api.IsObject() && api.HasMember("port")) { m_upgrade = true; m_http.load(api); } else { - m_http.load(doc["http"]); + m_http.load(json["http"]); } # else m_http.load(doc["http"]); diff --git a/src/common/config/CommonConfig.h b/src/common/config/CommonConfig.h index e3331fe06..55f36d0d5 100644 --- a/src/common/config/CommonConfig.h +++ b/src/common/config/CommonConfig.h @@ -71,7 +71,7 @@ protected: bool parseBoolean(int key, bool enable) override; bool parseString(int key, const char *arg) override; bool parseUint64(int key, uint64_t arg) override; - void parseJSON(const rapidjson::Document &doc) override; + void parseJSON(const rapidjson::Value &json) override; void setFileName(const char *fileName) override; Algorithm m_algorithm; diff --git a/src/common/config/ConfigLoader.cpp b/src/common/config/ConfigLoader.cpp index 6f1454404..2b7f50cec 100644 --- a/src/common/config/ConfigLoader.cpp +++ b/src/common/config/ConfigLoader.cpp @@ -48,8 +48,12 @@ #endif -xmrig::ConfigWatcher *xmrig::ConfigLoader::m_watcher = nullptr; -xmrig::IConfigListener *xmrig::ConfigLoader::m_listener = nullptr; +namespace xmrig { + +ConfigWatcher *ConfigLoader::m_watcher = nullptr; +IConfigListener *ConfigLoader::m_listener = nullptr; + +} // namespace xmrig #ifndef ARRAY_SIZE @@ -84,26 +88,26 @@ bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const char *json) } -bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const rapidjson::Document &doc) +bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const rapidjson::Value &json) { for (size_t i = 0; i < ARRAY_SIZE(config_options); i++) { - parseJSON(config, &config_options[i], doc); + parseJSON(config, &config_options[i], json); } - const rapidjson::Value &api = doc["api"]; + const rapidjson::Value &api = json["api"]; if (api.IsObject()) { for (size_t i = 0; i < ARRAY_SIZE(api_options); i++) { parseJSON(config, &api_options[i], api); } } - config->parseJSON(doc); + config->parseJSON(json); return config->finalize(); } -bool xmrig::ConfigLoader::reload(xmrig::IConfig *oldConfig, const char *json) +bool xmrig::ConfigLoader::reload(xmrig::IConfig *oldConfig, const rapidjson::Value &json) { IConfig *config = Config::create(); if (!loadFromJSON(config, json)) { @@ -134,7 +138,7 @@ bool xmrig::ConfigLoader::watch(IConfig *config) assert(m_watcher == nullptr); - m_watcher = new xmrig::ConfigWatcher(config->fileName(), m_listener); + m_watcher = new ConfigWatcher(config->fileName(), m_listener); return true; } @@ -225,7 +229,7 @@ bool xmrig::ConfigLoader::getJSON(const char *fileName, rapidjson::Document &doc bool xmrig::ConfigLoader::parseArg(xmrig::IConfig *config, int key, const char *arg) { - if (key == xmrig::IConfig::ConfigKey) { + if (key == IConfig::ConfigKey) { return loadFromFile(config, arg); } diff --git a/src/common/config/ConfigLoader.h b/src/common/config/ConfigLoader.h index 322aafcfb..f03de711e 100644 --- a/src/common/config/ConfigLoader.h +++ b/src/common/config/ConfigLoader.h @@ -49,8 +49,8 @@ class ConfigLoader public: static bool loadFromFile(IConfig *config, const char *fileName); static bool loadFromJSON(IConfig *config, const char *json); - static bool loadFromJSON(IConfig *config, const rapidjson::Document &doc); - static bool reload(IConfig *oldConfig, const char *json); + static bool loadFromJSON(IConfig *config, const rapidjson::Value &json); + static bool reload(IConfig *oldConfig, const rapidjson::Value &json); static bool watch(IConfig *config); static IConfig *load(Process *process, IConfigListener *listener); static void release(); @@ -67,4 +67,5 @@ private: } /* namespace xmrig */ + #endif /* XMRIG_CONFIGLOADER_H */ diff --git a/src/common/interfaces/IConfig.h b/src/common/interfaces/IConfig.h index 2228d2c94..c897ee376 100644 --- a/src/common/interfaces/IConfig.h +++ b/src/common/interfaces/IConfig.h @@ -150,7 +150,7 @@ public: virtual const Algorithm &algorithm() const = 0; virtual const String &fileName() const = 0; virtual void getJSON(rapidjson::Document &doc) const = 0; - virtual void parseJSON(const rapidjson::Document &doc) = 0; + virtual void parseJSON(const rapidjson::Value &json) = 0; virtual void setFileName(const char *fileName) = 0; static IConfig *create(); diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index 5b3371971..2b706d74c 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -55,7 +55,7 @@ xmrig::Config::Config() : xmrig::CommonConfig(), } -bool xmrig::Config::reload(const char *json) +bool xmrig::Config::reload(const rapidjson::Value &json) { return xmrig::ConfigLoader::reload(this, json); } @@ -277,11 +277,11 @@ bool xmrig::Config::parseUint64(int key, uint64_t arg) } -void xmrig::Config::parseJSON(const rapidjson::Document &doc) +void xmrig::Config::parseJSON(const rapidjson::Value &json) { - CommonConfig::parseJSON(doc); + CommonConfig::parseJSON(json); - const rapidjson::Value &threads = doc["threads"]; + const rapidjson::Value &threads = json["threads"]; if (threads.IsArray()) { for (const rapidjson::Value &value : threads.GetArray()) { diff --git a/src/core/config/Config.h b/src/core/config/Config.h index 261955c51..2a8ca11d1 100644 --- a/src/core/config/Config.h +++ b/src/core/config/Config.h @@ -67,7 +67,7 @@ public: Config(); - bool reload(const char *json); + bool reload(const rapidjson::Value &json); void getJSON(rapidjson::Document &doc) const override; @@ -90,7 +90,7 @@ protected: bool parseBoolean(int key, bool enable) override; bool parseString(int key, const char *arg) override; bool parseUint64(int key, uint64_t arg) override; - void parseJSON(const rapidjson::Document &doc) override; + void parseJSON(const rapidjson::Value &json) override; private: bool parseInt(int key, int arg); diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 02489b8d9..5de840ea2 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -166,7 +166,7 @@ void xmrig::Network::onPause(IStrategy *strategy) void xmrig::Network::onRequest(IApiRequest &request) { # ifdef XMRIG_FEATURE_API - if (request.method() == IApiRequest::METHOD_GET && request.url() == "/1/summary") { + if (request.method() == IApiRequest::METHOD_GET && (request.url() == "/1/summary" || request.url() == "/api.json")) { request.accept(); getResults(request.reply(), request.doc());