Browse Source

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)
0.10
Wladimir J. van der Laan 10 years ago
parent
commit
0b588168ab
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 2
      src/bitcoin-cli.cpp
  2. 27
      src/rpcprotocol.cpp
  3. 4
      src/rpcprotocol.h
  4. 4
      src/rpcserver.cpp

2
src/bitcoin-cli.cpp

@ -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)");

27
src/rpcprotocol.cpp

@ -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

4
src/rpcprotocol.h

@ -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);

4
src/rpcserver.cpp

@ -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…
Cancel
Save