aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Zeyde <me@romanzey.de>2024-06-22 11:46:10 +0300
committerRoman Zeyde <me@romanzey.de>2024-06-26 06:47:30 +0300
commit1556d21599a250297d5f20e5249c970340ab08bc (patch)
tree9029a71c29acf707b00fd46cf5336426bce52f9e
parent538363738e9e30813cf3e76ca4f71c1aaff349e7 (diff)
rest: don't copy data when sending binary response
Also, change `HTTPRequest::WriteReply` to accept `std::span`.
-rw-r--r--src/httpserver.cpp5
-rw-r--r--src/httpserver.h9
-rw-r--r--src/rest.cpp20
3 files changed, 17 insertions, 17 deletions
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
index b1d4dc9234..b6c6db8b35 100644
--- a/src/httpserver.cpp
+++ b/src/httpserver.cpp
@@ -26,6 +26,7 @@
#include <deque>
#include <memory>
#include <optional>
+#include <span>
#include <string>
#include <unordered_map>
@@ -634,7 +635,7 @@ void HTTPRequest::WriteHeader(const std::string& hdr, const std::string& value)
* Replies must be sent in the main loop in the main http thread,
* this cannot be done from worker threads.
*/
-void HTTPRequest::WriteReply(int nStatus, const std::string& strReply)
+void HTTPRequest::WriteReply(int nStatus, std::span<const std::byte> reply)
{
assert(!replySent && req);
if (m_interrupt) {
@@ -643,7 +644,7 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply)
// Send event to main http thread to send reply message
struct evbuffer* evb = evhttp_request_get_output_buffer(req);
assert(evb);
- evbuffer_add(evb, strReply.data(), strReply.size());
+ evbuffer_add(evb, reply.data(), reply.size());
auto req_copy = req;
HTTPEvent* ev = new HTTPEvent(eventBase, true, [req_copy, nStatus]{
evhttp_send_reply(req_copy, nStatus, nullptr, nullptr);
diff --git a/src/httpserver.h b/src/httpserver.h
index 9a49877f09..991081bab8 100644
--- a/src/httpserver.h
+++ b/src/httpserver.h
@@ -7,6 +7,7 @@
#include <functional>
#include <optional>
+#include <span>
#include <string>
namespace util {
@@ -123,12 +124,16 @@ public:
/**
* Write HTTP reply.
* nStatus is the HTTP status code to send.
- * strReply is the body of the reply. Keep it empty to send a standard message.
+ * reply is the body of the reply. Keep it empty to send a standard message.
*
* @note Can be called only once. As this will give the request back to the
* main thread, do not call any other HTTPRequest methods after calling this.
*/
- void WriteReply(int nStatus, const std::string& strReply = "");
+ void WriteReply(int nStatus, std::string_view reply = "")
+ {
+ WriteReply(nStatus, std::as_bytes(std::span{reply.data(), reply.size()}));
+ }
+ void WriteReply(int nStatus, std::span<const std::byte> reply);
};
/** Get the query parameter value from request uri for a specified key, or std::nullopt if the key
diff --git a/src/rest.cpp b/src/rest.cpp
index d43018f5af..4abbc4d2ca 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -248,9 +248,8 @@ static bool rest_headers(const std::any& context,
ssHeader << pindex->GetBlockHeader();
}
- std::string binaryHeader = ssHeader.str();
req->WriteHeader("Content-Type", "application/octet-stream");
- req->WriteReply(HTTP_OK, binaryHeader);
+ req->WriteReply(HTTP_OK, ssHeader);
return true;
}
@@ -321,9 +320,8 @@ static bool rest_block(const std::any& context,
switch (rf) {
case RESTResponseFormat::BINARY: {
- const std::string binaryBlock{block_data.begin(), block_data.end()};
req->WriteHeader("Content-Type", "application/octet-stream");
- req->WriteReply(HTTP_OK, binaryBlock);
+ req->WriteReply(HTTP_OK, std::as_bytes(std::span{block_data}));
return true;
}
@@ -451,9 +449,8 @@ static bool rest_filter_header(const std::any& context, HTTPRequest* req, const
ssHeader << header;
}
- std::string binaryHeader = ssHeader.str();
req->WriteHeader("Content-Type", "application/octet-stream");
- req->WriteReply(HTTP_OK, binaryHeader);
+ req->WriteReply(HTTP_OK, ssHeader);
return true;
}
case RESTResponseFormat::HEX: {
@@ -548,9 +545,8 @@ static bool rest_block_filter(const std::any& context, HTTPRequest* req, const s
DataStream ssResp{};
ssResp << filter;
- std::string binaryResp = ssResp.str();
req->WriteHeader("Content-Type", "application/octet-stream");
- req->WriteReply(HTTP_OK, binaryResp);
+ req->WriteReply(HTTP_OK, ssResp);
return true;
}
case RESTResponseFormat::HEX: {
@@ -729,9 +725,8 @@ static bool rest_tx(const std::any& context, HTTPRequest* req, const std::string
DataStream ssTx;
ssTx << TX_WITH_WITNESS(tx);
- std::string binaryTx = ssTx.str();
req->WriteHeader("Content-Type", "application/octet-stream");
- req->WriteReply(HTTP_OK, binaryTx);
+ req->WriteReply(HTTP_OK, ssTx);
return true;
}
@@ -900,10 +895,9 @@ static bool rest_getutxos(const std::any& context, HTTPRequest* req, const std::
// use exact same output as mentioned in Bip64
DataStream ssGetUTXOResponse{};
ssGetUTXOResponse << active_height << active_hash << bitmap << outs;
- std::string ssGetUTXOResponseString = ssGetUTXOResponse.str();
req->WriteHeader("Content-Type", "application/octet-stream");
- req->WriteReply(HTTP_OK, ssGetUTXOResponseString);
+ req->WriteReply(HTTP_OK, ssGetUTXOResponse);
return true;
}
@@ -981,7 +975,7 @@ static bool rest_blockhash_by_height(const std::any& context, HTTPRequest* req,
DataStream ss_blockhash{};
ss_blockhash << pblockindex->GetBlockHash();
req->WriteHeader("Content-Type", "application/octet-stream");
- req->WriteReply(HTTP_OK, ss_blockhash.str());
+ req->WriteReply(HTTP_OK, ss_blockhash);
return true;
}
case RESTResponseFormat::HEX: {