diff --git a/AUTHORS.md b/AUTHORS.md index 627f32bf..f54ad418 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -54,4 +54,7 @@ Kasper Laudrup Erik Lundin + bugfix in cpp-server stubgen -+ bugfix for gcc 4.7 compatibility ++ bugfix for gcc 4.7 compatibility + +Michał Górny ++ bugfixes in the build system diff --git a/CHANGELOG.md b/CHANGELOG.md index 677926a1..c812259a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,14 @@ -Changes in v0.4.3 [unreleased] +Changes in v0.5.0 ----------------- -- added `--version` option to jsonrpcstub -- added msvc support +- added `--version` option to jsonrpcstub. +- added msvc support. +- added data field support for JsonRpcException. +- added contributions guide: https://github.com/cinemast/libjson-rpc-cpp#contributions +- HttpClient uses Http Keep-Alive, which improves performance drastically. +- Added `LIB_SUFFIX` to CMake to support multilib. +- Fixed building tests with examples disabled. +- Made static library build optional (via `BUILD_STATIC_LIBS`). +- Fixed unnecessary rebuilds of stubs on each `make` call. Changes in v0.4.2 ----------------- diff --git a/CMakeLists.txt b/CMakeLists.txt index 74accc96..41fcbe36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,10 +11,13 @@ if (${CMAKE_MAJOR_VERSION} GREATER 2) endif() set(MAJOR_VERSION 0) -set(MINOR_VERSION 4) -set(PATCH_VERSION 2) +set(MINOR_VERSION 5) +set(PATCH_VERSION 0) set(SO_VERSION 0) +set(BUILD_STATIC_LIBS NO CACHE BOOL "Build static libraries in addition to shared") +set(LIB_SUFFIX "" CACHE STRING "Suffix for library directory (32/64)") + # defaults for modules that can be enabled/disabled set(HTTP_SERVER YES CACHE BOOL "Include HTTP server using libmicrohttpd") set(HTTP_CLIENT YES CACHE BOOL "Include HTTP client support using curl") @@ -58,7 +61,7 @@ if (COMPILE_STUBGEN) endif () # setup examples -if (COMPILE_EXAMPLES AND HTTP_SERVER AND HTTP_CLIENT) +if (HTTP_SERVER AND HTTP_CLIENT) add_subdirectory(src/examples) endif() diff --git a/dev/testcoverage.sh b/dev/testcoverage.sh index 64cfa271..bec01900 100755 --- a/dev/testcoverage.sh +++ b/dev/testcoverage.sh @@ -10,7 +10,7 @@ bin/unit_testsuite echo "Generate HTML report" mkdir -p reports -gcovr -r .. -d -e "src/test" --html --html-details -o reports/coverage.html +gcovr -r .. -d -e "build" -e "src/test" --html --html-details -o reports/coverage.html xdg-open reports/coverage.html cd ../dev diff --git a/doc/manpage.in b/doc/manpage.in index a1177b5f..92b54fa5 100644 --- a/doc/manpage.in +++ b/doc/manpage.in @@ -1,6 +1,6 @@ .\" Manpage for jsonrpcstub. .\" Contact psk@autistici.org to correct errors or typos. -.TH man 1 "22 November 2014" "@MAJOR_VERSION@.@MINOR_VERSION@.@PATCH_VERSION@" "jsonrpcstub man page" +.TH man 1 "7 April 2015" "@MAJOR_VERSION@.@MINOR_VERSION@.@PATCH_VERSION@" "jsonrpcstub man page" .SH NAME jsonrpcstub \- genearate stubs for the libjson\-rpc\-cpp framework. .SH SYNOPSIS @@ -8,7 +8,7 @@ jsonrpcstub \- genearate stubs for the libjson\-rpc\-cpp framework. jsonrpcstub specfile.json [\-\-cpp\-server=namespace::ClassName] [\-\-cpp\-server\-file=classqname.h] [\-\-cpp\-client=namespace::ClassName] [\-\-cpp\-client-file=classname.h] [\-\-js\-client=ClassName] -[\-\-js-client-file=classname.js] [\-h] [\-v] +[\-\-js-client-file=classname.js] [\-h] [\-v] [\-\-version] .PP .SH DESCRIPTION @@ -22,12 +22,12 @@ with their corresponding parameters and return values contained in a top\-level .nf [ { - "name": "method_with_positional_params", - "params": [3,4], + "name": "method_with_positional_params", + "params": [3,4], "returns": 7 }, { - "name": "methid_with_named_params", + "name": "method_with_named_params", "params": {"param1": 3, "param2": 4}, "returns": 7 }, @@ -42,25 +42,27 @@ The literal in each \fB"params"\fP and \fB"returns"\fP section defines the corr If the \fb"params"\fP contains an array, the parameters are accepted by position, if it contains an object, they are accepted by name. .SH OPTIONS -.IP -h +.IP \-h Print usage information. -.IP -v +.IP \-v Print verbose information during generation. -.IP --cpp-server=ClassName +.IP \-\-version +Print version info and exit. +.IP \-\-cpp\-server=ClassName Creates a Abstract Server class. Namespaces can be provided using the :: notation (e.g. ns1::ns2::Classname). -.IP --cpp-server-file=filename.h +.IP \-\-cpp\-server\-file=filename.h Defines the filename to use when generating the C++ Abstract Server class. If this is not provided, the lowercase classname is used. -.IP --cpp-client=ClassName +.IP \-\-cpp\-client=ClassName Creates a C++ client class. Namespaces can be provided using the :: notation (e.g. ns1::ns2::Classname). -.IP --cpp-client-file=filename.h +.IP \-\-cpp\-client\-file=filename.h Defines the filename to use when generating the C++ client class. If this is not provided, the lowercase classname is used. -.IP --js-client=ClassName +.IP \-\-js\-client=ClassName Creates a JavaScript client class. No namespaces are supported in this option. -.IP --js-client-file=filename.js +.IP \-\-js\-client-file=filename.js Defines the filename to use when generating the JavaScrip client class. .SH EXAMPLES .PP @@ -104,4 +106,4 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH OR OTHER DEALINGS IN THE SOFTWARE. .SH AUTHOR -Peter Spiess\-Knafl (psk@autistici.org) +Peter Spiess\-Knafl (dev@spiessknafl.at) diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt index caaa0d3b..ed399962 100644 --- a/src/examples/CMakeLists.txt +++ b/src/examples/CMakeLists.txt @@ -1,9 +1,8 @@ file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/gen) -# TODO optimize these scripts, so we will not have to recompile examples every time add_custom_command( - OUTPUT abstractstubserver.h - COMMAND jsonrpcstub ARGS ${CMAKE_CURRENT_SOURCE_DIR}/spec.json --cpp-server=AbstractStubServer --cpp-server-file=${CMAKE_BINARY_DIR}/gen/abstractsubserver.h + OUTPUT ${CMAKE_BINARY_DIR}/gen/abstractstubserver.h + COMMAND jsonrpcstub ARGS ${CMAKE_CURRENT_SOURCE_DIR}/spec.json --cpp-server=AbstractStubServer --cpp-server-file=${CMAKE_BINARY_DIR}/gen/abstractstubserver.h MAIN_DEPENDENCY spec.json DEPENDS jsonrpcstub COMMENT "Generating Server Stubfiles" @@ -11,7 +10,7 @@ add_custom_command( ) add_custom_command( - OUTPUT stubclient.h + OUTPUT ${CMAKE_BINARY_DIR}/gen/stubclient.h COMMAND jsonrpcstub ARGS ${CMAKE_CURRENT_SOURCE_DIR}/spec.json --cpp-client=StubClient --cpp-client-file=${CMAKE_BINARY_DIR}/gen/stubclient.h MAIN_DEPENDENCY spec.json DEPENDS jsonrpcstub @@ -19,8 +18,12 @@ add_custom_command( VERBATIM ) +add_custom_target(common_stubs + DEPENDS ${CMAKE_BINARY_DIR}/gen/abstractstubserver.h ${CMAKE_BINARY_DIR}/gen/stubclient.h +) + add_custom_command( - OUTPUT xbmcremote.h + OUTPUT ${CMAKE_BINARY_DIR}/gen/xbmcremote.h COMMAND jsonrpcstub ARGS ${CMAKE_CURRENT_SOURCE_DIR}/xbmc_remote.json --cpp-client=XbmcRemoteClient --cpp-client-file=${CMAKE_BINARY_DIR}/gen/xbmcremote.h MAIN_DEPENDENCY xbmc_remote.json DEPENDS jsonrpcstub @@ -33,22 +36,21 @@ include_directories(${CMAKE_BINARY_DIR}) include_directories(${JSONCPP_INCLUDE_DIRS}) include_directories(${MHD_INCLUDE_DIRS}) -if (HTTP_SERVER AND HTTP_CLIENT) +if (COMPILE_EXAMPLES) add_executable(simpleserversample simpleserver.cpp) target_link_libraries(simpleserversample jsonrpcserver) add_executable(simpleclientsample simpleclient.cpp) target_link_libraries(simpleclientsample jsonrpcclient) -endif() -if (COMPILE_STUBGEN AND HTTP_SERVER AND HTTP_CLIENT) - add_executable(stubclientsample stubclient.cpp stubclient.h) - target_link_libraries(stubclientsample jsonrpcclient) + if (COMPILE_STUBGEN) + add_executable(stubclientsample stubclient.cpp ${CMAKE_BINARY_DIR}/gen/stubclient.h) + target_link_libraries(stubclientsample jsonrpcclient) - add_executable(stubserversample stubserver.cpp abstractstubserver.h) - target_link_libraries(stubserversample jsonrpcserver) + add_executable(stubserversample stubserver.cpp ${CMAKE_BINARY_DIR}/gen/abstractstubserver.h) + target_link_libraries(stubserversample jsonrpcserver) - add_executable(xbmcremote xbmcremote.cpp xbmcremote.h) - target_link_libraries(xbmcremote jsonrpcclient) + add_executable(xbmcremote xbmcremote.cpp ${CMAKE_BINARY_DIR}/gen/xbmcremote.h) + target_link_libraries(xbmcremote jsonrpcclient) + endif() endif() - diff --git a/src/examples/stubserver.cpp b/src/examples/stubserver.cpp index d5734bba..e4c37a23 100644 --- a/src/examples/stubserver.cpp +++ b/src/examples/stubserver.cpp @@ -8,7 +8,7 @@ ************************************************************************/ #include -#include "gen/abstractsubserver.h" +#include "gen/abstractstubserver.h" #include #include diff --git a/src/jsonrpccpp/CMakeLists.txt b/src/jsonrpccpp/CMakeLists.txt index e52fadf2..34d60e3d 100644 --- a/src/jsonrpccpp/CMakeLists.txt +++ b/src/jsonrpccpp/CMakeLists.txt @@ -65,36 +65,48 @@ target_link_libraries(jsonrpccommon ${JSONCPP_LIBRARIES}) set_target_properties(jsonrpccommon PROPERTIES OUTPUT_NAME jsonrpccpp-common) # setup static common library -add_library(jsonrpccommonStatic STATIC ${jsonrpc_source_common} ${jsonrpc_header} ${jsonrpc_helper_source_common}) -target_link_libraries(jsonrpccommonStatic ${JSONCPP_LIBRARIES}) -set_target_properties(jsonrpccommonStatic PROPERTIES OUTPUT_NAME jsonrpccpp-common) +if (BUILD_STATIC_LIBS) + add_library(jsonrpccommonStatic STATIC ${jsonrpc_source_common} ${jsonrpc_header} ${jsonrpc_helper_source_common}) + target_link_libraries(jsonrpccommonStatic ${JSONCPP_LIBRARIES}) + set_target_properties(jsonrpccommonStatic PROPERTIES OUTPUT_NAME jsonrpccpp-common) +endif() # setup shared client library add_library(jsonrpcclient SHARED ${jsonrpc_source_client} ${jsonrpc_header} ${jsonrpc_header_client} ${client_connector_source}) -add_dependencies(jsonrpcclient jsonrpccommonStatic) +add_dependencies(jsonrpcclient jsonrpccommon) target_link_libraries(jsonrpcclient jsonrpccommon ${client_connector_libs}) set_target_properties(jsonrpcclient PROPERTIES OUTPUT_NAME jsonrpccpp-client) # setup static client library -add_library(jsonrpcclientStatic STATIC ${jsonrpc_source_client} ${jsonrpc_header} ${jsonrpc_header_client} ${client_connector_source}) -target_link_libraries(jsonrpcclientStatic jsonrpccommonStatic ${client_connector_libs}) -set_target_properties(jsonrpcclientStatic PROPERTIES OUTPUT_NAME jsonrpccpp-client) +if (BUILD_STATIC_LIBS) + add_library(jsonrpcclientStatic STATIC ${jsonrpc_source_client} ${jsonrpc_header} ${jsonrpc_header_client} ${client_connector_source}) + target_link_libraries(jsonrpcclientStatic jsonrpccommonStatic ${client_connector_libs}) + set_target_properties(jsonrpcclientStatic PROPERTIES OUTPUT_NAME jsonrpccpp-client) +endif() # setup shared server library add_library(jsonrpcserver SHARED ${jsonrpc_source_server} ${jsonrpc_header} ${jsonrpc_header_server} ${server_connector_source}) -add_dependencies(jsonrpcserver jsonrpccommonStatic) +add_dependencies(jsonrpcserver jsonrpccommon) target_link_libraries(jsonrpcserver jsonrpccommon ${server_connector_libs}) set_target_properties(jsonrpcserver PROPERTIES OUTPUT_NAME jsonrpccpp-server) # setup static server library -add_library(jsonrpcserverStatic STATIC ${jsonrpc_source_server} ${jsonrpc_header} ${jsonrpc_header_server} ${server_connector_source}) -target_link_libraries(jsonrpcserverStatic jsonrpccommonStatic ${server_connector_libs}) -set_target_properties(jsonrpcserverStatic PROPERTIES OUTPUT_NAME jsonrpccpp-server) +if (BUILD_STATIC_LIBS) + add_library(jsonrpcserverStatic STATIC ${jsonrpc_source_server} ${jsonrpc_header} ${jsonrpc_header_server} ${server_connector_source}) + target_link_libraries(jsonrpcserverStatic jsonrpccommonStatic ${server_connector_libs}) + set_target_properties(jsonrpcserverStatic PROPERTIES OUTPUT_NAME jsonrpccpp-server) +endif() + +set(ALL_LIBS jsonrpccommon jsonrpcclient jsonrpcserver) + +if (BUILD_STATIC_LIBS) + list(APPEND ALL_LIBS jsonrpccommonStatic jsonrpcclientStatic jsonrpcserverStatic) +endif() # setup version set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}) set_target_properties( - jsonrpccommon jsonrpccommonStatic jsonrpcclient jsonrpcclientStatic jsonrpcserver jsonrpcserverStatic + ${ALL_LIBS} PROPERTIES VERSION "${VERSION_STRING}" SOVERSION "${SO_VERSION}" ) @@ -114,9 +126,9 @@ if (WIN32) install(DIRECTORY ${CMAKE_SOURCE_DIR}/win32-deps/include DESTINATION .) endif() -install(TARGETS jsonrpccommon jsonrpccommonStatic jsonrpcclient jsonrpcclientStatic jsonrpcserver jsonrpcserverStatic - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib +install(TARGETS ${ALL_LIBS} + LIBRARY DESTINATION lib${LIB_SUFFIX} + ARCHIVE DESTINATION lib${LIB_SUFFIX} RUNTIME DESTINATION bin ) diff --git a/src/jsonrpccpp/client/connectors/httpclient.cpp b/src/jsonrpccpp/client/connectors/httpclient.cpp index f66e2ad4..58590f19 100644 --- a/src/jsonrpccpp/client/connectors/httpclient.cpp +++ b/src/jsonrpccpp/client/connectors/httpclient.cpp @@ -17,6 +17,15 @@ using namespace jsonrpc; +class curl_initializer { + public: + curl_initializer() {curl_global_init(CURL_GLOBAL_ALL);} + ~curl_initializer() {curl_global_cleanup();} +}; + +// See here: http://curl.haxx.se/libcurl/c/curl_global_init.html +static curl_initializer _curl_init = curl_initializer(); + /** * taken from http://stackoverflow.com/questions/2329571/c-libcurl-get-output-into-a-string */ @@ -48,11 +57,16 @@ HttpClient::HttpClient(const std::string& url) throw(JsonRpcException) : url(url) { this->timeout = 10000; + curl = curl_easy_init(); +} + +HttpClient::~HttpClient() +{ + curl_easy_cleanup(curl); } void HttpClient::SendRPCMessage(const std::string& message, std::string& result) throw (JsonRpcException) { - CURL* curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_URL, this->url.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); @@ -89,7 +103,6 @@ void HttpClient::SendRPCMessage(const std::string& message, std::string& result) str << " -> Could not connect to " << this->url; else if(res == 28) str << " -> Operation timed out"; - curl_easy_cleanup(curl); throw JsonRpcException(Errors::ERROR_CLIENT_CONNECTOR, str.str()); } @@ -98,11 +111,8 @@ void HttpClient::SendRPCMessage(const std::string& message, std::string& result) if (http_code != 200) { - curl_easy_cleanup(curl); throw JsonRpcException(Errors::ERROR_RPC_INTERNAL_ERROR, result); } - - curl_easy_cleanup(curl); } void HttpClient::SetUrl(const std::string& url) diff --git a/src/jsonrpccpp/client/connectors/httpclient.h b/src/jsonrpccpp/client/connectors/httpclient.h index 6f87c61e..5e2ef217 100644 --- a/src/jsonrpccpp/client/connectors/httpclient.h +++ b/src/jsonrpccpp/client/connectors/httpclient.h @@ -12,6 +12,7 @@ #include "../iclientconnector.h" #include +#include #include namespace jsonrpc @@ -20,7 +21,7 @@ namespace jsonrpc { public: HttpClient(const std::string& url) throw (JsonRpcException); - + virtual ~HttpClient(); virtual void SendRPCMessage(const std::string& message, std::string& result) throw (JsonRpcException); void SetUrl(const std::string& url); @@ -37,6 +38,7 @@ namespace jsonrpc * @brief timeout for http request in milliseconds */ long timeout; + CURL* curl; }; } /* namespace jsonrpc */ diff --git a/src/jsonrpccpp/client/rpcprotocolclient.cpp b/src/jsonrpccpp/client/rpcprotocolclient.cpp index 97c1224e..dfa9c757 100644 --- a/src/jsonrpccpp/client/rpcprotocolclient.cpp +++ b/src/jsonrpccpp/client/rpcprotocolclient.cpp @@ -21,13 +21,14 @@ const std::string RpcProtocolClient::KEY_RESULT = "result"; const std::string RpcProtocolClient::KEY_ERROR = "error"; const std::string RpcProtocolClient::KEY_ERROR_CODE = "code"; const std::string RpcProtocolClient::KEY_ERROR_MESSAGE = "message"; +const std::string RpcProtocolClient::KEY_ERROR_DATA = "data"; RpcProtocolClient::RpcProtocolClient(clientVersion_t version) : version(version) { } -void RpcProtocolClient::BuildRequest (const std::string &method, const Json::Value ¶meter, std::string &result, bool isNotification) +void RpcProtocolClient::BuildRequest(const std::string &method, const Json::Value ¶meter, std::string &result, bool isNotification) { Json::Value request; Json::FastWriter writer; @@ -35,7 +36,7 @@ void RpcProtocolClient::BuildRequest (const std::string &method, result = writer.write(request); } -void RpcProtocolClient::HandleResponse (const std::string &response, Json::Value& result) throw(JsonRpcException) +void RpcProtocolClient::HandleResponse(const std::string &response, Json::Value& result) throw(JsonRpcException) { Json::Reader reader; Json::Value value; @@ -69,7 +70,7 @@ int RpcProtocolClient::HandleResponse(const Json::Value &value, Json::Value &res return value[KEY_ID].asInt(); } -void RpcProtocolClient::BuildRequest (int id, const std::string &method, const Json::Value ¶meter, Json::Value &result, bool isNotification) +void RpcProtocolClient::BuildRequest(int id, const std::string &method, const Json::Value ¶meter, Json::Value &result, bool isNotification) { if (this->version == JSONRPC_CLIENT_V2) result[KEY_PROTOCOL_VERSION] = "2.0"; @@ -85,6 +86,8 @@ void RpcProtocolClient::BuildRequest (int id, const std::string & void RpcProtocolClient::throwErrorException(const Json::Value &response) { if (response[KEY_ERROR].isMember(KEY_ERROR_MESSAGE) && response[KEY_ERROR][KEY_ERROR_MESSAGE].isString()) + if (response[KEY_ERROR].isMember(KEY_ERROR_DATA)) + throw JsonRpcException(response[KEY_ERROR][KEY_ERROR_CODE].asInt(), response[KEY_ERROR][KEY_ERROR_MESSAGE].asString(), response[KEY_ERROR][KEY_ERROR_DATA]); throw JsonRpcException(response[KEY_ERROR][KEY_ERROR_CODE].asInt(), response[KEY_ERROR][KEY_ERROR_MESSAGE].asString()); throw JsonRpcException(response[KEY_ERROR][KEY_ERROR_CODE].asInt()); } diff --git a/src/jsonrpccpp/client/rpcprotocolclient.h b/src/jsonrpccpp/client/rpcprotocolclient.h index 91fd9eae..268f423c 100644 --- a/src/jsonrpccpp/client/rpcprotocolclient.h +++ b/src/jsonrpccpp/client/rpcprotocolclient.h @@ -69,6 +69,7 @@ namespace jsonrpc { static const std::string KEY_ERROR; static const std::string KEY_ERROR_CODE; static const std::string KEY_ERROR_MESSAGE; + static const std::string KEY_ERROR_DATA; private: clientVersion_t version; diff --git a/src/jsonrpccpp/common/exception.cpp b/src/jsonrpccpp/common/exception.cpp index 4d7e70a3..73b735a4 100644 --- a/src/jsonrpccpp/common/exception.cpp +++ b/src/jsonrpccpp/common/exception.cpp @@ -28,6 +28,17 @@ JsonRpcException::JsonRpcException(int code, const std::string& message) : this->setWhatMessage(); } +JsonRpcException::JsonRpcException(int code, const std::string &message, const Json::Value &data) : + code(code), + message(Errors::GetErrorMessage(code)), + data(data) +{ + if (this->message != "") + this->message = this->message + ": "; + this->message = this->message + message; + this->setWhatMessage(); +} + JsonRpcException::JsonRpcException(const std::string& message) : code(0), message(message) @@ -49,6 +60,11 @@ const std::string& JsonRpcException::GetMessage() const return message; } +const Json::Value& JsonRpcException::GetData() const +{ + return data; +} + const char* JsonRpcException::what() const throw () { return this->whatString.c_str(); @@ -60,6 +76,8 @@ void JsonRpcException::setWhatMessage() { std::stringstream ss; ss << "Exception " << this->code << " : " << this->message; + if (data != Json::nullValue) + ss << ", data: " << data.toStyledString(); this->whatString = ss.str(); } else diff --git a/src/jsonrpccpp/common/exception.h b/src/jsonrpccpp/common/exception.h index d3ad9131..3d5a3b09 100644 --- a/src/jsonrpccpp/common/exception.h +++ b/src/jsonrpccpp/common/exception.h @@ -22,16 +22,15 @@ namespace jsonrpc { public: JsonRpcException(int code); - JsonRpcException(int code, const std::string& message); - + JsonRpcException(int code, const std::string& message, const Json::Value &data); JsonRpcException(const std::string& message); virtual ~JsonRpcException() throw (); int GetCode() const; - const std::string& GetMessage() const; + const Json::Value& GetData() const; virtual const char* what() const throw (); @@ -39,7 +38,7 @@ namespace jsonrpc int code; std::string message; std::string whatString; - + Json::Value data; void setWhatMessage(); }; diff --git a/src/jsonrpccpp/server/rpcprotocolserverv1.cpp b/src/jsonrpccpp/server/rpcprotocolserverv1.cpp index 302f6747..b1818925 100644 --- a/src/jsonrpccpp/server/rpcprotocolserverv1.cpp +++ b/src/jsonrpccpp/server/rpcprotocolserverv1.cpp @@ -31,7 +31,7 @@ void RpcProtocolServerV1::HandleJsonRequest(const Json::Value &req, Json::Value } catch (const JsonRpcException & exc) { - this->WrapError(req, exc.GetCode(), exc.GetMessage(), response); + this->WrapException(req, exc, response); } } else @@ -80,6 +80,12 @@ void RpcProtocolServerV1::WrapError(const Json::Value &request, int code, const } } +void RpcProtocolServerV1::WrapException(const Json::Value &request, const JsonRpcException &exception, Json::Value &result) +{ + this->WrapError(request, exception.GetCode(), exception.GetMessage(), result); + result["error"]["data"] = exception.GetData(); +} + procedure_t RpcProtocolServerV1::GetRequestType(const Json::Value &request) { if (request[KEY_REQUEST_ID] == Json::nullValue) diff --git a/src/jsonrpccpp/server/rpcprotocolserverv1.h b/src/jsonrpccpp/server/rpcprotocolserverv1.h index 07318d1a..0e3d2e78 100644 --- a/src/jsonrpccpp/server/rpcprotocolserverv1.h +++ b/src/jsonrpccpp/server/rpcprotocolserverv1.h @@ -10,6 +10,7 @@ #ifndef JSONRPC_CPP_RPCPROTOCOLSERVERV1_H #define JSONRPC_CPP_RPCPROTOCOLSERVERV1_H +#include #include "abstractprotocolhandler.h" namespace jsonrpc { @@ -23,6 +24,7 @@ namespace jsonrpc { void HandleJsonRequest(const Json::Value &request, Json::Value &response); void WrapResult(const Json::Value& request, Json::Value& response, Json::Value& retValue); void WrapError(const Json::Value& request, int code, const std::string &message, Json::Value& result); + void WrapException(const Json::Value& request, const JsonRpcException& exception, Json::Value& result); procedure_t GetRequestType(const Json::Value& request); }; diff --git a/src/jsonrpccpp/server/rpcprotocolserverv2.cpp b/src/jsonrpccpp/server/rpcprotocolserverv2.cpp index b4c191c1..564b6169 100644 --- a/src/jsonrpccpp/server/rpcprotocolserverv2.cpp +++ b/src/jsonrpccpp/server/rpcprotocolserverv2.cpp @@ -46,7 +46,7 @@ void RpcProtocolServerV2::HandleSingleRequest (const Json::Value &req, Json::Val } catch (const JsonRpcException & exc) { - this->WrapError(req, exc.GetCode(), exc.GetMessage(), response); + this->WrapException(req, exc, response); } } else @@ -107,6 +107,12 @@ void RpcProtocolServerV2::WrapError(const Json::Value &request, int code, const } } +void RpcProtocolServerV2::WrapException(const Json::Value &request, const JsonRpcException &exception, Json::Value &result) +{ + this->WrapError(request, exception.GetCode(), exception.GetMessage(), result); + result["error"]["data"] = exception.GetData(); +} + procedure_t RpcProtocolServerV2::GetRequestType(const Json::Value &request) { if (request.isMember(KEY_REQUEST_ID)) diff --git a/src/jsonrpccpp/server/rpcprotocolserverv2.h b/src/jsonrpccpp/server/rpcprotocolserverv2.h index 861cf8bd..6cdaaaea 100644 --- a/src/jsonrpccpp/server/rpcprotocolserverv2.h +++ b/src/jsonrpccpp/server/rpcprotocolserverv2.h @@ -14,7 +14,7 @@ #include #include -#include +#include #include "abstractprotocolhandler.h" @@ -32,6 +32,7 @@ namespace jsonrpc bool ValidateRequestFields(const Json::Value &val); void WrapResult(const Json::Value& request, Json::Value& response, Json::Value& retValue); void WrapError(const Json::Value& request, int code, const std::string &message, Json::Value& result); + void WrapException(const Json::Value& request, const JsonRpcException &exception, Json::Value& result); procedure_t GetRequestType(const Json::Value& request); private: diff --git a/src/stubgenerator/CMakeLists.txt b/src/stubgenerator/CMakeLists.txt index eb017599..c6a3e3dc 100644 --- a/src/stubgenerator/CMakeLists.txt +++ b/src/stubgenerator/CMakeLists.txt @@ -29,8 +29,8 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") -install(TARGETS jsonrpcstub LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib +install(TARGETS jsonrpcstub LIBRARY DESTINATION lib${LIB_SUFFIX} + ARCHIVE DESTINATION lib${LIB_SUFFIX} RUNTIME DESTINATION bin ) diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 54bf7c08..ed51cf77 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -43,6 +43,10 @@ if (COMPILE_STUBGEN) target_link_libraries(unit_testsuite stubgen) endif() +if (HTTP_CLIENT AND HTTP_SERVER AND COMPILE_STUBGEN) + add_dependencies(unit_testsuite common_stubs) +endif() + add_test(client ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unit_testsuite --run_test=client) add_test(server ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unit_testsuite --run_test=server) add_test(NAME common WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unit_testsuite --run_test=common) diff --git a/src/test/test_client.cpp b/src/test/test_client.cpp index 6626deb1..5fd685b8 100644 --- a/src/test/test_client.cpp +++ b/src/test/test_client.cpp @@ -26,7 +26,7 @@ bool check_exception2(JsonRpcException const&ex) bool check_exception3(JsonRpcException const&ex) { - return ex.GetCode() == Errors::ERROR_RPC_INVALID_REQUEST; + return ex.GetCode() == Errors::ERROR_RPC_INVALID_REQUEST && ex.GetData().size() == 2; } BOOST_AUTO_TEST_SUITE(client) @@ -79,7 +79,7 @@ BOOST_FIXTURE_TEST_CASE(test_client_v2_notification_success, F) BOOST_FIXTURE_TEST_CASE(test_client_v2_errorresponse, F) { - c.SetResponse("{\"jsonrpc\":\"2.0\", \"error\": {\"code\": -32600, \"message\": \"Invalid Request\"}, \"id\": null}"); + c.SetResponse("{\"jsonrpc\":\"2.0\", \"error\": {\"code\": -32600, \"message\": \"Invalid Request\", \"data\": [1,2]}, \"id\": null}"); BOOST_CHECK_EXCEPTION(client.CallMethod("abcd", Json::nullValue), JsonRpcException, check_exception3); } @@ -200,10 +200,10 @@ BOOST_FIXTURE_TEST_CASE(test_client_v1_notification_success, F1) BOOST_FIXTURE_TEST_CASE(test_client_v1_errorresponse, F1) { - c.SetResponse("{\"result\": null, \"error\": {\"code\": -32600, \"message\": \"Invalid Request\"}, \"id\": null}"); + c.SetResponse("{\"result\": null, \"error\": {\"code\": -32600, \"message\": \"Invalid Request\", \"data\": [1,2]}, \"id\": null}"); BOOST_CHECK_EXCEPTION(client.CallMethod("abcd", Json::nullValue), JsonRpcException, check_exception3); - c.SetResponse("{\"result\": null, \"error\": {\"code\": -32600}, \"id\": null}"); + c.SetResponse("{\"result\": null, \"error\": {\"code\": -32600, \"message\": \"Invalid Request\", \"data\": [1,2]}, \"id\": null}"); BOOST_CHECK_EXCEPTION(client.CallMethod("abcd", Json::nullValue), JsonRpcException, check_exception3); } diff --git a/src/test/test_common.cpp b/src/test/test_common.cpp index 3c24c8f4..38138fbc 100644 --- a/src/test/test_common.cpp +++ b/src/test/test_common.cpp @@ -86,6 +86,15 @@ BOOST_AUTO_TEST_CASE(test_exception) BOOST_CHECK_EQUAL(ex3.what(), "addInfo"); BOOST_CHECK_EQUAL(ex3.GetMessage(), "addInfo"); BOOST_CHECK_EQUAL(ex3.GetCode(), 0); + + Json::Value data; + data.append(13); + data.append(41); + JsonRpcException ex4(Errors::ERROR_RPC_INTERNAL_ERROR, "internal error", data); + BOOST_CHECK_EQUAL(ex4.GetData().size(), 2); + BOOST_CHECK_EQUAL(ex4.GetData()[0].asInt(), 13); + BOOST_CHECK_EQUAL(ex4.GetData()[1].asInt(), 41); + } bool check_exception1(JsonRpcException const & ex) diff --git a/src/test/test_integration.cpp b/src/test/test_integration.cpp index 35deb725..a39b80b7 100644 --- a/src/test/test_integration.cpp +++ b/src/test/test_integration.cpp @@ -14,7 +14,7 @@ #include #include -#include "gen/abstractsubserver.h" +#include "gen/abstractstubserver.h" #include "gen/stubclient.h" using namespace jsonrpc; diff --git a/src/test/test_server.cpp b/src/test/test_server.cpp index 3db63964..7856b1ca 100644 --- a/src/test/test_server.cpp +++ b/src/test/test_server.cpp @@ -159,6 +159,7 @@ BOOST_FIXTURE_TEST_CASE(test_server_v2_method_error, F) c.SetRequest("{\"jsonrpc\":\"2.0\", \"id\": 1, \"method\": \"exceptionMethod\"}"); BOOST_CHECK_EQUAL(c.GetJsonResponse()["error"]["code"], -32099); BOOST_CHECK_EQUAL(c.GetJsonResponse()["error"]["message"], "User exception"); + BOOST_CHECK_EQUAL(c.GetJsonResponse()["error"]["data"][0], 33); BOOST_CHECK_EQUAL(c.GetJsonResponse().isMember("result"),false); } diff --git a/src/test/testserver.cpp b/src/test/testserver.cpp index 1e402a33..589a8e09 100644 --- a/src/test/testserver.cpp +++ b/src/test/testserver.cpp @@ -53,7 +53,9 @@ void TestServer::exceptionMethod(const Json::Value &request, Json::Value &respon { (void)request; (void)response; - throw JsonRpcException(-32099, "User exception"); + Json::Value data; + data.append(33); + throw JsonRpcException(-32099, "User exception", data); } void TestServer::initCounter(const Json::Value &request)