Browse Source

Merge pull request #4440

16f33f1 fix RPC error replies (kazcw)
0.10
Wladimir J. van der Laan 11 years ago
parent
commit
eba8c44fdd
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 40
      src/rpcprotocol.cpp
  2. 2
      src/rpcprotocol.h
  3. 8
      src/rpcserver.cpp

40
src/rpcprotocol.cpp

@ -54,8 +54,19 @@ static string rfc1123Time()
return DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", GetTime()); return DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", GetTime());
} }
string HTTPReply(int nStatus, const string& strMsg, bool keepalive, static const char *httpStatusDescription(int nStatus)
bool headersOnly, const char *contentType) {
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) if (nStatus == HTTP_UNAUTHORIZED)
return strprintf("HTTP/1.0 401 Authorization Required\r\n" 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" "<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
"</HTML>\r\n", rfc1123Time(), FormatFullVersion()); "</HTML>\r\n", rfc1123Time(), FormatFullVersion());
const char *cStatus; return HTTPReply(nStatus, httpStatusDescription(nStatus), keepalive,
if (nStatus == HTTP_OK) cStatus = "OK"; headersOnly, "text/plain");
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;
} }
string HTTPReply(int nStatus, const string& strMsg, bool keepalive,
bool headersOnly, const char *contentType)
{
return strprintf( return strprintf(
"HTTP/1.1 %d %s\r\n" "HTTP/1.1 %d %s\r\n"
"Date: %s\r\n" "Date: %s\r\n"
@ -99,14 +103,14 @@ string HTTPReply(int nStatus, const string& strMsg, bool keepalive,
"\r\n" "\r\n"
"%s", "%s",
nStatus, nStatus,
cStatus, httpStatusDescription(nStatus),
rfc1123Time(), rfc1123Time(),
keepalive ? "keep-alive" : "close", keepalive ? "keep-alive" : "close",
strMsg.size(), (headersOnly ? 0 : strMsg.size()),
contentType, contentType,
FormatFullVersion(), FormatFullVersion(),
(headersOnly ? "" : (headersOnly ? "" : strMsg.c_str())
(useInternalContent ? cStatus : strMsg.c_str()))); );
} }
bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto, bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto,

2
src/rpcprotocol.h

@ -141,6 +141,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,
bool headerOnly = false);
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");

8
src/rpcserver.cpp

@ -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. // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
if (!fUseSSL) if (!fUseSSL)
conn->stream() << HTTPReply(HTTP_FORBIDDEN, "", false) << std::flush; conn->stream() << HTTPError(HTTP_FORBIDDEN, false) << std::flush;
conn->close(); conn->close();
} }
else { else {
@ -807,7 +807,7 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn,
// Check authorization // Check authorization
if (mapHeaders.count("authorization") == 0) if (mapHeaders.count("authorization") == 0)
{ {
conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush; conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush;
return false; return false;
} }
@ -820,7 +820,7 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn,
if (mapArgs["-rpcpassword"].size() < 20) if (mapArgs["-rpcpassword"].size() < 20)
MilliSleep(250); MilliSleep(250);
conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush; conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush;
return false; return false;
} }
@ -888,7 +888,7 @@ void ServiceConnection(AcceptedConnection *conn)
if (!HTTPReq_JSONRPC(conn, strRequest, mapHeaders, fRun)) if (!HTTPReq_JSONRPC(conn, strRequest, mapHeaders, fRun))
break; break;
} else { } else {
conn->stream() << HTTPReply(HTTP_NOT_FOUND, "", false) << std::flush; conn->stream() << HTTPError(HTTP_NOT_FOUND, false) << std::flush;
break; break;
} }
} }

Loading…
Cancel
Save