mirror of
https://github.com/monitoring-plugins/monitoring-plugins.git
synced 2026-06-10 17:20:05 -04:00
Fix aberrant behaviours in check_http:
check_http used to ignore many parameters with check combinations - sometimes even time thresholds(!!) With this commit as long as a response is received *all* checks are performed on it. This fixes #1460312 plus a number of other issues I discovered over time.
This commit is contained in:
parent
ba132e9e52
commit
0d781712d7
1 changed files with 97 additions and 105 deletions
|
|
@ -133,9 +133,9 @@ main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int result = STATE_UNKNOWN;
|
int result = STATE_UNKNOWN;
|
||||||
|
|
||||||
setlocale (LC_ALL, "");
|
setlocale (LC_ALL, "");
|
||||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||||
textdomain (PACKAGE);
|
textdomain (PACKAGE);
|
||||||
|
|
||||||
/* Set default URL. Must be malloced for subsequent realloc if --onredirect=follow */
|
/* Set default URL. Must be malloced for subsequent realloc if --onredirect=follow */
|
||||||
server_url = strdup(HTTP_URL);
|
server_url = strdup(HTTP_URL);
|
||||||
|
|
@ -143,8 +143,8 @@ main (int argc, char **argv)
|
||||||
asprintf (&user_agent, "User-Agent: check_http/v%s (nagios-plugins %s)",
|
asprintf (&user_agent, "User-Agent: check_http/v%s (nagios-plugins %s)",
|
||||||
NP_VERSION, VERSION);
|
NP_VERSION, VERSION);
|
||||||
|
|
||||||
/* Parse extra opts if any */
|
/* Parse extra opts if any */
|
||||||
argv=np_extra_opts (&argc, argv, progname);
|
argv=np_extra_opts (&argc, argv, progname);
|
||||||
|
|
||||||
if (process_arguments (argc, argv) == ERROR)
|
if (process_arguments (argc, argv) == ERROR)
|
||||||
usage4 (_("Could not parse arguments"));
|
usage4 (_("Could not parse arguments"));
|
||||||
|
|
@ -596,12 +596,13 @@ expected_statuscode (const char *reply, const char *statuscodes)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
check_document_dates (const char *headers)
|
check_document_dates (const char *headers, char **msg)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
char *server_date = 0;
|
char *server_date = 0;
|
||||||
char *document_date = 0;
|
char *document_date = 0;
|
||||||
|
int date_result = STATE_OK;
|
||||||
|
|
||||||
s = headers;
|
s = headers;
|
||||||
while (*s) {
|
while (*s) {
|
||||||
|
|
@ -655,34 +656,38 @@ check_document_dates (const char *headers)
|
||||||
|
|
||||||
/* Done parsing the body. Now check the dates we (hopefully) parsed. */
|
/* Done parsing the body. Now check the dates we (hopefully) parsed. */
|
||||||
if (!server_date || !*server_date) {
|
if (!server_date || !*server_date) {
|
||||||
die (STATE_UNKNOWN, _("HTTP UNKNOWN - Server date unknown\n"));
|
asprintf (msg, _("%sServer date unknown, "), *msg);
|
||||||
|
date_result = max_state_alt(STATE_UNKNOWN, date_result);
|
||||||
} else if (!document_date || !*document_date) {
|
} else if (!document_date || !*document_date) {
|
||||||
die (STATE_CRITICAL, _("HTTP CRITICAL - Document modification date unknown\n"));
|
asprintf (msg, _("%sDocument modification date unknown, "), *msg);
|
||||||
|
date_result = max_state_alt(STATE_CRITICAL, date_result);
|
||||||
} else {
|
} else {
|
||||||
time_t srv_data = parse_time_string (server_date);
|
time_t srv_data = parse_time_string (server_date);
|
||||||
time_t doc_data = parse_time_string (document_date);
|
time_t doc_data = parse_time_string (document_date);
|
||||||
|
|
||||||
if (srv_data <= 0) {
|
if (srv_data <= 0) {
|
||||||
die (STATE_CRITICAL, _("HTTP CRITICAL - Server date \"%100s\" unparsable"), server_date);
|
asprintf (msg, _("%sServer date \"%100s\" unparsable, "), *msg, server_date);
|
||||||
|
date_result = max_state_alt(STATE_CRITICAL, date_result);
|
||||||
} else if (doc_data <= 0) {
|
} else if (doc_data <= 0) {
|
||||||
die (STATE_CRITICAL, _("HTTP CRITICAL - Document date \"%100s\" unparsable"), document_date);
|
asprintf (msg, _("%sDocument date \"%100s\" unparsable, "), *msg, document_date);
|
||||||
|
date_result = max_state_alt(STATE_CRITICAL, date_result);
|
||||||
} else if (doc_data > srv_data + 30) {
|
} else if (doc_data > srv_data + 30) {
|
||||||
die (STATE_CRITICAL, _("HTTP CRITICAL - Document is %d seconds in the future\n"), (int)doc_data - (int)srv_data);
|
asprintf (msg, _("%sDocument is %d seconds in the future, "), *msg, (int)doc_data - (int)srv_data);
|
||||||
|
date_result = max_state_alt(STATE_CRITICAL, date_result);
|
||||||
} else if (doc_data < srv_data - maximum_age) {
|
} else if (doc_data < srv_data - maximum_age) {
|
||||||
int n = (srv_data - doc_data);
|
int n = (srv_data - doc_data);
|
||||||
if (n > (60 * 60 * 24 * 2))
|
if (n > (60 * 60 * 24 * 2)) {
|
||||||
die (STATE_CRITICAL,
|
asprintf (msg, _("%sLast modified %.1f days ago, "), *msg, ((float) n) / (60 * 60 * 24));
|
||||||
_("HTTP CRITICAL - Last modified %.1f days ago\n"),
|
date_result = max_state_alt(STATE_CRITICAL, date_result);
|
||||||
((float) n) / (60 * 60 * 24));
|
} else {
|
||||||
else
|
asprintf (msg, _("%sLast modified %d:%02d:%02d ago, "), *msg, n / (60 * 60), (n / 60) % 60, n % 60);
|
||||||
die (STATE_CRITICAL,
|
date_result = max_state_alt(STATE_CRITICAL, date_result);
|
||||||
_("HTTP CRITICAL - Last modified %d:%02d:%02d ago\n"),
|
}
|
||||||
n / (60 * 60), (n / 60) % 60, n % 60);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free (server_date);
|
free (server_date);
|
||||||
free (document_date);
|
free (document_date);
|
||||||
}
|
}
|
||||||
|
return date_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -769,7 +774,7 @@ check_http (void)
|
||||||
long microsec;
|
long microsec;
|
||||||
double elapsed_time;
|
double elapsed_time;
|
||||||
int page_len = 0;
|
int page_len = 0;
|
||||||
int result = STATE_UNKNOWN;
|
int result = STATE_OK;
|
||||||
|
|
||||||
/* try to connect to the host at the given port number */
|
/* try to connect to the host at the given port number */
|
||||||
if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK)
|
if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK)
|
||||||
|
|
@ -889,6 +894,10 @@ check_http (void)
|
||||||
/* reset the alarm */
|
/* reset the alarm */
|
||||||
alarm (0);
|
alarm (0);
|
||||||
|
|
||||||
|
/* Save check time */
|
||||||
|
microsec = deltime (tv);
|
||||||
|
elapsed_time = (double)microsec / 1.0e6;
|
||||||
|
|
||||||
/* leave full_page untouched so we can free it later */
|
/* leave full_page untouched so we can free it later */
|
||||||
page = full_page;
|
page = full_page;
|
||||||
|
|
||||||
|
|
@ -937,11 +946,11 @@ check_http (void)
|
||||||
die (STATE_CRITICAL, "HTTP CRITICAL - %s", msg);
|
die (STATE_CRITICAL, "HTTP CRITICAL - %s", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exit here if server_expect was set by user and not default */
|
/* Bypass normal status line check if server_expect was set by user and not default */
|
||||||
|
/* NOTE: After this if/else block msg *MUST* be an asprintf-allocated string */
|
||||||
if ( server_expect_yn ) {
|
if ( server_expect_yn ) {
|
||||||
asprintf (&msg,
|
asprintf (&msg,
|
||||||
_("HTTP OK: Status line output matched \"%s\"\n"),
|
_("Status line output matched \"%s\" - "), server_expect);
|
||||||
server_expect);
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf ("%s\n",msg);
|
printf ("%s\n",msg);
|
||||||
}
|
}
|
||||||
|
|
@ -958,123 +967,107 @@ check_http (void)
|
||||||
|
|
||||||
/* check the return code */
|
/* check the return code */
|
||||||
|
|
||||||
if (http_status >= 600 || http_status < 100)
|
if (http_status >= 600 || http_status < 100) {
|
||||||
die (STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status (%s)\n"), status_line);
|
die (STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status (%s)\n"), status_line);
|
||||||
|
}
|
||||||
/* server errors result in a critical state */
|
/* server errors result in a critical state */
|
||||||
else if (http_status >= 500)
|
else if (http_status >= 500) {
|
||||||
die (STATE_CRITICAL, _("HTTP CRITICAL: %s\n"), status_line);
|
asprintf (&msg, _("%s - "), msg, status_line);
|
||||||
|
result = STATE_CRITICAL;
|
||||||
|
}
|
||||||
/* client errors result in a warning state */
|
/* client errors result in a warning state */
|
||||||
else if (http_status >= 400)
|
else if (http_status >= 400) {
|
||||||
die (STATE_WARNING, _("HTTP WARNING: %s\n"), status_line);
|
asprintf (&msg, _("%s - "), status_line);
|
||||||
|
result = max_state_alt(STATE_WARNING, result);
|
||||||
|
}
|
||||||
/* check redirected page if specified */
|
/* check redirected page if specified */
|
||||||
else if (http_status >= 300) {
|
else if (http_status >= 300) {
|
||||||
|
|
||||||
if (onredirect == STATE_DEPENDENT)
|
if (onredirect == STATE_DEPENDENT)
|
||||||
redir (header, status_line);
|
redir (header, status_line);
|
||||||
else if (onredirect == STATE_UNKNOWN)
|
else
|
||||||
printf (_("HTTP UNKNOWN"));
|
result = max_state_alt(onredirect, result);
|
||||||
else if (onredirect == STATE_OK)
|
asprintf (&msg, _("%s - "), status_line);
|
||||||
printf (_("HTTP OK"));
|
|
||||||
else if (onredirect == STATE_WARNING)
|
|
||||||
printf (_("HTTP WARNING"));
|
|
||||||
else if (onredirect == STATE_CRITICAL)
|
|
||||||
printf (_("HTTP CRITICAL"));
|
|
||||||
microsec = deltime (tv);
|
|
||||||
elapsed_time = (double)microsec / 1.0e6;
|
|
||||||
die (onredirect,
|
|
||||||
_(" - %s - %.3f second response time %s|%s %s\n"),
|
|
||||||
status_line, elapsed_time,
|
|
||||||
(display_html ? "</A>" : ""),
|
|
||||||
perfd_time (elapsed_time), perfd_size (pagesize));
|
|
||||||
} /* end if (http_status >= 300) */
|
} /* end if (http_status >= 300) */
|
||||||
|
else {
|
||||||
|
/* Print OK status anyway */
|
||||||
|
asprintf (&msg, _("%s - "), status_line);
|
||||||
|
}
|
||||||
|
|
||||||
} /* end else (server_expect_yn) */
|
} /* end else (server_expect_yn) */
|
||||||
|
|
||||||
if (maximum_age >= 0) {
|
if (maximum_age >= 0) {
|
||||||
check_document_dates (header);
|
result = max_state_alt(check_document_dates(header, &msg), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check elapsed time */
|
|
||||||
microsec = deltime (tv);
|
|
||||||
elapsed_time = (double)microsec / 1.0e6;
|
|
||||||
asprintf (&msg,
|
|
||||||
_(" - %s - %.3f second response time %s|%s %s\n"),
|
|
||||||
status_line, elapsed_time,
|
|
||||||
(display_html ? "</A>" : ""),
|
|
||||||
perfd_time (elapsed_time), perfd_size (pagesize));
|
|
||||||
if (check_critical_time == TRUE && elapsed_time > critical_time)
|
|
||||||
die (STATE_CRITICAL, "HTTP %s: %s", _("CRITICAL"), msg);
|
|
||||||
if (check_warning_time == TRUE && elapsed_time > warning_time)
|
|
||||||
die (STATE_WARNING, "HTTP %s: %s", _("WARNING"), msg);
|
|
||||||
|
|
||||||
/* Page and Header content checks go here */
|
/* Page and Header content checks go here */
|
||||||
/* these checks should be last */
|
|
||||||
|
|
||||||
if (strlen (string_expect)) {
|
if (strlen (string_expect)) {
|
||||||
if (strstr (page, string_expect)) {
|
if (!strstr (page, string_expect)) {
|
||||||
printf (_("HTTP OK %s - %.3f second response time %s|%s %s\n"),
|
asprintf (&msg, _("%sstring not found, "), msg);
|
||||||
status_line, elapsed_time,
|
result = STATE_CRITICAL;
|
||||||
(display_html ? "</A>" : ""),
|
|
||||||
perfd_time (elapsed_time), perfd_size (pagesize));
|
|
||||||
exit (STATE_OK);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf (_("HTTP CRITICAL - string not found%s|%s %s\n"),
|
|
||||||
(display_html ? "</A>" : ""),
|
|
||||||
perfd_time (elapsed_time), perfd_size (pagesize));
|
|
||||||
exit (STATE_CRITICAL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen (regexp)) {
|
if (strlen (regexp)) {
|
||||||
errcode = regexec (&preg, page, REGS, pmatch, 0);
|
errcode = regexec (&preg, page, REGS, pmatch, 0);
|
||||||
if ((errcode == 0 && invert_regex == 0) || (errcode == REG_NOMATCH && invert_regex == 1)) {
|
if ((errcode == 0 && invert_regex == 0) || (errcode == REG_NOMATCH && invert_regex == 1)) {
|
||||||
printf (_("HTTP OK %s - %.3f second response time %s|%s %s\n"),
|
/* OK - No-op to avoid changing the logic around it */
|
||||||
status_line, elapsed_time,
|
result = max_state_alt(STATE_OK, result);
|
||||||
(display_html ? "</A>" : ""),
|
|
||||||
perfd_time (elapsed_time), perfd_size (pagesize));
|
|
||||||
exit (STATE_OK);
|
|
||||||
}
|
}
|
||||||
else if ((errcode == REG_NOMATCH && invert_regex == 0) || (errcode == 0 && invert_regex == 1)) {
|
else if ((errcode == REG_NOMATCH && invert_regex == 0) || (errcode == 0 && invert_regex == 1)) {
|
||||||
if (invert_regex == 0)
|
if (invert_regex == 0)
|
||||||
msg = strdup(_("pattern not found"));
|
asprintf (&msg, _("%spattern not found, "), msg);
|
||||||
else
|
else
|
||||||
msg = strdup(_("pattern found"));
|
asprintf (&msg, _("%spattern found, "), msg);
|
||||||
printf (("%s - %s%s|%s %s\n"),
|
result = STATE_CRITICAL;
|
||||||
_("HTTP CRITICAL"),
|
|
||||||
msg,
|
|
||||||
(display_html ? "</A>" : ""),
|
|
||||||
perfd_time (elapsed_time), perfd_size (pagesize));
|
|
||||||
exit (STATE_CRITICAL);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
/* FIXME: Shouldn't that be UNKNOWN? */
|
||||||
regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
|
regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
|
||||||
printf (_("HTTP CRITICAL - Execute Error: %s\n"), errbuf);
|
asprintf (&msg, _("%sExecute Error: %s, "), msg, errbuf);
|
||||||
exit (STATE_CRITICAL);
|
result = STATE_CRITICAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make sure the page is of an appropriate size */
|
/* make sure the page is of an appropriate size */
|
||||||
/* page_len = get_content_length(header); */
|
/* page_len = get_content_length(header); */
|
||||||
|
/* FIXME: Will this work with -N ? IMHO we should use
|
||||||
|
* get_content_length(header) and always check if it's different than the
|
||||||
|
* returned pagesize
|
||||||
|
*/
|
||||||
|
/* FIXME: IIRC pagesize returns headers - shouldn't we make
|
||||||
|
* it == get_content_length(header) ??
|
||||||
|
*/
|
||||||
page_len = pagesize;
|
page_len = pagesize;
|
||||||
if ((max_page_len > 0) && (page_len > max_page_len)) {
|
if ((max_page_len > 0) && (page_len > max_page_len)) {
|
||||||
printf (_("HTTP WARNING: page size %d too large%s|%s\n"),
|
asprintf (&msg, _("%spage size %d too large, "), msg, page_len);
|
||||||
page_len, (display_html ? "</A>" : ""), perfd_size (page_len) );
|
result = max_state_alt(STATE_WARNING, result);
|
||||||
exit (STATE_WARNING);
|
|
||||||
} else if ((min_page_len > 0) && (page_len < min_page_len)) {
|
} else if ((min_page_len > 0) && (page_len < min_page_len)) {
|
||||||
printf (_("HTTP WARNING: page size %d too small%s|%s\n"),
|
asprintf (&msg, _("%spage size %d too small, "), msg, page_len);
|
||||||
page_len, (display_html ? "</A>" : ""), perfd_size (page_len) );
|
result = max_state_alt(STATE_WARNING, result);
|
||||||
exit (STATE_WARNING);
|
|
||||||
}
|
}
|
||||||
/* We only get here if all tests have been passed */
|
|
||||||
asprintf (&msg, _("HTTP OK %s - %d bytes in %.3f seconds %s|%s %s\n"),
|
/* Cut-off trailing characters */
|
||||||
status_line, page_len, elapsed_time,
|
if(msg[strlen(msg)-2] == ',')
|
||||||
|
msg[strlen(msg)-2] = '\0';
|
||||||
|
else
|
||||||
|
msg[strlen(msg)-3] = '\0';
|
||||||
|
|
||||||
|
/* check elapsed time */
|
||||||
|
asprintf (&msg,
|
||||||
|
_("%s - %.3f second response time %s|%s %s"),
|
||||||
|
msg, elapsed_time,
|
||||||
(display_html ? "</A>" : ""),
|
(display_html ? "</A>" : ""),
|
||||||
perfd_time (elapsed_time), perfd_size (page_len));
|
perfd_time (elapsed_time), perfd_size (page_len));
|
||||||
die (STATE_OK, "%s", msg);
|
|
||||||
|
if (check_critical_time == TRUE && elapsed_time > critical_time)
|
||||||
|
result = STATE_CRITICAL;
|
||||||
|
if (check_warning_time == TRUE && elapsed_time > warning_time)
|
||||||
|
result = max_state_alt(STATE_WARNING, result);
|
||||||
|
|
||||||
|
die (result, "HTTP %s: %s\n", state_text(result), msg);
|
||||||
|
/* die failed? */
|
||||||
return STATE_UNKNOWN;
|
return STATE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1227,7 +1220,6 @@ redir (char *pos, char *status_line)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
server_type_check (const char *type)
|
server_type_check (const char *type)
|
||||||
{
|
{
|
||||||
|
|
@ -1294,7 +1286,7 @@ print_help (void)
|
||||||
printf (" %s\n", "-I, --IP-address=ADDRESS");
|
printf (" %s\n", "-I, --IP-address=ADDRESS");
|
||||||
printf (" %s\n", _("IP address or name (use numeric address if possible to bypass DNS lookup)."));
|
printf (" %s\n", _("IP address or name (use numeric address if possible to bypass DNS lookup)."));
|
||||||
printf (" %s\n", "-p, --port=INTEGER");
|
printf (" %s\n", "-p, --port=INTEGER");
|
||||||
printf (" %s", _("Port number (default: "));
|
printf (" %s", _("Port number (default: "));
|
||||||
printf ("%d)\n", HTTP_PORT);
|
printf ("%d)\n", HTTP_PORT);
|
||||||
|
|
||||||
printf (_(UT_IPv46));
|
printf (_(UT_IPv46));
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue