line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# HTTP::Monkeywrench.pm |
2
|
|
|
|
|
|
|
# --------------------------------------------------------- |
3
|
|
|
|
|
|
|
# $Revision: 1.13 $ |
4
|
|
|
|
|
|
|
# $Date: 2000/09/12 00:14:54 $ |
5
|
|
|
|
|
|
|
# --------------------------------------------------------- |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 NAME |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
HTTP::Monkeywrench - Web testing application |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 SYNOPSIS |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
use HTTP::Monkeywrench; |
14
|
|
|
|
|
|
|
$session = [ |
15
|
|
|
|
|
|
|
{ |
16
|
|
|
|
|
|
|
name =E 'URL Name', |
17
|
|
|
|
|
|
|
url =E 'http://url', |
18
|
|
|
|
|
|
|
} |
19
|
|
|
|
|
|
|
]; |
20
|
|
|
|
|
|
|
HTTP::Monkeywrench-Etest($session); |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=head1 REQUIRES |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
CGI |
25
|
|
|
|
|
|
|
Net::SMTP |
26
|
|
|
|
|
|
|
HTTP::Cookies |
27
|
|
|
|
|
|
|
LWP::UserAgent |
28
|
|
|
|
|
|
|
Time::HiRes |
29
|
|
|
|
|
|
|
Data::Dumper |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=cut |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=head1 EXPORTS |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
None |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=head1 DESCRIPTION |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
HTTP::Monkeywrench is a test-harness application to test the integrity |
40
|
|
|
|
|
|
|
of a user's path through a web site. |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
To run HTTP::Monkeywrench-Etest(), first set up a Perl script that contains |
43
|
|
|
|
|
|
|
sessions (described below), settings if desired (also described below), |
44
|
|
|
|
|
|
|
and a call to HTTP::Monkeywrench-Etest(), passing it the settings hashref first, |
45
|
|
|
|
|
|
|
followed by the desired session hashrefs you want to test. |
46
|
|
|
|
|
|
|
HTTP::Monkeywrench-Etest($settings, $session1,... $sessionN) |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
HTTP::Monkeywrench can also be used in an object-oriented fashion -- simply |
49
|
|
|
|
|
|
|
take the result of HTTP::Monkeywrench-Enew (optionally passing the settings |
50
|
|
|
|
|
|
|
hashref) and call the test() method against it as above (optionally omitting |
51
|
|
|
|
|
|
|
the settings hashref.) |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
Each session arrayref contains one or more hashrefs, called clicks, |
54
|
|
|
|
|
|
|
which contain descriptive elements of a specific web page to be tested. |
55
|
|
|
|
|
|
|
The elements are described below under SESSION. |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=head1 SESSION |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=over 4 |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=item C<$session1> (ARRAYREF of HASHREFS) |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
A session is an arrayref of complex hashrefs that can be sent to the |
64
|
|
|
|
|
|
|
Ctest> application to perform tests on a website |
65
|
|
|
|
|
|
|
as a virtual user. |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
The following keys can be in each 'Click' hashref. |
68
|
|
|
|
|
|
|
Fields with a "*" are required: |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=back |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=over 8 |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=item name (SCALAR) |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
A name to visually reference that 'click' in the reports |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=item *url (SCALAR) |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
The url for Monkeywrench to test for that click. |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=item params (HASHREF) |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
The params to send to dynamic pages and cgi's. |
85
|
|
|
|
|
|
|
Params should be set up as such: { username => 'joe', password => 'blow' } |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
=item method (SCALAR) |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
'method' should be either 'POST' or 'GET'. If method is left |
90
|
|
|
|
|
|
|
blank, method will default to 'GET'. |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=item auth (ARRAYREF) |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
'auth' is the username and password if the site your are testing |
95
|
|
|
|
|
|
|
is password protected. 'auth' params must be passed to each |
96
|
|
|
|
|
|
|
element of a session that is accessing the same site. |
97
|
|
|
|
|
|
|
Example: ['username','password'] |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
=item success_res (ARRAYREF) |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
An arrayref of items for Monkeywrench to test for their existence. |
102
|
|
|
|
|
|
|
Each element of the array can either be a text string or a regexp object. |
103
|
|
|
|
|
|
|
If a string from success_res is not found in the page, Monkeywrench |
104
|
|
|
|
|
|
|
will report an error. |
105
|
|
|
|
|
|
|
EXAMPLE: ['string',qr/regexp_object/,'etc'] |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
=item error_res (ARRAYREF) |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
The same as success_res, except that an error will only be reported |
110
|
|
|
|
|
|
|
if strings in error_res ARE found on the page being tested. |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=item cookies (ARRAYREF of ARRAYREFS) |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
A preset cookie can be sent to a page. In order to send a cookie to |
115
|
|
|
|
|
|
|
a page the following elements should be included as an arrayref: |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
[$version, $key, $val, $path, $domain, $port, $path_spec, $secure, $maxage, $discard, \%rest] |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
An example cookie would look like: |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
[['0', 'sessnum', 'expires&2592000&type&consumer', '/','cookiemonster.org', '8014', '', '', '2000-09-11 16:15:15Z', '']], |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
=item acceptcookie (BIT) |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
A numeric flag set to 1 or 0 to tell Monkeywrench if it should accept and |
126
|
|
|
|
|
|
|
save a cookie passed from a server. |
127
|
|
|
|
|
|
|
Default is 0, cookies will not be accepted. |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=item sendcookie (BIT) |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
A numeric flag set to 1 or 0 to tell Monkeywrench to send a saved or |
132
|
|
|
|
|
|
|
pre made cookie back to the server. Default is 0, cookies will not be sent. |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
=item showhtml (BIT) |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
A numeric flag set to 1 or 0 to have the source html of a page displayed |
137
|
|
|
|
|
|
|
within the report. When set to 1 the reports can get messy if the page |
138
|
|
|
|
|
|
|
is heavy on html. |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
=back |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=head1 SETTINGS HASH |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
=over 4 |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=item $settings (HASHREF) |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
The settings hash is optional as are each of the elements of $settings. |
149
|
|
|
|
|
|
|
Elements that are not declared or set are defaulted to 0 (off). |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=back |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
=over 8 |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
=item match_detail (BIT) |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
A numeric flag set to 1 or 0. If set to 1 Match detail shows all of |
158
|
|
|
|
|
|
|
the reports of success_res and error_res no matter if they pass or fail. |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=item show_cookies (BIT) |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
A numeric flag set to 1 or 0. If set to 1 show_cookies will show all |
163
|
|
|
|
|
|
|
the cookies in the report, either passed from the session or sent |
164
|
|
|
|
|
|
|
from the server. |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=item smtp_server (SCALAR) |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
The SMTP server to be used by Net::SMTP. Only required if user wants |
169
|
|
|
|
|
|
|
output of Monkeywrench to be sent to an email address. |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
=item send_mail (ARRAYREF) |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
The send_mail arrayref is also only required if user plans on sending |
174
|
|
|
|
|
|
|
output to one or more email addresses. |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
=item send_if_err (BIT) |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
The send_if_err bit is a flag that should be set to either 1 or 0 and |
179
|
|
|
|
|
|
|
is only used if the user wants the Monkeywrench output sent via email. |
180
|
|
|
|
|
|
|
If set to 1 the output will only be sent to the email address(es) in |
181
|
|
|
|
|
|
|
the event of a failure in the success or error checking or any result |
182
|
|
|
|
|
|
|
code other than 200. |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=item print_results (BIT) |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
If set to 1, the results will be printed to the screen. If set to 0 nothing |
187
|
|
|
|
|
|
|
will be printed to the screen. The default setting is 1. |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=back |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=cut |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
=head1 METHODS |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
=over 4 |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
=cut |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
package HTTP::Monkeywrench; |
201
|
|
|
|
|
|
|
|
202
|
1
|
|
|
1
|
|
2262
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
35
|
|
203
|
1
|
|
|
1
|
|
4
|
use vars qw($totaltime $totalerrs @sessiontime $debug $default_settings $content); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
129
|
|
204
|
|
|
|
|
|
|
|
205
|
1
|
|
|
1
|
|
2230
|
use CGI; |
|
1
|
|
|
|
|
19076
|
|
|
1
|
|
|
|
|
7
|
|
206
|
1
|
|
|
1
|
|
1227
|
use Net::SMTP; |
|
1
|
|
|
|
|
49523
|
|
|
1
|
|
|
|
|
49
|
|
207
|
1
|
|
|
1
|
|
917
|
use HTTP::Cookies; |
|
1
|
|
|
|
|
16038
|
|
|
1
|
|
|
|
|
32
|
|
208
|
1
|
|
|
1
|
|
3656
|
use LWP::UserAgent; |
|
1
|
|
|
|
|
49853
|
|
|
1
|
|
|
|
|
35
|
|
209
|
|
|
|
|
|
|
#use LWP::Debug qw(+); # spits out a lot of helpful LWP debugging |
210
|
|
|
|
|
|
|
|
211
|
1
|
|
|
1
|
|
16343
|
use Time::HiRes qw(gettimeofday tv_interval); |
|
1
|
|
|
|
|
3029
|
|
|
1
|
|
|
|
|
7
|
|
212
|
1
|
|
|
1
|
|
1463
|
use Data::Dumper; # also used for debugging purposes |
|
1
|
|
|
|
|
8715
|
|
|
1
|
|
|
|
|
131
|
|
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
BEGIN { |
215
|
1
|
|
|
1
|
|
2
|
$HTTP::Monkeywrench::REVISION = (qw$Revision: 1.13 $)[-1]; |
216
|
1
|
|
|
|
|
2
|
$HTTP::Monkeywrench::VERSION = '1.0'; |
217
|
|
|
|
|
|
|
|
218
|
1
|
|
|
|
|
2
|
$CGI::NO_DEBUG = 1; # again, debugging |
219
|
1
|
|
|
|
|
2
|
$debug = undef; # set to 1 if you want to see debugging output |
220
|
1
|
|
|
|
|
2233
|
$default_settings = { |
221
|
|
|
|
|
|
|
match_detail => 1, |
222
|
|
|
|
|
|
|
show_cookies => 1, |
223
|
|
|
|
|
|
|
smtp_server => undef, |
224
|
|
|
|
|
|
|
send_mail => undef, |
225
|
|
|
|
|
|
|
send_if_err => 0, |
226
|
|
|
|
|
|
|
print_results => 1 |
227
|
|
|
|
|
|
|
}; |
228
|
|
|
|
|
|
|
} |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
$totalerrs = 0; # initialize the total errors string |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
=item C ( [ \%settings ] ) |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
Returns a new Monkeywrench object. Optionally takes a settings hash. |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
=cut |
237
|
|
|
|
|
|
|
sub new { |
238
|
1
|
|
|
1
|
1
|
3
|
my $proto = shift; |
239
|
1
|
|
33
|
|
|
8
|
my $class = ref($proto) || $proto; |
240
|
1
|
|
|
|
|
4
|
my $self = bless({}, $class); |
241
|
1
|
|
|
|
|
7
|
$self->settings(shift); |
242
|
1
|
|
|
|
|
13
|
$self->{'ua'} = new LWP::UserAgent; |
243
|
1
|
|
|
|
|
3895
|
$self->{'ua'}->agent('Monkeywrench/'.$HTTP::Monkeywrench::VERSION . $self->{'ua'}->agent); |
244
|
1
|
|
|
|
|
117
|
$self->{'cookie_jar'} = HTTP::Cookies->new; |
245
|
1
|
|
|
|
|
35
|
$self->{'cgi'} = CGI->new(''); |
246
|
1
|
|
|
|
|
4972
|
return $self; |
247
|
|
|
|
|
|
|
} # END method new |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
=item C ( $self, [ \%settings ] ) |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
Returns settings hash. Passing hashref will change settings in object. |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
=cut |
254
|
|
|
|
|
|
|
sub settings { |
255
|
7
|
|
|
7
|
1
|
16
|
my $self = shift; |
256
|
7
|
50
|
|
|
|
26
|
return undef unless (ref $self); |
257
|
7
|
100
|
|
|
|
23
|
if (my $settings = shift) { |
258
|
1
|
50
|
|
|
|
4
|
warn "SETTINGS ==> " . Dumper($settings) if ($debug); |
259
|
1
|
50
|
|
|
|
13
|
unless (ref($settings) eq 'HASH') { |
260
|
0
|
|
|
|
|
0
|
carp('Settings must be called with hashref...\n'); |
261
|
0
|
|
|
|
|
0
|
return undef; |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
|
264
|
6
|
100
|
|
|
|
28
|
$self->{'settings'} = { |
265
|
1
|
|
|
|
|
6
|
map { $_ => defined($settings->{$_}) ? $settings->{$_} : $default_settings->{$_} } |
266
|
|
|
|
|
|
|
keys %$default_settings }; |
267
|
|
|
|
|
|
|
} |
268
|
|
|
|
|
|
|
|
269
|
7
|
|
|
|
|
44
|
return $self->{'settings'}; |
270
|
|
|
|
|
|
|
} # END method settings |
271
|
|
|
|
|
|
|
|
272
|
3
|
|
|
3
|
0
|
20
|
sub ua { $_[0]->{'ua'}; } |
273
|
2
|
|
|
2
|
0
|
18
|
sub cookie_jar { $_[0]->{'cookie_jar'}; } |
274
|
1
|
|
|
1
|
0
|
6
|
sub cgi { $_[0]->{'cgi'}; } |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
=item C ( [ \%settings ], \@session [ , \@session, ... ] ) |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
Usable as both a static method and object method. |
279
|
|
|
|
|
|
|
Runs a series Monkeywrench tests on a web server using the parameters set forth in the |
280
|
|
|
|
|
|
|
sessions you pass. |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=cut |
283
|
|
|
|
|
|
|
sub test { |
284
|
1
|
|
|
1
|
1
|
106
|
my $self = shift; |
285
|
1
|
50
|
|
|
|
6
|
unless (ref($self)) { |
286
|
1
|
50
|
|
|
|
11
|
$self = $self->new(ref($_[0]) eq 'HASH' ? shift : ()); |
287
|
|
|
|
|
|
|
} |
288
|
|
|
|
|
|
|
#my $settings = $self->settings((ref($_[0]) eq 'HASH') && shift); |
289
|
1
|
|
|
|
|
5
|
my @sessions = @_; |
290
|
1
|
|
|
|
|
5
|
my $q = $self->cgi(); |
291
|
1
|
|
|
|
|
3
|
my $sessnum = 0; |
292
|
1
|
|
|
|
|
3
|
my $return = {}; |
293
|
1
|
|
|
|
|
1
|
my $res; |
294
|
|
|
|
|
|
|
|
295
|
1
|
|
|
|
|
22
|
$content .= sprintf("============================== Monkeywrench %.2f ==============================\n",($HTTP::Monkeywrench::REVISION)); |
296
|
|
|
|
|
|
|
|
297
|
1
|
|
|
|
|
3
|
foreach my $session (@sessions) { |
298
|
2
|
|
|
|
|
9
|
$content .= "Session $sessnum\n"; |
299
|
2
|
|
|
|
|
4
|
my $clicknum = 0; |
300
|
2
|
|
|
|
|
5
|
foreach (@$session) { |
301
|
3
|
|
|
|
|
45
|
my $click = { %$_ }; # Make a copy so we don't stomp on the original |
302
|
3
|
|
|
|
|
10
|
$click->{'params'} = join('&', map{ $q->escape($_) . '=' . $q->escape($click->{'params'}{$_} ) } keys %{$click->{'params'}} ); |
|
2
|
|
|
|
|
40
|
|
|
3
|
|
|
|
|
14
|
|
303
|
3
|
100
|
|
|
|
50
|
$click->{'method'} = $click->{'method'} ? $click->{'method'} : 'GET'; |
304
|
3
|
|
50
|
|
|
22
|
$click->{'showhtml'} = $click->{'showhtml'} || 0; |
305
|
3
|
|
|
|
|
6
|
push(@{ $click->{'urls'} },$click->{'url'}); |
|
3
|
|
|
|
|
13
|
|
306
|
|
|
|
|
|
|
|
307
|
3
|
50
|
|
|
|
13
|
if ($click->{'cookies'}) { |
308
|
3
|
|
|
|
|
24
|
foreach my $cookie (@{ $click->{'cookies'} }) { |
|
3
|
|
|
|
|
10
|
|
309
|
1
|
|
|
|
|
5
|
$self->cookie_jar->set_cookie(@$cookie); |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
|
313
|
3
|
|
|
|
|
41
|
my $t1 = [ gettimeofday ]; |
314
|
3
|
|
|
|
|
12
|
$res = $self->get_response($click); |
315
|
3
|
|
|
|
|
106
|
$return->{ session }[ $sessnum ][ $clicknum ]{ res } = $res->code; |
316
|
3
|
|
|
|
|
76
|
my $t2 = [ gettimeofday ]; |
317
|
|
|
|
|
|
|
|
318
|
3
|
|
|
|
|
23
|
$content .= " Summary for: " . $click->{'name'} . "\n"; |
319
|
3
|
|
|
|
|
6
|
my $r = 1; |
320
|
3
|
|
|
|
|
7
|
foreach my $url (@{ $click->{'urls'} }) { |
|
3
|
|
|
|
|
14
|
|
321
|
3
|
50
|
|
|
|
58
|
$content .= scalar (($r==1) ? ' URL: ' : ' Redirect: ') . "$url\n"; |
322
|
3
|
|
|
|
|
12
|
$r++; |
323
|
|
|
|
|
|
|
} |
324
|
3
|
50
|
66
|
|
|
25
|
if (($click->{'sendcookie'}) && ($self->settings->{'show_cookies'})) { |
325
|
0
|
|
|
|
|
0
|
my $cookie_to_print = $self->cookie_jar->as_string; |
326
|
0
|
|
|
|
|
0
|
$~ = "COOKIES"; |
327
|
0
|
|
|
|
|
0
|
write; |
328
|
|
|
|
|
|
|
format COOKIES = |
329
|
|
|
|
|
|
|
Cookie: |
330
|
|
|
|
|
|
|
~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< |
331
|
|
|
|
|
|
|
$cookie_to_print |
332
|
|
|
|
|
|
|
. |
333
|
|
|
|
|
|
|
} |
334
|
3
|
|
|
|
|
7
|
my $failed = 0; |
335
|
3
|
|
|
|
|
5
|
my $success = 0; |
336
|
|
|
|
|
|
|
|
337
|
3
|
|
|
|
|
14
|
$content .= ' Code: ' . $res->code . ' ' . $res->message . "\n"; |
338
|
3
|
100
|
66
|
|
|
73
|
if ($res->is_redirect || $res->is_success) { |
339
|
1
|
50
|
|
|
|
27
|
$content .= " Match Res:\n" if ($click->{'success_res'}); |
340
|
1
|
|
|
|
|
4
|
foreach my $sr (@{ $click->{'success_res'} }) { |
|
1
|
|
|
|
|
4
|
|
341
|
1
|
|
|
|
|
2
|
my $result; |
342
|
1
|
50
|
|
|
|
7
|
if ($res->content =~ $sr) { |
343
|
1
|
50
|
|
|
|
262
|
$result = "PASS" if ($self->settings->{'match_detail'}); |
344
|
|
|
|
|
|
|
} else { |
345
|
0
|
|
|
|
|
0
|
$result = "FAIL"; |
346
|
0
|
|
|
|
|
0
|
$failed++; |
347
|
0
|
|
|
|
|
0
|
$totalerrs++; |
348
|
|
|
|
|
|
|
} |
349
|
1
|
|
|
|
|
33
|
pipe (RFH,WFH); |
350
|
|
|
|
|
|
|
format WFH = |
351
|
|
|
|
|
|
|
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>>> |
352
|
|
|
|
|
|
|
$sr, $result |
353
|
|
|
|
|
|
|
. |
354
|
1
|
50
|
|
|
|
12
|
write WFH if ($result); |
355
|
1
|
|
|
|
|
22
|
close WFH; |
356
|
1
|
|
|
|
|
7
|
local $/ = undef; |
357
|
1
|
|
|
|
|
29
|
$content .= ; |
358
|
|
|
|
|
|
|
} |
359
|
|
|
|
|
|
|
|
360
|
1
|
50
|
|
|
|
8
|
$content .= " Match Error:\n" if ($click->{'error_res'}); |
361
|
1
|
|
|
|
|
3
|
foreach my $er (@{ $click->{'error_res'} }) { |
|
1
|
|
|
|
|
6
|
|
362
|
2
|
|
|
|
|
4
|
my $result; |
363
|
2
|
50
|
|
|
|
14
|
if ($res->content =~ $er) { |
364
|
0
|
|
|
|
|
0
|
$result = "FAIL"; |
365
|
0
|
|
|
|
|
0
|
$failed++; |
366
|
0
|
|
|
|
|
0
|
$totalerrs++; |
367
|
|
|
|
|
|
|
} else { |
368
|
2
|
50
|
|
|
|
1741
|
$result = "PASS" if ($self->settings->{'match_detail'}); |
369
|
|
|
|
|
|
|
} |
370
|
2
|
|
|
|
|
99
|
pipe (ERR_RFH,ERR_WFH); |
371
|
|
|
|
|
|
|
format ERR_WFH = |
372
|
|
|
|
|
|
|
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>>> |
373
|
|
|
|
|
|
|
$er, $result |
374
|
|
|
|
|
|
|
. |
375
|
2
|
50
|
|
|
|
20
|
write ERR_WFH if ($result); |
376
|
2
|
|
|
|
|
31
|
close ERR_WFH; |
377
|
2
|
|
|
|
|
8
|
local $/ = undef; |
378
|
2
|
|
|
|
|
32
|
$content .= ; |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
} else { |
382
|
2
|
|
|
|
|
44
|
$content .= " *** Request Failed ***\n"; #. $res->error_as_HTML; |
383
|
|
|
|
|
|
|
} |
384
|
|
|
|
|
|
|
|
385
|
3
|
|
|
|
|
22
|
$return->{ session }[ $sessnum ][ $clicknum ]{ clicktime } = my $clicktime = tv_interval($t1,$t2); |
386
|
3
|
|
|
|
|
51
|
$totaltime += $clicktime; |
387
|
3
|
|
|
|
|
13
|
$return->{ session }[ $sessnum ][ $clicknum ]{ sessiontime } = $sessiontime[$sessnum] += $clicktime; |
388
|
3
|
|
|
|
|
48
|
$content .= "\n Pageclick: $clicktime second\n"; # must kill clicktime nazis |
389
|
3
|
|
|
|
|
8
|
$content .= "-------------------------------------------------------------------------------\n"; |
390
|
3
|
|
|
|
|
25
|
$clicknum++; |
391
|
|
|
|
|
|
|
} |
392
|
|
|
|
|
|
|
|
393
|
2
|
|
|
|
|
109
|
$content .= " Session $sessnum: $sessiontime[$sessnum]\n"; |
394
|
2
|
|
|
|
|
6
|
$content .= "===============================================================================\n"; |
395
|
2
|
|
|
|
|
8
|
$sessnum++; |
396
|
|
|
|
|
|
|
} |
397
|
|
|
|
|
|
|
|
398
|
1
|
|
|
|
|
4
|
$content .= "Total Errors: $totalerrs\n"; |
399
|
1
|
|
|
|
|
5
|
$content .= " Total Test: $totaltime seconds\n\n"; |
400
|
1
|
|
|
|
|
4
|
$return->{ totaltime } = $totaltime; |
401
|
|
|
|
|
|
|
|
402
|
1
|
50
|
|
|
|
7
|
if ($self->settings->{'send_mail'}) { |
403
|
0
|
0
|
0
|
|
|
0
|
if (($self->settings->{'send_if_err'} == 0) || |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
404
|
|
|
|
|
|
|
(($self->settings->{'send_if_err'} == 1) && ((($res->code != 200) || ($totalerrs > 0))))) { |
405
|
0
|
0
|
|
|
|
0
|
$self->send_monkeymail($content,$self->settings->{'smtp_server'},$self->settings->{'send_mail'}) |
406
|
|
|
|
|
|
|
|| warn "Unable to send monkeymail"; |
407
|
|
|
|
|
|
|
} |
408
|
|
|
|
|
|
|
} |
409
|
1
|
50
|
|
|
|
4
|
print $content if $self->settings->{'print_results'}; |
410
|
1
|
|
|
|
|
79
|
return $return; |
411
|
|
|
|
|
|
|
} # end method test |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
=item C ($click) |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
get_response is a recursive method that loops through all |
417
|
|
|
|
|
|
|
possible redirects until a final response is returned, |
418
|
|
|
|
|
|
|
which is then returned to the caller. |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
=cut |
421
|
|
|
|
|
|
|
sub get_response { |
422
|
3
|
|
|
3
|
1
|
7
|
my $self = shift; |
423
|
3
|
|
|
|
|
5
|
my $click = shift; |
424
|
3
|
50
|
|
|
|
14
|
my $method = ($click->{'REDIRECT'} ? 'GET' : $click->{'method'}); |
425
|
3
|
50
|
|
|
|
43
|
my $req = HTTP::Request->new($method => $click->{'urls'}->[-1] . (($method eq 'GET') ? '?'.$click->{'params'} : '')); |
426
|
|
|
|
|
|
|
|
427
|
3
|
50
|
|
|
|
11860
|
$req->authorization_basic($click->{'auth'}->[0], $click->{'auth'}->[1]) if ($click->{'auth'}); |
428
|
3
|
50
|
|
|
|
2157
|
$req->content($click->{'params'}) unless ($click->{'REDIRECT'}); |
429
|
3
|
100
|
|
|
|
69
|
$self->cookie_jar->add_cookie_header($req) if ($click->{'sendcookie'}); |
430
|
|
|
|
|
|
|
|
431
|
3
|
50
|
|
|
|
479
|
$content .= "\$req ==> " . Dumper($req) if ($debug); |
432
|
|
|
|
|
|
|
|
433
|
3
|
|
|
|
|
14
|
my $res = $self->ua->request($req); |
434
|
|
|
|
|
|
|
|
435
|
3
|
50
|
|
|
|
2568537
|
$content .= "\$res ==> " . Dumper($res) if ($debug); |
436
|
3
|
50
|
|
|
|
18
|
$content .= "RESPONSE ==> " . $res->content . "\n" if ($click->{'showhtml'}); |
437
|
|
|
|
|
|
|
|
438
|
3
|
50
|
|
|
|
14
|
$self->cookie_jar->extract_cookies($res) if ($click->{'acceptcookie'}); |
439
|
|
|
|
|
|
|
|
440
|
3
|
50
|
|
|
|
16
|
if ($res->is_redirect) { |
441
|
0
|
|
|
|
|
0
|
$click->{'REDIRECT'} = 1; |
442
|
0
|
|
|
|
|
0
|
push(@{ $click->{'urls'} },$res->header('Location')); |
|
0
|
|
|
|
|
0
|
|
443
|
0
|
|
|
|
|
0
|
return $self->get_response($click) |
444
|
|
|
|
|
|
|
} else { |
445
|
3
|
|
|
|
|
46
|
return $res; |
446
|
|
|
|
|
|
|
} |
447
|
|
|
|
|
|
|
} # end method get_response |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
=item C ( $content, \$smtp_server \@address ) |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
send_monkeymail is called if the config script has an |
453
|
|
|
|
|
|
|
email address and depending on how send_if_err is setup. |
454
|
|
|
|
|
|
|
$content is the output of the session(s) called by the |
455
|
|
|
|
|
|
|
config script and the \@address arrayref contains the |
456
|
|
|
|
|
|
|
address(es) that the output will be sent to. $smtp_server |
457
|
|
|
|
|
|
|
is the smtp server for Net::SMTP to connect to and is also |
458
|
|
|
|
|
|
|
required in order for send_monkeymail to be called. |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
=cut |
461
|
|
|
|
|
|
|
sub send_monkeymail { |
462
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
463
|
0
|
|
0
|
|
|
|
my $content = shift || 'ERROR: NO OUTPUT'; |
464
|
0
|
|
0
|
|
|
|
my $smtp_server = shift || return undef; |
465
|
0
|
|
0
|
|
|
|
my $address = shift || return undef; |
466
|
|
|
|
|
|
|
|
467
|
0
|
|
0
|
|
|
|
my $smtp = Net::SMTP->new($smtp_server) || return undef; |
468
|
0
|
|
|
|
|
|
$smtp->mail($ENV{'USER'}); |
469
|
0
|
|
|
|
|
|
$smtp->to(@{$address}); |
|
0
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
|
471
|
0
|
|
|
|
|
|
$smtp->data(); |
472
|
0
|
|
|
|
|
|
$smtp->datasend("From: " . $ENV{'USER'} . "\n"); |
473
|
0
|
|
|
|
|
|
$smtp->datasend("To: @{$address}\n"); |
|
0
|
|
|
|
|
|
|
474
|
0
|
|
|
|
|
|
$smtp->datasend("Subject: Monkeywrench Output\n"); |
475
|
0
|
|
|
|
|
|
$smtp->datasend( "\n" . $content ); |
476
|
0
|
|
|
|
|
|
$smtp->dataend(); |
477
|
|
|
|
|
|
|
|
478
|
0
|
|
|
|
|
|
$smtp->quit; |
479
|
|
|
|
|
|
|
} |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
1; |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
__END__ |