The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

ASNMTAP::Asnmtap::Plugins::WebTransact is a Perl module that provides WebTransact functions used by ASNMTAP-based plugins.

SYNOPSIS

 use ASNMTAP::Asnmtap::Plugins::WebTransact;

 my @URLS = ();
 my $objectWebTransact = ASNMTAP::Asnmtap::Plugins::WebTransact->new ( \$objectPlugins, \@URLS );

 @URLS = (
   { Method => 'GET',  Url => 'http://www.citap.be/', Qs_var => [], Qs_fixed => [], Exp => "Consulting Internet Technology Alex Peeters", Exp_Fault => ">>>NIHIL<<<", Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Perfdata Label 1' },
 );

 $objectWebTransact->check ( { } );
 undef $objectWebTransact;

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

  • asnmtapInherited

    A required reference to an ASNMTAP::Asnmtap::Plugins or ASNMTAP::Asnmtap::Plugins::Nagios subclass

    Through this way of working we inherited the command line setting from the proxy.

    When we specify at the command prompt --proxy=username;password@proxyserver:port|domain[,domain], the needed and required proxy settings are automatically set.

    The command line options --timeout, --debug and --debugfile are also inherited.

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

    _browseragent is inherited and specifies the name that your application should use when it presents itself on the network.

    _SSLversion is inherited and specifies the SSL version to use.

  • 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 (WARNING, CRITICAL or UNKNOWN).

    'KeepAlive' and 'SSL session reuse'
     Only SSLv3 and TLSv1 are supporting 'KeepAlive' and 'SSL session reuse'.
    
     To make SSL session reuse possible, 'KeepAlive' need to be on 'On'.
    
     Verify that your browseragent string on the destination servers don't have someting like a 'nokeepalive', 'downgrade-1.0' or 'force-response-1.0'.
    
     Verify that the 'SSL Session Cache' on the destination servers are enabled.
    Apache
    httpd.conf
     # KeepAlive: Whether or not to allow persistent connections (more than one request per connection).
     KeepAlive On
    
     # The following directives modify normal HTTP response behavior to handle known problems with browser implementations.
     BrowserMatch "Mozilla/2" nokeepalive
     BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
    ssl.conf
     # Here I am allowing SSLv3 and TLSv1, I am NOT allowing the old SSLv2.
     # SSLProtocol all -SSLv2
     SSLProtocol -all +TLSv1 +SSLv3 
    
     # Notice: Most problems of broken clients are also related to the HTTP keep-alive facility.
     SetEnvIf User-Agent ".*MSIE.*" \
              nokeepalive ssl-unclean-shutdown \
              downgrade-1.0 force-response-1.0
    
     # Inter-Process Session Cache:
     # Configure the SSL Session Cache: First the mechanism to use and second the expiring timeout (in seconds).
     SSLSessionCache         dbm:/var/cache/mod_ssl/scache(512000)
     SSLSessionCacheTimeout  300

A new ASNMTAP::Asnmtap::Plugins::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.

ASNMTAP::Asnmtap::Plugins::WebTransact->new (ref_to_array_of_hash_refs)

A new ASNMTAP::Asnmtap::Plugins::WebTransact object must be created with the new method.

A reference to array of hash references ( \@URLS ) is required.

The field urls contains a reference to a list of (hashes) records representing the Web Transaction.

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

Structure of the array of hash references:

 {
   Method         => HEAD|GET|POST,
   Url            => 'http://...',
   Qs_var         => [ cgi_var_name_1 => val_at_run_time, ... ],
   Qs_fixed       => [ cgi_var_name_1 => val_1, ... ],
   Exp            => blah,
   Exp_Fault      => blurb,
   Exp_Return     => { var_label_1 => EXP_VAR_LABEL_1, ... },
   Msg            => 'Status error when not all Exp found',
   Msg_Fault      => 'Status error when Exp_Fault found',
   Timeout        => 30,
   Perfdata_Label => 'Label x'
 }

Qs_fixed and Qs_var are used to generate a query string.

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

Method

scalar, possible values: GET, HEAD or POST

GET

The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI. If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity in the response and not the source text of the process, unless that text happens to be the output of the process.

The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself. This method is often used for testing hypertext links for validity, accessibility, and recent modification.

POST

The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.

Url

scalar, any valid URL: RFC 1738

Request for Comments document (RFC) for Uniform Resource Locators (URL).

Qs_var

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.

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.

Is an array reference containing the name value pairs of any parameters whose value is known only at run time.

The format is [ cgi_parm_name => val_at_run_time, ... ] where cgi_parm_name is the name of a fill out form parameter and val_at_run_time is a string used as a key to get the value of the cgi parameter.

Qs_var = [ form_name_1 => 0, form_name_2 => 1 ..] will lead to a query_string like form_name_1 = $matches[0], form_name_2 = $matches[1] ... in $self->_make_req() by @matches = $self->matches() and using 0, 1 etc as indices of @matches.

Qs_fixed

Qs_fixed contains the name value pairs that are known at compile time whereas.

Is an array reference containing name value pairs.

The format is [ cgi_var_name => val, ... ] where cgi_var_name is the name of a fill out form parameter and val is a string with the value of the cgi parameter

Exp .

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

Is an scalar (value is a string) or an array

$objectWebTransact->matches() will updated with the set of matches it finds by matching patterns with memory (ie patterns in paren) from the Exp field against the request response.

Exp_Fault

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.

Is an scalar (value is a string), ex. blurb

Exp_Return

Exp_Return is the pattern that indicates the response is a return.

Is an hash, { var_label_1 => EXP_VAR_LABEL_1, ... }

Msg .

This message is added to the error field when not all Exp found.

Is an scalar (value is a string), ex. 'Status error when not all Exp found'

Msg_Fault

This message is added to the error field when Exp_Fault found.

Is an scalar (value is a string), ex. 'Status error when Exp_Fault found'

Timeout

This means that for this URL the specified timeout will be used.

Is an scalar (value is a integer greater then 0), ex. 30

Perfdata_Label

This means that for this URL there performance data will be created and the name for the label equals the value from Perfdata_Label.

Is an scalar (value is a string), ex. 'Label x'

Example:

  use ASNMTAP::Asnmtap::Plugins::WebTransact;

  my @URLS = (
    { Method => 'GET',  Url => 'http://www.citap.be/', Qs_var => [], Qs_fixed => [], Exp => "Consulting Internet Technology Alex Peeters", Exp_Fault => ">>>NIHIL<<<", Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 1' },
  );

  my $objectWebTransact = ASNMTAP::Asnmtap::Plugins::WebTransact->new ( \$objectPlugins, \@URLS );

equals to:

  use ASNMTAP::Asnmtap::Plugins::WebTransact;

  my @URLS = ();
  my $objectWebTransact = ASNMTAP::Asnmtap::Plugins::WebTransact->new ( \$objectPlugins, \@URLS );

  @URLS = (
    { Method => 'GET',  Url => 'http://www.citap.be/', Qs_var => [], Qs_fixed => [], Exp => "Consulting Internet Technology Alex Peeters", Exp_Fault => ">>>NIHIL<<<", Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 1' },
  );

  $objectWebTransact->urls( \@URLS );
$objectWebTransact->check( CGI_VALUES, OPTIONS )

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

  $objectWebTransact->check ( { } );

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.

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

Structure of the array of hash references:

 (
   custom           => undef,
   perfdataLabel    => undef,
   newAgent         => undef,
   timeout          => undef,
   triesTiming      => '1,3,15',
   triesCodes       => '408,500,502,503,504',
   openAppend       => 1,
   cookies          => 1,
   protocol         => 1,
   keepAlive        => 1,
   download_images  => 0,
   fail_if_1        => 1
 )

Possible options are:

custom

Optionally, you can specify an reference to a function. This function give you a extra control to ASNMTAP::Asnmtap::Plugins::WebTransact

 sub customWebTransact {
   my ($resp_string) = @_;

   for ( $resp_string ) {
     /Failure of server APACHE bridge/ &&
       do { return ( $ERRORS{CRITICAL}, 1, 'Failure of server APACHE bridge' ); last; };
     /Message from the NSAPI plugin:/ && /No backend server available for connection:/ &&
       do { return ( $ERRORS{CRITICAL}, 1, "'KBOWI - Message from the NSAPI plugin - No backend server available for connection'" ); last; };
     /\Q<FRAME NAME="NO_INFO" SRC="submain.html" SCROLLING="No" FRAMEBORDER="0" NORESIZE>\E/ &&
       do { return ( $ERRORS{CRITICAL}, 0, '+submain+' ); last; };
     return ( $ERRORS{OK}, 0, undef );
   }
 }

Is an scalar, reference to a function, default: undef

perfdataLabel

set the performancedata label for a group of URLs

Example
  my @URLS = (
    { Method => 'GET',  Url => 'http://www.citap.be/', Qs_var => [], Qs_fixed => [], Exp => "Consulting Internet Technology Alex Peeters", Exp_Fault => ">>>NIHIL<<<", Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 1' },
    { Method => 'GET',  Url => 'http://www.citap.com/', Qs_var => [], Qs_fixed => [], Exp => "Consulting Internet Technology Alex Peeters", Exp_Fault => ">>>NIHIL<<<", Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 1' },
  );

  $returnCode = $objectWebTransact->check ( { }, custom => \&customWebTransact, perfdataLabel => 'homepage' );

equals to:

  my @URLS = (
    { Method => 'GET',  Url => 'http://www.citap.be/', Qs_var => [], Qs_fixed => [], Exp => "Consulting Internet Technology Alex Peeters", Exp_Fault => ">>>NIHIL<<<", Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 1' },
    { Method => 'GET',  Url => 'http://www.citap.com/', Qs_var => [], Qs_fixed => [], Exp => "Consulting Internet Technology Alex Peeters", Exp_Fault => ">>>NIHIL<<<", Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 1' },
  );

  $startTime = $objectPlugins->setEndTime_and_getResponsTime ( $objectPlugins->pluginValue ('endTime') );
  $returnCode = $objectWebTransact->check ( { }, custom => \&customWebTransact );
  $responseTime = $objectPlugins->setEndTime_and_getResponsTime ( $startTime );
  $objectPlugins->appendPerformanceData ( 'homepage='. $responseTime .'ms;'. ($trendline*1000) .';;;' );
newAgent

The first time we call $objectWebTransact->check ( { }, ... ),

is an scalar, value is 0, 1 or undef (default)

 undef: current (browser) session will be used, but at the first 
        all a new (browser) session will automaticallybe created
 0    : current (browser) session will be used
 1    : new (browser) session will be created

This means that when you specify newAgent => 0 the first time you call $objectWebTransact->check, it will be treated as newAgent => 1, to ensure that an (browser) session is created.

Every time whel for a following call $objectWebTransact->check ( { }, ... ), newAgent equals 1, then a new (browser) session is created.

When newAgent equals 0, then we using the same (browser) session again.

Optional, is an scalar, value is 0 or 1

timeout

Every time we call $objectWebTransact->check ( { }, timeout => 30, ... ),

is an scalar, value greater then 0 or undef (default)

When timeout equals undef, then we using the timeout from the parent object.

Optional, is an scalar, value is greater the 0

triesTiming

Every time we call $objectWebTransact->check ( { }, triesTiming => '1,3,15', ... ), to get a web page and run into a possibly-temporary error (like a DNS lookup timeout), it'll wait a few seconds and retry a few times.

is an string that controls how many times it should retry, and how long the pauses should be, values greater then 0 separated by a ',' or undef (default)

When triesTiming equals undef or an empty-string, this means not to retry at all.

If you specify a string with several numbers in it (like '1,3,15'), then that means WebTransact can retry as that many times (i.e., one initial try, plus a maximum of the three retries, because three numbers there), and that it should wait first those numbers of seconds each time.

So triesTiming => '1,3,15' basically means:

  try the request; return it unless it's a temporary-looking error;
  sleep 1;
  retry the request; return it unless it's a temporary-looking error;
  sleep 3;
  retry the request; return it unless it's a temporary-looking error;
  sleep 15;
  retry the request; return it;
triesCodes

Is an string of HTTP codes that merit a retry (like 500 and 408, but unlike 404 or 200), values greater then 200 separated by a ',' or '408,500,502,503,504' (default).

  408 Request Timeout: The client did not send a request within the required time period

  500 Can't connect to ..., Connect failed, Proxy connect failed, Server Error, SSL negotiation failed, SSL read timeout or Internal Server Error: The server had some sort of internal error trying to fulfil the request. The client may see a partial page or error message. It's a fault in the server and happens all too frequently.

  502 Bad Gateway: Bad Gateway: a server being used by this Web server has sent an invalid response. The response by an intermediary server was invalid. This may happen if there is a problem with the DNS routing tables.

  503 Service Unavailable: Service temporarily unavailable because of currently/temporary overload or maintenance.

  504 Gateway Timeout: The server did not respond back to the gateway within acceptable time period
openAppend

Is an scalar, open debugfile as 'Writes, Appends, and Creates' mode when 1, otherwise open debugfile in 'Creates, Writes, and Truncates' mode.

cookies

Is an scalar, value is 0 or 1 (default)

protocol

0 = default and 1 = force 'HTTP/1.1'

Is an scalar, value is 0 or 1 (default)

keepAlive

0 = default and 1 = 'Keep-Alive'

Is an scalar, value is 0 or 1 (default)

download_images

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

Is an scalar, value is 0 (default) or 1

fail_if_1

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.

Is an scalar, value is 0 or 1 (default)

check semantics: $fail_if_1 ? return $ERRORS{CRITICAL} if any URL fails ! $fail_if_1 ? return $ERRORS{CRITICAL} if all URLs fail (same as return $ERRORS{OK} if any URL ok)

Example:

  $objectWebTransact->check ( { } );
  undef $objectWebTransact;
$objectWebTransact->matches()

Set and/or get matches

$objectWebTransact->get_matches()

Get the matched values from the last downloaded url

  foreach ( @{ $objectWebTransact->get_matches() } ) { print $_, "\n"; }
$objectWebTransact->set_matches()

Set the match values for the next url to download

  $objectWebTransact->set_matches( ['a', 'b', 'c', 1, 2, 3] );
$objectWebTransact->returns()

Set and/or get the return keys and values for all urls

$objectWebTransact->get_returns()

Get the return keys and values from all downloaded urls

  while ( my ($key, $value) = each %{ $objectWebTransact->get_returns() } ) {
    if ( ref $value eq 'ARRAY') {
      foreach ( @{ $value } ) { print "$key => $_\n"; }
    } else {
      print "$key => $value\n";
    }
  }
$objectWebTransact->set_returns()

Set the return keys and values from all next urls to download

  $objectWebTransact->set_returns( { ape => 'lucky' } );
$objectWebTransact->urls()

Set and/or get the urls

$objectWebTransact->get_urls()

Get the urls

  foreach ( @{ $objectWebTransact->get_urls() } ) {
    while ( my ($key, $value) = each %{ $_ } ) { print "$key => $value\n"; }
  };
$objectWebTransact->set_urls()

Set the urls used by the next call from $objectWebTransact->check ( { } )

  my @URLS = (
    { Method => 'GET',  Url => 'http://www.citap.be/', Qs_var => [], Qs_fixed => [], Exp => "Consulting Internet Technology Alex Peeters", Exp_Fault => ">>>NIHIL<<<", Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 1' },
  );

  $objectWebTransact->urls( \@URLS );

  $returnCode = $objectWebTransact->check ( { } );

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 and returns Exp_Return.

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

  use ASNMTAP::Asnmtap::Plugins::WebTransact;

  my $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',
               Exp_Return     => {},
               Msg            => 'Status error when not all Exp found',
               Msg_Fault      => 'Status error when Exp_Fault found',
               Timeout        => 30,
               Perfdata_Label => 'Label x' } ];

  my $objectWebTransact = ASNMTAP::Asnmtap::Plugins::WebTransact->new ( \$objectPlugins, $ar);
  my $returnCode = $objectWebTransact->check ( { tmno => $tmno } );

  foreach ( @{ $objectWebTransact->get_matches() } ) { print $_, "\n"; }

  undef $objectWebTransact;

This example checks if a complete ATMOSS transaction is successfull by getting a sequence of URLs, checking the content where the Qs_fixed and Qs_var fields are non null generating a query string for the request.

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

  use ASNMTAP::Asnmtap::Plugins::WebTransact;

  use constant Intro              => 'http://Pericles.IPAustralia.Gov.AU/atmoss/falcon.application_start';
  use constant ConnectToSearch    => 'http://Pericles.IPAustralia.Gov.AU/atmoss/Falcon_Users_Cookies.Define_User';
  use constant MultiSessConn      => 'http://Pericles.IPAustralia.Gov.AU/atmoss/Falcon_Users_Cookies.Run_Create';
  use constant Search             => 'http://Pericles.IPAustralia.Gov.AU/atmoss/Falcon.Result';
  use constant ResultAbstract     => 'http://Pericles.IPAustralia.Gov.AU/atmoss/falcon_details.show_tm_details';
  use constant ResultDetails      => 'http://Pericles.IPAustralia.Gov.AU/atmoss/Falcon_Details.Show_TM_Details';
  use constant DeleteSearches     => 'http://Pericles.IPAustralia.Gov.AU/atmoss/Falcon_Searches.Delete_All_Searches';

  use constant Int                => 'Welcome to ATMOSS';
  use constant ConnSrch           => 'Connect to Trade Mark Search';
  use constant MltiSess           => 'Fill in one or more of the fields below';
  use constant Srch               => 'Your search request retrieved\s+\d+\s+match(es)?';
  use constant ResAbs             => 'Trade Mark\s+:\s+\d+';
  use constant ResDet             => ResAbs;
  use constant DelSrch            => MltiSess;

  use constant MSC_f              => [p_Anon => 'REGISTERED', p_user_type => 'Connect to Existing Extract List', p_extID => 'Foo', p_password => 'Bar'];
  use constant Srch_v             => [p_tmno1 => 'tmno'];
  use constant RA_v               => [p_tm_number => 'tmno'];
  use constant RA_f               => [p_detail => 'QUICK', p_rec_all => 1, p_rec_no => 1, p_search_no => 1, p_ExtDisp => 'D'];
  use constant RD_v               => RA_v;
  use constant RD_f               => [p_Detail => 'DETAILED', p_rec_no => 1, p_search_no => 1,  p_ExtDisp => 'D'];

  use constant OraFault           => 'We were unable to process your request at this time';

  use constant URLS               => [
    {Method => 'GET',  Url => Intro,           Qs_var => [],     Qs_fixed => [], Exp => Int,        Exp_Fault => OraFault, Msg => '', Msg_Fault => ''},
    {Method => 'GET',  Url => ConnectToSearch, Qs_var => [],     Qs_fixed => [], Exp => ConnSrch,   Exp_Fault => OraFault, Msg => '', Msg_Fault => ''},
    {Method => 'POST', Url => MultiSessConn,   Qs_var => [],     Qs_fixed => MSC_f,Exp => MltiSess, Exp_Fault => OraFault, Msg => '', Msg_Fault => ''},
    {Method => 'POST', Url => Search,          Qs_var => Srch_v, Qs_fixed => [], Exp => Srch,       Exp_Fault => OraFault, Msg => '', Msg_Fault => ''},
    {Method => 'GET',  Url => ResultAbstract,  Qs_var => RA_v,   Qs_fixed => RA_f, Exp => ResAbs,   Exp_Fault => OraFault, Msg => '', Msg_Fault => ''},
    {Method => 'POST', Url => ResultDetails,   Qs_var => RD_v,   Qs_fixed => RD_f, Exp => ResDet,   Exp_Fault => OraFault, Msg => '', Msg_Fault => ''},
    {Method => 'POST', Url => DeleteSearches,  Qs_var => [],     Qs_fixed => [], Exp => DelSrch,    Exp_Fault => OraFault, Msg => '', Msg_Fault => ''},
  ];

  @tmarks = @ARGV ? @ARGV : (3, 100092, 200099, 300006, 400075, 500067, 600076, 700066, 800061);
  $i = @ARGV == 1 ? 0 : int( rand($#tmarks) + 0.5 );
  $tmno = $tmarks[$i];

  $objectWebTransact = ASNMTAP::Asnmtap::Plugins::WebTransact->new ( \$objectPlugins, URLS );
  $returnCode = $objectWebTransact->check ( {tmno => $tmno} )

  foreach ( @{ $objectWebTransact->get_matches() } ) { print $_, "\n"; }

  undef $objectWebTransact;

More examples:

Example 1
  use constant EXP_NAVIGATION_TOKEN => '<input\s+type="hidden"\s+name="NAVIGATION_TOKEN"\s+value="(-{0,1}\d+)"\s+/>';
  use constant VAL_NAVIGATION_TOKEN => [0, sub { $_[0] }];

  use constant EXP_TICKETNUMBER     => '<b>N°\s+de\s+ticket\s*:</b>\s*\n*\s*&nbsp;(\w{3}-\w{7}-\w{2}-\w)';
  use constant VAL_TICKETNUMBER     => [1, sub { $_[0] }];

  @URLS = (
    { Method => 'GET',  Url => "...", Qs_var => [], Qs_fixed => [], Exp => [EXP_NAVIGATION_TOKEN, EXP_TICKETNUMBER], ... },
    { Method => 'POST', Url => "...", Qs_var => [NAVIGATION_TOKEN => VAL_NAVIGATION_TOKEN, TICKETNUMBER => VAL_TICKETNUMBER], Qs_fixed => [], Exp => [EXP_NAVIGATION_TOKEN, EXP_TICKETNUMBER], ... },
  );

equals to:

  use constant EXP_NAVIGATION_TOKEN => '<input\s+type="hidden"\s+name="NAVIGATION_TOKEN"\s+value="(-{0,1}\d+)"\s+/>';

  use constant EXP_TICKETNUMBER     => '<b>N°\s+de\s+ticket\s*:</b>\s*\n*\s*&nbsp;(\w{3}-\w{7}-\w{2}-\w)';

  # [TICKETNUMBER => 1] means get the second match (from the last set of matches) and use it as the value of TICKETNUMBER.

  @URLS = (
    { Method => 'GET',  Url => "...", Qs_var => [], Qs_fixed => [], Exp => [EXP_NAVIGATION_TOKEN, EXP_TICKETNUMBER], ... },
    { Method => 'POST', Url => "...", Qs_var => [NAVIGATION_TOKEN => 0, TICKETNUMBER => 1], Qs_fixed => [], Exp => [EXP_NAVIGATION_TOKEN, EXP_TICKETNUMBER], ... },
  );
Example 2
  use constant EXP_NAVIGATION_TOKEN => '<input\s+type="hidden"\s+name="NAVIGATION_TOKEN"\s+value="(-{0,1}\d+)"\s+/>';

  @URLS = (
    { Method => 'POST', Url => "...", Qs_var => [], Exp => [EXP_NAVIGATION_TOKEN], ... },
  );

  my $objectWebTransact = ASNMTAP::Asnmtap::Plugins::WebTransact->new( \$objectPlugins, \@URLS );
  my $returnCode = $objectWebTransact->check( { } );

  my $matches = $objectWebTransact->matches();
  my $valNavigationToken = @$matches[0];
  
  @URLS = (
    { Method => 'POST', Url => "...", Qs_var => [NAVIGATION_TOKEN => 'valNavigationToken'], Qs_fixed => [], Exp => [EXP_NAVIGATION_TOKEN], ... },
    { Method => 'POST', Url => "...", Qs_var => [NAVIGATION_TOKEN => 0], Qs_fixed => [], Exp => [EXP_NAVIGATION_TOKEN], ... },
  );

  $returnCode = $objectWebTransact->check( { valNavigationToken => $valNavigationToken } );
  print "Navigation Token: $valNavigationToken\n";

equals to:

  use constant EXP_NAVIGATION_TOKEN => '<input\s+type="hidden"\s+name="NAVIGATION_TOKEN"\s+value="(-{0,1}\d+)"\s+/>';

  @URLS = (
    { Method => 'POST', Url => "...", Qs_var => [], Exp => [EXP_NAVIGATION_TOKEN], ... }, Exp_Return => {valNavigationToken => EXP_NAVIGATION_TOKEN},
    { Method => 'POST', Url => "...", Qs_var => [NAVIGATION_TOKEN => 0], Qs_fixed => [], Exp => [EXP_NAVIGATION_TOKEN], ... },
    { Method => 'POST', Url => "...", Qs_var => [NAVIGATION_TOKEN => 0], Qs_fixed => [], Exp => [EXP_NAVIGATION_TOKEN], ... },
  );

  my $objectWebTransact = ASNMTAP::Asnmtap::Plugins::WebTransact->new( \$objectPlugins, \@URLS );
  $returnCode = $objectWebTransact->check( { } );

  my %returns =  %{ $objectWebTransact->returns() };
  print 'Navigation Token: '. $returns{valNavigationToken} ."\n";
Example 3
  my $startTime;

  if ( defined $perfData and $perfData ) {
    ${$objectWebTransact->{asnmtapInherited}}->setEndTime_and_getResponsTime ( ${$objectWebTransact->{asnmtapInherited}}->pluginValue ('endTime') );
    $startTime = ${$objectWebTransact->{asnmtapInherited}}->pluginValue ('endTime');
  }

  my $returnCode = $objectWebTransact->check ( { }, newAgent => $newAgent );

  if ( defined $startTime ) {
    my $responseTime = ${$objectWebTransact->{asnmtapInherited}}->setEndTime_and_getResponsTime ( $startTime );
    ${$objectWebTransact->{asnmtapInherited}}->appendPerformanceData ( 'Logon='. $responseTime .'ms;;;;' );
  }
Example 4
  my $matches = $objectWebTransact->matches();
  my ($valNavigationToken, $valTicketnummer, undef) = @$matches[0..$#$matches];
  print "Navigation Token: ", $valNavigationToken, "\n" if (defined $valNavigationToken);
  print "Ticketnummer    : ", $valTicketnummer, "\n" if (defined $valTicketnummer);

  and

  my $matches = $objectWebTransact->matches();
  foreach my $match ( @$matches ) { print "-> $match <-"; }

  equals to:

  foreach my $match ( @{ $objectWebTransact->matches() } ) { print "-> $match <-\n"; }
Example 5
  my @URLS = ();
  my $objectWebTransact = ASNMTAP::Asnmtap::Plugins::WebTransact->new ( \$objectPlugins, \@URLS );

  use constant EXP_TITLE_1 => "\Q<TITLE>\E(Consulting Internet Technology Alex Peeters)\Q</TITLE>\E";
  use constant EXP_TITLE_2 => "\Q<TITLE>\E(Consulting) (Internet) (Technology) (Alex Peeters)\Q</TITLE>\E";

  use constant EXP_SUBMAIN => "\Q<FRAME NAME=\"NO_INFO\" SRC=\"\E(submain.htm)\Q\" SCROLLING=\"No\" FRAMEBORDER=\"0\" NORESIZE>\E";
  use constant VAL_SUBMAIN => [0, sub { my %pages = ( 'index.htm' => 'InDeX', 'submain.htm' => 'subMAIN' ); $pages { $_[0] }; } ];

  @URLS = (
    { Method => 'GET',  Url => 'http://www.citap.com/', Qs_var => [], Qs_fixed => [], Exp => [EXP_SUBMAIN, 'Consulting Internet Technology Alex Peeters'], Exp_Fault => ">>>NIHIL<<<", Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 2' },
    { Method => 'GET',  Url => 'http://www.citap.com/', Qs_var => [parameter => 0], Qs_fixed => [], Exp => [EXP_SUBMAIN, 'Consulting Internet Technology Alex Peeters'], Exp_Fault => ">>>NIHIL<<<", Exp_Return => { title1 => EXP_TITLE_1 }, Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 2' },
    { Method => 'GET',  Url => 'http://www.citap.com/', Qs_var => [parameter => VAL_SUBMAIN], Qs_fixed => [], Exp => 'Consulting Internet Technology Alex Peeters', Exp_Fault => ">>>NIHIL<<<", Exp_Return => { title2 => EXP_TITLE_2, submain => EXP_SUBMAIN }, Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 3' },
  );

  $returnCode = $objectWebTransact->check ( { }, custom => \&customWebTransact );

  foreach ( @{ $objectWebTransact->get_matches() } ) { print $_, "\n"; }

  while ( my ($key, $value) = each %{ $objectWebTransact->get_returns() } ) {
    if ( ref $value eq 'ARRAY') {
      foreach ( @{ $value } ) { print "$key => $_\n"; }
    } else {
      print "$key => $value\n";
    }
  }

  my %returns =  %{ $objectWebTransact->returns() };
  undef $objectWebTransact;

  print $returns {title1}, "\n";
  print $returns {submain}, "\n";
  print $returns {title2}[0], "\n";
  print $returns {title2}[1], "\n";
  print $returns {title2}[2], "\n";
  print $returns {title2}[3], "\n";
Example 6
  use constant EXP_TITLE_1 => "\Q<TITLE>\E(Consulting Internet Technology Alex Peeters)\Q</TITLE>\E";
  use constant EXP_TITLE_2 => "\Q<TITLE>\E(Consulting) (Internet) (Technology) (Alex Peeters)\Q</TITLE>\E";

  use constant EXP_SUBMAIN => "\Q<FRAME NAME=\"NO_INFO\" SRC=\"\E(submain.htm)\Q\" SCROLLING=\"No\" FRAMEBORDER=\"0\" NORESIZE>\E";
  use constant VAL_SUBMAIN => [0, sub { my %pages = ( 'index.htm' => 'InDeX', 'submain.htm' => 'subMAIN' ); $pages { $_[0] }; } ];

  @URLS = (
    { Method => 'GET',  Url => 'http://www.citap.com/', Qs_var => [], Qs_fixed => [], Exp => [EXP_SUBMAIN, 'Consulting Internet Technology Alex Peeters'], Exp_Fault => ">>>NIHIL<<<", Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 2' },
    { Method => 'GET',  Url => 'http://www.citap.com/', Qs_var => [parameter => 0], Qs_fixed => [], Exp => [EXP_SUBMAIN, 'Consulting Internet Technology Alex Peeters'], Exp_Fault => ">>>NIHIL<<<", Exp_Return => { title1 => EXP_TITLE_1 }, Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 2' },
    { Method => 'GET',  Url => 'http://www.citap.com/', Qs_var => [parameter => VAL_SUBMAIN], Qs_fixed => [], Exp => 'Consulting Internet Technology Alex Peeters', Exp_Fault => ">>>NIHIL<<<", Exp_Return => { title2 => EXP_TITLE_2, submain => EXP_SUBMAIN }, Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 3' },
  );

  $returnCode = $objectWebTransact->check ( { } );
  my %returns = %{ $objectWebTransact->returns() };
  $objectPlugins->pluginValues ( { alert => $returns {title1} .' - '. $returns {submain} .' - '. $returns {title2}[0] .' - '. $returns {title2}[1] .' - '. $returns {title2}[2] .' - '. $returns {title2}[3] }, $TYPE{REPLACE} );

equals to:

  use constant EXP_TITLE_1 => "\Q<TITLE>\E(Consulting Internet Technology Alex Peeters)\Q</TITLE>\E";
  use constant EXP_TITLE_2 => "\Q<TITLE>\E(Consulting) (Internet) (Technology) (Alex Peeters)\Q</TITLE>\E";

  use constant EXP_SUBMAIN => "\Q<FRAME NAME=\"NO_INFO\" SRC=\"\E(submain.htm)\Q\" SCROLLING=\"No\" FRAMEBORDER=\"0\" NORESIZE>\E";
  use constant VAL_SUBMAIN => [0, sub { my %pages = ( 'index.htm' => 'InDeX', 'submain.htm' => 'subMAIN' ); $pages { $_[0] }; } ];

  use constant RET_SUBMAIN => [0, sub { my %returns = %{ $objectWebTransact->returns() }; defined $returns { 'submain' } ? $returns { 'submain' } : ''; } ];
  use constant RET_TITLE1  => [0, sub { my %returns = %{ $objectWebTransact->returns() }; defined $returns { 'title1' } ? $returns { 'title1' } : ''; } ];

  @URLS = (
    { Method => 'GET',  Url => 'http://www.citap.com/', Qs_var => [], Qs_fixed => [], Exp => [EXP_SUBMAIN, 'Consulting Internet Technology Alex Peeters'], Exp_Fault => ">>>NIHIL<<<", Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 1' },
  );

  $returnCode = $objectWebTransact->check ( { } );

  @URLS = (
    { Method => 'GET',  Url => 'http://www.citap.com/', Qs_var => [parameter => 0], Qs_fixed => [], Exp => [EXP_SUBMAIN, 'Consulting Internet Technology Alex Peeters'], Exp_Fault => ">>>NIHIL<<<", Exp_Return => { title1 => EXP_TITLE_1 }, Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 2' },
    { Method => 'GET',  Url => 'http://www.citap.com/', Qs_var => [parameter => VAL_SUBMAIN, submain => RET_SUBMAIN, title1 => RET_TITLE1], Qs_fixed => [], Exp => 'Consulting Internet Technology Alex Peeters', Exp_Fault => ">>>NIHIL<<<", Exp_Return => { title2 => EXP_TITLE_2, submain => EXP_SUBMAIN }, Msg => "Consulting Internet Technology Alex Peeters", Msg_Fault => "Consulting Internet Technology Alex Peeters", Perfdata_Label => 'Label 3' },
  );

  $returnCode = $objectWebTransact->check ( { } );
Example 7
 @URLS = (
   { Method => 'GET',  Url => 'https://USERNAME:PASSWORD@secure.citap.be/authorization/', Qs_var => [], Qs_fixed => [], Exp => "Testing Client Authorization", Exp_Fault => ">>>NIHIL<<<", Msg => "Testing Client Authorization", Msg_Fault => "Testing Client Authorization" },
 );

 $returnCode = $objectWebTransact->check ( { } );

equals to:

 @URLS = (
   { Method => 'GET',  Url => 'https://secure.citap.com/authorization/', Qs_var => [], Qs_fixed => [], Exp => "Testing Client Authorization", Exp_Fault => ">>>NIHIL<<<", Msg => "Testing Client Authorization", Msg_Fault => "Testing Client Authorization" },
 );

 $objectWebTransact->ua->credentials ( 'secure.citap.com:443', "ASNMTAP's Authorization Access", 'USERNAME', 'PASSWORD' );

 $returnCode = $objectWebTransact->check ( { } );

TOOLS

GrinderCaptureConverter.pl
 ./GrinderCaptureConverter.pl -i /opt/grinder-2.8.6/examples/asnmtap/www.citap.be-grinder.proporties -o /opt/grinder-2.8.6/examples/asnmtap/www.citap.com.txt -f WEBTRANSACT
The Grinder 2

more information can found at: http://grinder.sourceforge.net/

Needed to run The Grinder

Java 2 Standard Edition 1.3.1, equivalent, or later

How do I start The Grinder to capture?

more information can found at: http://grinder.sourceforge.net/manual/tcpsniffer.html

Start an agent process
 mkdir /opt/grinder-2.8.6/capture
 cd /opt/grinder-2.8.6/capture

 CLASSPATH=/opt/grinder-2.8.6/lib/grinder.jar; export CLASSPATH or CLASSPATH=../../lib/grinder.jar; export CLASSPATH
 java net.grinder.TCPSniffer -proxy -httpPluginFilter > /opt/grinder-2.8.6/capture/grinder
 or
 cd /opt/grinder-2.8.6/examples/asnmtap
 java -classpath /opt/grinder-2.8.6/lib/grinder.jar net.grinder.TCPSniffer -proxy -httpPluginFilter> /opt/grinder-2.8.6/capture/grinder
How do I set Internet Explorer to capture?

Set for internet explorer the proxy setting to 127.0.0.1 with port 8001

How do I Capture a website?

Start surfing throug Internet Explorer

How do I stop the Capture?

Press 'ctrl C'

BUGS

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

AUTHOR

Stanley Hopcroft [Stanley.Hopcroft@IPAustralia.Gov.AU] Alex Peeters [alex.peeters@citap.be]

SEE ALSO

ASNMTAP::Asnmtap, ASNMTAP::Asnmtap::Plugins

  check_template-WebTransact.pl
  check_template-WebTransact-Perfdata.pl
  check_template-WebTransact-with-client-authorization.pl
  check_template-WebTransact-with-client-certificate.pl
  check_template-WebTransact-XML.pl
  check_template-WebTransact-XML-Cactus-parser.pl
  check_template-WebTransact-XML-Monitoring.pl
  check_template-WebTransact-XML-Monitoring-1.1.pl
  check_template-WebTransact-XML-Monitoring-1.2.pl

DEPENDENCIES

  ASNMTAP::Asnmtap::Plugins
  Bundle::LWP
  CGI
  Compress::Zlib
  Digest::MD5
  Crypt::SSLeay
  IO::Socket::SSL
  MIME::Base64
  Net::FTP
  Net::SSLeay
  URI

COPYRIGHT NOTICE

(c) Copyright 2003-2004 Stanley.Hopcroft@IPAustralia.Gov.AU

ASNMTAP::Asnmtap::Plugins::WebTransact is based on 'Nagios::WebTransact' v0.14.1 & v0.16 from Stanley Hopcroft [Stanley.Hopcroft@IPAustralia.Gov.AU]

1 POD Error

The following errors were encountered while parsing the POD:

Around line 661:

Non-ASCII character seen before =encoding in ''<b>N°\s+de\s+ticket\s*:</b>\s*\n*\s*&nbsp;(\w{3}-\w{7}-\w{2}-\w)';'. Assuming CP1252