C++ libcurl http 响应代码问题

发布于 2024-09-07 13:45:32 字数 1746 浏览 5 评论 0原文

这个问题/怪癖/副作用让我发疯。在代码的底部附近,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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我是有多爱你 2024-09-14 13:45:32

仅当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.

暖心男生 2024-09-14 13:45:32

使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文