Merge pull request #5376

8a5c951 [REST] make selection of output-format mandatory, support dot url syntax (Jonas Schnelli)
This commit is contained in:
Wladimir J. van der Laan 2014-12-02 15:31:08 +01:00
commit fec0d100d5
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
1 changed files with 57 additions and 32 deletions

View File

@ -18,6 +18,7 @@ using namespace std;
using namespace json_spirit; using namespace json_spirit;
enum RetFormat { enum RetFormat {
RF_UNDEF,
RF_BINARY, RF_BINARY,
RF_HEX, RF_HEX,
RF_JSON, RF_JSON,
@ -27,12 +28,14 @@ static const struct {
enum RetFormat rf; enum RetFormat rf;
const char* name; const char* name;
} rf_names[] = { } rf_names[] = {
{ RF_BINARY, "binary" }, // default, if match not found {RF_UNDEF, ""},
{RF_BINARY, "bin"},
{RF_HEX, "hex"}, {RF_HEX, "hex"},
{RF_JSON, "json"}, {RF_JSON, "json"},
}; };
class RestErr { class RestErr
{
public: public:
enum HTTPStatusCode status; enum HTTPStatusCode status;
string message; string message;
@ -49,15 +52,34 @@ static RestErr RESTERR(enum HTTPStatusCode status, string message)
return re; return re;
} }
static enum RetFormat ParseDataFormat(const string& format) static enum RetFormat ParseDataFormat(vector<string>& params, const string strReq)
{ {
boost::split(params, strReq, boost::is_any_of("."));
if (params.size() > 1) {
for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++) for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++)
if (format == rf_names[i].name) if (params[1] == rf_names[i].name)
return rf_names[i].rf; return rf_names[i].rf;
}
return rf_names[0].rf; return rf_names[0].rf;
} }
static string AvailableDataFormatsString()
{
string formats = "";
for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++)
if (strlen(rf_names[i].name) > 0) {
formats.append(".");
formats.append(rf_names[i].name);
formats.append(", ");
}
if (formats.length() > 0)
return formats.substr(0, formats.length() - 2);
return formats;
}
static bool ParseHashStr(const string& strReq, uint256& v) static bool ParseHashStr(const string& strReq, uint256& v)
{ {
if (!IsHex(strReq) || (strReq.size() != 64)) if (!IsHex(strReq) || (strReq.size() != 64))
@ -73,9 +95,7 @@ static bool rest_block(AcceptedConnection *conn,
bool fRun) bool fRun)
{ {
vector<string> params; vector<string> params;
boost::split(params, strReq, boost::is_any_of("/")); enum RetFormat rf = ParseDataFormat(params, strReq);
enum RetFormat rf = ParseDataFormat(params.size() > 1 ? params[1] : string(""));
string hashStr = params[0]; string hashStr = params[0];
uint256 hash; uint256 hash;
@ -105,7 +125,7 @@ static bool rest_block(AcceptedConnection *conn,
} }
case RF_HEX: { case RF_HEX: {
string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n";; string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n";
conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush; conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush;
return true; return true;
} }
@ -116,6 +136,10 @@ static bool rest_block(AcceptedConnection *conn,
conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
return true; return true;
} }
default: {
throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
}
} }
// not reached // not reached
@ -128,9 +152,7 @@ static bool rest_tx(AcceptedConnection *conn,
bool fRun) bool fRun)
{ {
vector<string> params; vector<string> params;
boost::split(params, strReq, boost::is_any_of("/")); enum RetFormat rf = ParseDataFormat(params, strReq);
enum RetFormat rf = ParseDataFormat(params.size() > 1 ? params[1] : string(""));
string hashStr = params[0]; string hashStr = params[0];
uint256 hash; uint256 hash;
@ -153,7 +175,7 @@ static bool rest_tx(AcceptedConnection *conn,
} }
case RF_HEX: { case RF_HEX: {
string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n";; string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n";
conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush; conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush;
return true; return true;
} }
@ -165,6 +187,10 @@ static bool rest_tx(AcceptedConnection *conn,
conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
return true; return true;
} }
default: {
throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
}
} }
// not reached // not reached
@ -199,8 +225,7 @@ bool HTTPReq_REST(AcceptedConnection *conn,
return uri_prefixes[i].handler(conn, strReq, mapHeaders, fRun); return uri_prefixes[i].handler(conn, strReq, mapHeaders, fRun);
} }
} }
} } catch (RestErr& re) {
catch (RestErr& re) {
conn->stream() << HTTPReply(re.status, re.message + "\r\n", false, false, "text/plain") << std::flush; conn->stream() << HTTPReply(re.status, re.message + "\r\n", false, false, "text/plain") << std::flush;
return false; return false;
} }