Skip to content

Instantly share code, notes, and snippets.

@connormanning
Last active August 11, 2022 04:35
Show Gist options
  • Save connormanning/41efa6075515019e499c to your computer and use it in GitHub Desktop.
Save connormanning/41efa6075515019e499c to your computer and use it in GitHub Desktop.
Curl HTTP GET and JsonCpp parsing - basic functionality
#include <cstdint>
#include <iostream>
#include <memory>
#include <string>
#include <curl/curl.h>
#include <json/json.h>
namespace
{
std::size_t callback(
const char* in,
std::size_t size,
std::size_t num,
std::string* out)
{
const std::size_t totalBytes(size * num);
out->append(in, totalBytes);
return totalBytes;
}
}
int main()
{
const std::string url("http://date.jsontest.com/");
CURL* curl = curl_easy_init();
// Set remote URL.
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
// Don't bother trying IPv6, which would increase DNS resolution time.
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
// Don't wait forever, time out after 10 seconds.
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
// Follow HTTP redirects if necessary.
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
// Response information.
long httpCode(0);
std::unique_ptr<std::string> httpData(new std::string());
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);
// Hook up data container (will be passed as the last parameter to the
// callback handling function). Can be any pointer type, since it will
// internally be passed as a void pointer.
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
// Run our HTTP GET command, capture the HTTP response code, and clean up.
curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
curl_easy_cleanup(curl);
if (httpCode == 200)
{
std::cout << "\nGot successful response from " << url << std::endl;
// Response looks good - done using Curl now. Try to parse the results
// and print them out.
Json::Value jsonData;
Json::Reader jsonReader;
if (jsonReader.parse(*httpData.get(), jsonData))
{
std::cout << "Successfully parsed JSON data" << std::endl;
std::cout << "\nJSON data received:" << std::endl;
std::cout << jsonData.toStyledString() << std::endl;
const std::string dateString(jsonData["date"].asString());
const std::size_t unixTimeMs(
jsonData["milliseconds_since_epoch"].asUInt64());
const std::string timeString(jsonData["time"].asString());
std::cout << "Natively parsed:" << std::endl;
std::cout << "\tDate string: " << dateString << std::endl;
std::cout << "\tUnix timeMs: " << unixTimeMs << std::endl;
std::cout << "\tTime string: " << timeString << std::endl;
std::cout << std::endl;
}
else
{
std::cout << "Could not parse HTTP data as JSON" << std::endl;
std::cout << "HTTP data was:\n" << *httpData.get() << std::endl;
return 1;
}
}
else
{
std::cout << "Couldn't GET from " << url << " - exiting" << std::endl;
return 1;
}
return 0;
}
Got successful response from http://date.jsontest.com/
Successfully parsed JSON data
JSON data received:
{
"date" : "03-09-2015",
"milliseconds_since_epoch" : 1425938476314,
"time" : "10:01:16 PM"
}
Natively parsed:
Date string: 03-09-2015
Unix timeMs: 1425938476314
Time string: 10:01:16 PM
#!/usr/bin/env bash
g++ curl_jsoncpp_example.cpp -ljsoncpp -lcurl -o example.out && ./example.out
@Binsoma
Copy link

Binsoma commented Dec 22, 2017

It works! thanks.

@alandipert
Copy link

alandipert commented May 2, 2018

This was very helpful, thank you! However int httpCode(0); on line 42 should be long httpCode(0);. If I don't make this change curl_easy_cleanup segfaults on my machine.

From curl/easy.h:

/*
 * NAME curl_easy_getinfo()
 *
 * DESCRIPTION
 *
 * Request internal information from the curl session with this function.  The
 * third argument MUST be a pointer to a long, a pointer to a char * or a
 * pointer to a double (as the documentation describes elsewhere).  The data
 * pointed to will be filled in accordingly and can be relied upon only if the
 * function returns CURLE_OK.  This function is intended to get used *AFTER* a
 * performed transfer, all results from this function are undefined until the
 * transfer is completed.
 */
CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);

@PauloZ
Copy link

PauloZ commented Jun 5, 2018

thanks

@rodolfobandeira
Copy link

Thanks @connormanning

This is very useful, although I got the same Segmentation fault on my machine. So thanks to @alandipert's comment figuring out the fix.

Copy link

ghost commented Sep 14, 2018

Please check for the more generic httpCode instead of just 200. This also allows the code to work with file:// URLs.
if (httpCode != CURLE_HTTP_RETURNED_ERROR)

@hypernova7
Copy link

How do I install the json library?

@rec0dex
Copy link

rec0dex commented Aug 13, 2019

Provide an example to send JSON request & recive ?

@Alppuccino
Copy link

Is there a way to get this working without using deprecated classes? It won't let me build it now as this is several years old, unfortunately.

@dota17
Copy link

dota17 commented Oct 30, 2019

Copy link

ghost commented Dec 22, 2019

How do I install the json library?

I want json Library please

Copy link

ghost commented Dec 23, 2019

It works! thanks.

Please send json.h Library

@shahzaib17
Copy link

shahzaib17 commented Apr 9, 2020

what to do if json returned is in array form and contains more then one record?
EDIT:-got it working with this for (Json::Value::ArrayIndex i = 0; i != jsonData.size(); i++)

@shahzaib17
Copy link

download jsoncpp-master from this link https://github.com/open-source-parsers/jsoncpp
now you need python to run python .py script named "amalgamate.py" its inside jsoncpp-master after running this script you will see new folder named "dist" copy this folder in your project and now simply add jsoncpp.cpp file in source files and json.h and json-forwards.h files in Header files in your project.
now go to your project properties->c++->general->additional include directories->
here give path "jsoncpp-master\include"
NOTE:- you have to give path where your jsoncpp-master\include is located on your pc.
now at top of your code type #include <json/json.h>
now use json in your code

@complexlol
Copy link

error C4996: 'Json::Reader': Use CharReader and CharReaderBuilder instead what I can do to fix it ?

@Mecanik
Copy link

Mecanik commented May 26, 2021

error C4996: 'Json::Reader': Use CharReader and CharReaderBuilder instead what I can do to fix it ?

This is because the person that posted this has not updated the code for the latest version.

class JSONCPP_DEPRECATED(
    "Use CharReader and CharReaderBuilder instead.") JSON_API Reader {

So basically replace:

Json::Reader jsonReader;

With:

Json::CharReaderBuilder builder;

Also replace:

std::unique_ptr<std::string> httpData(new std::string()); // why would you even do this!?

With:

std::string httpData;

Complete "fix":

        // Response looks good - done using Curl now.  Try to parse the results
        // and print them out.
        Json::Value jsonData;
        JSONCPP_STRING jsonError;
        Json::CharReaderBuilder builder;

        const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());

        if (reader->parse(httpData.c_str(), httpData.c_str() + httpData.length(), &jsonData, &jsonError))

@hirokoclanger
Copy link

after using the "fix" httpData.get is not available anymore

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment