#!/usr/bin/perl # vim: set ts=4 sw=4 tw=78 et si: # # http-injektor # use 5.010; use strict; use warnings; use Getopt::Long; use IO::Socket; use Pod::Usage; use Time::HiRes qw(gettimeofday sleep); my %opt; GetOptions( \%opt, 'help|?', 'manual', 'delay=i', 'input=s', 'output=s', 'proxy=s') or pod2usage(2); pod2usage(-exitval => 0, -verbose => 1, -input => \*DATA) if ($opt{help}); pod2usage(-exitval => 0, -verbose => 2, -input => \*DATA) if ($opt{manual}); my $server = shift; my $port = shift || 80; pod2usage(-exitval => 0, -verbose => 1, -input => \*DATA) unless ($server); my $socket = get_socket($server, $port, \%opt) or die "Can't get socket for $server:$port: $!"; my $input = get_input(\%opt); my $output = get_output(\%opt); my $t0 = gettimeofday; send_request($socket, $input, \%opt); my $t1 = gettimeofday; while (my $line = <$socket>) { print $output $line; } my $t2 = gettimeofday; close($output) if ( $opt{output} ); close($input) if ( $opt{input} ); close($socket); my $treq = $t1 - $t0; my $trep = $t2 - $t1; print "Request took $treq seconds.\nReply took $trep seconds.\n"; #---- only functions following ----- sub get_input { my ($opt) = @_; my $in; if ($opt->{input} && open($in, '<', $opt->{input})) { return $in; } return *STDIN; } # get_input() sub get_output { my ($opt) = @_; my $out; if ($opt->{output} && open($out, '>', $opt->{output})) { return $out; } return *STDOUT; } # get_output() sub get_socket { my ($server,$port,$opt) = @_; my $socket; if ($opt->{proxy}) { if ($opt->{proxy} =~ m|^(http://)?([^:]+):([0-9]+)?|) { my $pserver = $2; my $pport = $3; $socket = IO::Socket::INET->new(PeerAddr => $pserver, PeerPort => $pport, Proto => 'tcp', Type => SOCK_STREAM) or die "Can't get socket for proxy $pserver:$pport: $!"; print $socket "CONNECT $server:$port HTTP/1.0\r\n\r\n"; while (<$socket>) { last if /^[\r\n]?$/; } } } else { $socket = IO::Socket::INET->new(PeerAddr => $server, PeerPort => $port, Proto => 'tcp', Type => SOCK_STREAM); } return $socket; } # get_socket() sub send_request { my ($socket, $input, $opt) = @_; if (my $delay = $opt->{delay}) { my @in = <$input>; my $del = $delay / ( 1.0 + scalar @in ); foreach (@in) { s/[\r\n]+$//; sleep $del; print $socket $_, "\r\n"; } sleep $del; } else { while (<$input>) { s/[\r\n]+$//; print $socket $_, "\r\n"; } } print $socket "\r\n"; } # send_request() __END__ =head1 NAME http-injektor - inject HTTP requests with deliberate delay =head1 SYNOPSIS http-injektor [options] [server [port]] Send a HTTP request from stdin to port C (default 80) on server C (default I) and print the reply to stdout. =head1 OPTIONS =over 8 =item B<< -help >> Print a brief help message and exit. =item B<< -manual >> Print the manual page and exit. =item B<< -delay time >> Delay the request for I<< time >> seconds (only full seconds). =item B<< -input filename >> Read request for server form file I<< filename >> instead from STDIN. =item B<< -output filename >> Write output from server to file I<< filename >> instead to STDOUT. =item B<< -proxy proxyserver:proxyport >> Use HTTP proxy at I<< proxyserver >> with TCP port I<< proxyport >> to connect to the server. =back =head1 DESCRIPTION This program will do nothing. =head1 AUTHOR Mathias Weidner