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:
kazcw
2014-06-28 18:14:36 -07:00
parent 7b8fc9d8ad
commit 16f33f163d
3 changed files with 29 additions and 23 deletions

View File

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