Browse Source

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.
pull/1/head
Wladimir J. van der Laan 8 years ago
parent
commit
e17151ad2a
  1. 23
      src/rpcprotocol.cpp
  2. 2
      src/rpcprotocol.h
  3. 2
      src/rpcserver.cpp

23
src/rpcprotocol.cpp

@ -93,8 +93,7 @@ string HTTPError(int nStatus, bool keepalive, bool headersOnly) @@ -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, @@ -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,

2
src/rpcprotocol.h

@ -143,6 +143,8 @@ private: @@ -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");

2
src/rpcserver.cpp

@ -862,7 +862,7 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, @@ -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…
Cancel
Save