mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-15 01:10:52 +08:00
4a219509b9
some new features, and some bug fixed
118 lines
2.2 KiB
C++
118 lines
2.2 KiB
C++
#include "stdafx.h"
|
|
#include "util.h"
|
|
#include "http_thread.h"
|
|
#include "http_job.h"
|
|
|
|
http_job::http_job(acl::thread_pool& thrpool, const char* url,
|
|
const char* dns_ip, int dns_port)
|
|
: thrpool_(thrpool)
|
|
, url_(url)
|
|
, dns_ip_(dns_ip)
|
|
, dns_port_(dns_port)
|
|
{
|
|
}
|
|
|
|
http_job::~http_job()
|
|
{
|
|
}
|
|
|
|
void* http_job::run()
|
|
{
|
|
char addr[256];
|
|
if (acl::http_utils::get_addr(url_, addr, sizeof(addr)) == false)
|
|
{
|
|
logger_error("invalid url: %s", url_.c_str());
|
|
return NULL;
|
|
}
|
|
|
|
char* domain = addr, *ptr = strchr(domain, ':');
|
|
int port;
|
|
if (ptr == NULL)
|
|
port = 80;
|
|
else
|
|
{
|
|
*ptr++ = 0;
|
|
port = atoi(ptr);
|
|
}
|
|
|
|
std::vector<acl::string> ips;
|
|
|
|
struct timeval begin, end;
|
|
|
|
gettimeofday(&begin, NULL);
|
|
|
|
// 查询域名的 IP 列表
|
|
if (dns_lookup(domain, ips) == false)
|
|
{
|
|
delete this;
|
|
return NULL;
|
|
}
|
|
|
|
gettimeofday(&end, NULL);
|
|
|
|
// 计算 DNS 的查询耗时
|
|
double spent = util::stamp_sub(&end, &begin);
|
|
|
|
std::vector<acl::thread*> threads;
|
|
|
|
// 遍历 IP 地址列表,每一个 IP 创建一个 HTTP 客户端线程
|
|
std::vector<acl::string>::const_iterator cit = ips.begin();
|
|
for (; cit != ips.end(); ++cit)
|
|
{
|
|
// 创建并启动一个线程对象
|
|
acl::thread* thr = new http_thread(domain, (*cit).c_str(),
|
|
port, url_.c_str(), spent);
|
|
thr->set_detachable(false); // 设置线程为非分离状态
|
|
thr->start();
|
|
threads.push_back(thr);
|
|
}
|
|
|
|
// 等待所有 HTTP 工作线程执行完毕
|
|
std::vector<acl::thread*>::iterator it = threads.begin();
|
|
for (; it != threads.end(); ++it)
|
|
{
|
|
acl::thread* thr = (*it);
|
|
thr->wait();
|
|
delete thr;
|
|
}
|
|
|
|
delete this; // 自销毁
|
|
return NULL;
|
|
}
|
|
|
|
bool http_job::dns_lookup(const char* domain, std::vector<acl::string>& ips)
|
|
{
|
|
ACL_RES *res;
|
|
ACL_DNS_DB *dns_db;
|
|
|
|
res = acl_res_new(dns_ip_.c_str(), dns_port_);
|
|
|
|
// 直接向 DNS 服务器发送 DNS 查询数据包
|
|
dns_db = acl_res_lookup(res, domain);
|
|
if (dns_db == NULL)
|
|
{
|
|
logger_error("acl_res_lookup failed, dns addr: %s:%d, domain: %s",
|
|
dns_ip_.c_str(), dns_port_, domain);
|
|
acl_res_free(res);
|
|
return false;
|
|
}
|
|
|
|
ACL_ITER iter;
|
|
acl_foreach(iter, dns_db)
|
|
{
|
|
ACL_HOST_INFO* info = (ACL_HOST_INFO*) iter.data;
|
|
ips.push_back(info->ip);
|
|
}
|
|
|
|
acl_res_free(res);
|
|
acl_netdb_free(dns_db);
|
|
|
|
if (ips.empty())
|
|
{
|
|
logger_error("no ip for domain: %s", domain);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|