我目前正在编写类似REST的客户端,只需要执行PUT请求。
问题:
运行该程序并没有在URL的API上给我正确的结果,我不知道为什么。
使用curl_easy_perform(curl)不会在调用时抛出错误。但是,未在URL的API上生成预期结果。
使用curl_easy_send(curl,..,..,..)会抛出:不支持的协议错误
假设:
我假设我使用curl_easy_opts的顺序是个问题?我甚至错过了几条关键线?
我一直在这里阅读其他人如何做PUT请求并一直在使用他们的方法。
计划摘要:
我的程序提示用户输入一些字符串/字符数据,从中我自己构造字符串,例如标题和有效负载。标头和有效负载都是JSON格式,但有效负载只是一个字符串(在这种情况下,char * str =(char *)mallo ...等)。标题的构造方式如下所示。
我的标题正在使用
构建struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: application/json");
//there is more content being appended to the header
CURL函数调用:
//init winsock stuff
curl_global_init(CURL_GLOBAL_ALL);
//get a curl handle
curl = curl_easy_init();
if(curl){
//append the headers
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
//specify the target URL
curl_easy_setopt(curl, CURLOPT_URL, url);
//connect ( //i added this here since curl_easy_send() says it requires it. )
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY,1L);
//specify the request (PUT in our case)
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
//append the payload
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload);
res = curl_easy_perform(curl);
//res = curl_easy_send(curl, payload, strlen(payload),&iolen);
//check for errors
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
curl_easy_cleanup(curl);
}
答案 0 :(得分:1)
您不应该使用CURLOPT_CONNECT_ONLY
选项或curl_easy_send()
函数,这些函数旨在用于自定义的非HTTP协议。
有关如何使用libcurl执行PUT请求的示例,请参阅this page。基本上,您希望启用CURLOPT_UPLOAD
和CURLOPT_PUT
选项来表示您正在执行PUT请求并启用上传请求的正文,然后设置{{1} }和CURLOPT_READDATA
选项告诉libcurl如何读取您上传的数据以及数据的大小。
在您的情况下,如果您已经将数据存储在内存中,那么您不需要从文件中读取数据,并且您可以在阅读回调中CURLOPT_INFILESIZE_LARGE
。
下面复制的示例代码:
memcpy()
答案 1 :(得分:0)
我同意,不要使用CUSTOMREQUEST。我在这里看到的每一个与PUT和CURL相关的细节都是你需要设置文件大小,否则你会得到HTTP错误411。 使用CURLOPT_INFILESIZE或CURLOPT_INFILESIZE_LARGE。 在这里查看更多详细信息:
How do I send long PUT data in libcurl without using file pointers?
答案 2 :(得分:0)
我知道这是一个非常老的问题,但是如果有人想将libcurl与GLib和json-glib一起使用以发送带有PUT请求的JSON。 下面的代码对我有用:
#include <curl/curl.h>
#include <json-glib/json-glib.h>
//this is callback function for CURLOPT_READFUNCTION:
static size_t
curlPutJson ( void *ptr, size_t size, size_t nmemb, void *_putData )
{
GString *putData = ( GString * ) _putData;
size_t realsize = ( size_t ) putData->len;
memcpy ( ptr, putData->str, realsize );
return realsize;
}
/*now inside main or other function*/
//json_to_string ( jsonNode, FALSE ) is from json-glib to stringify JSON
//created in jsonNode
GString *putData = g_string_new ( json_to_string ( mainNode, FALSE ) );
//now goes curl as usual: headers, url, other options and so on
//and 4 most important lines
curl_easy_setopt ( curl, CURLOPT_READFUNCTION, curlPutJson );
curl_easy_setopt ( curl, CURLOPT_UPLOAD, 1L );
curl_easy_setopt ( curl, CURLOPT_READDATA, putData ); //GString
curl_easy_setopt ( curl, CURLOPT_INFILESIZE, putData->len ); //type long