使用C的原始libcurl JSON PUT请求

时间:2014-04-21 18:55:31

标签: c json curl put

我目前正在编写类似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);
}

3 个答案:

答案 0 :(得分:1)

您不应该使用CURLOPT_CONNECT_ONLY选项或curl_easy_send()函数,这些函数旨在用于自定义的非HTTP协议。

有关如何使用libcurl执行PUT请求的示例,请参阅this page。基本上,您希望启用CURLOPT_UPLOADCURLOPT_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