proxyhunter

 view release on metacpan or  search on metacpan

lib/App/ProxyHunter.pm  view on Meta::CPAN

	my ($class, $model, $conditions, $rules, $interval) = @_;
	
	$conditions->{in_progress} = 0;
	$rules->{limit} = SELECT_LIMIT;
	
	my $iter = $model->search('proxy', $conditions, $rules);
	my $now = DateTime->now(time_zone => TZ);
	my $date_column = $rules->{order_by};
	
	my @rows;
	my @ids;
	
	while (my $proxy = $iter->next) {
		if (defined $interval && 
			$interval - $now->subtract_datetime_absolute($proxy->$date_column)->seconds > MAX_SEC_IN_QUEUE) {
			
			next;
		}
		
		push @rows, $proxy;
		push @ids, $proxy->id;
	}
	
	if (@ids) {
		$model->update('proxy', {in_progress => 1}, {id => \@ids});
	}
	
	return @rows;
}

my %name2type = reverse %Net::Proxy::Type::NAME;
sub _check {
	my ($class, $checker, $types, $proxy) = @_;
	
	my $full_mask = 0;
	$full_mask |= $_ for map { $name2type{$_} } @$types;
	my @check_mask;
	
	if ($proxy->type) {
		# first check for previous type of the proxy to speed up
		push @check_mask, $proxy->type;
		push @check_mask, $full_mask&(~$proxy->type);
	}
	else {
		push @check_mask, $full_mask;
	}
	
	for my $mask (@check_mask) {
		next unless $mask;
		my ($type, $conn_time) = $checker->get($proxy->host, $proxy->port, $mask);
		
		unless ($type == DEAD_PROXY || $type == UNKNOWN_PROXY) {
			return ($type, $conn_time);
		}
	}
	
	return;
}

my %uri_scheme = (
	&HTTP_PROXY    => 'http',
	&CONNECT_PROXY => 'connect',
	&HTTPS_PROXY   => 'connect',
	&SOCKS4_PROXY  => 'socks4',
	&SOCKS5_PROXY  => 'socks',
);

sub _check_speed {
	my ($class, $checker, $config, $proxy) = @_;
	
	$checker->proxy(['http', 'https'] => sprintf('%s://%s:%s', $uri_scheme{$proxy->type}, $proxy->host, $proxy->port));
	
	my @speed_variations;
	my $received_bytes = 0;
	my $curspeed;
	my $maxbytes = 1024*1024;
	my $start = Time::HiRes::time();
	
	my $resp = $checker->get(
		$proxy->type == HTTPS_PROXY ? $config->https_url : $config->http_url,
		':content_cb' => sub {
			$received_bytes += length($_[0]);
			$curspeed = $received_bytes / (Time::HiRes::time() - $start);
			die if $received_bytes > $maxbytes;
			
			if (@speed_variations == 10) {
				my $ok = 1;
				for my $sv (@speed_variations) {
					if (abs($sv - $curspeed) > 5 * 1024) {
						$ok = 0;
						last;
					}
				}
				
				die if $ok;
				shift @speed_variations;
			}
			
			push @speed_variations, $curspeed;
		}
	);
	
	return if $resp->code > 299;
	return int($curspeed);
}

1;

=pod

=head1 NAME

App::ProxyHunter - main proxyhunter's class

=head1 METHODS

=head2 App::ProxyHunter->start(@ARGV)

Static method to start C<proxyhunter> execution. @ARGV is a list with options which C<proxyhunter> understands.

=head1 SEE ALSO



( run in 0.373 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )