7

With the curlpp C++ wrapper for libcurl how do I specify JSON payload for a post request and how can I receive JSON payload in response? Where do I go from here:

std::string json("{}");

std::list<std::string> header;
header.push_back("Content-Type: application/json");

cURLpp::Easy r;
r.setOpt(new curlpp::options::Url(url));
r.setOpt(new curlpp::options::HttpHeader(header));
// set payload from json?
r.perform();

Then, how do I await for a (JSON) response and retrieve the body?

Oleg Sklyar
  • 8,393
  • 3
  • 35
  • 53

2 Answers2

12

Turns out this is fairly straightforward to do, even asynchronously:

std::future<std::string> invoke(std::string const& url, std::string const& body) {
  return std::async(std::launch::async,
    [](std::string const& url, std::string const& body) mutable {
      std::list<std::string> header;
      header.push_back("Content-Type: application/json");

      curlpp::Cleanup clean;
      curlpp::Easy r;
      r.setOpt(new curlpp::options::Url(url));
      r.setOpt(new curlpp::options::HttpHeader(header));
      r.setOpt(new curlpp::options::PostFields(body));
      r.setOpt(new curlpp::options::PostFieldSize(body.length()));

      std::ostringstream response;
      r.setOpt(new curlpp::options::WriteStream(&response));

      r.perform();

      return std::string(response.str());
    }, url, body);
}
Oleg Sklyar
  • 8,393
  • 3
  • 35
  • 53
  • 1
    How do you execute this behemoth? – kroiz Aug 20 '18 at 12:48
  • I am sorry, but I do not understand the question. It is an isolted C++ function that needs to be compiled and linked with stl and curlpp. You can write a unit test, an application or embed it in your existing code to test run it as you would do with any other function. STL is normally available and curlpp can be compiled against and linked into the binary in a standard manner of C++ compilation and linking. – Oleg Sklyar Aug 20 '18 at 14:16
  • 1
    I mean I would love an example on calling it because I don't understand the syntax, for example is as simple as: invoke("www.example.com", "param1=value"); – kroiz Aug 21 '18 at 17:49
1

By analyzing the documentation, the fifth example shows how to set a callback to get a response:

// Set the writer callback to enable cURL to write result in a memory area
curlpp::types::WriteFunctionFunctor functor(WriteMemoryCallback);
curlpp::options::WriteFunction *test = new curlpp::options::WriteFunction(functor);
request.setOpt(test);

where the callback is defined as

size_t WriteMemoryCallback(char* ptr, size_t size, size_t nmemb)

Since a response can arrive in chunks, it can be called multiple times. Once the response is completed, use a JSON library to parse it.

karastojko
  • 1,090
  • 11
  • 13
  • Found that bit already, but thanks for the hint about chunking. Submitting the request is what is less clear to me, although... something with a reader (symmetric to the writer for the response) could probably do. Need to try – Oleg Sklyar Jan 31 '17 at 16:23