| blib/lib/Apache/MONITOR.pm | |||
|---|---|---|---|
| Criterion | Covered | Total | % |
| statement | 10 | 12 | 83.3 |
| branch | n/a | ||
| condition | n/a | ||
| subroutine | 4 | 4 | 100.0 |
| pod | n/a | ||
| total | 14 | 16 | 87.5 |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | package Apache::MONITOR; | ||||||
| 2 | |||||||
| 3 | require 5.005_62; | ||||||
| 4 | 1 | 1 | 553 | use strict; | |||
| 1 | 1 | ||||||
| 1 | 27 | ||||||
| 5 | 1 | 1 | 4 | use vars qw($VERSION @EXPORTER @ISA); | |||
| 1 | 1 | ||||||
| 1 | 59 | ||||||
| 6 | 1 | 1 | 4 | use warnings; | |||
| 1 | 3 | ||||||
| 1 | 22 | ||||||
| 7 | 1 | 1 | 1137 | use String::CRC::Cksum qw(cksum); | |||
| 0 | |||||||
| 0 | |||||||
| 8 | |||||||
| 9 | use DB_File; | ||||||
| 10 | |||||||
| 11 | require Exporter; | ||||||
| 12 | use AutoLoader qw(AUTOLOAD); | ||||||
| 13 | |||||||
| 14 | our @ISA = qw(Exporter); | ||||||
| 15 | |||||||
| 16 | our @EXPORT = qw(SUBSCRIBE UNSUBSCRIBE NOTIFY SHOW); | ||||||
| 17 | our $VERSION = '0.02'; | ||||||
| 18 | |||||||
| 19 | use URI::Escape; | ||||||
| 20 | use Apache::Constants qw(:common :http :response :methods); | ||||||
| 21 | use constant SUBSCRIBE_OK => 1; | ||||||
| 22 | use constant SUBSCRIBE_ALREADY => 2; | ||||||
| 23 | use constant SUBSCRIBE_ERROR => 3; | ||||||
| 24 | |||||||
| 25 | my $original_handler; | ||||||
| 26 | |||||||
| 27 | sub is_proxy_request | ||||||
| 28 | { | ||||||
| 29 | my $r = shift; | ||||||
| 30 | my $host = $r->header_in('Host'); | ||||||
| 31 | return 0 unless( $host ); | ||||||
| 32 | return ($r->server->server_hostname ne $host); | ||||||
| 33 | } | ||||||
| 34 | |||||||
| 35 | sub handler { | ||||||
| 36 | my $r = shift; | ||||||
| 37 | $r->warn( "prr_handler 1"); | ||||||
| 38 | $r->warn( "------------------------------------------" ); | ||||||
| 39 | $r->warn( $r->the_request() ); | ||||||
| 40 | my $href = $r->headers_in(); | ||||||
| 41 | foreach (keys %$href) | ||||||
| 42 | { | ||||||
| 43 | $r->warn( "$_ -> $href->{$_}\n"); | ||||||
| 44 | } | ||||||
| 45 | $r->warn( "------------------------------------------" ); | ||||||
| 46 | $r->warn( $r->server->server_hostname ); | ||||||
| 47 | $r->warn( $r->get_server_name ); | ||||||
| 48 | if( is_proxy_request($r) ) | ||||||
| 49 | { | ||||||
| 50 | $r->warn( "IS PROXYREQ"); | ||||||
| 51 | } | ||||||
| 52 | return DECLINED unless $r->method() eq 'MONITOR' ; | ||||||
| 53 | $r->warn( "Filename " , $r->filename, "\n" ); | ||||||
| 54 | $r->warn( "Uri " , $r->uri, "\n" ); | ||||||
| 55 | $r->warn( "pathinfop " , $r->path_info, "\n" ); | ||||||
| 56 | $r->warn( "prr_handler 2"); | ||||||
| 57 | |||||||
| 58 | $r->method_number(M_GET); | ||||||
| 59 | |||||||
| 60 | return OK; | ||||||
| 61 | } | ||||||
| 62 | |||||||
| 63 | sub hp_handler { | ||||||
| 64 | my $r = shift; | ||||||
| 65 | $r->warn( "hp handler 1"); | ||||||
| 66 | |||||||
| 67 | $r->set_handlers(PerlFixupHandler => undef); | ||||||
| 68 | return DECLINED unless $r->method() eq 'MONITOR' ; | ||||||
| 69 | $r->warn( "hp handler 2"); | ||||||
| 70 | |||||||
| 71 | $original_handler = $r->handler(); | ||||||
| 72 | |||||||
| 73 | $r->handler("perl-script"); | ||||||
| 74 | $r->set_handlers(PerlHandler => [ \&monitor_handler ] ); | ||||||
| 75 | $r->warn( "Filename " , $r->filename, "\n" ); | ||||||
| 76 | $r->warn( "Uri " , $r->uri, "\n" ); | ||||||
| 77 | $r->warn( "pathinfop " , $r->path_info, "\n" ); | ||||||
| 78 | $r->warn( "hp handler 3"); | ||||||
| 79 | |||||||
| 80 | if( $r->proxyreq() ) | ||||||
| 81 | { | ||||||
| 82 | $r->warn( "IS PROXYREQ"); | ||||||
| 83 | $r->filename(''); | ||||||
| 84 | } | ||||||
| 85 | |||||||
| 86 | $r->set_handlers(PerlAccessHandler => undef); | ||||||
| 87 | $r->set_handlers(PerlAuthenHandler => undef); | ||||||
| 88 | $r->set_handlers(PerlDispatchHandler => undef); | ||||||
| 89 | $r->set_handlers(PerlTypeHandler => undef); | ||||||
| 90 | $r->set_handlers(PerlFixupHandler => [ \&fixup ]); | ||||||
| 91 | |||||||
| 92 | return OK; | ||||||
| 93 | } | ||||||
| 94 | |||||||
| 95 | sub fixup | ||||||
| 96 | { | ||||||
| 97 | my $r = shift; | ||||||
| 98 | $r->warn( "FIXUP1: handler is now " . $r->handler()); | ||||||
| 99 | |||||||
| 100 | $r->handler("perl-script"); | ||||||
| 101 | $r->set_handlers(PerlHandler => [ \&monitor_handler ] ); | ||||||
| 102 | $r->warn( "FIXUP2: handler is now " . $r->handler()); | ||||||
| 103 | |||||||
| 104 | $r->set_handlers(PerlFixupHandler => undef); | ||||||
| 105 | |||||||
| 106 | return OK; | ||||||
| 107 | } | ||||||
| 108 | |||||||
| 109 | |||||||
| 110 | |||||||
| 111 | |||||||
| 112 | sub monitor_handler | ||||||
| 113 | { | ||||||
| 114 | my $r = shift; | ||||||
| 115 | |||||||
| 116 | my $state = 'NONE'; | ||||||
| 117 | |||||||
| 118 | my $host = $r->header_in( 'Host' ); | ||||||
| 119 | if( !defined $host || !$host) | ||||||
| 120 | { | ||||||
| 121 | #FIXME allow HTTP 1.0! | ||||||
| 122 | return BAD_REQUEST; | ||||||
| 123 | } | ||||||
| 124 | |||||||
| 125 | my $monitored_uri = $r->uri; | ||||||
| 126 | if($r->uri !~ /:\/\//) | ||||||
| 127 | { | ||||||
| 128 | $monitored_uri = "http://$host" . $r->uri; | ||||||
| 129 | } | ||||||
| 130 | $r->warn( "monitored URI: $monitored_uri"); | ||||||
| 131 | |||||||
| 132 | my $mon_string = ""; | ||||||
| 133 | if( is_proxy_request($r) ) | ||||||
| 134 | { | ||||||
| 135 | $mon_string = "proxy:" . $monitored_uri; | ||||||
| 136 | my($cs,$rv,$msg) = poll_to_checksum($monitored_uri); | ||||||
| 137 | $state = $cs; | ||||||
| 138 | if($rv) | ||||||
| 139 | { | ||||||
| 140 | $r->warn( "error when polling remote resource: $msg"); | ||||||
| 141 | } | ||||||
| 142 | } | ||||||
| 143 | else | ||||||
| 144 | { | ||||||
| 145 | my $monitor_code = get_monitor_code($r,$monitored_uri); | ||||||
| 146 | $r->warn( "monitor_code: " . ( $monitor_code ? $monitor_code : "undef" )); | ||||||
| 147 | |||||||
| 148 | if( (!$monitor_code) && ( ($r->filename =~ /cgi/) || (! -f $r->filename)) ) | ||||||
| 149 | { | ||||||
| 150 | $r->warn( "monitor_handler HTTP_METHOD_NOT_ALLOWED"); | ||||||
| 151 | return HTTP_METHOD_NOT_ALLOWED; | ||||||
| 152 | } | ||||||
| 153 | if( $monitor_code ) | ||||||
| 154 | { | ||||||
| 155 | $mon_string = "apply:" . $monitor_code; | ||||||
| 156 | } | ||||||
| 157 | else | ||||||
| 158 | { | ||||||
| 159 | $mon_string = "mtime:" . $r->filename; | ||||||
| 160 | } | ||||||
| 161 | |||||||
| 162 | } | ||||||
| 163 | |||||||
| 164 | $r->warn( "monitor_handler 3 , monstring=$mon_string"); | ||||||
| 165 | my $reply_uri = $r->header_in( 'Reply-To' ); | ||||||
| 166 | |||||||
| 167 | if( !defined $reply_uri || !$reply_uri) | ||||||
| 168 | { | ||||||
| 169 | $r->warn( "--------BAD REQUEST -------------" ); | ||||||
| 170 | $r->warn( $r->method ); | ||||||
| 171 | $r->warn( $r->method_number ); | ||||||
| 172 | $r->warn( "--------BAD REQUEST -------------" ); | ||||||
| 173 | return BAD_REQUEST; | ||||||
| 174 | } | ||||||
| 175 | |||||||
| 176 | |||||||
| 177 | my ($mon_url,$rv) = add_subscription($r,$monitored_uri,$mon_string,$state,$reply_uri); | ||||||
| 178 | if($rv == SUBSCRIBE_ERROR) | ||||||
| 179 | { | ||||||
| 180 | return SERVER_ERROR; | ||||||
| 181 | } | ||||||
| 182 | |||||||
| 183 | if( | ||||||
| 184 | ($r->header_in('Accept') =~ /text\/html/) | ||||||
| 185 | || ($r->header_in('Accept') =~ /\*\/\*/) | ||||||
| 186 | |||||||
| 187 | ) | ||||||
| 188 | { | ||||||
| 189 | my $msg = ($rv == SUBSCRIBE_OK) ? "You have been subscribed to the URL" | ||||||
| 190 | : "You are already subscribed to the URL"; | ||||||
| 191 | $r->status(200); | ||||||
| 192 | $r->send_http_header("text/html"); | ||||||
| 193 | |||||||
| 194 | $r->print(qq{ | ||||||
| 195 | |||||||
| 196 | |
||||||
| 197 | |||||||
| 198 | $msg | ||||||
| 199 | $monitored_uri | ||||||
| 200 | |
||||||
| 201 | |
||||||
| 202 | To edit or remove your subscription, visit the | ||||||
| 203 | monitor page | ||||||
| 204 | |||||||
| 205 | |||||||
| 206 | }); | ||||||
| 207 | } | ||||||
| 208 | else | ||||||
| 209 | { | ||||||
| 210 | $r->header_out('Content-type' => undef); | ||||||
| 211 | $r->header_out('Content-Type' => undef); | ||||||
| 212 | $r->header_out("Location" => $mon_url ); | ||||||
| 213 | $r->status(201); | ||||||
| 214 | $r->send_http_header(); | ||||||
| 215 | } | ||||||
| 216 | |||||||
| 217 | return OK; | ||||||
| 218 | } | ||||||
| 219 | |||||||
| 220 | sub moo | ||||||
| 221 | { | ||||||
| 222 | my $r = shift; | ||||||
| 223 | |||||||
| 224 | |||||||
| 225 | |||||||
| 226 | my $dir = $r->dir_config('MonitorDataDir'); | ||||||
| 227 | my $host = $r->header_in( 'Host' ); | ||||||
| 228 | my $mon_uri = 'http://' . $host . $r->uri(); | ||||||
| 229 | |||||||
| 230 | if($r->method eq "GET") | ||||||
| 231 | { | ||||||
| 232 | my %uris; | ||||||
| 233 | my %monitors; | ||||||
| 234 | |||||||
| 235 | open(LOCK,">$dir/lock") || die("unable to open $dir/lock, $!"); | ||||||
| 236 | flock(LOCK,1); | ||||||
| 237 | |||||||
| 238 | dbmopen(%monitors , "$dir/monitors", 0666) || die("unable to open $dir/monitors, $!"); | ||||||
| 239 | my $value = $monitors{$mon_uri}; | ||||||
| 240 | dbmclose(%monitors); | ||||||
| 241 | close(LOCK); | ||||||
| 242 | |||||||
| 243 | if(!defined $value) | ||||||
| 244 | { | ||||||
| 245 | return NOT_FOUND; | ||||||
| 246 | } | ||||||
| 247 | |||||||
| 248 | |||||||
| 249 | my ($u,$re) = split( / / , $value); | ||||||
| 250 | |||||||
| 251 | $r->send_http_header("text/html" ); | ||||||
| 252 | $r->print( qq{ | ||||||
| 253 | |||||||
| 254 | |||||||
| 255 | |
||||||
| 256 | |||||||
| 257 | |||||||
| 258 | |||||||
| 259 |
|
||||||
| 260 | Monitor $mon_uri | ||||||
| 261 | |||||||
| 262 | |||||||
| 263 | Monitors: $u |
||||||
| 264 | Reply-To: $re | ||||||
| 265 | |||||||
| 266 | |||||||
| 275 | |||||||
| 276 | |||||||
| 277 | |||||||
| 278 | |||||||
| 279 | |||||||
| 280 | |||||||
| 281 | |||||||
| 282 | }); | ||||||
| 283 | return OK; | ||||||
| 284 | |||||||
| 285 | } | ||||||
| 286 | elsif($r->method eq "POST") | ||||||
| 287 | { | ||||||
| 288 | my %params = $r->content; | ||||||
| 289 | return HTTP_METHOD_NOT_ALLOWED; | ||||||
| 290 | } | ||||||
| 291 | elsif($r->method eq "DELETE") | ||||||
| 292 | { | ||||||
| 293 | my %uris; | ||||||
| 294 | my %monitors; | ||||||
| 295 | my $uri_still_monitored = 0; | ||||||
| 296 | |||||||
| 297 | open(LOCK,">$dir/lock") || die("unable to open $dir/lock, $!"); | ||||||
| 298 | flock(LOCK,2); | ||||||
| 299 | |||||||
| 300 | dbmopen(%monitors , "$dir/monitors", 0666) || die("unable to open $dir/monitors, $!"); | ||||||
| 301 | if(!exists($monitors{$mon_uri})) | ||||||
| 302 | { | ||||||
| 303 | dbmclose(%monitors); | ||||||
| 304 | close(LOCK); | ||||||
| 305 | return NOT_FOUND; | ||||||
| 306 | } | ||||||
| 307 | my ($monitored_uri,$re) = split(/ / , $monitors{$mon_uri}); | ||||||
| 308 | delete $monitors{$mon_uri}; | ||||||
| 309 | foreach my $muri (keys %monitors) | ||||||
| 310 | { | ||||||
| 311 | die("XXXXX") if($mon_uri eq $muri); | ||||||
| 312 | my $value = $monitors{$muri}; | ||||||
| 313 | my ($u,$re) = split(/ / , $value); | ||||||
| 314 | if($u eq $monitored_uri) | ||||||
| 315 | { | ||||||
| 316 | $uri_still_monitored = 1; | ||||||
| 317 | last; | ||||||
| 318 | } | ||||||
| 319 | } | ||||||
| 320 | dbmclose(%monitors); | ||||||
| 321 | if(!$uri_still_monitored) | ||||||
| 322 | { | ||||||
| 323 | dbmopen(%uris , "$dir/uris", 0666) || die("unable to open $dir/uris, $!"); | ||||||
| 324 | delete $uris{$monitored_uri}; | ||||||
| 325 | dbmclose(%uris); | ||||||
| 326 | } | ||||||
| 327 | close(LOCK); | ||||||
| 328 | |||||||
| 329 | $r->send_http_header("text/html" ); | ||||||
| 330 | $r->print( qq{ | ||||||
| 331 | |||||||
| 332 | |||||||
| 333 | |
||||||
| 334 | |||||||
| 335 | |||||||
| 336 | |||||||
| 337 | Monitor $mon_uri has been deleted. | ||||||
| 338 | |||||||
| 339 | |||||||
| 340 | }); | ||||||
| 341 | |||||||
| 342 | } | ||||||
| 343 | |||||||
| 344 | return OK; | ||||||
| 345 | } | ||||||
| 346 | |||||||
| 347 | sub show_monitors | ||||||
| 348 | { | ||||||
| 349 | my $r = shift; | ||||||
| 350 | my %uris; | ||||||
| 351 | my %monitors; | ||||||
| 352 | my $dir = $r->dir_config('MonitorDataDir'); | ||||||
| 353 | my $host = $r->header_in( 'Host' ); | ||||||
| 354 | my $mon_uri = 'http://' . $host . $r->uri(); | ||||||
| 355 | |||||||
| 356 | $r->send_http_header("text/html" ); | ||||||
| 357 | $r->print( qq{ | ||||||
| 358 | |||||||
| 359 | |||||||
| 360 | |
||||||
| 361 | |||||||
| 362 | |||||||
| 363 | }); | ||||||
| 364 | |||||||
| 365 | |||||||
| 366 | |||||||
| 367 | open(LOCK,">$dir/lock") || die("unable to open $dir/lock, $!"); | ||||||
| 368 | flock(LOCK,1); | ||||||
| 369 | |||||||
| 370 | dbmopen( %uris , "$dir/uris" , 0040) || die("unable to open $dir/uris, $!"); | ||||||
| 371 | dbmopen( %monitors , "$dir/monitors" , 0040) || die("unable to open $dir/monitors, $!"); | ||||||
| 372 | foreach my $uri ( keys %uris) | ||||||
| 373 | { | ||||||
| 374 | my $value = $uris{$uri}; | ||||||
| 375 | my ($u,$mon_string,$t,$state) = split(/ /,$value); | ||||||
| 376 | $r->print(qq{ $u |
||||||
| 377 | foreach my $muri (keys %monitors) | ||||||
| 378 | { | ||||||
| 379 | my $value = $monitors{$muri}; | ||||||
| 380 | #print "-- $value --\n"; | ||||||
| 381 | my ($u,$re) = split(/ / , $value); | ||||||
| 382 | if($u eq $uri) | ||||||
| 383 | { | ||||||
| 384 | $r->print(qq{ | ||||||
| 385 | $muri | ||||||
| 386 | ($re) [$mon_string] \n}); |
||||||
| 387 | } | ||||||
| 388 | } | ||||||
| 389 | $r->print("\n"); | ||||||
| 390 | } | ||||||
| 391 | dbmclose(%uris); | ||||||
| 392 | dbmclose(%monitors); | ||||||
| 393 | |||||||
| 394 | close(LOCK); | ||||||
| 395 | } | ||||||
| 396 | |||||||
| 397 | |||||||
| 398 | sub add_subscription | ||||||
| 399 | { | ||||||
| 400 | my ($r,$uri,$mon_string,$state,$reply_to) = @_; | ||||||
| 401 | |||||||
| 402 | my $dir = $r->dir_config('MonitorDataDir'); | ||||||
| 403 | my $mon_prefix = $r->dir_config('MonitorUrlPrefix'); | ||||||
| 404 | |||||||
| 405 | my $monitor_url = $mon_prefix; | ||||||
| 406 | my %uris; | ||||||
| 407 | my %monitors; | ||||||
| 408 | |||||||
| 409 | |||||||
| 410 | open(LOCK,">$dir/lock") || die("unable to open $dir/lock, $!"); | ||||||
| 411 | flock(LOCK,2); | ||||||
| 412 | |||||||
| 413 | dbmopen( %uris , "$dir/uris", 0666) || die("unable to open $dir/uris, $!"); | ||||||
| 414 | if(! exists $uris{$uri}) | ||||||
| 415 | { | ||||||
| 416 | my $now = time(); | ||||||
| 417 | my $value = join(' ', ($uri,$mon_string,$now,$state) ); | ||||||
| 418 | $uris{$uri} = $value; | ||||||
| 419 | } | ||||||
| 420 | dbmclose(%uris); | ||||||
| 421 | |||||||
| 422 | dbmopen( %monitors , "$dir/monitors", 0666) || die("unable to open $dir/monitors, $!"); | ||||||
| 423 | foreach my $muri (keys %monitors) | ||||||
| 424 | { | ||||||
| 425 | my $value = $monitors{$muri}; | ||||||
| 426 | my ($u,$re) = split (/ /,$value); | ||||||
| 427 | if( ($u eq $uri) && ($re eq $reply_to) ) | ||||||
| 428 | { | ||||||
| 429 | |||||||
| 430 | dbmclose(%monitors); | ||||||
| 431 | close(LOCK); | ||||||
| 432 | return ($muri,SUBSCRIBE_ALREADY); | ||||||
| 433 | } | ||||||
| 434 | } | ||||||
| 435 | my $id = time() . $$; | ||||||
| 436 | $monitor_url .= $id; | ||||||
| 437 | $monitors{$monitor_url} = "$uri $reply_to"; | ||||||
| 438 | dbmclose(%monitors); | ||||||
| 439 | close(LOCK); | ||||||
| 440 | |||||||
| 441 | |||||||
| 442 | return ($monitor_url,SUBSCRIBE_OK); | ||||||
| 443 | } | ||||||
| 444 | |||||||
| 445 | |||||||
| 446 | sub get_monitor_code | ||||||
| 447 | { | ||||||
| 448 | my ($r,$monitored_uri) = @_; | ||||||
| 449 | return undef; | ||||||
| 450 | return "checker"; | ||||||
| 451 | } | ||||||
| 452 | |||||||
| 453 | |||||||
| 454 | |||||||
| 455 | |||||||
| 456 | |||||||
| 457 | sub SUBSCRIBE | ||||||
| 458 | { | ||||||
| 459 | require LWP::UserAgent; | ||||||
| 460 | @Apache::MONITOR::ISA = qw(LWP::UserAgent); | ||||||
| 461 | |||||||
| 462 | my $ua = __PACKAGE__->new; | ||||||
| 463 | |||||||
| 464 | my $args = @_ ? \@_ : \@ARGV; | ||||||
| 465 | |||||||
| 466 | my ($url,$reply_to,$proxy) = @$args; | ||||||
| 467 | $ua->proxy(['http'], $proxy ) if(defined $proxy); | ||||||
| 468 | my $req = HTTP::Request->new('MONITOR' => $url ); | ||||||
| 469 | |||||||
| 470 | $req->header('Reply_To' => $reply_to ); | ||||||
| 471 | #$req->header('Accept' => 'text/plain' ); | ||||||
| 472 | my $res = $ua->request($req); | ||||||
| 473 | |||||||
| 474 | if($res->is_success) | ||||||
| 475 | { | ||||||
| 476 | print $res->as_string(); | ||||||
| 477 | print "Monitor created at: ",$res->header('Location') , "\n"; | ||||||
| 478 | } | ||||||
| 479 | else | ||||||
| 480 | { | ||||||
| 481 | print $res->as_string(); | ||||||
| 482 | } | ||||||
| 483 | |||||||
| 484 | } | ||||||
| 485 | sub UNSUBSCRIBE | ||||||
| 486 | { | ||||||
| 487 | require LWP::UserAgent; | ||||||
| 488 | @Apache::MONITOR::ISA = qw(LWP::UserAgent); | ||||||
| 489 | |||||||
| 490 | my $ua = __PACKAGE__->new; | ||||||
| 491 | |||||||
| 492 | my $args = @_ ? \@_ : \@ARGV; | ||||||
| 493 | |||||||
| 494 | my ($mon_url) = @$args; | ||||||
| 495 | my $req = HTTP::Request->new('DELETE' => $mon_url ); | ||||||
| 496 | |||||||
| 497 | my $res = $ua->request($req); | ||||||
| 498 | |||||||
| 499 | if($res->is_success) | ||||||
| 500 | { | ||||||
| 501 | print $res->as_string(); | ||||||
| 502 | #print $res->content; | ||||||
| 503 | print "Monitor deleted\n"; | ||||||
| 504 | } | ||||||
| 505 | else | ||||||
| 506 | { | ||||||
| 507 | print $res->as_string(); | ||||||
| 508 | } | ||||||
| 509 | |||||||
| 510 | } | ||||||
| 511 | |||||||
| 512 | sub NOTIFY | ||||||
| 513 | { | ||||||
| 514 | require LWP::UserAgent; | ||||||
| 515 | @Apache::MONITOR::ISA = qw(LWP::UserAgent); | ||||||
| 516 | my $ua = __PACKAGE__->new; | ||||||
| 517 | my $args = @_ ? \@_ : \@ARGV; | ||||||
| 518 | |||||||
| 519 | my ($dir) = @$args; | ||||||
| 520 | |||||||
| 521 | my %uris; | ||||||
| 522 | my %monitors; | ||||||
| 523 | |||||||
| 524 | open(LOCK,">$dir/lock") || die("unable to open $dir/lock, $!"); | ||||||
| 525 | flock(LOCK,2); | ||||||
| 526 | |||||||
| 527 | dbmopen( %uris , "$dir/uris" , 0040) || die("unable to open $dir/uris, $!"); | ||||||
| 528 | dbmopen( %monitors , "$dir/monitors" , 0040) || die("unable to open $dir/monitors, $!"); | ||||||
| 529 | foreach my $monitored_uri ( keys %uris ) | ||||||
| 530 | { | ||||||
| 531 | my $value = $uris{$monitored_uri}; | ||||||
| 532 | my ($u,$mon_string,$lastmod,$state) = split(/ /,$value); | ||||||
| 533 | my $modified_time = $lastmod; | ||||||
| 534 | #print "--$u $mon_string $lastmod\n"; | ||||||
| 535 | print "*--------------------------------------------------\n"; | ||||||
| 536 | |||||||
| 537 | if( $mon_string =~ /^apply:(.+)$/ ) | ||||||
| 538 | { | ||||||
| 539 | # apply code | ||||||
| 540 | my $code = $1; | ||||||
| 541 | require "/tmp/" . $code; | ||||||
| 542 | $modified_time = $code->check($u); | ||||||
| 543 | } | ||||||
| 544 | elsif( $mon_string =~ /^mtime:(.+)$/ ) | ||||||
| 545 | { | ||||||
| 546 | my $filename = $1; | ||||||
| 547 | print "$monitored_uri: checking file mtime of $filename\n"; | ||||||
| 548 | my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, | ||||||
| 549 | $atime,$mtime,$ctime,$blksize,$blocks) = stat($filename); | ||||||
| 550 | $modified_time = $mtime; | ||||||
| 551 | } | ||||||
| 552 | else | ||||||
| 553 | { | ||||||
| 554 | my $old_checksum = $state; | ||||||
| 555 | print "$monitored_uri: checking checksum via HTTP GET\n"; | ||||||
| 556 | my ($checksum,$rv,$msg) = poll_to_checksum($monitored_uri); | ||||||
| 557 | if($rv) | ||||||
| 558 | { | ||||||
| 559 | print "$monitored_uri: ",$msg, "\n"; | ||||||
| 560 | next; | ||||||
| 561 | } | ||||||
| 562 | print " ....old checksum $old_checksum\n"; | ||||||
| 563 | print " ....new checksum $checksum\n"; | ||||||
| 564 | if( $checksum != $old_checksum) | ||||||
| 565 | { | ||||||
| 566 | $modified_time = time(); | ||||||
| 567 | $state = $checksum; | ||||||
| 568 | } | ||||||
| 569 | } | ||||||
| 570 | |||||||
| 571 | next unless ($modified_time > $lastmod); | ||||||
| 572 | |||||||
| 573 | print "...$monitored_uri has changed, getting monitors\n"; | ||||||
| 574 | |||||||
| 575 | # updating record with new lastmod | ||||||
| 576 | |||||||
| 577 | $uris{$monitored_uri} = "$u $mon_string $modified_time $state"; | ||||||
| 578 | |||||||
| 579 | foreach my $muri (keys %monitors) | ||||||
| 580 | { | ||||||
| 581 | my $value = $monitors{$muri}; | ||||||
| 582 | my ($u,$re) = split(/ / , $value); | ||||||
| 583 | next unless ($u eq $monitored_uri); | ||||||
| 584 | |||||||
| 585 | #my $req = HTTP::Request->new('GET' => $monitored_uri); | ||||||
| 586 | #my $res = $ua->request($req); | ||||||
| 587 | #my $body; | ||||||
| 588 | #if($res->is_success) | ||||||
| 589 | #{ | ||||||
| 590 | # $body = $res->content; | ||||||
| 591 | #} | ||||||
| 592 | #else | ||||||
| 593 | #{ | ||||||
| 594 | # $body = $res->as_string(); | ||||||
| 595 | #} | ||||||
| 596 | #$req->header('Reply_To' => $reply_to ); | ||||||
| 597 | |||||||
| 598 | if( $re =~ /^mailto:(.*)$/ ) | ||||||
| 599 | { | ||||||
| 600 | my $to = $1; | ||||||
| 601 | open(MAIL,"|mail $to -s \"Resource $monitored_uri has changed\""); | ||||||
| 602 | print MAIL "Resource state has changed at ". localtime($modified_time) ."\n"; | ||||||
| 603 | print MAIL "View the monitored resource: $monitored_uri\n"; | ||||||
| 604 | print MAIL "Edit your monitor: $muri\n"; | ||||||
| 605 | close(MAIL); | ||||||
| 606 | print " notified $re\n"; | ||||||
| 607 | } | ||||||
| 608 | } | ||||||
| 609 | |||||||
| 610 | } | ||||||
| 611 | dbmclose(%uris); | ||||||
| 612 | dbmclose(%monitors); | ||||||
| 613 | |||||||
| 614 | close(LOCK); | ||||||
| 615 | |||||||
| 616 | } | ||||||
| 617 | sub poll_to_checksum | ||||||
| 618 | { | ||||||
| 619 | require LWP::UserAgent; | ||||||
| 620 | @Apache::MONITOR::ISA = qw(LWP::UserAgent); | ||||||
| 621 | my $ua = __PACKAGE__->new; | ||||||
| 622 | my $args = @_ ? \@_ : \@ARGV; | ||||||
| 623 | |||||||
| 624 | my ($uri) = @$args; | ||||||
| 625 | |||||||
| 626 | my $req = HTTP::Request->new('GET' => $uri); | ||||||
| 627 | my $res = $ua->request($req); | ||||||
| 628 | if($res->is_success) | ||||||
| 629 | { | ||||||
| 630 | my $s = $res->content; | ||||||
| 631 | $s =~ s/]+>//gi; | ||||||
| 632 | my $cs = cksum($s); | ||||||
| 633 | return ($cs,0,''); | ||||||
| 634 | } | ||||||
| 635 | else | ||||||
| 636 | { | ||||||
| 637 | return (0,1,'GET error'); | ||||||
| 638 | } | ||||||
| 639 | } | ||||||
| 640 | |||||||
| 641 | 1; | ||||||
| 642 | __END__ |