Skip to content

Commit

Permalink
fixup! rest: don't copy block data when sending binary response
Browse files Browse the repository at this point in the history
Also, skip a few more copies.
  • Loading branch information
romanz committed Jun 23, 2024
1 parent 0777060 commit 9c9375c
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 17 deletions.
4 changes: 2 additions & 2 deletions src/httpserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,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_view strReply)
void HTTPRequest::WriteReply(int nStatus, Span<const std::byte> reply)
{
assert(!replySent && req);
if (m_interrupt) {
Expand All @@ -643,7 +643,7 @@ void HTTPRequest::WriteReply(int nStatus, const std::string_view 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);
Expand Down
10 changes: 8 additions & 2 deletions src/httpserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <optional>
#include <string>

#include <span.h>

namespace util {
class SignalInterrupt;
} // namespace util
Expand Down Expand Up @@ -123,12 +125,16 @@ class HTTPRequest
/**
* 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_view strReply = "");
void WriteReply(int nStatus, std::string_view reply = "")
{
WriteReply(nStatus, AsBytes(Span{reply}));
}
void WriteReply(int nStatus, Span<const std::byte> reply);
};

/** Get the query parameter value from request uri for a specified key, or std::nullopt if the key
Expand Down
20 changes: 7 additions & 13 deletions src/rest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -321,9 +320,8 @@ static bool rest_block(const std::any& context,

switch (rf) {
case RESTResponseFormat::BINARY: {
const std::string_view binaryBlock{reinterpret_cast<const char *>(block_data.data()), block_data.size()};
req->WriteHeader("Content-Type", "application/octet-stream");
req->WriteReply(HTTP_OK, binaryBlock);
req->WriteReply(HTTP_OK, AsBytes(Span{block_data}));
return true;
}

Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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: {
Expand Down

0 comments on commit 9c9375c

Please sign in to comment.