The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Nagios::WebTransact - Class for generating Nagios service checks of Web transactions.

SYNOPSIS

    use Nagios::WebTransact();
    
    # Constructors
    $web_trx = Nagios::WebTransact->new(\@url_set);

DESCRIPTION

This module implements a check of a Web Transaction.

A Web transaction is a sequence of web pages, often fill out forms, that accomplishes an enquiry or an update. Common examples are database searches and registration activities.

A Web transaction is specified by

  • a list of URLs where each URL is a page in the transaction

  • corresponding Query Strings containing the CGI names and value pairs to post the page

  • a means of determining from the content, whether a response is either Ok or a failure.

A new Nagios::WebTransact object must be created with the new method. Once this has been done, the check of the web transaction is done with the check method.

EXAMPLES

This example performs a primitive content check of the ADDS service, getting the page specified by the Url field, and if there is a response from the web server, comparing the response to the fields Exp and Exp_Fault.

If the response matches the Exp field the check succeeds; if the response matches the Exp_Fault field the check fails.

    #!/usr/local/bin/perl -w
    
    use Nagios::WebTransact;
    
    $ar = [ { Method    => "GET",
              Url       => "http://Pericles.IPAustralia.Gov.AU/adds2/ADDS.ADDS_START.intro",
              Qs_var    => [],
              Qs_fixed  => [],
              Exp       => "Designs Data Searching - Introduction",
              Exp_Fault => "We were unable to process your request at this time" } ] ;
    $web_trx = Nagios::WebTransact->new($ar) ;
    ($rc, $message) = $web_trx->check({}, debug => 0, proxy => { Server => 'http://Foo:3128', Account => 'lu$er', Pass => '00##00' } ) ;
    print $rc ? 'Adds Ok: ' : 'Adds b0rked: ', $message ;

This example checks if a complete ATMOSS transaction is successfull by requesting a sequence of URLs and checking the content against the Exp and Exp_Fault fields. Where the Qs_fixed and Qs_var fields are non null, the corresponding Query String is generated for the URL.

