#!/usr/bin/perl

use strict;
use Getopt::Std;
use HTTPD::Bench::ApacheBench;

my %options;
getopt('ncpC', \%options);
getopts('V', \%options);

if ($options{'V'}) {
    &show_version;
    exit;
}
if (!@ARGV) {
    &show_usage;
    exit;
}

my $postdata;
if ($options{'p'}) {
    open(FILE, $options{'p'});
    $postdata = join('', <FILE>);
    close FILE;
}

my $c = $options{'c'} || 1;
my $n = $options{'n'} || 1;


my $b = HTTPD::Bench::ApacheBench->new;
$b->concurrency($c);
my $r = HTTPD::Bench::ApacheBench::Run->new
  ({
    cookies   => [ $options{'C'} ],
    urls      => [ map { $ARGV[0] } 1..$n ],
    postdata  => [ map { $postdata } 1..$n ],
    memory    => 2,
   });
$b->add_run($r);

$b->execute;

&show_results();


sub show_results {
    my $time_in_sec = $b->total_time / 1000;
    my $hps = $n / $time_in_sec;
    my $kps = $b->bytes_received / 1024 / $time_in_sec;

    my $completed_requests = $b->total_responses_received;
    my $failed_requests = $b->total_requests - $completed_requests;

    my $doc_length = $r->response_body_lengths()->[0];
    my $html_size = $n * $doc_length;
    my $total_bytes_read = $r->sum_bytes_read();

    my ($software) = ( $r->response_headers()->[0] =~ m/Server: (.*)/ );
    my ($hostname) = ( $r->urls()->[0] =~ m,http://([^/:]+), );
    my ($port) = ( $r->urls()->[0] =~ m,http://[^/:]+:(\d+), );
    $port = 80 unless $port;
    my ($path) = ( $r->urls()->[0] =~ m,http://[^/]+(/.*), );

    &show_version;
    print qq`Server Software:        $software
Server Hostname:        $hostname
Server Port:            $port

Document Path:          $path
Document Length:        $doc_length bytes

Concurrency Level:      $c
Time taken for tests:   $time_in_sec seconds
Completed requests:     $completed_requests
Failed requests:        $failed_requests
Total transferred:      $total_bytes_read bytes
HTML transferred:       $html_size bytes
Requests per second:    $hps
Transfer rate:          $kps kb/s received

Connnection Times (ms)
              min   avg   max
Connect:   `.sprintf("%6d%6d%6d",
		     $r->min_connect_time,
		     $r->avg_connect_time,
		     $r->max_connect_time).qq`
Response:  `.sprintf("%6d%6d%6d",
		     $r->min_response_time,
		     $r->avg_response_time,
		     $r->max_response_time)
  ."\n";
}


sub show_usage {
    print qq`Usage: $0 [options] http://hostname[:port]/path
Options are:
    -n requests     Number of requests to perform
    -c concurrency  Number of multiple requests to make
    -p postfile     File containg data to POST
    -C attribute    Add cookie, eg. 'Apache=1234'
    -V              Print version number and exit
    -h              Display usage information (this message)
`;
}


sub show_version {
    print qq`This is ab implemented using the ApacheBench Perl API, version 0.2
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998-1999 The Apache Group, http://www.apache.org/
Copyright (c) 2000-2001 Ling Wu, Adi Fairbank, http://www.certsite.com/

`;
}
