Avoid a copy in RPC output
Split up HTTPReply into HTTPReply and HTTPReplyHeader, so that the message data can be streamed directly. Also removes a c_str(), which would have prevented binary output with NUL characters in it.
This commit is contained in:
parent
5e94d0036a
commit
e17151ad2a
3 changed files with 18 additions and 9 deletions
|
@ -93,8 +93,7 @@ string HTTPError(int nStatus, bool keepalive, bool headersOnly)
|
|||
headersOnly, "text/plain");
|
||||
}
|
||||
|
||||
string HTTPReply(int nStatus, const string& strMsg, bool keepalive,
|
||||
bool headersOnly, const char *contentType)
|
||||
string HTTPReplyHeader(int nStatus, bool keepalive, size_t contentLength, const char *contentType)
|
||||
{
|
||||
return strprintf(
|
||||
"HTTP/1.1 %d %s\r\n"
|
||||
|
@ -103,17 +102,25 @@ string HTTPReply(int nStatus, const string& strMsg, bool keepalive,
|
|||
"Content-Length: %u\r\n"
|
||||
"Content-Type: %s\r\n"
|
||||
"Server: bitcoin-json-rpc/%s\r\n"
|
||||
"\r\n"
|
||||
"%s",
|
||||
"\r\n",
|
||||
nStatus,
|
||||
httpStatusDescription(nStatus),
|
||||
rfc1123Time(),
|
||||
keepalive ? "keep-alive" : "close",
|
||||
(headersOnly ? 0 : strMsg.size()),
|
||||
contentLength,
|
||||
contentType,
|
||||
FormatFullVersion(),
|
||||
(headersOnly ? "" : strMsg.c_str())
|
||||
);
|
||||
FormatFullVersion());
|
||||
}
|
||||
|
||||
string HTTPReply(int nStatus, const string& strMsg, bool keepalive,
|
||||
bool headersOnly, const char *contentType)
|
||||
{
|
||||
if (headersOnly)
|
||||
{
|
||||
return HTTPReplyHeader(nStatus, keepalive, 0, contentType);
|
||||
} else {
|
||||
return HTTPReplyHeader(nStatus, keepalive, strMsg.size(), contentType) + strMsg;
|
||||
}
|
||||
}
|
||||
|
||||
bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto,
|
||||
|
|
|
@ -143,6 +143,8 @@ private:
|
|||
std::string HTTPPost(const std::string& strMsg, const std::map<std::string,std::string>& mapRequestHeaders);
|
||||
std::string HTTPError(int nStatus, bool keepalive,
|
||||
bool headerOnly = false);
|
||||
std::string HTTPReplyHeader(int nStatus, bool keepalive, size_t contentLength,
|
||||
const char *contentType = "application/json");
|
||||
std::string HTTPReply(int nStatus, const std::string& strMsg, bool keepalive,
|
||||
bool headerOnly = false,
|
||||
const char *contentType = "application/json");
|
||||
|
|
|
@ -862,7 +862,7 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn,
|
|||
else
|
||||
throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error");
|
||||
|
||||
conn->stream() << HTTPReply(HTTP_OK, strReply, fRun) << std::flush;
|
||||
conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, strReply.size()) << strReply << std::flush;
|
||||
}
|
||||
catch (Object& objError)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue