AnyEvent-Whois-Raw

 view release on metacpan or  search on metacpan

lib/AnyEvent/Whois/Raw.pm  view on Meta::CPAN

			$resp = Net::Whois::Raw::Common::parse_www_content($resp, $tld, $qurl->{url}, $Net::Whois::Raw::CHECK_EXCEED);
			push @{$stash->{results}{www_whois_query}}, $resp;
			$stash->{calls}{www_whois_query} = 0;
			$stash->{caller}->(@{$stash->{args}});
		}
	};
	
	my $headers = {Referer => $referer};
	my @params;
	push @params, on_prepare => sub { 
		my $fh = shift;
		local $stash = $stash_ref;
		_sock_prepare_cb($fh, 'www_whois');
	};
	
	if (exists $stash->{params}{timeout}) {
		push @params, timeout => $stash->{params}{timeout};
	}
	
	if ($method eq 'POST') {
		require URI::URL;
		
		my $curl = URI::URL->new("http:");
		$curl->query_form( %{$qurl->{form}} );
		http_post $qurl->{url}, $curl->equery, headers => $headers, @params, $cb;
	}
	else {
		http_get $qurl->{url}, headers => $headers,  @params, $cb;
	}
}

1;

__END__

How Net::Whois::Raw works:
whois
	get_whois
		get_all_whois  __
		|                \
		recursive_whois   www_whois_query
		|                 [BLOCKING]  
		whois_query
		[BLOCKING]        

There are two blocking functions.

What we do:
First of all redefine two blocking functions to non-blocking AnyEvent equivalents.
Now when get_all_whois will call whois_query or www_whois_query our AnyEvent
equivalents will be started. But when AnyEvent based function called result not ready
yet and we should interrupt get_all_whois. We do it using die("Call me later").
_whois and _get_whois ready to receive exception, they uses eval to catch it and calls
callback only if there was no exceptions. When result from AnyEvent based function becomes
ready it saves result and calls _whois or _get_whois again with same arguments as before interrupt.
So, now get_all_whois will not block because result already ready. Net::Whois::Raw::whois() or
Net::Whois::Raw::get_whois() will return without exceptions and so, callback will be called.
To store current state we are using localized stash.
recursive_whois() has one problem, it catches exceptions and our die("Call me later") will not interrupt
it. We using require hook to workaround it. We replace eval with our
defined smart_eval, which will rethrow exception if it was our exception.

=pod

=head1 NAME

AnyEvent::Whois::Raw - Non-blocking wrapper for Net::Whois::Raw

=head1 SYNOPSIS

  use AnyEvent::Whois::Raw;
  
  $Net::Whois::Raw::CHECK_FAIL = 1;
  
  whois 'google.com', timeout => 10, sub {
    my $data = shift;
    if ($data) {
      my $srv = shift;
      print "$data from $srv\n";
    }
    elsif (! defined $data) {
      my $srv = shift;
      print "no information for domain on $srv found";
    }
    else {
      my $reason = shift;
      print "whois error: $reason";
    }
  };

=head1 DESCRIPTION

This module provides non-blocking AnyEvent compatible wrapper for Net::Whois::Raw.
It is not trivial to make non-blocking module from blocking one without full rewrite.
This wrapper makes such attempt. To decide how ugly or beautiful this attempt implemented
see source code of the module.

=head1 IMPORT

whois() and get_whois() by default

=head1 Net::Whois::Raw compatibilities and incompatibilities

=over

=item All global $Net::Whois::Raw::* options could be specified to change the behavior

=item User defined functions such as *Net::Whois::Raw::whois_query_sockparams and others
will not affect anything

=item In contrast with Net::Whois::Raw whois and get_whois from this module will never die.
On error first parameter of the callback will be false and second will contain error reason

=back

=head1 FUNCTIONS

=head2 whois DOMAIN [, SRV [, WHICH_WHOIS] [, %PARAMS]], CB

DOMAIN, SRV and WHICH_WHOIS are same as whois arguments from Net::Whois::Raw.



( run in 1.524 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )