| 1 | /************************************************************************* |
| 2 | * libjson-rpc-cpp |
| 3 | ************************************************************************* |
| 4 | * @file abstractprotocolhandler.cpp |
| 5 | * @date 10/23/2014 |
| 6 | * @author Peter Spiess-Knafl <dev@spiessknafl.at> |
| 7 | * @license See attached LICENSE.txt |
| 8 | ************************************************************************/ |
| 9 | |
| 10 | #include "abstractprotocolhandler.h" |
| 11 | #include <jsonrpccpp/common/errors.h> |
| 12 | #include <sstream> |
| 13 | #include <map> |
| 14 | |
| 15 | using namespace jsonrpc; |
| 16 | using namespace std; |
| 17 | |
| 18 | AbstractProtocolHandler::AbstractProtocolHandler(IProcedureInvokationHandler &handler) : handler(handler) {} |
| 19 | |
| 20 | AbstractProtocolHandler::~AbstractProtocolHandler() {} |
| 21 | |
| 22 | void AbstractProtocolHandler::AddProcedure(const Procedure &procedure) { this->procedures[procedure.GetProcedureName()] = procedure; } |
| 23 | |
| 24 | void AbstractProtocolHandler::HandleRequest(const std::string &request, std::string &retValue) { |
| 25 | Json::Value req; |
| 26 | Json::Value resp; |
| 27 | Json::StreamWriterBuilder wbuilder; |
| 28 | wbuilder["indentation" ] = "" ; |
| 29 | |
| 30 | try { |
| 31 | istringstream(request) >> req; |
| 32 | this->HandleJsonRequest(req, resp); |
| 33 | } catch (const Json::Exception &e) { |
| 34 | this->WrapError(Json::nullValue, Errors::ERROR_RPC_JSON_PARSE_ERROR, Errors::GetErrorMessage(Errors::ERROR_RPC_JSON_PARSE_ERROR), resp); |
| 35 | } |
| 36 | |
| 37 | if (resp != Json::nullValue) |
| 38 | retValue = Json::writeString(wbuilder, resp); |
| 39 | } |
| 40 | |
| 41 | void AbstractProtocolHandler::ProcessRequest(const Json::Value &request, Json::Value &response) { |
| 42 | Procedure &method = this->procedures[request[KEY_REQUEST_METHODNAME].asString()]; |
| 43 | Json::Value result; |
| 44 | |
| 45 | if (method.GetProcedureType() == RPC_METHOD) { |
| 46 | handler.HandleMethodCall(method, request[KEY_REQUEST_PARAMETERS], result); |
| 47 | this->WrapResult(request, response, result); |
| 48 | } else { |
| 49 | handler.HandleNotificationCall(method, request[KEY_REQUEST_PARAMETERS]); |
| 50 | response = Json::nullValue; |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | int AbstractProtocolHandler::ValidateRequest(const Json::Value &request) { |
| 55 | int error = 0; |
| 56 | Procedure proc; |
| 57 | if (!this->ValidateRequestFields(request)) { |
| 58 | error = Errors::ERROR_RPC_INVALID_REQUEST; |
| 59 | } else { |
| 60 | map<string, Procedure>::iterator it = this->procedures.find(request[KEY_REQUEST_METHODNAME].asString()); |
| 61 | if (it != this->procedures.end()) { |
| 62 | proc = it->second; |
| 63 | if (this->GetRequestType(request) == RPC_METHOD && proc.GetProcedureType() == RPC_NOTIFICATION) { |
| 64 | error = Errors::ERROR_SERVER_PROCEDURE_IS_NOTIFICATION; |
| 65 | } else if (this->GetRequestType(request) == RPC_NOTIFICATION && proc.GetProcedureType() == RPC_METHOD) { |
| 66 | error = Errors::ERROR_SERVER_PROCEDURE_IS_METHOD; |
| 67 | } else if (!proc.ValdiateParameters(request[KEY_REQUEST_PARAMETERS])) { |
| 68 | error = Errors::ERROR_RPC_INVALID_PARAMS; |
| 69 | } |
| 70 | } else { |
| 71 | error = Errors::ERROR_RPC_METHOD_NOT_FOUND; |
| 72 | } |
| 73 | } |
| 74 | return error; |
| 75 | } |
| 76 | |