Skip to content

Commit b4b9854

Browse files
committed
Merge bitcoin/bitcoin#30321: rest: don't copy data when sending binary response
1556d21 rest: don't copy data when sending binary response (Roman Zeyde) Pull request description: Also, change `HTTPRequest::WriteReply` to accept `std::span`. ACKs for top commit: laanwj: re-ACK 1556d21 stickies-v: ACK 1556d21 Tree-SHA512: 3e563d8072f0e1b90b00f85adb140d4e5fef169b6882a837b08d1e8391b64c21bea3c4256c4e2a624ac1fb3d374f12a1cc16dc59b2155ec857728162d1daaceb
2 parents 2cd7c6b + 1556d21 commit b4b9854

File tree

3 files changed

+17
-17
lines changed

3 files changed

+17
-17
lines changed

src/httpserver.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <deque>
2727
#include <memory>
2828
#include <optional>
29+
#include <span>
2930
#include <string>
3031
#include <unordered_map>
3132

@@ -634,7 +635,7 @@ void HTTPRequest::WriteHeader(const std::string& hdr, const std::string& value)
634635
* Replies must be sent in the main loop in the main http thread,
635636
* this cannot be done from worker threads.
636637
*/
637-
void HTTPRequest::WriteReply(int nStatus, const std::string& strReply)
638+
void HTTPRequest::WriteReply(int nStatus, std::span<const std::byte> reply)
638639
{
639640
assert(!replySent && req);
640641
if (m_interrupt) {
@@ -643,7 +644,7 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply)
643644
// Send event to main http thread to send reply message
644645
struct evbuffer* evb = evhttp_request_get_output_buffer(req);
645646
assert(evb);
646-
evbuffer_add(evb, strReply.data(), strReply.size());
647+
evbuffer_add(evb, reply.data(), reply.size());
647648
auto req_copy = req;
648649
HTTPEvent* ev = new HTTPEvent(eventBase, true, [req_copy, nStatus]{
649650
evhttp_send_reply(req_copy, nStatus, nullptr, nullptr);

src/httpserver.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <functional>
99
#include <optional>
10+
#include <span>
1011
#include <string>
1112

1213
namespace util {
@@ -123,12 +124,16 @@ class HTTPRequest
123124
/**
124125
* Write HTTP reply.
125126
* nStatus is the HTTP status code to send.
126-
* strReply is the body of the reply. Keep it empty to send a standard message.
127+
* reply is the body of the reply. Keep it empty to send a standard message.
127128
*
128129
* @note Can be called only once. As this will give the request back to the
129130
* main thread, do not call any other HTTPRequest methods after calling this.
130131
*/
131-
void WriteReply(int nStatus, const std::string& strReply = "");
132+
void WriteReply(int nStatus, std::string_view reply = "")
133+
{
134+
WriteReply(nStatus, std::as_bytes(std::span{reply.data(), reply.size()}));
135+
}
136+
void WriteReply(int nStatus, std::span<const std::byte> reply);
132137
};
133138

134139
/** Get the query parameter value from request uri for a specified key, or std::nullopt if the key

src/rest.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,8 @@ static bool rest_headers(const std::any& context,
248248
ssHeader << pindex->GetBlockHeader();
249249
}
250250

251-
std::string binaryHeader = ssHeader.str();
252251
req->WriteHeader("Content-Type", "application/octet-stream");
253-
req->WriteReply(HTTP_OK, binaryHeader);
252+
req->WriteReply(HTTP_OK, ssHeader);
254253
return true;
255254
}
256255

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

322321
switch (rf) {
323322
case RESTResponseFormat::BINARY: {
324-
const std::string binaryBlock{block_data.begin(), block_data.end()};
325323
req->WriteHeader("Content-Type", "application/octet-stream");
326-
req->WriteReply(HTTP_OK, binaryBlock);
324+
req->WriteReply(HTTP_OK, std::as_bytes(std::span{block_data}));
327325
return true;
328326
}
329327

@@ -451,9 +449,8 @@ static bool rest_filter_header(const std::any& context, HTTPRequest* req, const
451449
ssHeader << header;
452450
}
453451

454-
std::string binaryHeader = ssHeader.str();
455452
req->WriteHeader("Content-Type", "application/octet-stream");
456-
req->WriteReply(HTTP_OK, binaryHeader);
453+
req->WriteReply(HTTP_OK, ssHeader);
457454
return true;
458455
}
459456
case RESTResponseFormat::HEX: {
@@ -548,9 +545,8 @@ static bool rest_block_filter(const std::any& context, HTTPRequest* req, const s
548545
DataStream ssResp{};
549546
ssResp << filter;
550547

551-
std::string binaryResp = ssResp.str();
552548
req->WriteHeader("Content-Type", "application/octet-stream");
553-
req->WriteReply(HTTP_OK, binaryResp);
549+
req->WriteReply(HTTP_OK, ssResp);
554550
return true;
555551
}
556552
case RESTResponseFormat::HEX: {
@@ -729,9 +725,8 @@ static bool rest_tx(const std::any& context, HTTPRequest* req, const std::string
729725
DataStream ssTx;
730726
ssTx << TX_WITH_WITNESS(tx);
731727

732-
std::string binaryTx = ssTx.str();
733728
req->WriteHeader("Content-Type", "application/octet-stream");
734-
req->WriteReply(HTTP_OK, binaryTx);
729+
req->WriteReply(HTTP_OK, ssTx);
735730
return true;
736731
}
737732

@@ -900,10 +895,9 @@ static bool rest_getutxos(const std::any& context, HTTPRequest* req, const std::
900895
// use exact same output as mentioned in Bip64
901896
DataStream ssGetUTXOResponse{};
902897
ssGetUTXOResponse << active_height << active_hash << bitmap << outs;
903-
std::string ssGetUTXOResponseString = ssGetUTXOResponse.str();
904898

905899
req->WriteHeader("Content-Type", "application/octet-stream");
906-
req->WriteReply(HTTP_OK, ssGetUTXOResponseString);
900+
req->WriteReply(HTTP_OK, ssGetUTXOResponse);
907901
return true;
908902
}
909903

@@ -981,7 +975,7 @@ static bool rest_blockhash_by_height(const std::any& context, HTTPRequest* req,
981975
DataStream ss_blockhash{};
982976
ss_blockhash << pblockindex->GetBlockHash();
983977
req->WriteHeader("Content-Type", "application/octet-stream");
984-
req->WriteReply(HTTP_OK, ss_blockhash.str());
978+
req->WriteReply(HTTP_OK, ss_blockhash);
985979
return true;
986980
}
987981
case RESTResponseFormat::HEX: {

0 commit comments

Comments
 (0)