C++ libcurl http 响应代码问题
这个问题/怪癖/副作用让我发疯。在代码的底部附近,HTTP 交互的响应代码通过引用传递到responseCode_。然而,即使可以以其他方式访问该站点,它通常也会显示为 0,并且返回得太快而无法超时...
所有变量都已定义,下面的代码只是类中 C++ 方法的片段。任何 var_ 变量都是基于实例的。它在多个线程上运行,但这应该不是问题。每个使用 libcurl 的类在各自的线程上都有自己的实例。
预先感谢您提供任何想法或建议...
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);
更新:
当响应代码为 0 时,curl_easy_perform
未返回 CURLE_OK,如标记答案所述。然而,调试钩子也非常有用,并且是一个很好的建议
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
仅当curl_easy_perform()返回CURLE_OK时才会设置响应代码,因此您应该首先检查以确保curl确实成功执行了请求。您确定用于写入标题和正文的回调函数设置正确吗?
另外,请确保在这些 easy_perform 线程启动之前调用curl_global_init(CURL_GLOBAL_ALL)。
假设curl_easy_init()返回的curl句柄中没有任何内容在线程之间共享,那么代码看起来是正确的。
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.
使用 libcurl 中内置的调试钩子。
说真的。 libcurl 是一个由
void*
和错误代码组成的“C”噩梦。使用 libcurl 时一切都可能出错。编写一次 libcurl 调试挂钩,不要将它们从代码中删除。你会一次又一次地需要它们……一次又一次。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.