2009-06-25 43 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