mirror of
https://github.com/xmrig/xmrig.git
synced 2025-01-03 09:29:46 +00:00
Restored API.
This commit is contained in:
parent
e39ddeeea2
commit
f8f9d6c0ef
16 changed files with 272 additions and 352 deletions
|
@ -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 "")
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,292 +0,0 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
|
||||
#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<rapidjson::StringBuffer> 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<uint16_t>(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<xmrig::IThread *> &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);
|
||||
}
|
|
@ -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<IApiRequest::Method>(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<kParseCommentsFlag | kParseTrailingCommasFlag>(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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
179
src/api/v1/ApiRouter.cpp
Normal file
179
src/api/v1/ApiRouter.cpp
Normal file
|
@ -0,0 +1,179 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#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<xmrig::IThread *> &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);
|
||||
}
|
|
@ -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 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 */
|
|
@ -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"]);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in a new issue