--- /dev/null
+#! /usr/bin/perl -w
+
+use strict;
+use warnings;
+use utf8;
+
+use Getopt::Long;
+use Parallel::ForkManager;
+use LWP::Simple;
+use Time::HiRes qw(sleep);
+
+GetOptions(
+ 'h|help' => \ my $help,
+ 'i|inputfile=s' => \ my $file,
+ 'c|concurrency=i' => \ my $concurrency,
+ 'n|loops=i' => \ my $loops,
+ 'w|wait=f' => \ my $wait,
+) or usage();
+
+usage() if $help;
+
+$concurrency ||= 1;
+$loops ||= 1;
+$wait ||= 0;
+
+my @urls = file2urls($file) if ($file);
+push @urls, @ARGV;
+
+my $num = scalar @urls;
+warn "$num urls with $concurrency clients, $loops loops\n";
+warn "Total: ", $num * $concurrency * $loops, " requests\n";
+warn "wait for $wait second between requests\n";
+
+
+
+my $pm = Parallel::ForkManager->new($concurrency);
+for (my $i = 0; $i < $loops; $i++) {
+ for (my $child = 0; $child < $concurrency; $child++) {
+ $pm->start and next;
+ foreach my $url (@urls) {
+ get($url) or warn "fail: $url\n";
+ sleep($wait);
+ }
+ $pm->finish;
+ }
+ print STDERR " ... ", $num * $concurrency * ($i + 1), " requesting\r";
+}
+$pm->wait_all_children;
+
+warn "\n ...done.\n";
+
+
+sub usage {
+ warn "$0 -i urls.txt -c concurrency -n loops -w wait_interval\n",
+ " OR...\n",
+ "$0 url1 url2\n"
+ ;
+
+ exit;
+}
+
+sub file2urls {
+ my $file = shift;
+
+ open my $fh, '<', $file or die "$file: $!";
+
+ my(@urls, $url);
+ while ($url = <$fh>) {
+ chomp $url;
+ push @urls, $url;
+ }
+
+ return @urls;
+}