Descrição do problema
Eu tenho um executável que envia dados repetidamente para um endpoint HTTPS, usando libcurl com libcares. Isso está recebendo tempos limite de resolução de DNS ocasionais em alguns clientes (não todos). Se eu executar o comando equivalente no curl da linha de comando, nunca vejo nenhum tempo limite.
O que torna isso ainda mais confuso é que o host é explicitamente especificado em / etc / hosts, portanto, não deve haver nenhuma resolução de DNS necessária.
O erro do libcurl (com o modo detalhado) é:
* 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
Meu executável libcurl está enviando 2-3 consultas por segundo e vejo esse erro uma vez a cada 300 solicitações. Usando o curl de linha de comando, executei 10000 consultas sem um único tempo limite.
Alguém pode sugerir algo que eu possa tentar resolver esses erros do libcurl? Existe alguma configuração que eu preciso adicionar à minha configuração libcurl,
ou configuração do sistema eu poderia estar faltando?
Eu não tinha certeza se deveria colocar isso no Stack Overflow, Server Fault ou Ask Ubuntu; desculpas se estiver no lugar errado.
Obrigado pelo seu tempo!
Informações mais detalhadas
O cliente é o Ubuntu 12.04, 64 bits. O mesmo problema foi observado em vários clientes, todos com o mesmo sistema operacional.
Os nomes de usuário / senhas / URLs foram ofuscados nos snippets a seguir.
Testador de curvas de linha de comando (usando 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 &
Código-fonte do Libcurl (usando o curl 7.30.0, com 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);
}
}
}