Curl command line operation, C ++ curl library not

I am trying to execute some request through the curl library from C ++. I can successfully execute my request and get the correct answer through the command line but I can't get the correct answer through C ++ code . My command line command looks like this:

curl -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' -H 'Authorization: <some_hash_value>' -k <my_full_url> -data '<my_json_string>' 

It works great. Now I am trying to execute the same request in C ++ code. My code is as follows:

 void performRequest(const std::string& json, const void* userData, CallbackFunction callback) { 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, (std::string("Authorization: ") + m_authorization).c_str()); CURL* curlHandle = curl_easy_init(); if (!curlHandle) { std::cerr << "Curl handler initialization failed"; } curl_easy_setopt(curlHandle, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(curlHandle, CURLOPT_HTTPHEADER, headers); // specify target URL, and note that this URL should include a file name, not only a directory curl_easy_setopt(curlHandle, CURLOPT_URL, m_url.c_str()); // enable uploading curl_easy_setopt(curlHandle, CURLOPT_UPLOAD, 1L); // set HTTP method to POST curl_easy_setopt(curlHandle, CURLOPT_CUSTOMREQUEST, "POST"); // set json data; I use EXACTLY the same string as in command line curl_easy_setopt(curlHandle, CURLOPT_COPYPOSTFIELDS, json.c_str()); // set data size curl_easy_setopt(curlHandle, CURLOPT_POSTFIELDSIZE_LARGE, json.size()); // set user data for getting it in response curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, userData); // pointer to a custom struct // set callback function for getting response curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, callback); // some callback // send request curl_easy_perform(curlHandle); curl_easy_cleanup(curlHandle); curl_slist_free_all(headers); } 

However, for some reason, I get an error in the response from the server, from which I can assume that my code request is not equivalent to the command line command. It seems that the body is not sent. I cannot see my Json body request when I use CURLOPT_DEBUGFUNCTION to reset debug information.

What is the problem? What am I doing wrong? Any ideas?

+7
c ++ json c curl libcurl
source share
3 answers

The problem was resolved in the Rocki and drew010 tanks .

  • I deleted the instructions CURLOPT_CUSTOMREQUEST , CURLOPT_UPLOAD and CURLOPT_NOSIGNAL since they are not needed.
  • I also deleted the line for setting CURLOPT_POSTFIELDSIZE_LARGE , although it works fine if it was set before setting CURLOPT_COPYPOSTFIELDS . If the size has not been set before CURLOPT_COPYPOSTFIELDS , it is assumed that the data is a zero-terminated string; otherwise, the saved size informs the library about the number of bytes to copy. In any case, the size should not be changed after CURLOPT_COPYPOSTFIELDS , unless another parameter CURLOPT_POSTFIELDS or CURLOPT_COPYPOSTFIELDS . (See: curl.haxx.se/libcurl/c/CURLOPT_COPYPOSTFIELDS.html )
+1
source share

Here is an example of code that should work for you.

Note that I:

  • Removed CURLOPT_UPLOAD , because it doesn’t look like you are actually downloading something, but just doing a simple POST .

  • Changed CURLOPT_CUSTOMREQUEST to CURLOPT_POST (not so that it matters), but I find it cleaner.

  • CURLOPT_POSTFIELDSIZE_LARGE and CURLOPT_COPYPOSTFIELDS

  • CURLOPT_WRITEDATA line CURLOPT_WRITEDATA for this sample code.

I tested the following only by connecting to an instance of nc -l localhost 80

  static size_t callback(char *ptr, size_t size, size_t nmemb, void *userdata) { string s(ptr); cout << s << endl; return size * nmemb; } int main(int argc, char** argv) { string m_authorization("PWNED"); string m_url("http://localhost"); string m_json("{}"); curl_global_init(CURL_GLOBAL_ALL); CURL* curlHandle = curl_easy_init(); struct curl_slist* headers = nullptr; headers = curl_slist_append(headers, "Accept: application/json"); headers = curl_slist_append(headers, "Content-Type: application/json"); headers = curl_slist_append(headers, (std::string("Authorization: ") + m_authorization).c_str()); curl_easy_setopt(curlHandle, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(curlHandle, CURLOPT_HTTPHEADER, headers); // specify target URL, and note that this URL should include a file name, not only a directory curl_easy_setopt(curlHandle, CURLOPT_URL, m_url.c_str()); // <= You are not uploading anything actually, this is a simple POST with payload // enable uploading // curl_easy_setopt(curlHandle, CURLOPT_UPLOAD, 1L); // set HTTP method to POST curl_easy_setopt(curlHandle, CURLOPT_POST, 1L); // set data size before copy curl_easy_setopt(curlHandle, CURLOPT_POSTFIELDSIZE_LARGE, m_json.size()); // set json data; I use EXACTLY the same string as in command line curl_easy_setopt(curlHandle, CURLOPT_COPYPOSTFIELDS, m_json.c_str()); // set user data for getting it in response // curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, userData); // pointer to a custom struct // set callback function for getting response curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, callback); // some callback // send request curl_easy_perform(curlHandle); curl_slist_free_all(headers); curl_easy_cleanup(curlHandle); curl_global_cleanup(); return 0; } 
+1
source share

In windows you should launch winsock stuff using the function below

 curl_global_init(CURL_GLOBAL_ALL); 
+1
source share

All Articles