如何使用 C++ 从 libcURL 获取响应标头

kcu*_*tzo 4 c++ libcurl

好的,基本上我想要在发送帖子请求后得到响应标头。

这是我的发送邮政编码



    pDataInfo->recvHeadBuff = (char*)VirtualAlloc(NULL, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    InitPost(pDataInfo);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 5L);
    curl_easy_setopt(curl, CURLOPT_URL, pDataInfo->URL);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, pDataInfo->PostData.c_str());
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, pDataInfo->recvHeadBuff);
    curl_easy_perform(curl);
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &pDataInfo->repCode);


Run Code Online (Sandbox Code Playgroud)

k 所以在这里我试图创建一个缓冲区,我将用于我的用户数据*

回调函数:

static size_t header_callback(char* buffer, size_t size,
    size_t nitems, void* userdata)
{
    
    strcpy((char*)userdata, buffer);
    
    std::cout << (char*)userdata; // This prints the headers correctly

    return nitems * size;
}

Run Code Online (Sandbox Code Playgroud)

现在我认为我的缓冲区将填充来自标头缓冲区的字符,但是当我尝试从这个回调函数外部再次计算缓冲区时,我什么也得不到。

基本上需要帮助如何使用用户数据和缓冲区来将我的变量从这个函数中取出,ik它的noobxd。

Rem*_*eau 5

您的CURLOPT_HEADERFUNCTION回调假设提供的内容buffer以空终止,但事实并非如此。文档甚至是这样说

一旦 libcurl 收到标头数据,该函数就会被调用。将为每个标头调用一次标头回调,并且只有完整的标头行才会传递给回调。使用它解析标头非常容易。buffer指向传递的数据,该数据的大小为nitemssize始终为 1。不要假设标题行以 null 结尾!

您还假设完整的标头适合recvHeadBuff您分配的 4K,但这也不能保证,因此您面临缓冲区溢出的风险。

尝试更像这样的事情:

std::string headers;
InitPost(pDataInfo);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 5L);
curl_easy_setopt(curl, CURLOPT_URL, pDataInfo->URL);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, pDataInfo->PostData.c_str());
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &headers);
curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &pDataInfo->repCode);
// use headers as needed...
DWORD size = (headers.size() + 1) * sizeof(char);
pDataInfo->recvHeadBuff = (char*) VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (pDataInfo->recvHeadBuff)
    CopyMemory(pDataInfo->recvHeadBuff, headers.c_str(), size);
...
Run Code Online (Sandbox Code Playgroud)
static size_t header_callback(char* buffer, size_t size,
    size_t nitems, void* userdata)
{
    std::string *headers = (std::string*) userdata;
    headers->append(buffer, nitems * size);
    return nitems * size;
}
Run Code Online (Sandbox Code Playgroud)

或者,您应该更改为使用与 using (我假设) 而不是 apDataInfo->recvHeadBuff相同的字符串类型,然后您可以这样做:pDataInfo->PostDatastd::stringchar*

InitPost(pDataInfo);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 5L);
curl_easy_setopt(curl, CURLOPT_URL, pDataInfo->URL);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, pDataInfo->PostData.c_str());
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &(pDataInfo->recvHeaders));
curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &pDataInfo->repCode);
...
Run Code Online (Sandbox Code Playgroud)
static size_t header_callback(char* buffer, size_t size,
    size_t nitems, void* userdata)
{
    std::string *headers = (std::string*) userdata;
    headers->append(buffer, nitems * size);
    return nitems * size;
}
Run Code Online (Sandbox Code Playgroud)