diff --git a/src/base/api/Httpd.cpp b/src/base/api/Httpd.cpp index 27e7dc448..36f046164 100644 --- a/src/base/api/Httpd.cpp +++ b/src/base/api/Httpd.cpp @@ -5,8 +5,8 @@ * 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> + * Copyright 2018-2020 SChernykh <https://github.com/SChernykh> + * Copyright 2016-2020 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 @@ -54,6 +54,8 @@ xmrig::Httpd::Httpd(Base *base) : m_server(nullptr), m_port(0) { + m_httpListener = std::make_shared<HttpListener>(this); + base->addListener(this); } @@ -69,7 +71,7 @@ bool xmrig::Httpd::start() return true; } - m_http = new HttpServer(this); + m_http = new HttpServer(m_httpListener); m_server = new TcpServer(config.host(), config.port(), m_http); const int rc = m_server->bind(); diff --git a/src/base/api/Httpd.h b/src/base/api/Httpd.h index ebfbcbf7e..25d88577e 100644 --- a/src/base/api/Httpd.h +++ b/src/base/api/Httpd.h @@ -5,8 +5,8 @@ * 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> + * Copyright 2018-2020 SChernykh <https://github.com/SChernykh> + * Copyright 2016-2020 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 @@ -26,14 +26,15 @@ #define XMRIG_HTTPD_H -#include <cstdint> - - #include "base/kernel/interfaces/IBaseListener.h" -#include "base/kernel/interfaces/IHttpListener.h" +#include "base/net/http/HttpListener.h" #include "base/tools/Object.h" +#include <cstdint> +#include <memory> + + namespace xmrig { @@ -62,6 +63,7 @@ private: Base *m_base; HttpServer *m_http; + std::shared_ptr<IHttpListener> m_httpListener; TcpServer *m_server; uint16_t m_port; }; diff --git a/src/base/base.cmake b/src/base/base.cmake index 47996f33f..1426deb57 100644 --- a/src/base/base.cmake +++ b/src/base/base.cmake @@ -34,6 +34,7 @@ set(HEADERS_BASE src/base/net/dns/Dns.h src/base/net/dns/DnsRecord.h src/base/net/http/Http.h + src/base/net/http/HttpListener.h src/base/net/stratum/BaseClient.h src/base/net/stratum/Client.h src/base/net/stratum/Job.h diff --git a/src/base/net/http/HttpClient.cpp b/src/base/net/http/HttpClient.cpp index 9db1e8093..364b3248a 100644 --- a/src/base/net/http/HttpClient.cpp +++ b/src/base/net/http/HttpClient.cpp @@ -6,8 +6,8 @@ * Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2014-2019 heapwolf <https://github.com/heapwolf> - * Copyright 2018-2019 SChernykh <https://github.com/SChernykh> - * Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * Copyright 2018-2020 SChernykh <https://github.com/SChernykh> + * Copyright 2016-2020 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 @@ -77,7 +77,7 @@ private: } // namespace xmrig -xmrig::HttpClient::HttpClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size) : +xmrig::HttpClient::HttpClient(int method, const String &url, const std::weak_ptr<IHttpListener> &listener, const char *data, size_t size) : HttpContext(HTTP_RESPONSE, listener) { this->method = method; diff --git a/src/base/net/http/HttpClient.h b/src/base/net/http/HttpClient.h index acf873dc7..62ac72977 100644 --- a/src/base/net/http/HttpClient.h +++ b/src/base/net/http/HttpClient.h @@ -6,8 +6,8 @@ * Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2014-2019 heapwolf <https://github.com/heapwolf> - * Copyright 2018-2019 SChernykh <https://github.com/SChernykh> - * Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * Copyright 2018-2020 SChernykh <https://github.com/SChernykh> + * Copyright 2016-2020 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 @@ -44,7 +44,7 @@ class HttpClient : public HttpContext, public IDnsListener public: XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpClient); - HttpClient(int method, const String &url, IHttpListener *listener, const char *data = nullptr, size_t size = 0); + HttpClient(int method, const String &url, const std::weak_ptr<IHttpListener> &listener, const char *data = nullptr, size_t size = 0); ~HttpClient() override; inline uint16_t port() const { return m_port; } diff --git a/src/base/net/http/HttpContext.cpp b/src/base/net/http/HttpContext.cpp index af5762578..81479f2aa 100644 --- a/src/base/net/http/HttpContext.cpp +++ b/src/base/net/http/HttpContext.cpp @@ -6,8 +6,8 @@ * Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2014-2019 heapwolf <https://github.com/heapwolf> - * Copyright 2018-2019 SChernykh <https://github.com/SChernykh> - * Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * Copyright 2018-2020 SChernykh <https://github.com/SChernykh> + * Copyright 2016-2020 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 @@ -45,7 +45,7 @@ static uint64_t SEQUENCE = 0; } // namespace xmrig -xmrig::HttpContext::HttpContext(int parser_type, IHttpListener *listener) : +xmrig::HttpContext::HttpContext(int parser_type, const std::weak_ptr<IHttpListener> &listener) : HttpData(SEQUENCE++), m_timestamp(Chrono::steadyMSecs()), m_listener(listener) @@ -107,15 +107,14 @@ uint64_t xmrig::HttpContext::elapsed() const void xmrig::HttpContext::close(int status) { - if (status < 0 && m_listener) { + auto listener = httpListener(); + + if (status < 0 && listener) { this->status = status; - m_listener->onHttpData(*this); + listener->onHttpData(*this); } - auto it = storage.find(id()); - if (it != storage.end()) { - storage.erase(it); - } + storage.erase(id()); if (!uv_is_closing(handle())) { uv_close(handle(), [](uv_handle_t *handle) -> void { delete reinterpret_cast<HttpContext*>(handle->data); }); @@ -135,7 +134,7 @@ xmrig::HttpContext *xmrig::HttpContext::get(uint64_t id) void xmrig::HttpContext::closeAll() { - for (auto kv : storage) { + for (auto &kv : storage) { if (!uv_is_closing(kv.second->handle())) { uv_close(kv.second->handle(), [](uv_handle_t *handle) -> void { delete reinterpret_cast<HttpContext*>(handle->data); }); } @@ -217,9 +216,13 @@ void xmrig::HttpContext::attach(http_parser_settings *settings) settings->on_message_complete = [](http_parser *parser) -> int { - auto ctx = static_cast<HttpContext*>(parser->data); - ctx->m_listener->onHttpData(*ctx); - ctx->m_listener = nullptr; + auto ctx = static_cast<HttpContext*>(parser->data); + auto listener = ctx->httpListener(); + + if (listener) { + listener->onHttpData(*ctx); + ctx->m_listener.reset(); + } return 0; }; diff --git a/src/base/net/http/HttpContext.h b/src/base/net/http/HttpContext.h index 9c304139a..5091c24bc 100644 --- a/src/base/net/http/HttpContext.h +++ b/src/base/net/http/HttpContext.h @@ -6,8 +6,8 @@ * Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2014-2019 heapwolf <https://github.com/heapwolf> - * Copyright 2018-2019 SChernykh <https://github.com/SChernykh> - * Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * Copyright 2018-2020 SChernykh <https://github.com/SChernykh> + * Copyright 2016-2020 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 @@ -40,6 +40,9 @@ using uv_tcp_t = struct uv_tcp_s; #include "base/tools/Object.h" +#include <memory> + + namespace xmrig { @@ -51,7 +54,7 @@ class HttpContext : public HttpData public: XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpContext) - HttpContext(int parser_type, IHttpListener *listener); + HttpContext(int parser_type, const std::weak_ptr<IHttpListener> &listener); virtual ~HttpContext(); inline uv_stream_t *stream() const { return reinterpret_cast<uv_stream_t *>(m_tcp); } @@ -69,6 +72,8 @@ protected: uv_tcp_t *m_tcp; private: + inline IHttpListener *httpListener() const { return m_listener.expired() ? nullptr : m_listener.lock().get(); } + static int onHeaderField(http_parser *parser, const char *at, size_t length); static int onHeaderValue(http_parser *parser, const char *at, size_t length); static void attach(http_parser_settings *settings); @@ -78,9 +83,9 @@ private: bool m_wasHeaderValue = false; const uint64_t m_timestamp; http_parser *m_parser; - IHttpListener *m_listener; std::string m_lastHeaderField; std::string m_lastHeaderValue; + std::weak_ptr<IHttpListener> m_listener; }; diff --git a/src/base/net/http/HttpListener.h b/src/base/net/http/HttpListener.h new file mode 100644 index 000000000..428f9c49a --- /dev/null +++ b/src/base/net/http/HttpListener.h @@ -0,0 +1,45 @@ +/* XMRig + * Copyright 2018-2020 SChernykh <https://github.com/SChernykh> + * Copyright 2016-2020 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/>. + */ + +#ifndef XMRIG_HTTPLISTENER_H +#define XMRIG_HTTPLISTENER_H + + +#include "base/kernel/interfaces/IHttpListener.h" + + +namespace xmrig { + + +class HttpListener : public IHttpListener +{ +public: + inline HttpListener(IHttpListener *listener) : m_listener(listener) {} + +protected: + inline void onHttpData(const HttpData &data) override { m_listener->onHttpData(data); }; + +private: + IHttpListener *m_listener; +}; + + +} /* namespace xmrig */ + + +#endif // XMRIG_HTTPLISTENER_H diff --git a/src/base/net/http/HttpServer.cpp b/src/base/net/http/HttpServer.cpp index 5aae1b6f2..4af39c2eb 100644 --- a/src/base/net/http/HttpServer.cpp +++ b/src/base/net/http/HttpServer.cpp @@ -6,8 +6,8 @@ * Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2014-2019 heapwolf <https://github.com/heapwolf> - * Copyright 2018-2019 SChernykh <https://github.com/SChernykh> - * Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * Copyright 2018-2020 SChernykh <https://github.com/SChernykh> + * Copyright 2016-2020 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 @@ -35,7 +35,7 @@ #include "base/net/http/HttpServer.h" -xmrig::HttpServer::HttpServer(IHttpListener *listener) : +xmrig::HttpServer::HttpServer(const std::shared_ptr<IHttpListener> &listener) : m_listener(listener) { } diff --git a/src/base/net/http/HttpServer.h b/src/base/net/http/HttpServer.h index 74e846b91..2ced767fd 100644 --- a/src/base/net/http/HttpServer.h +++ b/src/base/net/http/HttpServer.h @@ -6,8 +6,8 @@ * Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2014-2019 heapwolf <https://github.com/heapwolf> - * Copyright 2018-2019 SChernykh <https://github.com/SChernykh> - * Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * Copyright 2018-2020 SChernykh <https://github.com/SChernykh> + * Copyright 2016-2020 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 @@ -36,6 +36,9 @@ using http_parser_settings = struct http_parser_settings; #include "base/tools/Object.h" +#include <memory> + + namespace xmrig { @@ -47,14 +50,14 @@ class HttpServer : public ITcpServerListener public: XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpServer) - HttpServer(IHttpListener *listener); + HttpServer(const std::shared_ptr<IHttpListener> &listener); ~HttpServer() override; protected: void onConnection(uv_stream_t *stream, uint16_t port) override; private: - IHttpListener *m_listener; + std::weak_ptr<IHttpListener> m_listener; }; diff --git a/src/base/net/http/HttpsClient.cpp b/src/base/net/http/HttpsClient.cpp index 747aeb31f..7bebb3bd0 100644 --- a/src/base/net/http/HttpsClient.cpp +++ b/src/base/net/http/HttpsClient.cpp @@ -6,8 +6,8 @@ * Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2014-2019 heapwolf <https://github.com/heapwolf> - * Copyright 2018-2019 SChernykh <https://github.com/SChernykh> - * Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * Copyright 2018-2020 SChernykh <https://github.com/SChernykh> + * Copyright 2016-2020 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 @@ -39,7 +39,7 @@ #endif -xmrig::HttpsClient::HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size, const String &fingerprint) : +xmrig::HttpsClient::HttpsClient(int method, const String &url, const std::weak_ptr<IHttpListener> &listener, const char *data, size_t size, const String &fingerprint) : HttpClient(method, url, listener, data, size), m_ready(false), m_buf(), diff --git a/src/base/net/http/HttpsClient.h b/src/base/net/http/HttpsClient.h index a0de150e5..13eb5f679 100644 --- a/src/base/net/http/HttpsClient.h +++ b/src/base/net/http/HttpsClient.h @@ -6,8 +6,8 @@ * Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2014-2019 heapwolf <https://github.com/heapwolf> - * Copyright 2018-2019 SChernykh <https://github.com/SChernykh> - * Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com> + * Copyright 2018-2020 SChernykh <https://github.com/SChernykh> + * Copyright 2016-2020 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 @@ -46,7 +46,7 @@ class HttpsClient : public HttpClient public: XMRIG_DISABLE_COPY_MOVE_DEFAULT(HttpsClient) - HttpsClient(int method, const String &url, IHttpListener *listener, const char *data, size_t size, const String &fingerprint); + HttpsClient(int method, const String &url, const std::weak_ptr<IHttpListener> &listener, const char *data, size_t size, const String &fingerprint); ~HttpsClient() override; const char *fingerprint() const; diff --git a/src/base/net/stratum/DaemonClient.cpp b/src/base/net/stratum/DaemonClient.cpp index 8e89c5477..bf22e6111 100644 --- a/src/base/net/stratum/DaemonClient.cpp +++ b/src/base/net/stratum/DaemonClient.cpp @@ -24,17 +24,13 @@ */ -#include <algorithm> -#include <cassert> - - +#include "base/net/stratum/DaemonClient.h" #include "3rdparty/http-parser/http_parser.h" #include "base/io/json/Json.h" #include "base/io/json/JsonRequest.h" #include "base/io/log/Log.h" #include "base/kernel/interfaces/IClientListener.h" #include "base/net/http/HttpClient.h" -#include "base/net/stratum/DaemonClient.h" #include "base/net/stratum/SubmitResult.h" #include "base/tools/Buffer.h" #include "base/tools/Timer.h" @@ -50,6 +46,10 @@ #endif +#include <algorithm> +#include <cassert> + + namespace xmrig { static const char *kBlocktemplateBlob = "blocktemplate_blob"; @@ -66,7 +66,8 @@ xmrig::DaemonClient::DaemonClient(int id, IClientListener *listener) : BaseClient(id, listener), m_monero(true) { - m_timer = new Timer(this); + m_httpListener = std::make_shared<HttpListener>(this); + m_timer = new Timer(this); } @@ -327,12 +328,12 @@ void xmrig::DaemonClient::send(int method, const char *url, const char *data, si HttpClient *client; # ifdef XMRIG_FEATURE_TLS if (m_pool.isTLS()) { - client = new HttpsClient(method, url, this, data, size, m_pool.fingerprint()); + client = new HttpsClient(method, url, m_httpListener, data, size, m_pool.fingerprint()); } else # endif { - client = new HttpClient(method, url, this, data, size); + client = new HttpClient(method, url, m_httpListener, data, size); } client->setQuiet(isQuiet()); diff --git a/src/base/net/stratum/DaemonClient.h b/src/base/net/stratum/DaemonClient.h index 8e36b8fb2..adaef14e0 100644 --- a/src/base/net/stratum/DaemonClient.h +++ b/src/base/net/stratum/DaemonClient.h @@ -27,12 +27,15 @@ #define XMRIG_DAEMONCLIENT_H -#include "base/kernel/interfaces/IHttpListener.h" #include "base/kernel/interfaces/ITimerListener.h" +#include "base/net/http/HttpListener.h" #include "base/net/stratum/BaseClient.h" #include "base/tools/Object.h" +#include <memory> + + namespace xmrig { @@ -74,6 +77,7 @@ private: void setState(SocketState state); bool m_monero; + std::shared_ptr<IHttpListener> m_httpListener; String m_blocktemplate; String m_prevHash; String m_tlsFingerprint; diff --git a/src/base/net/stratum/SelfSelectClient.cpp b/src/base/net/stratum/SelfSelectClient.cpp index cc442cd89..d69bc0fb8 100644 --- a/src/base/net/stratum/SelfSelectClient.cpp +++ b/src/base/net/stratum/SelfSelectClient.cpp @@ -63,7 +63,8 @@ static const char * const required_fields[] = { kBlocktemplateBlob, kBlockhashin xmrig::SelfSelectClient::SelfSelectClient(int id, const char *agent, IClientListener *listener) : m_listener(listener) { - m_client = new Client(id, agent, this); + m_httpListener = std::make_shared<HttpListener>(this); + m_client = new Client(id, agent, this); } @@ -181,12 +182,12 @@ void xmrig::SelfSelectClient::send(int method, const char *url, const char *data HttpClient *client; # ifdef XMRIG_FEATURE_TLS if (pool().daemon().isTLS()) { - client = new HttpsClient(method, url, this, data, size, String()); + client = new HttpsClient(method, url, m_httpListener, data, size, String()); } else # endif { - client = new HttpClient(method, url, this, data, size); + client = new HttpClient(method, url, m_httpListener, data, size); } client->setQuiet(isQuiet()); diff --git a/src/base/net/stratum/SelfSelectClient.h b/src/base/net/stratum/SelfSelectClient.h index ba675ffe9..5c9431c76 100644 --- a/src/base/net/stratum/SelfSelectClient.h +++ b/src/base/net/stratum/SelfSelectClient.h @@ -29,11 +29,14 @@ #include "base/kernel/interfaces/IClient.h" #include "base/kernel/interfaces/IClientListener.h" -#include "base/kernel/interfaces/IHttpListener.h" +#include "base/net/http/HttpListener.h" #include "base/net/stratum/Job.h" #include "base/tools/Object.h" +#include <memory> + + namespace xmrig { @@ -113,6 +116,7 @@ private: int64_t m_sequence = 1; Job m_job; State m_state = IdleState; + std::shared_ptr<IHttpListener> m_httpListener; uint64_t m_retryPause = 5000; uint64_t m_timestamp = 0; };