#!/usr/local/bin/perl # File: lwp-http.mon # Author: Daniel Hagerty, hag@linnaean.org # Date: Sun Mar 19 22:06:02 2000 # Description: Perform a simple top level HTTP get using LWP. # Lots of options. # # $Id: lwp-http.mon,v 1.3 2000/03/20 05:55:48 hag Exp $ use strict; use LWP::UserAgent; use HTTP::Cookies; use HTTP::Request; use Getopt::Std; use File::Basename; use URI; ### use vars qw($opt_h $opt_p $opt_t $opt_z $opt_d $opt_r $opt_s $opt_P $opt_v $opt_c); ## # Configure this. my $maintainer = 'youremailhere@localhost'; ## my $port; my $directory; my $regex; my $proto = "http"; my $timeout = 60; my $version = "0.1"; my $agent = "Yet Another Monitor Bot/$version"; my $u_proto; ### sub main { do_usage() if(@_ == 0); $directory = $opt_d if($opt_d); $port = $opt_p if($opt_p); $timeout = $opt_t if($opt_t); $regex = $opt_r if($opt_r); $proto = "https" if ($opt_s); $proto = $opt_P if($opt_P); $directory =~ s/^\///; # Nuke leading slash $u_proto = $proto; $u_proto =~ tr/[a-z]/[A-Z]/; my $user_agent = LWP::UserAgent->new() || lose("LWP create failure"); $user_agent->agent($agent); $user_agent->from($maintainer); $user_agent->timeout($timeout); my @failed; my %failure; host: foreach my $host (@_) { my $ht_lose = sub { push(@failed, $host); $failure{$host} = join(" ", @_); # This generates a warning. next host; }; if($opt_c) { # Generate new cookies for each host. my $cookies = HTTP::Cookies->new() || &{$ht_lose}("HTTP::Cookies create failure"); $user_agent->cookie_jar($cookies); } # XXX Kludge around some wierness with generating our own # URI interacting with cookies. my $uri_str = "$proto://$host/$directory"; my $request = HTTP::Request->new("GET" => $uri_str) || &{$ht_lose}("HTTP::Request create failure"); my $uri = $request->uri(); $uri->port($port) if(defined($port)); my $response = $user_agent->request($request) || &{$ht_lose}("UserAgent request failure"); unless($response->is_success) { &{$ht_lose}("Request failed:", $response->message); } my $strref = $response->content_ref; if(!$opt_z && length($$strref) == 0) { &{$ht_lose}("Empty document"); } if(defined($regex)) { my $winning; map {$winning++ if(/$regex/);} split("\n", $$strref); if($opt_v) { &{$ht_lose}("Failure regex matches:", $winning) if($winning); } elsif(!$winning) { &{$ht_lose}("Regex not found"); } } } if(@failed) { print "$u_proto Failures: " . join(" ", @failed) . "\n"; foreach my $fail (@failed) { print "$fail: $failure{$fail}\n"; } exit(1); } exit; } sub lose { die join(" ", @_); } sub do_usage { my $extended = shift; my $base = basename $0; print STDERR "Usage: $base [options...] hosts ...\n"; if($extended) { print <<'EOF'; -h Help. You're reading it. -d URL URL to test on the remote host. Default is /. -p PORT Port to connect to. Default is proto specific. -P PROTO Protocol to fetch. Default is http. -s Fetch via https. Equivalent to -P https. -t TIMEOUT Timeout for the fetch. Default is 60 seconds. -r REGEX A regular expression that the retrieved content must match. -v Invert the regular expression. Content must NOT match. -z Supress zero-length check. -c Enable Cookies. EOF } exit 1; } ### getopts("hszvcp:t:d:r:P:") || do_usage(); do_usage($opt_h) if($opt_h); &main(@ARGV); # EOF