Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ POST request with cURL + JSON Lib

Tags:

c++

json

curl

c++11

I would like to do a POST request using cURL. I am using this (github:nlohmann/json) library to handle my JSON object creation. I receive the HTTP 200 Response, but the POST data is not being appended.

When calling std::cout<< json_data.dump() << std::endl; I receive a well-formed JSON.

{
    "a": [
        {
            "c": "0",
            "d": "0",
            "e": "0",
            "f": "0",
            "g": "1506961983",
            "h": "1506961986",
            "i": "3"
        },
        {
            "c": "1",
            "d": "2",
            "e": "1",
            "f": "1",
            "g": "1506961987",
            "h": "1506961991",
            "i": "4"
        }
    ],
    "b": "test"
}

I use this to append my data.

   struct curl_slist *headers=NULL; 
   headers = curl_slist_append(headers, "Accept: application/json");  
   headers = curl_slist_append(headers, "Content-Type: application/json");
   headers = curl_slist_append(headers, "charset: utf-8"); 
   curl_easy_setopt(curl, CURLOPT_POSTFIELDS,json_data.dump().c_str());

Documentation curl_easy_setopt documentation

If I look into my AWS logs. It says:

{
  "format": "json",
  "payload": 5,
  "qos": 0,
  "timestamp": 1506961394810,
  "topic": "test_topic"
}

Why is it showing the value of 5 instead of my JSON object?

Thanks for help, if anyone knows why.

like image 463
zer02 Avatar asked Dec 21 '25 03:12

zer02


1 Answers

On this line:

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data.dump().c_str());

The string object returned by dump() is temporary and destroyed when curl_easy_setopt() exits, thus leaving CURLOPT_POSTFIELDS with a dangling pointer that may or may not still be pointing to the JSON data in memory by the time libCURL tries to post it.

Per the CURLOPT_POSTFIELDS documentation:

The data pointed to is NOT copied by the library: as a consequence, it must be preserved by the calling application until the associated transfer finishes. This behaviour can be changed (so libcurl does copy the data) by setting the CURLOPT_COPYPOSTFIELDS option.

So, you need to either:

  • change CURLOPT_POSTFIELDS to CURLOPT_COPYPOSTFIELDS:

    curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, json_data.dump().c_str());
    
  • save the result of json_data.dump() to a local variable that does not go out of scope until after curl_easy_perform() exits:

    std::string json = json_data.dump();
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json.c_str());
    ...
    
like image 109
Remy Lebeau Avatar answered Dec 22 '25 16:12

Remy Lebeau



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!