mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
fix RPC error replies
After pull #4288, RPC messages indicating errors have a Content-Length unrelated to their actual contents, rendering bitcoin-cli and curl unable to decode the reply. This patch sets the Content-Length field based on the actual content returned. Additionally, pull #4288 clobbered the error descriptions provided in ErrorReply, which bitcoin-cli relies upon; this patch moves #4288 http-error descriptions to an HTTPError method, allowing HTTPReply to pass content on unchanged.
This commit is contained in:
parent
7b8fc9d8ad
commit
16f33f163d
@ -54,8 +54,19 @@ static string rfc1123Time()
|
||||
return DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", GetTime());
|
||||
}
|
||||
|
||||
string HTTPReply(int nStatus, const string& strMsg, bool keepalive,
|
||||
bool headersOnly, const char *contentType)
|
||||
static const char *httpStatusDescription(int nStatus)
|
||||
{
|
||||
switch (nStatus) {
|
||||
case HTTP_OK: return "OK";
|
||||
case HTTP_BAD_REQUEST: return "Bad Request";
|
||||
case HTTP_FORBIDDEN: return "Forbidden";
|
||||
case HTTP_NOT_FOUND: return "Not Found";
|
||||
case HTTP_INTERNAL_SERVER_ERROR: return "Internal Server Error";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
string HTTPError(int nStatus, bool keepalive, bool headersOnly)
|
||||
{
|
||||
if (nStatus == HTTP_UNAUTHORIZED)
|
||||
return strprintf("HTTP/1.0 401 Authorization Required\r\n"
|
||||
@ -75,20 +86,13 @@ string HTTPReply(int nStatus, const string& strMsg, bool keepalive,
|
||||
"<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
|
||||
"</HTML>\r\n", rfc1123Time(), FormatFullVersion());
|
||||
|
||||
const char *cStatus;
|
||||
if (nStatus == HTTP_OK) cStatus = "OK";
|
||||
else if (nStatus == HTTP_BAD_REQUEST) cStatus = "Bad Request";
|
||||
else if (nStatus == HTTP_FORBIDDEN) cStatus = "Forbidden";
|
||||
else if (nStatus == HTTP_NOT_FOUND) cStatus = "Not Found";
|
||||
else if (nStatus == HTTP_INTERNAL_SERVER_ERROR) cStatus = "Internal Server Error";
|
||||
else cStatus = "";
|
||||
|
||||
bool useInternalContent = false;
|
||||
if (nStatus != HTTP_OK) {
|
||||
contentType = "text/plain";
|
||||
useInternalContent = true;
|
||||
}
|
||||
return HTTPReply(nStatus, httpStatusDescription(nStatus), keepalive,
|
||||
headersOnly, "text/plain");
|
||||
}
|
||||
|
||||
string HTTPReply(int nStatus, const string& strMsg, bool keepalive,
|
||||
bool headersOnly, const char *contentType)
|
||||
{
|
||||
return strprintf(
|
||||
"HTTP/1.1 %d %s\r\n"
|
||||
"Date: %s\r\n"
|
||||
@ -99,14 +103,14 @@ string HTTPReply(int nStatus, const string& strMsg, bool keepalive,
|
||||
"\r\n"
|
||||
"%s",
|
||||
nStatus,
|
||||
cStatus,
|
||||
httpStatusDescription(nStatus),
|
||||
rfc1123Time(),
|
||||
keepalive ? "keep-alive" : "close",
|
||||
strMsg.size(),
|
||||
(headersOnly ? 0 : strMsg.size()),
|
||||
contentType,
|
||||
FormatFullVersion(),
|
||||
(headersOnly ? "" :
|
||||
(useInternalContent ? cStatus : strMsg.c_str())));
|
||||
(headersOnly ? "" : strMsg.c_str())
|
||||
);
|
||||
}
|
||||
|
||||
bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto,
|
||||
|
@ -141,6 +141,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 HTTPReply(int nStatus, const std::string& strMsg, bool keepalive,
|
||||
bool headerOnly = false,
|
||||
const char *contentType = "application/json");
|
||||
|
@ -481,7 +481,7 @@ static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol,
|
||||
{
|
||||
// Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
|
||||
if (!fUseSSL)
|
||||
conn->stream() << HTTPReply(HTTP_FORBIDDEN, "", false) << std::flush;
|
||||
conn->stream() << HTTPError(HTTP_FORBIDDEN, false) << std::flush;
|
||||
conn->close();
|
||||
}
|
||||
else {
|
||||
@ -807,7 +807,7 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn,
|
||||
// Check authorization
|
||||
if (mapHeaders.count("authorization") == 0)
|
||||
{
|
||||
conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush;
|
||||
conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -820,7 +820,7 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn,
|
||||
if (mapArgs["-rpcpassword"].size() < 20)
|
||||
MilliSleep(250);
|
||||
|
||||
conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush;
|
||||
conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -888,7 +888,7 @@ void ServiceConnection(AcceptedConnection *conn)
|
||||
if (!HTTPReq_JSONRPC(conn, strRequest, mapHeaders, fRun))
|
||||
break;
|
||||
} else {
|
||||
conn->stream() << HTTPReply(HTTP_NOT_FOUND, "", false) << std::flush;
|
||||
conn->stream() << HTTPError(HTTP_NOT_FOUND, false) << std::flush;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user