使用 libcurl 在 PUT 请求中发送字符串
我的代码如下所示:
curl = curl_easy_init();
if (curl) {
headers = curl_slist_append(headers, client_id_header);
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, "127.0.0.1/test.php");
curl_easy_setopt(curl, CURLOPT_PUT, 1L);
res = curl_easy_perform(curl);
res = curl_easy_send(curl, json_struct, strlen(json_struct), &io_len);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
这不起作用,程序永远挂起。
在 test.php 中,这些是我得到的请求标头:
array(6) {
["Host"]=>
string(9) "127.0.0.1"
["Accept"]=>
string(3) "*/*"
["Transfer-Encoding"]=>
string(7) "chunked"
["X-ClientId"]=>
string(36) "php_..."
["Content-Type"]=>
string(16) "application/json"
["Expect"]=>
string(12) "100-continue"
}
但正文是空的,意味着请求中没有发送任何 json 数据。
我想用 libcurl 做的实际上就是这些命令行脚本:
curl -X PUT -H "Content-Type: application/json" -d '... some json ...' 127.0.0.1/test.php
My code looks like this:
curl = curl_easy_init();
if (curl) {
headers = curl_slist_append(headers, client_id_header);
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, "127.0.0.1/test.php");
curl_easy_setopt(curl, CURLOPT_PUT, 1L);
res = curl_easy_perform(curl);
res = curl_easy_send(curl, json_struct, strlen(json_struct), &io_len);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
Which doesnt work, the program just hangs forever.
In test.php these are the request headers I get:
array(6) {
["Host"]=>
string(9) "127.0.0.1"
["Accept"]=>
string(3) "*/*"
["Transfer-Encoding"]=>
string(7) "chunked"
["X-ClientId"]=>
string(36) "php_..."
["Content-Type"]=>
string(16) "application/json"
["Expect"]=>
string(12) "100-continue"
}
But the body is empty, means, no json data is sent with the request.
What I want to do with libcurl is actually nothing else then these command line script:
curl -X PUT -H "Content-Type: application/json" -d '... some json ...' 127.0.0.1/test.php
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
明白了:)
不要使用
发出自定义请求并将数据作为 POSTFIELDS 发送:
Got it :)
Dont use
Make a custom request and send the data as POSTFIELDS:
CURLOPT_PUT
已被弃用,并且已经有一段时间了。您应该使用CURLOPT_UPLOAD
。对于 HTTP 未知数量的数据,您应该使用分块传输编码。
CURLOPT_UPLOAD
文档说:CURLOPT_PUT
is deprecated, and has been for a while. You should useCURLOPT_UPLOAD
.For unknown amounts of data with HTTP, you should be using chunked transfer encoding. The
CURLOPT_UPLOAD
docs say:这对我不起作用。
我必须使用 UPLOAD 和 PUT 才能正确执行此操作。
对我有用的答案在这里:
如何在不使用文件指针的情况下在 libcurl 中发送长 PUT 数据?
您需要 READFILE 的回调函数,然后使用它来复制您的回调中提供的指针curl 的数据。
最终对我有用的是确保根据您的负载使用 CURLOPT_INFILESIZE 或 CURLOPT_INFILESIZE_LARGE 设置文件大小。否则你会在背景故事中发现问题。
背景故事:
我期待一个 JSON 请求,但使用 PUT CURL 选项或此自定义请求方法得到与通过控制台执行此操作相同的结果
另一方面,在控制台上发出相同的请求并添加数据字段 (PUT -d "" URL)让我得到了我想要的:
总之,看起来我需要弄清楚 CURL 选项,它的作用相当于 PUT -d ""。您还可以看到两种响应之间的差异,在一种情况下返回的是 HTML 并且连接已关闭。在另一种情况下,内容是 JSON 并且连接保持活动状态。
根据我在错误 411 上发现的内容:
http://www.checkupdown.com/status /E411.html
问题在于,无论您使用带有 CURLOPT_PUT 的 CURLOPT_UPLOAD 还是 CUSTOM 选项,都需要设置内容长度。
因此,如果您有数据流,则似乎必须使用 READDATA 和 READFUNCTION 选项来确定数据的长度。
管理员注意:
请记住,需要代表 50 才能发表评论,因此我别无选择,只能单独发表帖子以便进行交流。因此,当您考虑像过去那样删除这些帖子时,请考虑这一点。
This one did not work for me.
I HAD to use UPLOAD and PUT to perform this correctly.
The answer that worked for me is here:
How do I send long PUT data in libcurl without using file pointers?
You need the callback function for READFILE and then use that to copy your data to the pointer curl offers in that callback.
What ultimately worked for me was to make sure I set the FILE size using either CURLOPT_INFILESIZE or CURLOPT_INFILESIZE_LARGE depending on your payload. Otherwise you get the problem posted in the backstory.
Backstory:
I was expecting a JSON request but using either the PUT CURL option or this custom request approach I get the same result as doing this via console
On the other hand making the same request on the console and adding a data field (PUT -d "" URL)gets me what I want:
In summary it looks like I need to figure out the CURL options that'll do the equivalent of PUT -d "". Also you can see the difference between both response, in one case the return is HTML and the connection is closed. In the other case the Content is JSON and the connection is kept alive.
Based on what I've found on error 411:
http://www.checkupdown.com/status/E411.html
The problem is that the content length needs to be set regardless of whether you use CURLOPT_UPLOAD with CURLOPT_PUT or the CUSTOM option.
So, if you have a stream of data you have it seems you HAVE to use the READDATA and READFUNCTION options to determine the length of your data.
Note to admin:
Keep in mind rep 50 is REQUIRED to post comments so I HAVE NO CHOICE but to make separate posts in order to communicate. So consider this when you are thinking about deleting these posts as it has been done in the past.