如何使用 libcurl 存储 sent/received 数据
How to store sent/received data with libcurl
我正在尝试为一个小项目实现一些 curl 和 curlcpp 功能。
到目前为止,我已经实现了一些功能,但现在我想添加功能。这个想法是将发送和接收数据存储在缓冲区中,以便稍后我可以访问:
- 已发送数据
- 已发送Headers
- 收到数据
- 收到Headers
我知道有 CURLOPT_WRITEFUNCTION 但这只适用于响应数据,我也需要输出 data/headers。 CURLOPT_DEBUGFUNCTION 看起来对我有用,但我无法在 CPP 上配置它。
这是我的示例代码 class:
class CurlCPPClient
{
private:
...
int trace_data(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr);
curl::curl_easy curl_easy;
std::string raw_data;
public:
...
}
CurlCPPClient::CurlCPPClient()
{
curl_easy.add<CURLOPT_DEBUGFUNCTION>(this->trace_data);
}
int CurlCPPClient::trace_data(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr)
{
std::string frame_info(data);
switch(type)
{
case CURLINFO_HEADER_OUT:
case CURLINFO_DATA_OUT:
raw_data += frame_info;
break;
case CURLINFO_HEADER_IN:
case CURLINFO_DATA_IN:
raw_data += frame_info;
break;
default:
break;
}
return 0;
}
我在将函数指针设置为 trace_data 时遇到编译器问题。我得到“错误 C3867”和“错误 C2228”:this->trace_data、this.trace_data、trace_data。
如果我不使用 trace_data 作为我的 class 的方法,我可以调用它,但我无法保存成员的信息以便稍后在 class 的另一部分访问它。
libcurl 的回调需要独立的 C 风格函数。您不能使用 非静态 class 方法 进行回调。
将您的 trace_data()
方法声明为 static。您可以使用 CURLOPT_DEBUGDATA
将 CurlCPPClient
对象的 this
指针传递给方法的 userptr
参数。
class CurlCPPClient
{
private:
...
static int trace_data(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr);
curl::curl_easy curl_easy;
std::string raw_data;
public:
...
}
CurlCPPClient::CurlCPPClient()
{
curl_easy.add<CURLOPT_DEBUGFUNCTION>(&CurlCPPClient::trace_data);
curl_easy.add<CURLOPT_DEBUGDATA>(this);
}
int CurlCPPClient::trace_data(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr)
{
CurlCPPClient *pThis = static_cast<CurlCPPClient*>(userptr);
std::string frame_info(data, size);
switch(type)
{
case CURLINFO_HEADER_OUT:
case CURLINFO_DATA_OUT:
pThis->raw_data += frame_info;
break;
case CURLINFO_HEADER_IN:
case CURLINFO_DATA_IN:
pThis->raw_data += frame_info;
break;
default:
break;
}
return 0;
}
或者,使用 CURLOPT_DEBUGDATA
仅将 raw_data
成员传递给回调:
class CurlCPPClient
{
private:
...
static int trace_data(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr);
curl::curl_easy curl_easy;
std::string raw_data;
public:
...
}
CurlCPPClient::CurlCPPClient()
{
curl_easy.add<CURLOPT_DEBUGFUNCTION>(&CurlCPPClient::trace_data);
curl_easy.add<CURLOPT_DEBUGDATA>(&raw_data);
}
int CurlCPPClient::trace_data(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr)
{
std::string *pRawData = static_cast<std::string*>(userptr);
std::string frame_info(data, size);
switch(type)
{
case CURLINFO_HEADER_OUT:
case CURLINFO_DATA_OUT:
*pRawData += frame_info;
break;
case CURLINFO_HEADER_IN:
case CURLINFO_DATA_IN:
*pRawData += frame_info;
break;
default:
break;
}
return 0;
}
我正在尝试为一个小项目实现一些 curl 和 curlcpp 功能。
到目前为止,我已经实现了一些功能,但现在我想添加功能。这个想法是将发送和接收数据存储在缓冲区中,以便稍后我可以访问:
- 已发送数据
- 已发送Headers
- 收到数据
- 收到Headers
我知道有 CURLOPT_WRITEFUNCTION 但这只适用于响应数据,我也需要输出 data/headers。 CURLOPT_DEBUGFUNCTION 看起来对我有用,但我无法在 CPP 上配置它。
这是我的示例代码 class:
class CurlCPPClient
{
private:
...
int trace_data(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr);
curl::curl_easy curl_easy;
std::string raw_data;
public:
...
}
CurlCPPClient::CurlCPPClient()
{
curl_easy.add<CURLOPT_DEBUGFUNCTION>(this->trace_data);
}
int CurlCPPClient::trace_data(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr)
{
std::string frame_info(data);
switch(type)
{
case CURLINFO_HEADER_OUT:
case CURLINFO_DATA_OUT:
raw_data += frame_info;
break;
case CURLINFO_HEADER_IN:
case CURLINFO_DATA_IN:
raw_data += frame_info;
break;
default:
break;
}
return 0;
}
我在将函数指针设置为 trace_data 时遇到编译器问题。我得到“错误 C3867”和“错误 C2228”:this->trace_data、this.trace_data、trace_data。 如果我不使用 trace_data 作为我的 class 的方法,我可以调用它,但我无法保存成员的信息以便稍后在 class 的另一部分访问它。
libcurl 的回调需要独立的 C 风格函数。您不能使用 非静态 class 方法 进行回调。
将您的 trace_data()
方法声明为 static。您可以使用 CURLOPT_DEBUGDATA
将 CurlCPPClient
对象的 this
指针传递给方法的 userptr
参数。
class CurlCPPClient
{
private:
...
static int trace_data(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr);
curl::curl_easy curl_easy;
std::string raw_data;
public:
...
}
CurlCPPClient::CurlCPPClient()
{
curl_easy.add<CURLOPT_DEBUGFUNCTION>(&CurlCPPClient::trace_data);
curl_easy.add<CURLOPT_DEBUGDATA>(this);
}
int CurlCPPClient::trace_data(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr)
{
CurlCPPClient *pThis = static_cast<CurlCPPClient*>(userptr);
std::string frame_info(data, size);
switch(type)
{
case CURLINFO_HEADER_OUT:
case CURLINFO_DATA_OUT:
pThis->raw_data += frame_info;
break;
case CURLINFO_HEADER_IN:
case CURLINFO_DATA_IN:
pThis->raw_data += frame_info;
break;
default:
break;
}
return 0;
}
或者,使用 CURLOPT_DEBUGDATA
仅将 raw_data
成员传递给回调:
class CurlCPPClient
{
private:
...
static int trace_data(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr);
curl::curl_easy curl_easy;
std::string raw_data;
public:
...
}
CurlCPPClient::CurlCPPClient()
{
curl_easy.add<CURLOPT_DEBUGFUNCTION>(&CurlCPPClient::trace_data);
curl_easy.add<CURLOPT_DEBUGDATA>(&raw_data);
}
int CurlCPPClient::trace_data(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr)
{
std::string *pRawData = static_cast<std::string*>(userptr);
std::string frame_info(data, size);
switch(type)
{
case CURLINFO_HEADER_OUT:
case CURLINFO_DATA_OUT:
*pRawData += frame_info;
break;
case CURLINFO_HEADER_IN:
case CURLINFO_DATA_IN:
*pRawData += frame_info;
break;
default:
break;
}
return 0;
}