在一个请求中下载正文之前C++ libcurl 检查标头
C++ libcurl check header before downloading body in one request
在C++中,我想使用 libcurl 来检查 URL 是否是文本/html,如果是,然后下载正文,否则它会停止。
我希望这个待办事项一步到位,而不是先发送 HEAD,如果 HEAD 没问题,请再次请求页面下载。
如果 libcurl 无法做到这一点,它是否为C++提供了其他 lib,这将支持这一点?
要发送 HTTP HEAD 请求,您需要设置此选项:
curl_easy_setopt(ctx,CURLOPT_NOBODY ,1 );
你也可以看看这个问题:在发送HTTP HEAD请求时需要libcurl编程的帮助
要将标题与正文分开(不知道是否真的需要),您可以查看:
http://curl.haxx.se/libcurl/c/sepheaders.html
要下载许多不同的网址libcurl-multi,您应该查看:
http://curl.haxx.se/libcurl/c/libcurl-multi.html
http://curl.haxx.se/libcurl/c/sendrecv.html 的轻微修改:
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
/* Auxiliary function that waits on the socket. */
static int wait_on_socket(curl_socket_t sockfd, int for_recv, long timeout_ms)
{
struct timeval tv;
fd_set infd, outfd, errfd;
int res;
tv.tv_sec = timeout_ms / 1000;
tv.tv_usec= (timeout_ms % 1000) * 1000;
FD_ZERO(&infd);
FD_ZERO(&outfd);
FD_ZERO(&errfd);
FD_SET(sockfd, &errfd); /* always check for error */
if(for_recv)
{
FD_SET(sockfd, &infd);
}
else
{
FD_SET(sockfd, &outfd);
}
/* select() returns the number of signalled sockets or -1 */
res = select(sockfd + 1, &infd, &outfd, &errfd, &tv);
return res;
}
int main(void)
{
CURL *curl;
CURLcode res;
/* Minimalistic http request */
const char *request = "GET / HTTP/1.0rnHost: m0g.netrnrn";
curl_socket_t sockfd; /* socket */
long sockextr;
size_t iolen;
curl_off_t nread;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://m0g.net");
/* Do not do the transfer - only connect to host */
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
res = curl_easy_perform(curl);
if(CURLE_OK != res)
{
printf("Error: %sn", strerror(res));
return 1;
}
/* Extract the socket from the curl handle - we'll need it for waiting.
* Note that this API takes a pointer to a 'long' while we use
* curl_socket_t for sockets otherwise.
*/
res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockextr);
if(CURLE_OK != res)
{
printf("Error: %sn", curl_easy_strerror(res));
return 1;
}
sockfd = sockextr;
/* wait for the socket to become ready for sending */
if(!wait_on_socket(sockfd, 0, 60000L))
{
printf("Error: timeout.n");
return 1;
}
puts("Sending request.");
/* Send the request. Real applications should check the iolen
* to see if all the request has been sent */
res = curl_easy_send(curl, request, strlen(request), &iolen);
if(CURLE_OK != res)
{
printf("Error: %sn", curl_easy_strerror(res));
return 1;
}
puts("Reading response.");
char data[2048];
int idxread=0;
/* read the response */
for(;;)
{
char buf[1024];
wait_on_socket(sockfd, 1, 60000L);
res = curl_easy_recv(curl, buf, 32, &iolen);
if(CURLE_OK != res)
break;
if (nread+idxread > 2048)
break;
strncpy(data+idxread,buf,nread);
idxread+=nread;
if (strstr(data,"rnrn") != NULL) {
if (strstr(data,"Content-Type: text/html") == NULL) {
printf("not an html document.");
return 2;
}
}
nread = (curl_off_t)iolen;
printf("Received %" CURL_FORMAT_CURL_OFF_T " bytes.n", nread);
}
printf("'''%s'''n", data);
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
这已经晚了几年,但这是cURL的原作者Linus Nielsen Feltzing提出的另一种方法。
#include <curl/curl.h>
int main(int argc, char *argv[])
{
CURLcode ret;
CURL *hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_URL, "http://www.haxx.se");
curl_easy_setopt(hnd, CURLOPT_HEADER, 1);
curl_easy_setopt(hnd, CURLOPT_NOBODY, 1);
ret = curl_easy_perform(hnd);
curl_easy_cleanup(hnd);
}
Linus在2007年curl-library
邮件列表中的一个帖子中提出了这个建议。
相关文章:
- 发送一个带有libcurl C++问题的帖子请求:s
- 使用libcurl提交批量url的正确BING Api POST url是什么
- 在 libcurl 连接池中预创建连接
- libcurl 和 DNS ttl 中的内部连接管理
- 如何在 cmake 库中包含 libcurl
- 如何应用 libcurl 的持久连接选项
- VS 2015 链接错误 无法构建依赖于 libcurl 的项目
- 组合字符串不适用于 libCurl,C++
- Poloniex API "Invalid command" c++ libcurl
- libcurl :显示正在运行的上传和下载速率
- c++ libCurl :如何使用libCurl接受过期的证书
- libcurl :C++处理多个异步请求
- 现代C++的libcurl和JSON问题
- 使用 Libcurl 库进行文件下载
- 如何在C++生成器中使用libcurl
- Libcurl c++ "undefined reference to" (Windows/MinGW/g++)
- 如何使用 libcurl 在本地 IP 上获取 HTML?
- 如何将带有 -F 选项的 curl 命令转换为 libcurl
- 如何使用 libCurl 将访问令牌发送到服务器 API
- C++ libcurl - 无法从 URL 检索整个 html 内容