|
|
@ -317,7 +317,7 @@ string rfc1123Time() |
|
|
|
|
|
|
|
|
|
|
|
static string HTTPReply(int nStatus, const string& strMsg, bool keepalive) |
|
|
|
static string HTTPReply(int nStatus, const string& strMsg, bool keepalive) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (nStatus == 401) |
|
|
|
if (nStatus == HTTP_UNAUTHORIZED) |
|
|
|
return strprintf("HTTP/1.0 401 Authorization Required\r\n" |
|
|
|
return strprintf("HTTP/1.0 401 Authorization Required\r\n" |
|
|
|
"Date: %s\r\n" |
|
|
|
"Date: %s\r\n" |
|
|
|
"Server: bitcoin-json-rpc/%s\r\n" |
|
|
|
"Server: bitcoin-json-rpc/%s\r\n" |
|
|
@ -335,11 +335,11 @@ static 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().c_str(), FormatFullVersion().c_str()); |
|
|
|
"</HTML>\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str()); |
|
|
|
const char *cStatus; |
|
|
|
const char *cStatus; |
|
|
|
if (nStatus == 200) cStatus = "OK"; |
|
|
|
if (nStatus == HTTP_OK) cStatus = "OK"; |
|
|
|
else if (nStatus == 400) cStatus = "Bad Request"; |
|
|
|
else if (nStatus == HTTP_BAD_REQUEST) cStatus = "Bad Request"; |
|
|
|
else if (nStatus == 403) cStatus = "Forbidden"; |
|
|
|
else if (nStatus == HTTP_FORBIDDEN) cStatus = "Forbidden"; |
|
|
|
else if (nStatus == 404) cStatus = "Not Found"; |
|
|
|
else if (nStatus == HTTP_NOT_FOUND) cStatus = "Not Found"; |
|
|
|
else if (nStatus == 500) cStatus = "Internal Server Error"; |
|
|
|
else if (nStatus == HTTP_INTERNAL_SERVER_ERROR) cStatus = "Internal Server Error"; |
|
|
|
else cStatus = ""; |
|
|
|
else cStatus = ""; |
|
|
|
return strprintf( |
|
|
|
return strprintf( |
|
|
|
"HTTP/1.1 %d %s\r\n" |
|
|
|
"HTTP/1.1 %d %s\r\n" |
|
|
@ -366,7 +366,7 @@ int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto) |
|
|
|
vector<string> vWords; |
|
|
|
vector<string> vWords; |
|
|
|
boost::split(vWords, str, boost::is_any_of(" ")); |
|
|
|
boost::split(vWords, str, boost::is_any_of(" ")); |
|
|
|
if (vWords.size() < 2) |
|
|
|
if (vWords.size() < 2) |
|
|
|
return 500; |
|
|
|
return HTTP_INTERNAL_SERVER_ERROR; |
|
|
|
proto = 0; |
|
|
|
proto = 0; |
|
|
|
const char *ver = strstr(str.c_str(), "HTTP/1."); |
|
|
|
const char *ver = strstr(str.c_str(), "HTTP/1."); |
|
|
|
if (ver != NULL) |
|
|
|
if (ver != NULL) |
|
|
@ -411,7 +411,7 @@ int ReadHTTP(std::basic_istream<char>& stream, map<string, string>& mapHeadersRe |
|
|
|
// Read header
|
|
|
|
// Read header
|
|
|
|
int nLen = ReadHTTPHeader(stream, mapHeadersRet); |
|
|
|
int nLen = ReadHTTPHeader(stream, mapHeadersRet); |
|
|
|
if (nLen < 0 || nLen > (int)MAX_SIZE) |
|
|
|
if (nLen < 0 || nLen > (int)MAX_SIZE) |
|
|
|
return 500; |
|
|
|
return HTTP_INTERNAL_SERVER_ERROR; |
|
|
|
|
|
|
|
|
|
|
|
// Read message
|
|
|
|
// Read message
|
|
|
|
if (nLen > 0) |
|
|
|
if (nLen > 0) |
|
|
@ -484,10 +484,10 @@ string JSONRPCReply(const Value& result, const Value& error, const Value& id) |
|
|
|
void ErrorReply(std::ostream& stream, const Object& objError, const Value& id) |
|
|
|
void ErrorReply(std::ostream& stream, const Object& objError, const Value& id) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Send error reply from json-rpc error object
|
|
|
|
// Send error reply from json-rpc error object
|
|
|
|
int nStatus = 500; |
|
|
|
int nStatus = HTTP_INTERNAL_SERVER_ERROR; |
|
|
|
int code = find_value(objError, "code").get_int(); |
|
|
|
int code = find_value(objError, "code").get_int(); |
|
|
|
if (code == RPC_INVALID_REQUEST) nStatus = 400; |
|
|
|
if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST; |
|
|
|
else if (code == RPC_METHOD_NOT_FOUND) nStatus = 404; |
|
|
|
else if (code == RPC_METHOD_NOT_FOUND) nStatus = HTTP_NOT_FOUND; |
|
|
|
string strReply = JSONRPCReply(Value::null, objError, id); |
|
|
|
string strReply = JSONRPCReply(Value::null, objError, id); |
|
|
|
stream << HTTPReply(nStatus, strReply, false) << std::flush; |
|
|
|
stream << HTTPReply(nStatus, strReply, false) << std::flush; |
|
|
|
} |
|
|
|
} |
|
|
@ -699,7 +699,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(403, "", false) << std::flush; |
|
|
|
conn->stream() << HTTPReply(HTTP_FORBIDDEN, "", false) << std::flush; |
|
|
|
delete conn; |
|
|
|
delete conn; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -946,7 +946,7 @@ void ThreadRPCServer3(void* parg) |
|
|
|
// Check authorization
|
|
|
|
// Check authorization
|
|
|
|
if (mapHeaders.count("authorization") == 0) |
|
|
|
if (mapHeaders.count("authorization") == 0) |
|
|
|
{ |
|
|
|
{ |
|
|
|
conn->stream() << HTTPReply(401, "", false) << std::flush; |
|
|
|
conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!HTTPAuthorized(mapHeaders)) |
|
|
|
if (!HTTPAuthorized(mapHeaders)) |
|
|
@ -958,7 +958,7 @@ void ThreadRPCServer3(void* parg) |
|
|
|
if (mapArgs["-rpcpassword"].size() < 20) |
|
|
|
if (mapArgs["-rpcpassword"].size() < 20) |
|
|
|
Sleep(250); |
|
|
|
Sleep(250); |
|
|
|
|
|
|
|
|
|
|
|
conn->stream() << HTTPReply(401, "", false) << std::flush; |
|
|
|
conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if (mapHeaders["connection"] == "close") |
|
|
|
if (mapHeaders["connection"] == "close") |
|
|
@ -989,7 +989,7 @@ void ThreadRPCServer3(void* parg) |
|
|
|
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(200, strReply, fRun) << std::flush; |
|
|
|
conn->stream() << HTTPReply(HTTP_OK, strReply, fRun) << std::flush; |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Object& objError) |
|
|
|
catch (Object& objError) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -1077,9 +1077,9 @@ Object CallRPC(const string& strMethod, const Array& params) |
|
|
|
map<string, string> mapHeaders; |
|
|
|
map<string, string> mapHeaders; |
|
|
|
string strReply; |
|
|
|
string strReply; |
|
|
|
int nStatus = ReadHTTP(stream, mapHeaders, strReply); |
|
|
|
int nStatus = ReadHTTP(stream, mapHeaders, strReply); |
|
|
|
if (nStatus == 401) |
|
|
|
if (nStatus == HTTP_UNAUTHORIZED) |
|
|
|
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)"); |
|
|
|
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)"); |
|
|
|
else if (nStatus >= 400 && nStatus != 400 && nStatus != 404 && nStatus != 500) |
|
|
|
else if (nStatus >= 400 && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR) |
|
|
|
throw runtime_error(strprintf("server returned HTTP error %d", nStatus)); |
|
|
|
throw runtime_error(strprintf("server returned HTTP error %d", nStatus)); |
|
|
|
else if (strReply.empty()) |
|
|
|
else if (strReply.empty()) |
|
|
|
throw runtime_error("no response from server"); |
|
|
|
throw runtime_error("no response from server"); |
|
|
|