diff --git a/doc/release-notes.md b/doc/release-notes.md index 0be192233d..f2d8ca3a15 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -59,6 +59,10 @@ git merge commit are mentioned. ### RPC and REST +UTXO set query (`GET /rest/getutxos//-/-/.../-.`) responses +were changed to return status code HTTP_BAD_REQUEST (400) instead of HTTP_INTERNAL_SERVER_ERROR (500) when requests +contain invalid parameters. + ### Configuration and command-line options ### Block and transaction handling diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py index c9c2eaf7f3..b769cd71f2 100755 --- a/qa/rpc-tests/rest.py +++ b/qa/rpc-tests/rest.py @@ -179,14 +179,14 @@ class RESTTest (BitcoinTestFramework): #do some invalid requests json_request = '{"checkmempool' response = http_post_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'json', json_request, True) - assert_equal(response.status, 500) #must be a 500 because we send a invalid json request + assert_equal(response.status, 400) #must be a 400 because we send a invalid json request json_request = '{"checkmempool' response = http_post_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'bin', json_request, True) - assert_equal(response.status, 500) #must be a 500 because we send a invalid bin request + assert_equal(response.status, 400) #must be a 400 because we send a invalid bin request response = http_post_call(url.hostname, url.port, '/rest/getutxos/checkmempool'+self.FORMAT_SEPARATOR+'bin', '', True) - assert_equal(response.status, 500) #must be a 500 because we send a invalid bin request + assert_equal(response.status, 400) #must be a 400 because we send a invalid bin request #test limits json_request = '/checkmempool/' @@ -194,14 +194,14 @@ class RESTTest (BitcoinTestFramework): json_request += txid+'-'+str(n)+'/' json_request = json_request.rstrip("/") response = http_post_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json', '', True) - assert_equal(response.status, 500) #must be a 500 because we exceeding the limits + assert_equal(response.status, 400) #must be a 400 because we exceeding the limits json_request = '/checkmempool/' for x in range(0, 15): json_request += txid+'-'+str(n)+'/' json_request = json_request.rstrip("/") response = http_post_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json', '', True) - assert_equal(response.status, 200) #must be a 500 because we exceeding the limits + assert_equal(response.status, 200) #must be a 200 because we are within the limits self.nodes[0].generate(1) #generate block to not affect upcoming tests self.sync_all() diff --git a/src/rest.cpp b/src/rest.cpp index 2dff8d7dad..c815592124 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -420,7 +420,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) // throw exception in case of a empty request std::string strRequestMutable = req->ReadBody(); if (strRequestMutable.length() == 0 && uriParts.size() == 0) - return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); + return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request"); bool fInputParsed = false; bool fCheckMemPool = false; @@ -444,7 +444,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) std::string strOutput = uriParts[i].substr(uriParts[i].find("-")+1); if (!ParseInt32(strOutput, &nOutput) || !IsHex(strTxid)) - return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Parse error"); + return RESTERR(req, HTTP_BAD_REQUEST, "Parse error"); txid.SetHex(strTxid); vOutPoints.push_back(COutPoint(txid, (uint32_t)nOutput)); @@ -453,7 +453,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) if (vOutPoints.size() > 0) fInputParsed = true; else - return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); + return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request"); } switch (rf) { @@ -469,7 +469,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) if (strRequestMutable.size() > 0) { if (fInputParsed) //don't allow sending input over URI and HTTP RAW DATA - return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Combination of URI scheme inputs and raw post data is not allowed"); + return RESTERR(req, HTTP_BAD_REQUEST, "Combination of URI scheme inputs and raw post data is not allowed"); CDataStream oss(SER_NETWORK, PROTOCOL_VERSION); oss << strRequestMutable; @@ -478,14 +478,14 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) } } catch (const std::ios_base::failure& e) { // abort in case of unreadable binary data - return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Parse error"); + return RESTERR(req, HTTP_BAD_REQUEST, "Parse error"); } break; } case RF_JSON: { if (!fInputParsed) - return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); + return RESTERR(req, HTTP_BAD_REQUEST, "Error: empty request"); break; } default: { @@ -495,7 +495,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) // limit max outpoints if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS) - return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size())); + return RESTERR(req, HTTP_BAD_REQUEST, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size())); // check spentness and form a bitmap (as well as a JSON capable human-readable string representation) vector bitmap;