views:

51

answers:

2

Hello everyone,

This issue/quirk/side-effect is driving me crazy. Near the bottom the code, the response code of the HTTP interaction is passed by reference into responseCode_. However it often comes out as 0 even though the site can otherwise be accessed, and returns too quickly to be a timeout...

All variables are defined, the code below is just a snippet of a C++ method in a class. Any var_ variables are instance based. It runs on several threads, but that should not be a problem. Each class that uses libcurl has its own instance on the respective threads.

Thanks in advance for any ideas or advice...

 CURL *curl;
 curl = curl_easy_init();
 //The URL
 curl_easy_setopt(curl, CURLOPT_URL, url.getURLString().c_str());
 //Timeout
 curl_easy_setopt(curl, CURLOPT_TIMEOUT, &timeout_);
 //disable signals to use with threads
 curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
 //Redirecting
 curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5);
 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
 //Writing callback
 curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, &writerh);
 curl_easy_setopt(curl, CURLOPT_HEADERDATA, &head_);
 //Writing callback
 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &writerb);
 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &body_);
 //Headers
 struct curl_slist *headers = NULL;
 for (std::map<std::string, std::string>::iterator itr = requestHeaders_.begin(); itr != requestHeaders_.end(); itr++) {
  std::stringstream header;
  header << itr->first << ": " << itr->second;
  headers = curl_slist_append(headers, header.str().c_str());
 }
 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
 //UA
 curl_easy_setopt(curl, CURLOPT_USERAGENT, "RDFaS-Bot/1.0 (+http://www.rdfas.com/bot)");
 curl_easy_perform(curl); /* ignores error */
 //Response code
 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode_);
 //clean headers
 curl_slist_free_all(headers);
 curl_easy_cleanup(curl);

Update:

curl_easy_perform was not returning CURLE_OK when the response code was 0, as the marked answer explains. However debug hooks are very useful too and an excellent suggestion

+1  A: 

The response code is only going to be set if curl_easy_perform() returns CURLE_OK so you should check that first to make sure curl actually performed the request successfully. Are you sure the callback functions for writing the header and body are set up correctly?

Also, make sure curl_global_init(CURL_GLOBAL_ALL) is called before these easy_perform threads start.

Assuming nothing in the curl handle returned by curl_easy_init() is shared across threads, then the code looks correct.

Mike
+1  A: 

Use the debugging hooks built into libcurl.

Seriously. libcurl is a "C" nightmare of void*s and error codes. Everything can go wrong when using libcurl. Write your libcurl debugging hooks once and don't remove them from your code. You'll need them again, and again,... and again.

John