diff --git a/src/base/base.cmake b/src/base/base.cmake index 5f32f4253..688f3ef82 100644 --- a/src/base/base.cmake +++ b/src/base/base.cmake @@ -33,6 +33,7 @@ set(HEADERS_BASE src/base/net/tools/RecvBuf.h src/base/net/tools/Storage.h src/base/tools/Arguments.h + src/base/tools/Baton.h src/base/tools/Buffer.h src/base/tools/Chrono.h src/base/tools/Handle.h diff --git a/src/base/net/http/HttpResponse.cpp b/src/base/net/http/HttpResponse.cpp index 3b88e29be..d782217b8 100644 --- a/src/base/net/http/HttpResponse.cpp +++ b/src/base/net/http/HttpResponse.cpp @@ -33,6 +33,7 @@ #include "base/io/log/Log.h" #include "base/net/http/HttpContext.h" #include "base/net/http/HttpResponse.h" +#include "base/tools/Baton.h" namespace xmrig { @@ -40,6 +41,52 @@ namespace xmrig { static const char *kCRLF = "\r\n"; static const char *kUserAgent = "user-agent"; + +class WriteBaton : public Baton +{ +public: + inline WriteBaton(const std::stringstream &ss, const char *data, size_t size, HttpContext *ctx) : + m_ctx(ctx), + m_header(ss.str()) + { + req.data = this; + bufs[0].len = m_header.size(); + bufs[0].base = const_cast(m_header.c_str()); + + if (data) { + bufs[1].len = size; + bufs[1].base = new char[size]; + memcpy(bufs[1].base, data, size); + } + else { + bufs[1].base = nullptr; + bufs[1].len = 0; + } + } + + + inline ~WriteBaton() + { + if (count() == 2) { + delete [] bufs[1].base; + } + + m_ctx->close(); + } + + + inline size_t count() const { return bufs[1].base == nullptr ? 1 : 2; } + inline size_t size() const { return bufs[0].len + bufs[1].len; } + inline static void onWrite(uv_write_t *req, int) { delete reinterpret_cast(req->data); } + + + uv_buf_t bufs[2]; + +private: + HttpContext *m_ctx; + std::string m_header; +}; + } // namespace xmrig @@ -82,28 +129,9 @@ void xmrig::HttpResponse::end(const char *data, size_t size) } ss << kCRLF; - const std::string header = ss.str(); - uv_buf_t bufs[2]; - bufs[0].base = const_cast(header.c_str()); - -# ifdef _WIN32 - bufs[0].len = static_cast(header.size()); -# else - bufs[0].len = header.size(); -# endif - - if (data) { - bufs[1].base = const_cast(data); - -# ifdef _WIN32 - bufs[1].len = static_cast(size); -# else - bufs[1].len = size; -# endif - } - - HttpContext *ctx = HttpContext::get(m_id); + HttpContext *ctx = HttpContext::get(m_id); + WriteBaton *baton = new WriteBaton(ss, data, size, ctx); # ifndef APP_DEBUG if (statusCode() >= 400) @@ -128,12 +156,10 @@ void xmrig::HttpResponse::end(const char *data, size_t size) ctx->url.c_str(), err ? 31 : 32, statusCode(), - header.size() + size, + baton->size(), ctx->headers.count(kUserAgent) ? ctx->headers.at(kUserAgent).c_str() : nullptr ); } - uv_try_write(ctx->stream(), bufs, data ? 2 : 1); - - ctx->close(); + uv_write(&baton->req, ctx->stream(), baton->bufs, baton->count(), WriteBaton::onWrite); } diff --git a/src/base/tools/Baton.h b/src/base/tools/Baton.h new file mode 100644 index 000000000..7bea0af04 --- /dev/null +++ b/src/base/tools/Baton.h @@ -0,0 +1,45 @@ +/* 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 . + */ + +#ifndef XMRIG_BATON_H +#define XMRIG_BATON_H + + +namespace xmrig { + + +template +class Baton +{ +public: + inline Baton() { req.data = this; } + + T req; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_BATON_H */