| 145 | } |
| 146 | |
| 147 | static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) |
| 148 | { |
| 149 | // JSONRPC handles only POST |
| 150 | if (req->GetRequestMethod() != HTTPRequest::POST) { |
| 151 | req->WriteReply(HTTP_BAD_METHOD, "JSONRPC server handles only POST requests"); |
| 152 | return false; |
| 153 | } |
| 154 | // Check authorization |
| 155 | std::pair<bool, std::string> authHeader = req->GetHeader("authorization"); |
| 156 | if (!authHeader.first) { |
| 157 | req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA); |
| 158 | req->WriteReply(HTTP_UNAUTHORIZED); |
| 159 | return false; |
| 160 | } |
| 161 | |
| 162 | JSONRPCRequest jreq; |
| 163 | jreq.peerAddr = req->GetPeer().ToString(); |
| 164 | if (!RPCAuthorized(authHeader.second, jreq.authUser)) { |
| 165 | LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", jreq.peerAddr); |
| 166 | |
| 167 | /* Deter brute-forcing |
| 168 | If this results in a DoS the user really |
| 169 | shouldn't have their RPC port exposed. */ |
| 170 | MilliSleep(250); |
| 171 | |
| 172 | req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA); |
| 173 | req->WriteReply(HTTP_UNAUTHORIZED); |
| 174 | return false; |
| 175 | } |
| 176 | |
| 177 | try { |
| 178 | // Parse request |
| 179 | UniValue valRequest; |
| 180 | if (!valRequest.read(req->ReadBody())) |
| 181 | throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); |
| 182 | |
| 183 | // Set the URI |
| 184 | jreq.URI = req->GetURI(); |
| 185 | |
| 186 | std::string strReply; |
| 187 | // singleton request |
| 188 | if (valRequest.isObject()) { |
| 189 | jreq.parse(valRequest); |
| 190 | |
| 191 | UniValue result = tableRPC.execute(jreq); |
| 192 | |
| 193 | // Send reply |
| 194 | strReply = JSONRPCReply(result, NullUniValue, jreq.id); |
| 195 | |
| 196 | // array of requests |
| 197 | } else if (valRequest.isArray()) |
| 198 | strReply = JSONRPCExecBatch(jreq, valRequest.get_array()); |
| 199 | else |
| 200 | throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error"); |
| 201 | |
| 202 | req->WriteHeader("Content-Type", "application/json"); |
| 203 | req->WriteReply(HTTP_OK, strReply); |
| 204 | } catch (const UniValue& objError) { |
nothing calls this directly
no test coverage detected