use strict; use warnings; # Provide a simple server that can be used to test the various bits. package TestServer; use base qw/Test::HTTP::Server::Simple HTTP::Server::Simple::CGI/; use Time::HiRes qw(sleep time); use Data::Dumper; use LWP::UserAgent; sub handle_request { my ( $self, $cgi ) = @_; my $params = $cgi->Vars; # If we are on port 8081 then we are a proxy - we should forward the # requests. return act_as_proxy(@_) if $self->port == 8081; # We should act as a final destination server and so expect an absolute URL. my $request_uri = $ENV{REQUEST_URI}; if ( $request_uri !~ m!^/! ) { warn "ERROR - not absolute request_uri '$request_uri'"; return; } # Flush the output so that it goes straight away. Needed for the timeout # trickle tests. $self->stdout_handle->autoflush(1); # warn "START REQUEST - " . time; # Do the right thing depending on what is asked of us. if ( exists $params->{redirect} ) { my $num = $params->{redirect} || 0; $num--; if ( $num > 0 ) { print $cgi->redirect( -uri => "?redirect=$num", -nph => 1, ); print "You are being redirected..."; } else { print $cgi->header( -nph => 1 ); print "No longer redirecting"; } } elsif ( exists $params->{delay} ) { sleep( $params->{delay} ); print $cgi->header( -nph => 1 ); print "Delayed for '$params->{delay}'.\n"; } elsif ( exists $params->{trickle} ) { my $trickle_for = $params->{trickle}; my $finish_at = time + $trickle_for; print $cgi->header( -nph => 1 ); while ( time <= $finish_at ) { print time . " trickle $$\n"; sleep 0.1; } print "Trickled for '$trickle_for'.\n"; } elsif ( exists $params->{bad_header} ) { my $headers = $cgi->header( -nph => 1, ); # trim trailing whitspace to single newline. $headers =~ s{ \s* \z }{\n}xms; # Add a bad header: $headers .= "Bad header: BANG!\n"; print $headers . "\n\n"; print "Produced some bad headers."; } elsif ( my $when = $params->{break_connection} ) { for (1) { last if $when eq 'before_headers'; print $cgi->header( -nph => 1 ); last if $when eq 'before_content'; print "content\n"; } } elsif ( my $id = $params->{set_time} ) { my $now = time; print $cgi->header( -nph => 1 ); print "$id\n$now\n"; } elsif ( exists $params->{not_modified} ) { my $last_modified = HTTP::Date::time2str( time - 60 * 60 * 24 ); print $cgi->header( -status => '304', -nph => 1, 'Last-Modified' => $last_modified, ); print "content\n"; } else { warn "DON'T KNOW WHAT TO DO: " . Dumper $params; } # warn "STOP REQUEST - " . time; } sub act_as_proxy { my ( $self, $cgi ) = @_; my $request_uri = $ENV{REQUEST_URI}; # According to the RFC the request_uri must be fully qualified if the # request is to a proxy and absolute if it is to a destination server. CHeck # that this is the case. # # http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2 if ( $request_uri !~ m!^http://! ) { warn "ERROR - not fully qualified request_uri '$request_uri'"; return; } my $response = LWP::UserAgent->new( max_redirect => 0 )->get($request_uri); # Add a header so that we know that this was proxied. $response->header( WasProxied => 'yes' ); print $response->as_string; return 1; } 1;