For example, the POST request for 'http://Perciles.IPAustralia/atmoss/Falcon.Result' is accompanied by the query string, p_tm_number_list=<current_value_of_arg_hash{'tmno'}

    #!/usr/local/bin/perl -w
    
    use Nagios::WebTransact;

    my $Proxy = {} ;
    $Proxy = { server => "http://$proxy/" } if $proxy ;
    $Proxy->{account} = $account  if $account ;
    $Proxy->{pass}    = $pass     if $pass ;
    
    my $Intro               = 'http://Pericles.IPAustralia.Gov.AU/atmoss/falcon.application_start' ;
    my $MultiSessConn       = 'http://Pericles.IPAustralia.Gov.AU/atmoss/Falcon_Users_Cookies.Run_Create' ;
    my $Search              = 'http://Pericles.IPAustralia.Gov.AU/atmoss/Falcon.Result' ;
    my $ResultDetails       = 'http://Pericles.IPAustralia.Gov.AU/atmoss/Falcon_Details.Show_TM_Details' ;
    my $SrchList            = 'http://Pericles.IPAustralia.Gov.AU/atmoss/Falcon_Searches.List_Search' ;
    my $DelSrchLists        = 'http://Pericles.IPAustralia.Gov.AU/atmoss/Falcon_Searches.SubmitChoice' ;
    my $EndSession          = 'http://Pericles.IPAustralia.Gov.AU/atmoss/Falcon_Users_Cookies.clear_User' ;
    
    my $Int                 = 'Welcome to ATMOSS' ;
    my $ConnSrch            = 'Connect to Trade Mark Search' ;
    my $MltiSess            = 'Fill in one or more of the fields below' ;
    my $Srch                = 'Your search request retrieved\s+\d+\s+match(es)?' ;
    my $ResSum              = 'Trade Mark\s+:\s+\d+' ;
    my $ResDet              = 'Indexing Details' ;
    my $SrchLs              = 'Search List' ;
    
    my $MSC_f               = [p_Anon => 'ANONYMOUS', p_user_type => 'Enter as Guest', p_JS => 'N'] ;
    
    my $Srch_v              = [p_tm_number_list => 'tmno'] ;
    
    my $RD_v                = [p_tm_number => 'tmno'] ;
    my $RD_f                = [p_Detail => 'DETAILED', p_search_no => 0];
    my $DAS_f               = [p_CmbDelete => 1, p_Button => 'Delete All Searches', p_extID => 'ANONYMOUS', p_password => '', p_CmbDisplay => 1, 
                               p_CmbRefine => 1, p_CmbCombine1 => 1, p_CmbCombineOperator => 'INTERSECT', p_CmbCombine2 => 1, p_search_used => 0 ] ;
    
    my $OraFault            = 'We were unable to process your request at this time' ;
    
    my @URLS                = (
      {Method => 'GET',  Url => $Intro,           Qs_var => [],     Qs_fixed => [],    Exp => $Int,     Exp_Fault => $OraFault},
      {Method => 'POST', Url => $MultiSessConn,   Qs_var => [],     Qs_fixed => $MSC_f,Exp => $MltiSess,Exp_Fault => $OraFault},
      {Method => 'POST', Url => $Search,          Qs_var => $Srch_v,Qs_fixed => [],    Exp => $ResSum,  Exp_Fault => $OraFault},
      {Method => 'GET',  Url => $ResultDetails,   Qs_var => $RD_v,  Qs_fixed => $RD_f, Exp => $ResDet,  Exp_Fault => $OraFault},
      {Method => 'GET',  Url => $SrchList,        Qs_var => [],     Qs_fixed => [],    Exp => $SrchLs,  Exp_Fault => $OraFault},
      {Method => 'POST', Url => $DelSrchLists,    Qs_var => [],     Qs_fixed => $DAS_f,Exp => $MltiSess,Exp_Fault => $OraFault},
      {Method => 'GET',  Url => $EndSession,      Qs_var => [],     Qs_fixed => [],    Exp => $Int,     Exp_Fault => $OraFault},
            ) ;
    
    my (@tmarks, $tmno, $i) ;
    
    @tmarks = @ARGV ? @ARGV : (3, 100092, 200099, 300006, 400075, 500067, 600076, 700066, 800061) ;
    $i = @ARGV == 1 ? 0 : int( rand($#tmarks) + 0.5 ) ;
    $tmno = $tmarks[$i] ;
    
    my $x = Nagios::WebTransact->new( \@URLS ) ;
    my ($rc, $message) =  $x->check( {tmno => $tmno}, debug => $debug, proxy => $Proxy, download_images => $download_images ) ;
    
    print $rc ? 'ATMOSS Ok. ' : 'ATMOSS b0rked: ', $message, "\n" ; 

Complete examples can be found in the t/ directory of the distribution.

CONSTRUCTOR

Nagios::WebTransact->new(ref_to_array_of_hash_refs)

This is the constructor for a new Nagios::WebTransact object. ref_to_array_of_hash_refs is a reference to an array of records (anon hash refs) in the format :-

{ Method => HEAD|GET|POST, Url => 'http://foo/bar', Qs_fixed => [cgi_var_name_1 => val1, ... ] NB that now square brackets refer to a Perl array ref Qs_var => [cgi_var_name_1 => val_at_run_time], Exp => blah, Exp_Fault=> blurb }

Exp and Exp_Fault are normal Perl patterns without pattern match delimiters. Most often they are strings.

Exp is the pattern that when matched against the respose to the URL (in the same hash) indicates success.
Exp_Fault is the pattern that indicates the response is a failure.

If these patterns contain parentheses eg 'match a lot (.*)', then the match is saved for use by Qs_var. Note that there should be only one pattern per element of the Exp list. Nested patterns ( yada(blah(.+)blurble(x|y|zz(top.*)) ) will not work as expected.

Qs_fixed and Qs_var are used to generate a query string.

Qs_fixed contains the name value pairs that are known at compile time whereas
Qs_var contains placeholders for values that are not known until run time.

In both cases, the format of these fields is a reference to an array containing alternating CGI variable names and values eg \(name1, v1, name2, v2, ...) produces a query string name1=v1&name2=v2&..

Qs_var allows values to be specified in three ways :-

  . a string that will be used as a key in the hash of arguments passed to
    the check method.

  . a positive integer (0, 1, ...)

In the latter case, the integer will be used as an index of the array of matches found from the last set of patterns with memory (specified by the Exp field). So [ cgi_var_name => 0 ] leads to a query string cgi_var_name=<the_first_match_in_the_set_of_Exp_patterns>

 . an array ref of the form [ match_index => code_ref ]

In this case, the subroutine referred to by coderef is a subroutine with one parameter and it will be called with that parameter set to the first element in the array (the index of a former match). One may choose to do this with very dynamic web systems such as the SAP R3 module for IIS in which the CGI names and values may need to be dragged out of former responses.

An example may make this more comprehensible !

    use constant CmrDetailPat       => [ qw(
            name="addr1_data-name1\[1\]"\s+value="(.*?)"
        ) ] ;

    use constant Stars              => '*' x 8 ;
    my $star_pat = quotemeta( Stars ) . '$';
    use constant AddStars_to_Name   => [ 'addr1_data-name1[1]' => [0, sub { $_[0] . Stars }] ] ;
    use constant DelStars_from_Name => [ 'addr1_data-name1[1]' => [0, sub { $_[0] =~ s#$star_pat##; $_[0] }] ] ;

If 'CmrDetailPat' is used as an Exp field, then a subsequent GET or POST can make use of Qs_var values 'AddStars_to_Name' and 'DelStars_from_Name' to either append some asterisks to the value of the web form name addr1_data-name1[1] or remove the stars.

METHODS

Unless otherwise stated all methods return either a true or false value, with true meaning that the check of the web transaction was a success. false is a zero (0).

check( CGI_VALUES, OPTIONS )

Performs a check of the Web transaction by getting the sequence or URLs specified in the constructor argument.

<OPTIONS> are passed in a hash like fashion, using key and value pairs. Possible options are:

debug writes the string form of the request (including query_string) and the response to STDERR.

proxy is a reference to a hash like { Server => 'http://ProxyServer:Port/', Account => account_on_proxy_server, Pass => identity_token }

fail_if_1 if set (the default) causes the check to fail when the first web page fails. Clearing this flag is useful if you want to get a bunch of pages and return a failure if they all fail.

timeout the default wait time for a response - to a request for one page - is 30 seconds.

download_images get the images found by HTML::LinkExtor in the page, provided those images have not already been fetched.

agent the default value of the User-Agent field in the HTTP request is Mozilla/4.7.

CGI_VALUES is a reference to a hash whose keys are the values used in the Qs_var lists. This allows the check method to get the value of these variables at run time (useful if you want to generate web parameters in your program, using a random number generator for example [vs]).

This hash ref is required and must be set to {} if there are no variables.

matches([ match1, match2, ..])

Accessor to set or get the value of the matches field.

urls([ ( { Method => , Url => , Qs_var => , Qs_fixed, Exp => , Exp_Fault => } .. ) ])

Accessor to get or set or the urls field. Useful for changing the set of pages to be checked for a subsequent conditional check (eg if first transaction, do a second with this set of pages).

Optional argument is a ref to a list of hashes like that used by the constructor.

set_urls, get_urls

Synonym for urls method.

set_matches, get_matches

Synonym for matches method.

BUGS

  • you must identify the URLs and the query strings required by the transaction using tools like ethereal or by examining the HTML source of the forms.

  • All fields are mandatory (can't neglect Exp_Fault for example).

  • Failing to use the correct format for the URL list can return hard to understand errors (eg not an array reference at line ..)

  • Timeout is per page and not for the overall transaction. Further, the timeout for image download is applied independently of the HTML. This effectively doubles the time allowed for the transaction to complete.

  • All of the keys (field names) are case sensitive.

  • patterns in Exp cannot be nested.

  • There can only be one pattern in each element of Exp ie match me (.*) and me (.*) and don't forget me (.*) does not save three strings.

AUTHOR

S Hopcroft, Stanley.Hopcroft@IPAustralia.Gov.AU

SEE ALSO

  WWW::Automate
  WWW::Mechanize

  perl(1).
  Nagios http://www.Nagios.ORG

3 POD Errors

The following errors were encountered while parsing the POD:

Around line 624:

You forgot a '=back' before '=head1'

Around line 687:

'=item' outside of any '=over'

Around line 706:

You forgot a '=back' before '=head1'