【问题标题】:Problem with libcurl cookie enginelibcurl cookie 引擎的问题
【发布时间】:2009-06-25 15:59:35
【问题描述】:

[来自 lib-curl 邮件列表的交叉发布]

我有一个针对静态构建的单线程应用程序 (MSVC C++ 2005) LIBCURL 7.19.4

测试应用程序连接到内部服务器并执行定制 身份验证过程,包括发布几个表格,以及 当这成功创建一个新资源(POST),然后更新 使用 If-Match 的资源 (PUT)。

我只使用一个到 libcurl 的连接(即只有一个 CURL*)

cookie 引擎从一开始就使用 curl_easy_setopt(CURLOPT_COOKIEFILE, "")

在身份验证过程结束时清除 cookie 缓存 使用 curl_easy_setopt(CURLOPT_COOKIELIST, "SESS")。这是必需的 通过身份验证过程。

下一个调用完成了成功的身份验证,结果是 从服务器返回的几个安全 cookie - 它们 没有设置有效期。

服务器(和我)希望随后发送安全 cookie 对服务器的所有后续请求。问题是有时 他们被发送,有时他们不是。

我不是 CURL 专家,所以我可能做错了什么,但我 不知道是什么。在循环结果中运行测试应用程序会显示 正确 cookie 处理的随机分布。

作为一种解决方法,我已禁用 cookie 引擎并正在做基本操作 手动 cookie 处理。像这样它按预期工作,但我更喜欢 尽可能使用图书馆。

有人有什么想法吗?

谢谢 赛博

【问题讨论】:

    标签: libcurl


    【解决方案1】:

    当标头具有特定大小时,我们遇到了 libcurl 丢失“会话”的问题。

    我们见过的两个已知案例是 1425 和 2885。

    sent 标头是这个特定大小时,服务器似乎没有接收到正确的 cookie。我们还没有针对受控服务器进行实际测试,以查看服务器实际接收到的内容。

    我们想出的解决方法是稍微改变 User-Agent,在末尾添加一个空格来更改标题大小。

    这里有一些代码可以在发送请求之前预测标头大小

    size_t PredictHeaderOutSize(CURL *curl, bool doPost, const char* request, char* userAgent, const char* host, const char* form)
    {
        size_t predictedHeaderOutSize = 0;
    
        // Note, so far predicting 1 byte per newline, fix the hard coded #'s below if that turns out to be wrong
    
        // POST/GET line
        predictedHeaderOutSize += (doPost ? 4 : 3); // POST vs GET
        predictedHeaderOutSize += strlen(request);
        predictedHeaderOutSize += 11; // Extra characters in 'POST <request> HTTP/1.1' not accounted for above
    
        // User-Agent line
        predictedHeaderOutSize += strlen(userAgent);
        predictedHeaderOutSize += 13;
    
        // Host: header
        predictedHeaderOutSize += strlen(host);
        predictedHeaderOutSize += 7;
    
        // Accept: */*
        predictedHeaderOutSize += 12;
    
        // Cookie:
        struct curl_slist *cookies=NULL;
        struct curl_slist *next_cookie;
        int num_cookies = 0;
        CURLcode res = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies);
        if (res == CURLE_OK)
        {
            if (cookies != NULL)
            {
                // At least 1 cookie so add the extra space taken on cookie line
                predictedHeaderOutSize += 7;
                next_cookie = cookies;
                num_cookies = 1;
                while (next_cookie)
                {
                    std::vector<std::string> cookie = QueueHelper::Split("\t", next_cookie->data, 7);
                    if (cookie.size() != 7)
                    {
                        // wtf?
                    }
                    else
                    {
                        // For each cookie we add length of key + value + 3 (for the = ; and extra space)
                        predictedHeaderOutSize += cookie[5].length() + cookie[6].length() + 3;
                    }
                    next_cookie = next_cookie->next;
                    num_cookies++;
                }
                curl_slist_free_all(cookies);
            }
        }
        else
        {
            printf("curl_easy_getinfo failed: %s\n", curl_easy_strerror(res));
        }
    
        if (doPost)
        {
            // Content-Length:
            size_t formLength = strlen(form);
            if (formLength < 10)
                predictedHeaderOutSize += 1;
            if (formLength >= 10 && formLength < 100)
                predictedHeaderOutSize += 2;
            if (formLength >= 100 && formLength < 1000)
                predictedHeaderOutSize += 3;
            if (formLength >= 1000 && formLength < 10000)
                predictedHeaderOutSize += 4;
            predictedHeaderOutSize += 17;
    
            // Content-Type: application/x-www-form-urlencoded
            predictedHeaderOutSize += 48;
        }
    
        predictedHeaderOutSize += 2; // 2 newlines at the end? something else? not sure
    
        return predictedHeaderOutSize;
    }
    

    【讨论】:

    • 这很有趣,谢谢。你用的是什么版本的 libcurl?您是否曾向开发人员提出过缺陷?
    • 几个版本,包括 7.19.5。我还没有测试7.20。不,从来没有时间将它发布到邮件列表中。我的主要建议是在收到错误时记录标题大小。您可能很快就会发现错误只出现在非常特定的标题大小上。
    猜你喜欢
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 2010-11-15
    • 1970-01-01
    • 2016-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多