#!/usr/bin/perl

use URI::Escape qw(uri_escape);
use IO::Socket;

$debug = 1;

sub usage {
    print STDERR "usage: $0 <url> <var=val>...\n";
    exit(-1);
}

if ($#ARGV == -1) {
    usage();
}

# parse out the URL

$url = shift(@ARGV);
$url =~ m#^http://([-a-z0-9.]+)(:\d+)?(/.*)# || usage();

$host = $1;
$port = $2;
$doc = $3;
$host_hdr = $host . $port;

if (length($port) > 0) {
    $port =~ s/^://;
} else {
    $port = 80;
}

$debug && print STDERR "host = $host\nport = $port\ndoc = $doc\nhost-hdr = $host_hdr\n";

# now construct our data string
$data_string = "";
$first_one = 1;

while ($_ = shift(@ARGV)) {
    /([^=]+)=(.*)/ || do {
	print STDERR "bad <var>=<val>: $_\n";
	usage();
    };

    if ($first_one == 0) {
	$data_string .= '&';
    }
    $data_string .= "$1=" . uri_escape($2);

    $first_one = 0;
}

$debug && print STDERR "data-string = $data_string\n";

$socket = new IO::Socket(Domain=>PF_INET,
			 Proto=>getprotobyname('tcp'),
			 PeerAddr=>$host,
			 PeerPort=>$port
			 ) || die "can't open connection: $!";

$socket->print("POST $doc HTTP/1.0\r\n");
$socket->print("Host: $host_hdr\r\n");
$socket->print("Content-type: application/x-www-form-urlencoded\r\n");
$socket->print("Content-length: " . length($data_string) . "\r\n\r\n");
$socket->print($data_string);
$socket->flush();

$SIG{ALRM} = sub { die "timed out waiting for server\n"; };
alarm(60); # don't wait more than 60 seconds for at least the header

$resp = <$socket>;
alarm(0);

$resp =~ /\S+\s+(2.*)/ || die "bad response: $resp\n";
$debug && print STDERR "Good response: $1\n";

while (<$socket>) {
    $debug && print STDERR $_;

    s/[\r\n]+$//; # chop() but more robust

    length($_) > 0 || last;

    /^content-length: (\d+)/ && do {
	$content_length = $1;
	$got_length = 1;
    };
}

if ($got_length) {
    while ($content_length >= 0) {
	alarm(60);

	$read_len = ($content_length > 4096 ? 4096 : $content_length);
	$read_len = $socket->sysread($buffer, $read_len);

	if ($read_len <= 0) {
	    die "socket crapped out with $content_length bytes to go: $!\n";
	}

	alarm(0);

	$content_length -= $read_len;
	print($buffer); # give the output to stdout
    }
} else {
    # oh well, just read lines until the socket craps out or we timeout
    alarm(60);
    while (<$socket>) {
	alarm(60);
	print $_;
    }
    alarm(0);
}

exit(0);


	
