使用 libcurl easy API 的简单 C++ HTTP 下载
问题
使用 libcurl easy API 你想使用 HTTP GET 下载文件。不应使用认证等扩展功能。
下载结果应存储在 std::string 中
解决方案
你可以使用这个简单的包装类:
头文件:
HTTPDownloader.hpp
/**
* HTTPDownloader.hpp
*
* libcurl easy API 的简单 C++ 包装器。
*
* 由 Uli Köhler (techoverflow.net) 编写
* 在 CC0 1.0 Universal(公共领域)下发布
*/
#ifndef HTTPDOWNLOADER_HPP
#define HTTPDOWNLOADER_HPP
#include <string>
/**
* 非线程安全的简单 libcURL-easy HTTP 下载器
*/
class HTTPDownloader {
public:
HTTPDownloader();
~HTTPDownloader();
/**
* 使用 HTTP GET 下载文件并存储在 std::string 中
* @param url 要下载的 URL
* @return 下载结果
*/
std::string download(const std::string& url);
private:
void* curl;
};
#endif /* HTTPDOWNLOADER_HPP */源文件:
HTTPDownloader.cpp
/**
* HTTPDownloader.cpp
*
* libcurl easy API 的简单 C++ 包装器。
*
* 由 Uli Köhler (techoverflow.net) 编写
* 在 CC0 1.0 Universal(公共领域)下发布
*/
#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 被重定向,所以我们告诉 libcurl 跟随重定向 */
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); //防止 "longjmp 导致未初始化堆栈帧" 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);
/* 执行请求,res 将获取返回代码 */
CURLcode res = curl_easy_perform(curl);
/* 检查错误 */
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
return out.str();
}示例用法代码:
HTTPDownloaderExample.cpp
/**
* HTTPDownloaderExample.cpp
*
* libcurl easy API 的简单 C++ 包装器。
* 此文件包含如何使用 HTTPDownloader 类的示例代码。
*
* 编译方式:g++ -o HTTPDownloaderExample HTTPDownloaderExample.cpp HTTPDownloader.cpp -lcurl
*
* 由 Uli Köhler (techoverflow.net) 编写
* 在 CC0 1.0 Universal(公共领域)下发布
*/
#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