Save cURL content result into a string in C++ Save cURL content result into a string in C++ curl curl

Save cURL content result into a string in C++


You will have to use CURLOPT_WRITEFUNCTION to set a callback for writing. I can't test to compile this right now, but the function should look something close to;

static std::string readBuffer;static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp){     size_t realsize = size * nmemb;    readBuffer.append(contents, realsize);    return realsize;}

Then call it by doing;

readBuffer.clear();curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);// ...other curl optionsres = curl_easy_perform(curl);

After the call, readBuffershould have your contents.

Edit: You can use CURLOPT_WRITEDATA to pass the buffer string instead of making it static. In this case I just made it static for simplicity. A good page to look (besides the linked example above) is here for an explanation of the options.

Edit2: As requested, here's a complete working example without the static string buffer;

#include <iostream>#include <string>#include <curl/curl.h>static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp){    ((std::string*)userp)->append((char*)contents, size * nmemb);    return size * nmemb;}int main(void){  CURL *curl;  CURLcode res;  std::string readBuffer;  curl = curl_easy_init();  if(curl) {    curl_easy_setopt(curl, CURLOPT_URL, "http://www.google.com");    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);    res = curl_easy_perform(curl);    curl_easy_cleanup(curl);    std::cout << readBuffer << std::endl;  }  return 0;}


This might not work right away but should give you an idea:

#include <string>#include <curl.h>#include <stdio.h>size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {    size_t written;    written = fwrite(ptr, size, nmemb, stream);    return written;}int main() {    std::string tempname = "temp";    CURL *curl;    CURLcode res;    curl = curl_easy_init();    if(curl) {      FILE *fp = fopen(tempname.c_str(),"wb");      curl_easy_setopt(curl, CURLOPT_URL, "http://www.google.com");      curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);       curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);      res = curl_easy_perform(curl);      curl_easy_cleanup(curl);      fclose(fp);      fp = fopen(tempname.c_str(),"rb");      fseek (fp , 0 , SEEK_END);      long lSize = ftell (fp);      rewind(fp);      char *buffer = new char[lSize+1];      fread (buffer, 1, lSize, fp);      buffer[lSize] = 0;      fclose(fp);      std::string content(buffer);      delete [] buffer;    }}


On my blog I have published a simple wrapper class to perform this task.

Usage example:

#include "HTTPDownloader.hpp"int main(int argc, char** argv) {    HTTPDownloader downloader;    std::string content = downloader.download("https://stackoverflow.com");    std::cout << content << std::endl;}

Here's the header file:

/** * HTTPDownloader.hpp * * A simple C++ wrapper for the libcurl easy API. * * Written by Uli Köhler (techoverflow.net) * Published under CC0 1.0 Universal (public domain) */#ifndef HTTPDOWNLOADER_HPP#define HTTPDOWNLOADER_HPP#include <string>/** * A non-threadsafe simple libcURL-easy based HTTP downloader */class HTTPDownloader {public:    HTTPDownloader();    ~HTTPDownloader();    /**     * Download a file using HTTP GET and store in in a std::string     * @param url The URL to download     * @return The download result     */    std::string download(const std::string& url);private:    void* curl;};#endif  /* HTTPDOWNLOADER_HPP */

Here's the source code:

/** * HTTPDownloader.cpp * * A simple C++ wrapper for the libcurl easy API. * * Written by Uli Köhler (techoverflow.net) * Published under CC0 1.0 Universal (public domain) */#include "HTTPDownloader.hpp"#include <curl/curl.h>#include <curl/easy.h>#include <curl/curlbuild.h>#include <sstream>#include <iostream>using namespace std;size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) {    string data((const char*) ptr, (size_t) size * nmemb);    *((stringstream*) stream) << data;    return size * nmemb;}HTTPDownloader::HTTPDownloader() {    curl = curl_easy_init();}HTTPDownloader::~HTTPDownloader() {    curl_easy_cleanup(curl);}string HTTPDownloader::download(const std::string& url) {    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());    /* example.com is redirected, so we tell libcurl to follow redirection */    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); //Prevent "longjmp causes uninitialized stack frame" bug    curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "deflate");    std::stringstream out;    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &out);    /* Perform the request, res will get the return code */    CURLcode res = curl_easy_perform(curl);    /* Check for errors */    if (res != CURLE_OK) {        fprintf(stderr, "curl_easy_perform() failed: %s\n",                curl_easy_strerror(res));    }    return out.str();}