#!/usr/bin/perl

# Copyright (C) 1999 Peter Friedman
# Licensed under the GNU General Public License

#
# Fetches a single file via HTTP and saves it to the local filesystem
#

#
# 1999-12-02 v1.0: Original 15 minute hack
# 1999-12-12 v1.1: Added additional client headers
#
# TODO:
# Turn this standalone program into a Bastille module
# Optionally save to a different directory / filename
# More client headers?
# Handle 3## redirect responses
# Do any server headers need to be handled?
# 

use IO::Socket;

$version = "1.1";

$url = shift || die "Usage: webget <URL>\n";

($host, $path) = $url =~ /http:\/\/([^\/]+)(\/.*)/;
if ($host =~ /:/){
   ($hostname, $port) = $host =~ /(.*):(\d+)/;
}
else {
   $hostname = $host;
   $port = 80;
}

$socket = new IO::Socket::INET(PeerAddr => $hostname,
                               PeerPort => $port,
                               Proto    => 'tcp',
                               Timeout  => 5);

die "Failed to open connection\n" if (!$socket);

$socket->autoflush(1);

$socket->print("GET $path HTTP/1.0\n");
$socket->print("Connection: close\n");
$socket->print("User-Agent: Bastille-Webget/$version\n");
$socket->print("Pragma: no-cache\n");
$socket->print("Host: $hostname\n");
$socket->print("Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*\n");
$socket->print("Accept-Encoding: gzip\n");
$socket->print("Accept-Language: en\n");
$socket->print("Accept-Charset: iso-8859-1,*,utf-8\n");
$socket->print("\n");

$statusline = $socket->getline();
($http, $code, $message) = $statusline =~ /(HTTP.*) (\d{3}) (.*)/;

if ($code >= 100 && $code <= 199){
   print STDERR "Got informational response $code: $message\n";
}
if ($code >= 200 && $code <= 299){

   ($filename) = $path =~ /([^\/]*)$/;
   open(OUTFILE, "> $filename") || die "Couldn't open $filename\n";

   while ($stuff = $socket->getline()){
      $stuff =~ s/\r\n$//;
      last if ($stuff eq "");
      $stuff = uc($stuff);
      if ($stuff =~ /CONTENT-LENGTH/){
         ($length) = $stuff =~ /CONTENT-LENGTH\s*:\s*(\d+)/;
      }
   }
   $bytes_received = 0;
   while ($bytes_received < $length){
      $data_read = $socket->getline();
      $how_much = length($data_read);
      print OUTFILE $data_read;
      $bytes_received += $how_much;
   }
   close(OUTFILE);
}
if ($code >= 300 && $code <= 399){
   print STDERR "Got redirect response $code: $message\n";
   print STDERR "Redirects not handled yet\n";
}
if ($code >= 400 && $code <= 499){
   print STDERR "Request incomplete $code: $message\n";
}
if ($code >= 500 && $code <= 599){
   print STDERR "Server error $code: $message\n";
}

$socket->close();
