How do I POST a buffer of JSON using libcurl?

Randall Cook picture Randall Cook · Nov 24, 2011 · Viewed 42.4k times · Source

My C++ program currently invokes curl through a pipe (popen("curl ...")) to POST a file of JSON data to a web server. This has obvious performance limitations due to the need to save the JSON to a file and invoke curl in a subshell. I'd like to rewrite it to use libcurl, but it is not clear to me how to do this. The command line I pass to popen() is:

curl -s -S -D /dev/null -H "Content-Type: application/json" -X POST -d file-of-json http://server/handler.php

The JSON data (about 3K) is sitting in a buffer in RAM before I need to post it. I was expecting to use libcurl's CURLOPT_READFUNCTION to spool the buffer to libcurl (but I am open to alternatives), and CURLOPT_WRITEFUNCTION to capture the server's reply, similar to how I read the reply from popen's pipe.

All that seems straightforward. What is confusing is which combination of CURLOPT_POST, CURLOPT_HTTPPOST, CURLOPT_POSTFIELDS, CURLOPT_HTTPHEADER I need. I have read many posts on this subject (no pun intended), and none exactly match my scenario. Any suggestions?

[Note that I normally do not have any URL-encoded form fields, like this: http://server/handler.php?I=do&not=use&these=in&my=query]

Answer

Greg Prisament picture Greg Prisament · Sep 23, 2014

You can use CURLOPT_POSTFIELDS:

CURL *curl = curl_easy_init();

curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/api/endpoint");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"hi\" : \"there\"}");

curl_easy_perform(curl);

Since CURLOPT_POSTFIELDS does not modify the payload in any way, it is very convenient for POSTing JSON data. Also note that, when CURLOPT_POSTFIELDS is supplied, it automatically enables CURLOPT_POST so there is no need to provide CURLOPT_POST in the request.