Merge pull request #4640
733177e
Remove size limit in RPC client, keep it in server (Wladimir J. van der Laan)e17151a
Avoid a copy in RPC output (Wladimir J. van der Laan)
This commit is contained in:
commit
0b588168ab
4 changed files with 23 additions and 14 deletions
|
@ -126,7 +126,7 @@ Object CallRPC(const string& strMethod, const Array& params)
|
||||||
// Receive HTTP reply message headers and body
|
// Receive HTTP reply message headers and body
|
||||||
map<string, string> mapHeaders;
|
map<string, string> mapHeaders;
|
||||||
string strReply;
|
string strReply;
|
||||||
ReadHTTPMessage(stream, mapHeaders, strReply, nProto);
|
ReadHTTPMessage(stream, mapHeaders, strReply, nProto, std::numeric_limits<size_t>::max());
|
||||||
|
|
||||||
if (nStatus == HTTP_UNAUTHORIZED)
|
if (nStatus == HTTP_UNAUTHORIZED)
|
||||||
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
|
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
|
||||||
|
|
|
@ -93,8 +93,7 @@ string HTTPError(int nStatus, bool keepalive, bool headersOnly)
|
||||||
headersOnly, "text/plain");
|
headersOnly, "text/plain");
|
||||||
}
|
}
|
||||||
|
|
||||||
string HTTPReply(int nStatus, const string& strMsg, bool keepalive,
|
string HTTPReplyHeader(int nStatus, bool keepalive, size_t contentLength, const char *contentType)
|
||||||
bool headersOnly, const char *contentType)
|
|
||||||
{
|
{
|
||||||
return strprintf(
|
return strprintf(
|
||||||
"HTTP/1.1 %d %s\r\n"
|
"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-Length: %u\r\n"
|
||||||
"Content-Type: %s\r\n"
|
"Content-Type: %s\r\n"
|
||||||
"Server: bitcoin-json-rpc/%s\r\n"
|
"Server: bitcoin-json-rpc/%s\r\n"
|
||||||
"\r\n"
|
"\r\n",
|
||||||
"%s",
|
|
||||||
nStatus,
|
nStatus,
|
||||||
httpStatusDescription(nStatus),
|
httpStatusDescription(nStatus),
|
||||||
rfc1123Time(),
|
rfc1123Time(),
|
||||||
keepalive ? "keep-alive" : "close",
|
keepalive ? "keep-alive" : "close",
|
||||||
(headersOnly ? 0 : strMsg.size()),
|
contentLength,
|
||||||
contentType,
|
contentType,
|
||||||
FormatFullVersion(),
|
FormatFullVersion());
|
||||||
(headersOnly ? "" : strMsg.c_str())
|
}
|
||||||
);
|
|
||||||
|
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,
|
bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto,
|
||||||
|
@ -194,14 +201,14 @@ int ReadHTTPHeaders(std::basic_istream<char>& stream, map<string, string>& mapHe
|
||||||
|
|
||||||
int ReadHTTPMessage(std::basic_istream<char>& stream, map<string,
|
int ReadHTTPMessage(std::basic_istream<char>& stream, map<string,
|
||||||
string>& mapHeadersRet, string& strMessageRet,
|
string>& mapHeadersRet, string& strMessageRet,
|
||||||
int nProto)
|
int nProto, size_t max_size)
|
||||||
{
|
{
|
||||||
mapHeadersRet.clear();
|
mapHeadersRet.clear();
|
||||||
strMessageRet = "";
|
strMessageRet = "";
|
||||||
|
|
||||||
// Read header
|
// Read header
|
||||||
int nLen = ReadHTTPHeaders(stream, mapHeadersRet);
|
int nLen = ReadHTTPHeaders(stream, mapHeadersRet);
|
||||||
if (nLen < 0 || nLen > (int)MAX_SIZE)
|
if (nLen < 0 || (size_t)nLen > max_size)
|
||||||
return HTTP_INTERNAL_SERVER_ERROR;
|
return HTTP_INTERNAL_SERVER_ERROR;
|
||||||
|
|
||||||
// Read message
|
// Read message
|
||||||
|
|
|
@ -143,6 +143,8 @@ private:
|
||||||
std::string HTTPPost(const std::string& strMsg, const std::map<std::string,std::string>& mapRequestHeaders);
|
std::string HTTPPost(const std::string& strMsg, const std::map<std::string,std::string>& mapRequestHeaders);
|
||||||
std::string HTTPError(int nStatus, bool keepalive,
|
std::string HTTPError(int nStatus, bool keepalive,
|
||||||
bool headerOnly = false);
|
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,
|
std::string HTTPReply(int nStatus, const std::string& strMsg, bool keepalive,
|
||||||
bool headerOnly = false,
|
bool headerOnly = false,
|
||||||
const char *contentType = "application/json");
|
const char *contentType = "application/json");
|
||||||
|
@ -151,7 +153,7 @@ bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto,
|
||||||
int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto);
|
int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto);
|
||||||
int ReadHTTPHeaders(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet);
|
int ReadHTTPHeaders(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet);
|
||||||
int ReadHTTPMessage(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet,
|
int ReadHTTPMessage(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet,
|
||||||
std::string& strMessageRet, int nProto);
|
std::string& strMessageRet, int nProto, size_t max_size);
|
||||||
std::string JSONRPCRequest(const std::string& strMethod, const json_spirit::Array& params, const json_spirit::Value& id);
|
std::string JSONRPCRequest(const std::string& strMethod, const json_spirit::Array& params, const json_spirit::Value& id);
|
||||||
json_spirit::Object JSONRPCReplyObj(const json_spirit::Value& result, const json_spirit::Value& error, const json_spirit::Value& id);
|
json_spirit::Object JSONRPCReplyObj(const json_spirit::Value& result, const json_spirit::Value& error, const json_spirit::Value& id);
|
||||||
std::string JSONRPCReply(const json_spirit::Value& result, const json_spirit::Value& error, const json_spirit::Value& id);
|
std::string JSONRPCReply(const json_spirit::Value& result, const json_spirit::Value& error, const json_spirit::Value& id);
|
||||||
|
|
|
@ -862,7 +862,7 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn,
|
||||||
else
|
else
|
||||||
throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error");
|
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)
|
catch (Object& objError)
|
||||||
{
|
{
|
||||||
|
@ -891,7 +891,7 @@ void ServiceConnection(AcceptedConnection *conn)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Read HTTP message headers and body
|
// Read HTTP message headers and body
|
||||||
ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto);
|
ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto, MAX_SIZE);
|
||||||
|
|
||||||
// HTTP Keep-Alive is false; close connection immediately
|
// HTTP Keep-Alive is false; close connection immediately
|
||||||
if (mapHeaders["connection"] == "close")
|
if (mapHeaders["connection"] == "close")
|
||||||
|
|
Loading…
Reference in a new issue