c++ - 如何通过 CURLOPT_HEADERFUNCTION 提取标题信息?
问题描述
我想通过在我的 c++ 程序中使用 CURLOPT_HEADERFUNCTION 来提取标题信息。
如何使用 CURLOPT_HEADERFUNCTION 读取单个响应标头字段?提供了有关如何获取这些标头信息的解决方案,但我想知道为什么我的代码不起作用以及一个可能的示例解决方案。
//readHeader function which returns the specific header information
size_t readHeader(char* header, size_t size, size_t nitems, void *userdata) {
Erza oprations; //class which contains string function like startsWith etc
if (oprations.startsWith(header, "Content-Length:")) {
std::string header_in_string = oprations.replaceAll(header, "Content-Length:", "");
long size = atol(header_in_string.c_str());
file_size = size; // file_size is global variable
std::cout << size; // here it is showing correct file size
}
else if (oprations.startsWith(header, "Content-Type:")) {
// do something
}else
// do something
return size * nitems;
}
// part of main function
curl = curl_easy_init();
if (curl) {
fp = fopen(path, "wb");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_CAINFO, "./ca-bundle.crt");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, readHeader);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
std::cout << file_size; // showing value 0
在 readHeader 函数中获取正确的文件大小,但在 main 函数中获取 0 字节。
解决方案
如您的 github depot 所示,oprations
(operations !?) 是一个局部变量,将在 readHeader 函数结束时释放。处理 readHeader 函数并为给定 Erza 实例获取正确文件大小的方法是将其指针传递给userdata
value。Erza 类可以重写为:
class Erza : public Endeavour {
//... your class body
public:
bool download (const char *url,const char* path){
curl = curl_easy_init();
if (curl) {
fp = fopen(path, "wb");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_CAINFO, "./ca-bundle.crt");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, readHeader);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, this ); //<-- set this pointer to userdata value used in the callback.
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
return false;
}else
return true;
}
size_t analyseHeader( char* header, size_t size, size_t nitems ){
if (startsWith(header, "Content-Length:")) {
std::string header_in_string = replaceAll(header, "Content-Length:", "");
long size = atol(header_in_string.c_str());
file_size = size; // file_size is a member variable
std::cout << size; // here it is showing correct file size
}
else if (startsWith(header, "Content-Type:")) {
// do something
}else
// do something
return size * nitems;
}
}//Eof class Erza
size_t readHeader(char* header, size_t size, size_t nitems, void *userdata) {
//get the called context (Erza instance pointer set in userdata)
Erza * oprations = (Erza *)userdata;
return oprations->analyseHeader( header, size, nitems );
}
推荐阅读
- javascript - 在单击按钮的情况下执行方法
- python-3.x - Python 映射列表乱序返回字典
- javascript - 用打字稿和角度对父母和孩子进行排序
- android - 根据屏幕密度分离 Jetpack 可组合功能
- vue.js - 覆盖 Vuetify 变量
- node.js - 为什么 api 调用需要很长时间才能响应?通过邮递员调用相同的 api url 立即给出结果
- google-apps-script - Google Apps 脚本从 Stripe 接收 webhook,未能提取部分接收到的事件信息
- rust - 使用类似“复制”的语义在可变引用上创建包装器
- c# - 如何使用 CsvHelper 正确映射集合
- django - 如何在 Django ModelForm 中测试自定义的清理方法