2014-11-18 23:08:34 +08:00
# 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 ;
}