Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON request using cURL in C++

Tags:

c++

json

curl

I have following command in cURL, this works fine in terminal.

curl --insecure -X POST --data "username=testuser&password=12345" https://m360-prototype.herokuapp.com/sessions.json

This json api sends a few parameters like these-- "status":{"code":200,"message":"OK"}

Now i want my c++ program to execute it. I have set up and used cURL before for ftp upload and download from ftp examples. But i did not find any example to do this.

I want to know how can i pass username and password parameters to the json api, and get response from it.

Here is what i have tried in some code I found on web, it didnt work.

struct curl_slist *headers=NULL; // init to NULL is important

headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "charsets: utf-8");

curl = curl_easy_init();
if(curl) {
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    curl_easy_setopt(curl, CURLOPT_URL, "https://m360-prototype.herokuapp.com/sessions.json");
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "username=testuser&password=12345");

    curl_easy_setopt(curl, CURLOPT_HTTPGET,1);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    res = curl_easy_perform(curl);

    if(CURLE_OK == res) {
        char *ct;
        /* ask for the content-type */
        res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
        if((CURLE_OK == res) && ct)
            printf("We received Content-Type: %s\n", ct);
    }
}

How do i get response from the web? i know it will be in the form of strings, and i am capable enough to parse it.

I am looking up all the params (--insecure, -X, POST, --data)passed to the curl command executed on terminal, so as to get little idea about what i have to do.

I am a graphics programmer :) not so good with web services. I'd appreciate any help.

like image 287
2am Avatar asked Apr 14 '14 05:04

2am


2 Answers

The Curl command has an option --libcurl . It should help you figure out the correct libcurl code to use.

Add this option to the end of your working Curl command along with a filename and Curl will output a working libcurl c example of your Curl command.

curl --insecure -X POST --data "username=testuser&password=12345" https://m360-prototype.herokuapp.com/sessions.json --libcurl test.cpp

Compile the outputted code with the -lcurl option.

g++ -lcurl test.cpp -o testcurl

Below is an example of the libcurl code I use to POST JSON from c++ to node.js.

  CURLcode ret;
  CURL *hnd;
  struct curl_slist *slist1;
  std::string jsonstr = "{\"username\":\"bob\",\"password\":\"12345\"}";

  slist1 = NULL;
  slist1 = curl_slist_append(slist1, "Content-Type: application/json");

  hnd = curl_easy_init();
  curl_easy_setopt(hnd, CURLOPT_URL, "https://example.com/");
  curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
  curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, jsonstr.c_str());
  curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/7.38.0");
  curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, slist1);
  curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
  curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST");
  curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);

  ret = curl_easy_perform(hnd);

  curl_easy_cleanup(hnd);
  hnd = NULL;
  curl_slist_free_all(slist1);
  slist1 = NULL;

Node.js (Express) receives the JSON as:

{ username: 'bob', password: '12345' }

like image 111
Rahim Khoja Avatar answered Oct 10 '22 20:10

Rahim Khoja


To send post data, you need to tell curl where it is. Something like:

std::string data = "username=testuser&password=12345";
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, data.length());
curl_easy_setopt(curl, CURLOPT_POST, 1);

To read the response into memory, it is a bit more complicated - you need to have a callback function that is called to store the data. There is an example of this in the curl docs, although you could just append the results into a std::string, rather than having your own chunk structure like they do.

like image 39
The Dark Avatar answered Oct 10 '22 22:10

The Dark