为啥 JsonCpp http 客户端在 201 响应代码上失败?

Posted

技术标签:

【中文标题】为啥 JsonCpp http 客户端在 201 响应代码上失败?【英文标题】:Why does JsonCpp http client fail on a 201 response code?为什么 JsonCpp http 客户端在 201 响应代码上失败? 【发布时间】:2019-08-14 09:34:28 【问题描述】:

使用json-rpc-cpp 库,我正在使用wallet RPC 创建一个EOS 钱包。

HttpClient *temp = new HttpClient("http://127.0.0.1:30031/v1/wallet/create"); 

string res;
string str = "testwallet1";
temp->SendRPCMessage(str, res);
cout<<"res : "<<res<<endl;

它正在成功创建钱包,但之后我收到以下异常。

unknown file: Failure
C++ exception with description "Exception -32603 : INTERNAL_ERROR: : "PW5JcEu7jTXd7XUYLWkPuCUbr1pqBhusqRFfhSVToqUNcDuZ3oeYK"" thrown in the test body.

我发现HttpClient 收到了 201 响应代码。我不知道如何避免这种异常。有人知道吗?

【问题讨论】:

【参考方案1】:

该问题是由 HttpClient::SendRPCMessage() 实现中的错误引起的。

在内部,HttpClient 使用 libcurl 进行 HTTP 处理,在SendRPCMessage() 实现的最后,检查curl_easy_perform() 是否成功:

long http_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);

if (http_code != 200) 
  throw JsonRpcException(Errors::ERROR_RPC_INTERNAL_ERROR, result);

如您所见,SendRPCMessage()ANY 200 以外的 HTTP 响应代码抛出异常。但 per the HTTP standard,ALL 2xx 响应代码表示成功,而不是只有 200。在这种情况下,response code 201 表示:

10.2.2 201 创建

请求已完成并导致创建新资源。 新创建的资源可以由响应实体中返回的 URI 引用,具有最具体的 URI对于 Location 标头字段给出的资源。响应应该包括一个实体,其中包含资源特征和位置列表,用户或用户代理可以从中选择最合适的一个。实体格式由 Content-Type 标头字段中给出的媒体类型指定。源服务器必须在返回 201 状态码之前创建资源。如果无法立即执行该操作,则服务器应该以 202 (Accepted) 响应来响应。

201 响应可能包含一个 ETag 响应头字段,指示刚刚创建的请求变体的实体标签的当前值,请参阅section 14.19。

这显然是SendRPCMessage()的实现逻辑错误。 http_code 的检查应该更像这样:

if ((http_code / 100) != 2)

这会将所有 2xx 响应代码视为成功。

我已经向 json-rpc-cpp 的作者提交了一份错误报告:

#278 HttpClient::SendRPCMessage() throws ERROR_RPC_INTERNAL for successful HTTP responses

【讨论】:

【参考方案2】:

201 基本表示你的请求处理成功了。正如this source 解释的那样:

201 CREATED 请求已完成,并导致创建一个或多个新资源。

请求创建的主要资源由以下任一标识 响应中的 Location 标头字段,或者,如果没有 Location 字段 通过有效的请求 URI 接收到。

201 响应负载通常描述并链接到 创建的资源。请参阅 RFC7231 的第 7.2 节以了解 验证器标头字段的含义和用途,例如 ETag 和 Last-Modified,在 201 响应中。

当对响应数据进行任何进一步处理时,必须抛出异常。 如果没有更多信息,我无法说出究竟是什么原因造成的。

【讨论】:

以上是关于为啥 JsonCpp http 客户端在 201 响应代码上失败?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 解析Json——jsoncpp

C++ jsoncpp 输出名称和值

如何在安卓ndk工程中引入jsoncpp

语法错误 (-201) 为啥?

jsoncpp 解码编码 中文为空 乱码问题

在C++环境中使用JsonCpp读写Json数据