Listing 3: The code for run_test() and its helpers random_string() and escape() sub run_test { my $doit = shift; for (1..$TIMES) { sleep(rand $DELAY) if $DELAY; # create a string of random stuff my $garbage = random_string(rand $MAXLEN) if $MAXLEN > 0; $garbage = escape($garbage) unless $RAW; my @parameters; CASE: { if (length($garbage) == 0) { @parameters = ($URL); last CASE; } if ($POST) { @parameters = ($URL,$garbage); last CASE; } if ($PATH) { chop($url) if substr($url,-1,1) eq '/'; @parameters = ("$URL/$garbage"); last CASE; } @parameters = ("$URL?$garbage"); } my ($status,$message,$contents); my $start = time(); ($status,$message,$contents) = fetch(@parameters) if $doit; ($status,$message,$contents) = (200,'','') unless $doit; my $elapsed = time() - $start; my $bytes = length($garbage) + length($contents); warn "$$: ",$message,"\n" if $status >= 500; print join("\t",$$,$elapsed,$bytes,$status),"\n"; } } # return some random data of the requested length sub random_string { my $length = shift; my $string = ' ' x $length; for (my $i=0;$i<$length;$i++) {substr($string,$i,1) = chr(rand(255)); } return $string; } # replacement for URI::escape sub escape { my $s = shift; $s =~ s/([^;\/?:@&=+\$,A-Za-z0-9\-_.!~*\'()])/$ESCAPES{$1}/g; return $s; }