LibCurl- 如何更新已设置的特定 header 信息?

LibCurl- How to update a specific header information which is aleady set?

我需要修改 header 请求中的授权令牌等特定信息。有没有办法只更新那个特定的header,保留其余的?目前我正在做类似下面的事情。但是不知道有没有其他方法可以做到?

        struct curl_slist* headers = NULL;

        headers = curl_slist_append(headers, "Accept:");

        headers = curl_slist_append(headers, "Authorization: ABCDC0F725997BEF3C6B90B0E39D9C314DCB58553FA47CD3598BBB8910A8CE6E");

        headers = curl_slist_append(headers, "Host: localhost");

        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);


        //Updating the header like this
        auto *test = headers;

        while (test != NULL)
        {
            if (strstr(test->data, "Authorization:"))
            {
                strcpy_s(test->data, strlen("Authorization: A5484526D0F7A671ABCD0C091755532A63475719E460ED6A807C4AAD70BCEDA0") + 1, "Authorization: A5484526D0F7A671CE400C091755532A63475719E460ED6A807C4AAD70BCEDA0");
                break;
            }
            test = test->next;
        }

由于以下两个原因,您正在做的事情很危险:

  1. test->data 可能没有足够长的时间来保存数据复制,你最终会把数据写到你不应该写的地方。
  2. test->data 可能比您正在复制的数据更长,因此 header 末尾会有不需要的数据。

基于 curl 的 source code,打破抽象似乎可以正常工作,因此我们可以使用您设置 test->data 的方法,但进行以下修改:

static const char *newheaderdata = "Authorization: A5484526D0F7A671CE400C091755532A63475719E460ED6A807C4AAD70BCEDA0";
while (test != NULL)
{
    if (strstr(test->data, "Authorization:"))
    {
        free(test->data);
        test->data = strdup(newheaderdata) 
        break;
    }
    test = test->next;
}

通常你不能像你实现的那样去做。 test->data 的分配大小未知。仅当 header 长度固定时,您的代码才有效。

libcurl 代码可能会更改,因此 free(test->data); test->data = strdup(newdata) 不是一个好主意。

我会像下面这样。

#include <curl/curl.h>

#if LIBCURL_VERSION_MAJOR != 7 || LIBCURL_VERSION_MINOR != 79 || LIBCURL_VERSION_PATCH != 1
# error "libcurl version is is changed. Be sure Curl_slist_duplicate is not changed in lib/slist.h"
#endif

struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist);

struct curl_slist* headers = nullptr;
struct curl_slist* commonheaders = nullptr;
commonheaders = curl_slist_append(commonheaders, "Accept:");
commonheaders = curl_slist_append(commonheaders, "Host: localhost");

// Update the headers.
curl_slist_free_all(headers);
headers = Curl_slist_duplicate(commonheaders);
headers = curl_slist_append(headers, "Authorization: ABCDC0F725997BEF3C6B90B0E39D9C314DCB58553FA47CD3598BBB8910A8CE6E");

curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

或者

#include <curl/curl.h>

struct curl_slist* headers = nullptr;
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Accept:");
headers = curl_slist_append(headers, "Host: localhost");
headers = curl_slist_append(headers, "Authorization: ABCDC0F725997BEF3C6B90B0E39D9C314DCB58553FA47CD3598BBB8910A8CE6E");

curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

// Remove the last header.
curl_slist* h = headers;
for (curl_slist* next = h->next; next->next; h = next->next, next = h->next) {}
curl_slist_free_all(h->next);
h->next = nullptr;
// Append new header.
headers = curl_slist_append(headers, "Authorization: ABCDC0F725997BEF3C6B90B0E39D9C314DCB58553FA47CD3598BBB8910A8CE6E");

curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);