use strict; use Test::More; #plan skip_all => 'MSWin32 does not have a proper fork()' if $^O eq 'MSWin32'; BEGIN { eval { require POE::Component::Client::HTTP; }; plan skip_all => 'POE::Component::Client::HTTP is required for this test' if $@; } plan tests => 6; use HTTP::Request; use POE; use POE::Kernel; #sub POE::Component::Server::SimpleHTTP::DEBUG () { 1 } use POE::Component::Server::SimpleHTTP; my $PORT = 2080; my $IP = "localhost"; our %STREAMS; #################################################################### POE::Component::Server::SimpleHTTP->new( 'ALIAS' => 'HTTPD', 'ADDRESS' => "$IP", 'PORT' => $PORT, 'HOSTNAME' => 'pocosimpletest.com', 'HANDLERS' => [ { 'DIR' => '.*', 'SESSION' => 'HTTP_GET', 'EVENT' => 'GOT_MAIN', }, ], SETUPHANDLER => { SESSION => 'HTTP_GET', EVENT => '_tests', }, ); # Create our own session to receive events from SimpleHTTP POE::Component::Client::HTTP->spawn( Agent => 'TestAgent', Alias => 'ua', Protocol => 'HTTP/1.1', From => 'test@tester', Streaming => 100, Proxy => q{}, ); POE::Session->create( inline_states => { '_start' => sub { $_[KERNEL]->alias_set( 'HTTP_GET' ); $_[KERNEL]->yield('keepalive'); return; }, '_tests' => \&_tests, 'GOT_MAIN' => \&GOT_MAIN, 'GOT_STREAM' => \&GOT_STREAM, keepalive => \&keepalive, response => \&response, '_shutdown' => \&_shutdown, 'on_close' => \&on_close, }, ); $poe_kernel->run(); is( 0+keys %STREAMS, 0, "No open streams" ); exit 0; sub GOT_MAIN { # ARG0 = HTTP::Request object, ARG1 = HTTP::Response object, ARG2 = the DIR that matched my( $kernel, $heap, $request, $response, $dirmatch ) = @_[KERNEL, HEAP, ARG0 .. ARG2 ]; # Do our stuff to HTTP::Response $response->code( 200 ); $response->content_type("text/plain"); print "# GOT_MAIN \n"; # sets the response as streamed within our session with the stream event $response->stream( session => 'HTTP_GET', event => 'GOT_STREAM' ); $heap->{'count'} ||= 0; my $c = $response->connection; $STREAMS{ $c->ID }=1; $_[KERNEL]->call( $_[SENDER], 'SETCLOSEHANDLER', $c, 'on_close', $c->ID ); # We are done! $kernel->yield('GOT_STREAM', $response); return; } sub GOT_STREAM { my ( $kernel, $heap, $response ) = @_[KERNEL, HEAP, ARG0]; # lets go on streaming ... if ($heap->{'count'} <= 2) { my $text = "Hello World ".$heap->{'count'}." \n"; #print "send ".$text."\n"; $response->content($text); $heap->{'count'}++; POE::Kernel->post('HTTPD', 'STREAM', $response); } else { $STREAMS{ $response->connection->ID }--; POE::Kernel->post('HTTPD', 'CLOSE', $response ); } return; } sub keepalive { my $heap = $_[HEAP]; $_[KERNEL]->delay_set('keepalive', 1); return; } sub _shutdown { $poe_kernel->alarm_remove_all(); $poe_kernel->alias_remove( 'HTTP_GET' ); $poe_kernel->post( 'ua', 'shutdown' ); $poe_kernel->post( 'HTTPD', 'SHUTDOWN' ); return; } sub _tests { my ( $kernel, $heap, $session ) = @_[KERNEL, HEAP, SESSION ]; $heap->{'client_count'} = 0; my $request = HTTP::Request->new(GET => "http://$IP:$PORT/"); diag('Test a stream of 3 helloworlds ..'); POE::Kernel->post('ua', 'request', 'response', $request); return; } sub response { my ( $kernel, $heap, $session, $request_packet, $response_packet ) = @_[KERNEL, HEAP, SESSION, ARG0, ARG1]; my $return; # HTTP::Request my $request = $request_packet->[0]; my $response = $response_packet->[0]; # the PoCoClientHTTP sends the first chunk in the content # of the http response #if ($heap->{'count'} == 1) { # my $data = $response->content; # chomp($data); #print $data."\n"; # ok($data =~ /Hello World 0/, "First one as response content received"); #} # then all streamed data in the second element of the response # array ... my ($resp, $data) = @$response_packet; return unless $data; chomp($data); foreach my $hello ( split /\n/, $data ) { ok($hello =~ /Hello World/, "Received a hello"); $heap->{'client_count'}++; } if ($heap->{'client_count'} == 3) { is($heap->{'client_count'}, 3, "Got 3 streamed helloworlds ... all good :)"); $kernel->yield( '_shutdown' ); return; } return; } sub on_close { my $wid = $_[ARG0]; is( $STREAMS{$wid}, 0, "on_close comes after CLOSE" ); delete $STREAMS{ $wid } if $STREAMS{ $wid } == 0; }