mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-15 09:20:52 +08:00
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);
|
|||
|
|
|||
|
// <20><>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP <20>б<EFBFBD>
|
|||
|
if (dns_lookup(domain, ips) == false)
|
|||
|
{
|
|||
|
delete this;
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
gettimeofday(&end, NULL);
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD> DNS <20>IJ<EFBFBD>ѯ<EFBFBD><D1AF>ʱ
|
|||
|
double spent = util::stamp_sub(&end, &begin);
|
|||
|
|
|||
|
std::vector<acl::thread*> threads;
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD> IP <20><>ַ<EFBFBD>б<EFBFBD><D0B1><EFBFBD>ÿһ<C3BF><D2BB> IP <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> HTTP <20>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD>߳<EFBFBD>
|
|||
|
std::vector<acl::string>::const_iterator cit = ips.begin();
|
|||
|
for (; cit != ips.end(); ++cit)
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>̶߳<DFB3><CCB6><EFBFBD>
|
|||
|
acl::thread* thr = new http_thread(domain, (*cit).c_str(),
|
|||
|
port, url_.c_str(), spent);
|
|||
|
thr->set_detachable(false); // <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>Ϊ<EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>״̬
|
|||
|
thr->start();
|
|||
|
threads.push_back(thr);
|
|||
|
}
|
|||
|
|
|||
|
// <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
std::vector<acl::thread*>::iterator it = threads.begin();
|
|||
|
for (; it != threads.end(); ++it)
|
|||
|
{
|
|||
|
acl::thread* thr = (*it);
|
|||
|
thr->wait();
|
|||
|
delete thr;
|
|||
|
}
|
|||
|
|
|||
|
delete this; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
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_);
|
|||
|
|
|||
|
// ֱ<><D6B1><EFBFBD><EFBFBD> DNS <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DNS <20><>ѯ<EFBFBD><D1AF><EFBFBD>ݰ<EFBFBD>
|
|||
|
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;
|
|||
|
}
|