#!/usr/bin/perl

# Author: Matt Judge
#   Date: 26/09/08
#   Desc: Script to poll given URLs and verify the response code.
#

use strict;
use IO::Socket::INET;

$| = 1;

my @URLS      = (
                  { url => 'http://125.16.147.226:8119/Vcil.VCW.CW/ContentwarehouseWebService.asmx', response => '200' },
                  { url => 'http://125.16.147.226:8119/Vcil.VCW.CH/Fulfillment.aspx', response => '302' }
                );

#
# Who to send an email to :)
my @email     = qw(Deji.Akala@informa.com Robert.Heywood@informa.com Israr.Nazir@informa.com listukiwmonitoring@informa.com);

#
# Storage for the email body should it be required
#
my $msg_body = "";

sub mylocaltime
{
  my $timestamp = shift;

  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($timestamp);

  $year  = sprintf "%04d", ($year + 1900);
  $mon   = sprintf "%02d",($mon + 1);
  $mday  = sprintf "%02d",$mday;
  $wday  = sprintf "%02d",$wday + 1;
  $yday  = sprintf "%02d",$yday;
  $hour  = sprintf "%02d",$hour;
  $min   = sprintf "%02d",$min;
  $sec   = sprintf "%02d",$sec;

  return ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst);
}

sub ourlog
{
  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = mylocaltime(time());
  print "$hour:$min:$sec $mday/$mon/$year - " . shift;
}

#
# Check each URL and verify the response is as expected
#
for ( my $c=0; $c < scalar (@URLS); $c++ )
{
  my $URL = $URLS[$c]{'url'};

  #
  # Split the URL into domain/port/URL
  my($domain,$port,$url) = $URL =~ /http:\/\/([a-z0-9\.\-]+):(\d+)(.*)/i;

  my $socket = "";
  my $reason = "";
  for ( my $tries = 0; !$socket && $tries < 3; $tries++ )
  {
    #
    # Connect to the remote IP/port
    $socket = IO::Socket::INET->new( PeerAddr  => $domain,
                                     PeerPort  => $port,
                                     Proto     => 'tcp',
                                     Timeout   => 5 ) or $reason .= "URL: $URL\n\nCan't connect to $domain:$port ($!)\n\n";
    #
    # Log multiple attempts to connect to the server
    if ( !$socket )
    {
      ourlog "Try: $tries, $reason\n";
    }

  }

  #
  # Append any fail reason to the message body.
  $msg_body .= $reason;

  #
  # Skip to the next URL if we failed to open a socket.
  next if not $socket;

  #
  # Prepare the HTTP message to fetch the URL
  my $string  = "GET $url HTTP/1.1\n";
  $string .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1\n";
  $string .= "Accept: */*\n";
  $string .= "Host: $domain:$port\n";
  $string .= "Connection: Keep-Alive\n\n";
  send($socket, $string, 0);

  #
  # Fetch the response from the server.
  # Include an alarm as the connection can take some time to terminate
  my @lines = ();
  eval {
    local $SIG{ALRM} = sub { die "darn it"};
    alarm 10;
    while (<$socket>)
    {
      # The below line doesn't work within the eval statement for some reason!?
      # @lines = <$socket>;
      push (@lines, $_);
    }
    alarm 0;
  };
  close($socket);

  # Analyse the response.
  # We do this in two parts so that the output can be sent via email
  my $status = 0;
  foreach $_ (@lines)
  {
    if ( /^HTTP\/1.1\s+(\d+)\s+(\S+)/ )
    {
      $URLS[$c]{'received'} = $1;
      if ( $1 == $URLS[$c]{'response'} )
      {
        $status = 1;
      }
    }
  }

  if ( !$status )
  {
    if ( !scalar(@lines) )
    {
      ourlog "Did not receive any output for: $URL\n";
    }
    else
    {
      ourlog "Did not receive the expected status code\n";

      $msg_body .= "\n********************************************************\n";
      $msg_body .= "Error fetching: $URL\n";
      $msg_body .= "The response from the web server has been included below:";
      $msg_body .= "\n********************************************************\n";
      foreach $_ (@lines)
      {
        $msg_body .= $_;
        if ( /^\s+$/ )
        {
          last;
        }
      }
    }
  }
}

#
# If we have anything in the msg_body then send an emaail
#
if ( $msg_body )
{
  open OUT, "| /usr/sbin/sendmail -t";
  print OUT "From: root\@mon02.internal.informaworld.com\r\n";
  foreach my $address (@email)
  {
    print OUT "To: $address\r\n";
  }
  print OUT "Subject: Value Chain's PDF Server Responded OOB\r\n\r\n";
  print OUT $msg_body;

  close (OUT);

  ourlog "Tests completed with errors\n";
}
else
{
  ourlog "Tests completed OK\n";
}

