Handle hostnames with upper-case letters
[webmin.git] / status / http-monitor.pl
1 # http-monitor.pl
2 # Monitor a remote HTTP server
3
4 sub get_http_status
5 {
6 # Connect to the server
7 local $up = 0;
8 local $st = time();
9 local $desc;
10 eval {
11         local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
12         alarm($_[0]->{'alarm'} ? $_[0]->{'alarm'} : 10);
13
14         local $re = $_[0]->{'regexp'};
15         local $method = $_[0]->{'method'} || "HEAD";
16         local $con = &make_http_connection($_[0]->{'host'}, $_[0]->{'port'},
17                                    $_[0]->{'ssl'}, $method, $_[0]->{'page'});
18         if (!ref($con)) {
19                 $up = 0;
20                 $desc = $con;
21                 return;
22                 }
23         &write_http_connection($con, "Host: $_[0]->{'host'}\r\n");
24         &write_http_connection($con, "User-agent: Webmin\r\n");
25         if ($_[0]->{'user'}) {
26                 local $auth = &encode_base64("$_[0]->{'user'}:$_[0]->{'pass'}");
27                 $auth =~ s/\n//g;
28                 &write_http_connection($con, "Authorization: Basic $auth\r\n");
29                 }
30         &write_http_connection($con, "\r\n");
31         local $line = &read_http_connection($con);
32         $up = $line =~ /^HTTP\/1\..\s+(200|301|302|303)\s+/ ? 1 : 0;
33         if ($re && $up) {
34                 # Read the headers
35                 local %header;
36                 while(1) {
37                         $line = &read_http_connection($con);
38                         $line =~ tr/\r\n//d;
39                         $line =~ /^(\S+):\s+(.*)$/ || last;
40                         $header{lc($1)} = $2;
41                         }
42
43                 # Read the body
44                 local ($buf, $data);
45                 while(defined($buf = &read_http_connection($con))) {
46                         $data .= $buf;
47                         }
48                 eval {
49                         # Check for regexp match
50                         eval {
51                                 if ($data !~ /$re/i) {
52                                         $up = 0;
53                                         $desc = "No match on : $re";
54                                         }
55                                 };
56                         };
57                 }
58         elsif (!$up) {
59                 $desc = $line;
60                 }
61
62         &close_http_connection($con);
63         alarm(0);
64         };
65
66 if ($@) {
67         die unless $@ eq "alarm\n";   # propagate unexpected errors
68         return { 'up' => 0,
69                  'desc' => $desc };
70         }
71 else { 
72         return { 'up' => $up,
73                  'time' => time() - $st,
74                  'desc' => $desc };
75         }
76 }
77
78 sub show_http_dialog
79 {
80 local $url;
81 if ($_[0]->{'host'}) {
82         $url = ($_[0]->{'ssl'} ? "https" : "http")."://";
83         if (&check_ip6address($_[0]->{'host'})) {
84                 $url .= "[".$_[0]->{'host'}."]";
85                 }
86         else {
87                 $url .= $_[0]->{'host'};
88                 }
89         $url .= ":$_[0]->{'port'}$_[0]->{'page'}";
90         }
91 else {
92         $url = "http://";
93         }
94 print &ui_table_row($text{'http_url'},
95         &ui_textbox("url", $url, 50), 3);
96
97 print &ui_table_row($text{'http_alarm'},
98         &ui_opt_textbox("alarm", $_[0]->{'alarm'}, 5, $text{'default'}).
99         " ".$text{'oldfile_secs'});
100
101 print &ui_table_row($text{'http_method'},
102         &ui_select("method", $_[0]->{'method'},
103                    [ [ "HEAD" ], [ "GET" ], [ "POST" ] ]));
104
105 print &ui_table_row($text{'http_login'},
106         &ui_radio("user_def", $_[0]->{'user'} ? 0 : 1,
107                 [ [ 1, $text{'http_none'} ],
108                   [ 0, $text{'http_user'}." ".
109                        &ui_textbox("huser", $_[0]->{'user'}, 15)." ".
110                        $text{'http_pass'}." ".
111                        &ui_password("hpass", $_[0]->{'pass'}, 15) ] ]), 3);
112
113 print &ui_table_row($text{'http_regexp'},
114         &ui_opt_textbox("regexp", $_[0]->{'regexp'}, 50, $text{'http_none2'}),
115         3);
116 }
117
118 sub parse_http_dialog
119 {
120 local ($host, $port, $page, $ssl) = &parse_http_url($in{'url'});
121 if ($host) {
122         $_[0]->{'ssl'} = $ssl;
123         $_[0]->{'host'} = $host;
124         $_[0]->{'port'} = $port;
125         $_[0]->{'page'} = $page;
126         }
127 else {
128         &error($text{'http_eurl'});
129         }
130
131 if ($in{'alarm_def'}) {
132         delete($_[0]->{'alarm'});
133         }
134 else {
135         $in{'alarm'} =~ /^\d+$/ || &error($text{'http_ealarm'});
136         $_[0]->{'alarm'} = $in{'alarm'};
137         }
138
139 if ($in{'user_def'}) {
140         delete($_[0]->{'user'});
141         delete($_[0]->{'pass'});
142         }
143 else {
144         $in{'huser'} || &error($text{'http_euser'});
145         $_[0]->{'user'} = $in{'huser'};
146         $_[0]->{'pass'} = $in{'hpass'};
147         }
148
149 $_[0]->{'method'} = $in{'method'};
150
151 if ($in{'regexp_def'}) {
152         delete($_[0]->{'regexp'});
153         }
154 else {
155         $in{'regexp'} || &error($text{'http_eregexp'});
156         $_[0]->{'regexp'} = $in{'regexp'};
157         $in{'method'} eq 'HEAD' && &error($text{'http_ehead'});
158         }
159 }
160