简介
最近在做一个crawler,为了更好的发挥抓取web的能力,需要用到异步http。其中DNS解析、下载都需要异步。 本组件基于WinHTTP实现,如果以后有需要再从头构造轮子吧(基于iocp的异步框架)。
对于WinHTTP的思想,MSDN很多介绍,这里,这里
说明
该组件使用十分简单,只需要完成几种回调接口即可
1. 完成HTTP HEADER
2. 完成HTTP 整个内容
3. 读取HTTP正文
4. 跳转URL
5. 错误处理
针对WinHTTP的思想,抽象了几个重要概念
1. url--对URL的一个简单wrapper
2. session--每个http访问都会产生一个session,用于记录状态及调整访问策略属性
3. connection--链接到http服务器需要此对象,通过一个session和一个url来构造一个链接
4. request--链接上服务器后需要请求服务器上相应资源,控制请求服务器方式
示例
void header(const http::request &req, std::uint32_t size)
{
http::query::raw_headers accept;
req.query_http_header(accept);
http::query::content_type content_type;
req.query_http_header(content_type);
http::query::date date;
req.query_http_header(date);
http::query::expires expires;
req.query_http_header(expires);
std::wcout << (const wchar_t *)accept.buffer() << std::endl << size << std::endl;
}
void response_complete(bool suc)
{
assert(suc);
}
bool read(const char *buf, size_t len)
{
std::cout.write(buf, len);
return true;
}
void redirect(const wchar_t *url, size_t len)
{
std::cout << url << std::endl;
}
void error(const std::string &msg)
{
std::cout << msg << std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
try
{
http::session session(L"test");
std::chrono::seconds second(5);
session.set_timeout(second, second, second, second);
http::url url(L"http://www.baidu.com");
http::connection con(session, url);
http::request request(con, L"GET", url);
/*request.set_option(http::option::security(SECURITY_FLAG_IGNORE_CERT_CN_INVALID
| SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
| SECURITY_FLAG_IGNORE_UNKNOWN_CA));
request.set_option(http::option::user_name(L"default proxy name"));
request.set_option(http::option::password(L"default proxy password"));*/
request.register_callback(&header, &response_complete, &read, &redirect, &error);
request.send_request(L"");
system("pause");
}
catch(std::exception &e)
{
std::cerr << e.what() << std::endl;
}
system("pause");
return 0;
}
可以看到,接口使用非常简单,这里有几个需要注意的地方。
1. std::chrono::seconds,这是最新进入标准库的time libaray,具体请参看文档
2. request.set_option(...),针对访问策略进行属性配置,这里预定义了一组option,具体参看源码
3. request.register_callback,这就是对处理过程的回调注册。有
注意:本组件使用C++0x写成,开发环境VS2010以上。
遗憾
当然,本组件还很不完善,但是对于目前我的应用来说已经够用,如果遇到需要扩展的,也十分容易。
比如可以加上身份验证、代理设置
如有不妥之处,请大家互相讨论,谢谢。
下载