use Data::Dumper; use IO::Zlib; use POE qw( Component::Client::HTTP Component::Client::DNS ); use POE::Session; use HTTP::Request; use File::Temp qw/ tempfile /; use MIME::Base64; my $number_of_urls; my @responses; my $uname = $ARGV[0] || die("first arg is grub username"); my $pass = $ARGV[1] || die("second arg is grub password"); POE::Component::Client::HTTP->spawn( Agent => 'POEGrubCrawler/0.01', Alias => 'useragent', Timeout => 10, FollowRedirects => 0, ); POE::Component::Client::HTTP->spawn( Agent => 'POEGrubCrawler/0.01', Alias => 'putagent', Timeout => 600, FollowRedirects => 2, ); sub got_response { my ($kernel, $heap, $request_packet, $response_packet ) = @_[ KERNEL, HEAP, ARG0, ARG1 ]; my $http_request = $request_packet->[0]; my $http_response = $response_packet->[0]; my $tag = $request_packet->[1]; my $response_string = $http_response->as_string(); $response_string =~ s/^/| /mg; print 'request '.$tag." = ".$http_response->status_line,"\n"; # http://www.tea-and-coffee.com/ 195.7.239.133 19691231175959 text/html 19468 my $body = $http_response->as_string; my $ctype = $http_response->content_type || "message/http"; my $ip = $http_response->header("client-peer") || "127.0.0.1"; $ip =~ s/([\d|\.]+)/$1/; $responses[$tag] = "\n".$http_request->uri." $ip 19691231175959 $ctype ".length($body)."\n$body"; $heap->{done}++; if ($heap->{done} == $number_of_urls) { print "Work unit completed \n"; my $j = 0; my ($fh, $filename) = tempfile(); $arc = IO::Zlib->new($filename, "wb"); print $arc <new( PUT, $heap->{put_url} ); $request->content($content); $request->header("Content-Length" => length($content)); $kernel->post( 'putagent', 'request', 'got_submission_result', $request ); } } sub got_submission_result { my ($kernel, $heap, $request_packet, $response_packet ) = @_[ KERNEL, HEAP, ARG0, ARG1 ]; my $http_request = $request_packet->[0]; my $http_response = $response_packet->[0]; my $response_string = $http_response->as_string(); $response_string =~ s/^/| /mg; print ",", '-' x 78, "\n"; print $response_string; print "`", '-' x 78, "\n"; $kernel->yield("get_units"); } sub got_units { my ($kernel, $heap, $request_packet, $response_packet ) = @_[ KERNEL, HEAP, ARG0, ARG1 ]; my $request_object = $request_packet->[0]; my $response_object = $response_packet->[0]; my $response_string = $response_object->as_string(); my $stream_chunk; # HTTP::Response if (! defined($response_object->content)) { $stream_chunk = $response_packet->[1]; } my @workunits; my $i = 0; foreach my $unit (split /\r\n\r\n/, $response_object->as_string) { my ($first, @headers) = split /\r\n/, $unit; my ($method, $path) = split / /,$first; my $host; foreach my $header (@headers) { $host = $1 if($header =~ /Host\: (.+)$/); } if($method eq "PUT") { $heap->{put_url} = "http://$host$path"; } else { # print "GET "."http://$host$path"."\n"; push @workunits, "http://$host$path"; $kernel->post( 'useragent', 'request', 'got_response', HTTP::Request->new( GET, "http://$host$path", ), $i++ ); } } $number_of_urls = $i; @responses = (); print "Sent $i requests\n"; } sub _start { my ( $heap, $kernel ) = @_[ HEAP, KERNEL ]; $kernel->yield("get_units"); } sub get_units { my ( $heap, $kernel ) = @_[ HEAP, KERNEL ]; print "Getting a workunit\n"; $kernel->post( 'useragent', 'request', 'got_units', HTTP::Request->new( GET, 'http://dispatch.grub.swlabs.org/do/workunit', HTTP::Headers->new( Authorization => 'Basic '.encode_base64($uname.':'.$pass), ) ) ); } POE::Session->create( package_states => [ main => [ "_start", "got_response", "got_units", "get_units", "got_submission_result", ] ] ); $poe_kernel->run();