卷曲 PUT JSON 正文在处理数组时出现问题
我正在开发一个与 REST API 通信的库。到目前为止,我为 PUT 调用编写的方法已经有效。
void Command::put(const std::string url, const std::string body)
{
CURLcode ret;
struct curl_slist *slist1;
slist1 = NULL;
// slist1 = curl_slist_append(slist1, "Content-Type: multipart/form-data;");
slist1 = curl_slist_append(slist1, "Content-Type: application/json;");
curl = curl_easy_init();
if(curl)
{
curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 102400L);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)12);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist1);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.79.1");
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
curl_easy_setopt(curl, CURLOPT_SSH_KNOWNHOSTS, "/Users/$USER/.ssh/known_hosts");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_easy_setopt(curl, CURLOPT_FTP_SKIP_PASV_IP, 1L);
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
ret = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl = NULL;
curl_slist_free_all(slist1);
slist1 = NULL;
}
curl_easy_cleanup(curl);
curl = nullptr;
curl_slist_free_all(slist1);
slist1 = NULL;
}
但是,它似乎不适用于数组。下面是三个调试 put 调用及其输出。前两个有效。第三个没有。
// *** DEBUG ***
commandWrapper->put(
"http://192.168.1.7/api/x1CAh16Nr8NcKwgkUMVbyZX3YKFQrEaMAj5pFz0Z/lights/6/state", "{\"on\":true}");
commandWrapper->put(
"http://192.168.1.7/api/x1CAh16Nr8NcKwgkUMVbyZX3YKFQrEaMAj5pFz0Z/lights/6/state", "{\"bri\":123}");
commandWrapper->put(
"http://192.168.1.7/api/x1CAh16Nr8NcKwgkUMVbyZX3YKFQrEaMAj5pFz0Z/lights/6/state", "{\"xy\":[0.04,0.98]}");
[{"success":{"/lights/6/state/on":true}}]
[{"success":{"/lights/6/state/bri":123}}]
[{"error":{"type":2,"address":"/lights/6/state","description":"body contains invalid json"}}]2022-04-02T02:56:47.220Z - Living Room 1 - Status: 0
我有点不知道如何继续。我验证了该命令在命令行上确实有效。
I'm developing a library that communicates with a REST API. The method I wrote for PUT calls has worked up until this point.
void Command::put(const std::string url, const std::string body)
{
CURLcode ret;
struct curl_slist *slist1;
slist1 = NULL;
// slist1 = curl_slist_append(slist1, "Content-Type: multipart/form-data;");
slist1 = curl_slist_append(slist1, "Content-Type: application/json;");
curl = curl_easy_init();
if(curl)
{
curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 102400L);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)12);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist1);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.79.1");
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
curl_easy_setopt(curl, CURLOPT_SSH_KNOWNHOSTS, "/Users/$USER/.ssh/known_hosts");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_easy_setopt(curl, CURLOPT_FTP_SKIP_PASV_IP, 1L);
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
ret = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl = NULL;
curl_slist_free_all(slist1);
slist1 = NULL;
}
curl_easy_cleanup(curl);
curl = nullptr;
curl_slist_free_all(slist1);
slist1 = NULL;
}
However, it seems to not work with arrays. Below are three debug put calls and their output. The first two work. The third does not.
// *** DEBUG ***
commandWrapper->put(
"http://192.168.1.7/api/x1CAh16Nr8NcKwgkUMVbyZX3YKFQrEaMAj5pFz0Z/lights/6/state", "{\"on\":true}");
commandWrapper->put(
"http://192.168.1.7/api/x1CAh16Nr8NcKwgkUMVbyZX3YKFQrEaMAj5pFz0Z/lights/6/state", "{\"bri\":123}");
commandWrapper->put(
"http://192.168.1.7/api/x1CAh16Nr8NcKwgkUMVbyZX3YKFQrEaMAj5pFz0Z/lights/6/state", "{\"xy\":[0.04,0.98]}");
[{"success":{"/lights/6/state/on":true}}]
[{"success":{"/lights/6/state/bri":123}}]
[{"error":{"type":2,"address":"/lights/6/state","description":"body contains invalid json"}}]2022-04-02T02:56:47.220Z - Living Room 1 - Status: 0
I'm a little lost on how to proceed. I verified that this command does work on the command line.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要更改此行:
改为:
或者,只需完全省略
CURLOPT_POSTFIELDSIZE_LARGE
,因为在这种情况下body.c_str()
是指向以 null 结尾的字符串的指针。卷曲可以为您决定尺寸。JSON
{xy:[0.04,0.98]}
为 16 个字符,比您声明的 12 个字符长,因此您在传输过程中截断了 JSON,这就是服务器认为它无效的原因。{"on":true}
和{"bri":123}
都是 11 个字符(如果算上空终止符则为 12 个字符),因此它们不会被截断。You need to change this line:
To this instead:
Or, simply omit
CURLOPT_POSTFIELDSIZE_LARGE
completely, sincebody.c_str()
is a pointer to a null-terminated string in this situation. Curl can determinant the size for you.The JSON
{xy:[0.04,0.98]}
is 16 characters, longer than the 12 characters you are claiming, so you are truncating the JSON during transmission, which is why the server thinks it is invalid. Both{"on":true}
and{"bri":123}
are 11 characters (12 if you count the null terminator), so they are not truncated.