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, readBuffer
should 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();}