问题描述
我有一个可执行文件,使用libcurl和libcares重复发送数据到HTTPS端点。 这是偶尔的DNSparsing超时在某些客户端(不是全部)。 如果我在命令行curl中运行等价命令,我从来没有看到任何超时。
更令人困惑的是,主机是在/ etc / hosts中显式指定的,所以不应该有任何DNSparsing。
来自libcurl的错误(详细模式)是:
* Adding handle: conn: 0xcbca20 * Adding handle: send: 0 * Adding handle: recv: 0 * Curl_addHandleToPipeline: length: 1 * - Conn 88 (0xcbca20) send_pipe: 1, recv_pipe: 0 * Resolving timed out after 2002 milliseconds * Closing connection 88
我的libcurl可执行文件每秒发送2-3次查询,每300次请求就会发生一次这个错误。 使用命令行curl,我已经运行10000个查询没有一个超时。
任何人都可以build议任何我可以尝试从libcurl解决这些错误? 有什么设置,我需要添加到我的libcurl设置,或者我可能会丢失系统configuration?
我不确定是把这个放在堆栈溢出,服务器故障还是请求Ubuntu; 如果它在错误的地方,表示歉意。
谢谢你的时间!
更详细的信息
客户端是Ubuntu 12.04,64位。 在几个客户端上都观察到同样的问题,所有客户端都使用相同的操作系统
用户名/密码/url在下面的代码片段中被混淆了。
命令行curltesting器(使用v 7.22.0):
while true; do curl -v -u username:password "https://myhost.com/endpoint" -X POST --data "a=x&b=y" >> /tmp/commandLine.log 2>&1; sleep 0.1; done &
Libcurl源代码(使用curl 7.30.0,使用c-ares 1.10.0):
#include <curl/curl.h> #include <unistd.h> #include <string> #include <iostream> using namespace std; int main(int argc, char** argv) { while (1) { // Initialise curl CURL *curl = curl_easy_init(); // Set endpoint string urlWithEndpoint = "https://myhost.com/endpoint"; curl_easy_setopt(curl, CURLOPT_URL, urlWithEndpoint.c_str()); // Set-up username and password for request curl_easy_setopt(curl, CURLOPT_USERPWD, "username:password"); // Append POST data specific stuff string postData = "a=x&b=y"; long postSize = postData.length(); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postSize); curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, postData.c_str()); //set timeouts curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 2); curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, 60); cout << endl << endl << "=========================================================" << endl << endl; cout << "Making curl request to " << urlWithEndpoint << "(POST size " << postSize << "B)" << endl; // Set curl to log verbose information curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); // Perform the request CURLcode curlRes = curl_easy_perform(curl); // Handle response bool success = false; if (curlRes == CURLE_OK) { long httpCode; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode); success = (httpCode==200); cout << "Received response " << httpCode << endl; } else if ( curlRes == CURLE_OPERATION_TIMEDOUT ) { cout << "Received timeout" << endl; } else { cout << "CURL error" << endl; } curl_easy_cleanup(curl); if (success) { cout << "SUCCESS! (" << time(0) << ")" << endl; usleep(0.1*1e6); } else { cout << "FAILURE!!!! (" << time(0) << ")" << endl; usleep(10*1e6); } } }
回答我自己的问题
事实certificate,问题出在lib c-ares(在libcurl中提供了线程安全的DNSparsing)。 使用–enable-threaded-resolver重新编译libcurl,分辨率超时将停止。
我已经尝试更新到最新的lib c-ares,并且在c-ares论坛上寻找类似的bug,但是在前面没有运气。 所以我在放弃c-ares,并使用Curl线程parsing器继续前进。