Einfacher C++ HTTP-Download mit libcurl Easy API
Problem
Mit der libcurl Easy API möchtest du eine Datei über HTTP GET herunterladen. Es sollen keine erweiterten Features wie Authentifizierung verwendet werden.
Das Download-Ergebnis soll in einem std::string gespeichert werden.
Lösung
Du kannst diese einfache Wrapper-Klasse verwenden:
Header:
HTTPDownloader.hpp
/**
* HTTPDownloader.hpp
*
* Ein einfacher C++-Wrapper für die libcurl Easy API.
*
* Geschrieben von Uli Köhler (techoverflow.net)
* Veröffentlicht unter CC0 1.0 Universal (public domain)
*/
#ifndef HTTPDOWNLOADER_HPP
#define HTTPDOWNLOADER_HPP
#include <string>
/**
* Ein nicht-thread-sicherer einfacher HTTP-Downloader basierend auf libcURL-easy
*/
class HTTPDownloader {
public:
HTTPDownloader();
~HTTPDownloader();
/**
* Lädt eine Datei über HTTP GET herunter und speichert sie in einem std::string
* @param url Die URL zum Herunterladen
* @return Das Download-Ergebnis
*/
std::string download(const std::string& url);
private:
void* curl;
};
#endif /* HTTPDOWNLOADER_HPP */Quellcode:
HTTPDownloader.cpp
/**
* HTTPDownloader.cpp
*
* Ein einfacher C++-Wrapper für die libcurl Easy API.
*
* Geschrieben von Uli Köhler (techoverflow.net)
* Veröffentlicht unter 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 << endl;
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 wird weitergeleitet, also sagen wir libcurl, Weiterleitungen zu folgen */
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); //Verhindert den "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);
/* Anfrage ausführen, res erhält den Rückgabecode */
CURLcode res = curl_easy_perform(curl);
/* Auf Fehler prüfen */
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
return out.str();
}Beispielverwendungscode:
HTTPDownloaderExample.cpp
/**
* HTTPDownloaderExample.cpp
*
* Ein einfacher C++-Wrapper für die libcurl Easy API.
* Diese Datei enthält Beispielcode zur Verwendung der HTTPDownloader-Klasse.
*
* Kompilieren wie folgt: g++ -o HTTPDownloaderExample HTTPDownloaderExample.cpp HTTPDownloader.cpp -lcurl
*
* Geschrieben von Uli Köhler (techoverflow.net)
* Veröffentlicht unter CC0 1.0 Universal (public domain)
*/
#include "HTTPDownloader.hpp"
#include <iostream>
#include <string>
int main(int argc, char** argv) {
HTTPDownloader downloader;
std::string content = downloader.download("https://stackoverflow.com");
std::cout << content << std::endl;
}Check out similar posts by category:
C/C++, Networking
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow