ヘッダーが特定のサイズの場合、libcurl が「セッション」を失うという問題が発生しました。
私たちが確認した 2 つの既知のケースは、1425 と 2885 です。
送信されたヘッダーがこの特定のサイズの場合、サーバーは適切な 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;
}