2009-06-25 57 views
1

问题的libcurl的饼干发动机

[从libcurl的邮件列表交叉贴]我有一个单线程应用程序(MSVC C++ 2005)建立针对静态 的libcurl 7.19.4

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

我只使用一个连接到libcurl的

该Cookie引擎使用 curl_easy_setopt(CURLOPT_COOKIEFILE,“”)开始启用(即只有一个卷曲*)

的cookie缓存在清除使用curl_easy_setopt(CURLOPT_COOKIELIST,“SESS”)验证过程 的结束。认证过程需要 。

下一个呼叫完成成功的身份验证,导致 从服务器返回一对安全Cookie - 他们的 没有设置终止日期。

服务器(和I)期望安全性cookie随后会以 的所有后续请求发送到服务器。问题是,有时 他们发送和有时他们不是。

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

作为一种解决方法,我已禁用cookie引擎,并正在执行基本的手动cookie处理 。像这样,它按预期工作,但我希望 尽可能使用该库。

有没有人有任何想法?

感谢 勒布

回答

1

我们已经经历过的libcurl问题失去了“会话”的时候,头是一个特定的大小。

我们见过的两个已知的情况是1425和2885

发送头是服务器没有出现接收不到正确的cookies,这些具体的尺寸。我们并未实际测试受控服务器以查看服务器实际收到的内容。

我们想出的解决方法是稍微改变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; 
} 
+0

这很有趣,谢谢。 你使用的是什么版本的libcurl?你有没有向开发者提出过缺陷? – 2010-04-06 19:55:55