diff options
author | Thomas Guyot-Sionnest <dermoth@aei.ca> | 2009-02-03 04:20:29 -0500 |
---|---|---|
committer | Thomas Guyot-Sionnest <dermoth@aei.ca> | 2009-02-03 04:50:47 -0500 |
commit | 0d781712d7c8405460ab9f2bd9e262d49fe42a3f (patch) | |
tree | 6944e65436a2be94ab198a239f0945c8334facb9 /plugins/check_http.c | |
parent | ba132e9e521218efc5d35aa5f7a024cba93f5e29 (diff) | |
download | monitoring-plugins-0d781712d7c8405460ab9f2bd9e262d49fe42a3f.tar.gz |
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.
Diffstat (limited to 'plugins/check_http.c')
-rw-r--r-- | plugins/check_http.c | 202 |
1 files changed, 97 insertions, 105 deletions
diff --git a/plugins/check_http.c b/plugins/check_http.c index f4a7e5e6..933e9d4f 100644 --- a/plugins/check_http.c +++ b/plugins/check_http.c | |||
@@ -133,9 +133,9 @@ main (int argc, char **argv) | |||
133 | { | 133 | { |
134 | int result = STATE_UNKNOWN; | 134 | int result = STATE_UNKNOWN; |
135 | 135 | ||
136 | setlocale (LC_ALL, ""); | 136 | setlocale (LC_ALL, ""); |
137 | bindtextdomain (PACKAGE, LOCALEDIR); | 137 | bindtextdomain (PACKAGE, LOCALEDIR); |
138 | textdomain (PACKAGE); | 138 | textdomain (PACKAGE); |
139 | 139 | ||
140 | /* Set default URL. Must be malloced for subsequent realloc if --onredirect=follow */ | 140 | /* Set default URL. Must be malloced for subsequent realloc if --onredirect=follow */ |
141 | server_url = strdup(HTTP_URL); | 141 | server_url = strdup(HTTP_URL); |
@@ -143,8 +143,8 @@ main (int argc, char **argv) | |||
143 | asprintf (&user_agent, "User-Agent: check_http/v%s (nagios-plugins %s)", | 143 | asprintf (&user_agent, "User-Agent: check_http/v%s (nagios-plugins %s)", |
144 | NP_VERSION, VERSION); | 144 | NP_VERSION, VERSION); |
145 | 145 | ||
146 | /* Parse extra opts if any */ | 146 | /* Parse extra opts if any */ |
147 | argv=np_extra_opts (&argc, argv, progname); | 147 | argv=np_extra_opts (&argc, argv, progname); |
148 | 148 | ||
149 | if (process_arguments (argc, argv) == ERROR) | 149 | if (process_arguments (argc, argv) == ERROR) |
150 | usage4 (_("Could not parse arguments")); | 150 | usage4 (_("Could not parse arguments")); |
@@ -596,12 +596,13 @@ expected_statuscode (const char *reply, const char *statuscodes) | |||
596 | return result; | 596 | return result; |
597 | } | 597 | } |
598 | 598 | ||
599 | static void | 599 | static int |
600 | check_document_dates (const char *headers) | 600 | check_document_dates (const char *headers, char **msg) |
601 | { | 601 | { |
602 | const char *s; | 602 | const char *s; |
603 | char *server_date = 0; | 603 | char *server_date = 0; |
604 | char *document_date = 0; | 604 | char *document_date = 0; |
605 | int date_result = STATE_OK; | ||
605 | 606 | ||
606 | s = headers; | 607 | s = headers; |
607 | while (*s) { | 608 | while (*s) { |
@@ -655,34 +656,38 @@ check_document_dates (const char *headers) | |||
655 | 656 | ||
656 | /* Done parsing the body. Now check the dates we (hopefully) parsed. */ | 657 | /* Done parsing the body. Now check the dates we (hopefully) parsed. */ |
657 | if (!server_date || !*server_date) { | 658 | if (!server_date || !*server_date) { |
658 | die (STATE_UNKNOWN, _("HTTP UNKNOWN - Server date unknown\n")); | 659 | asprintf (msg, _("%sServer date unknown, "), *msg); |
660 | date_result = max_state_alt(STATE_UNKNOWN, date_result); | ||
659 | } else if (!document_date || !*document_date) { | 661 | } else if (!document_date || !*document_date) { |
660 | die (STATE_CRITICAL, _("HTTP CRITICAL - Document modification date unknown\n")); | 662 | asprintf (msg, _("%sDocument modification date unknown, "), *msg); |
663 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
661 | } else { | 664 | } else { |
662 | time_t srv_data = parse_time_string (server_date); | 665 | time_t srv_data = parse_time_string (server_date); |
663 | time_t doc_data = parse_time_string (document_date); | 666 | time_t doc_data = parse_time_string (document_date); |
664 | 667 | ||
665 | if (srv_data <= 0) { | 668 | if (srv_data <= 0) { |
666 | die (STATE_CRITICAL, _("HTTP CRITICAL - Server date \"%100s\" unparsable"), server_date); | 669 | asprintf (msg, _("%sServer date \"%100s\" unparsable, "), *msg, server_date); |
670 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
667 | } else if (doc_data <= 0) { | 671 | } else if (doc_data <= 0) { |
668 | die (STATE_CRITICAL, _("HTTP CRITICAL - Document date \"%100s\" unparsable"), document_date); | 672 | asprintf (msg, _("%sDocument date \"%100s\" unparsable, "), *msg, document_date); |
673 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
669 | } else if (doc_data > srv_data + 30) { | 674 | } else if (doc_data > srv_data + 30) { |
670 | die (STATE_CRITICAL, _("HTTP CRITICAL - Document is %d seconds in the future\n"), (int)doc_data - (int)srv_data); | 675 | asprintf (msg, _("%sDocument is %d seconds in the future, "), *msg, (int)doc_data - (int)srv_data); |
676 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
671 | } else if (doc_data < srv_data - maximum_age) { | 677 | } else if (doc_data < srv_data - maximum_age) { |
672 | int n = (srv_data - doc_data); | 678 | int n = (srv_data - doc_data); |
673 | if (n > (60 * 60 * 24 * 2)) | 679 | if (n > (60 * 60 * 24 * 2)) { |
674 | die (STATE_CRITICAL, | 680 | asprintf (msg, _("%sLast modified %.1f days ago, "), *msg, ((float) n) / (60 * 60 * 24)); |
675 | _("HTTP CRITICAL - Last modified %.1f days ago\n"), | 681 | date_result = max_state_alt(STATE_CRITICAL, date_result); |
676 | ((float) n) / (60 * 60 * 24)); | 682 | } else { |
677 | else | 683 | asprintf (msg, _("%sLast modified %d:%02d:%02d ago, "), *msg, n / (60 * 60), (n / 60) % 60, n % 60); |
678 | die (STATE_CRITICAL, | 684 | date_result = max_state_alt(STATE_CRITICAL, date_result); |
679 | _("HTTP CRITICAL - Last modified %d:%02d:%02d ago\n"), | 685 | } |
680 | n / (60 * 60), (n / 60) % 60, n % 60); | ||
681 | } | 686 | } |
682 | |||
683 | free (server_date); | 687 | free (server_date); |
684 | free (document_date); | 688 | free (document_date); |
685 | } | 689 | } |
690 | return date_result; | ||
686 | } | 691 | } |
687 | 692 | ||
688 | int | 693 | int |
@@ -769,7 +774,7 @@ check_http (void) | |||
769 | long microsec; | 774 | long microsec; |
770 | double elapsed_time; | 775 | double elapsed_time; |
771 | int page_len = 0; | 776 | int page_len = 0; |
772 | int result = STATE_UNKNOWN; | 777 | int result = STATE_OK; |
773 | 778 | ||
774 | /* try to connect to the host at the given port number */ | 779 | /* try to connect to the host at the given port number */ |
775 | if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) | 780 | if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) |
@@ -889,6 +894,10 @@ check_http (void) | |||
889 | /* reset the alarm */ | 894 | /* reset the alarm */ |
890 | alarm (0); | 895 | alarm (0); |
891 | 896 | ||
897 | /* Save check time */ | ||
898 | microsec = deltime (tv); | ||
899 | elapsed_time = (double)microsec / 1.0e6; | ||
900 | |||
892 | /* leave full_page untouched so we can free it later */ | 901 | /* leave full_page untouched so we can free it later */ |
893 | page = full_page; | 902 | page = full_page; |
894 | 903 | ||
@@ -937,11 +946,11 @@ check_http (void) | |||
937 | die (STATE_CRITICAL, "HTTP CRITICAL - %s", msg); | 946 | die (STATE_CRITICAL, "HTTP CRITICAL - %s", msg); |
938 | } | 947 | } |
939 | 948 | ||
940 | /* Exit here if server_expect was set by user and not default */ | 949 | /* Bypass normal status line check if server_expect was set by user and not default */ |
950 | /* NOTE: After this if/else block msg *MUST* be an asprintf-allocated string */ | ||
941 | if ( server_expect_yn ) { | 951 | if ( server_expect_yn ) { |
942 | asprintf (&msg, | 952 | asprintf (&msg, |
943 | _("HTTP OK: Status line output matched \"%s\"\n"), | 953 | _("Status line output matched \"%s\" - "), server_expect); |
944 | server_expect); | ||
945 | if (verbose) | 954 | if (verbose) |
946 | printf ("%s\n",msg); | 955 | printf ("%s\n",msg); |
947 | } | 956 | } |
@@ -958,123 +967,107 @@ check_http (void) | |||
958 | 967 | ||
959 | /* check the return code */ | 968 | /* check the return code */ |
960 | 969 | ||
961 | if (http_status >= 600 || http_status < 100) | 970 | if (http_status >= 600 || http_status < 100) { |
962 | die (STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status (%s)\n"), status_line); | 971 | die (STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status (%s)\n"), status_line); |
963 | 972 | } | |
964 | /* server errors result in a critical state */ | 973 | /* server errors result in a critical state */ |
965 | else if (http_status >= 500) | 974 | else if (http_status >= 500) { |
966 | die (STATE_CRITICAL, _("HTTP CRITICAL: %s\n"), status_line); | 975 | asprintf (&msg, _("%s - "), msg, status_line); |
967 | 976 | result = STATE_CRITICAL; | |
977 | } | ||
968 | /* client errors result in a warning state */ | 978 | /* client errors result in a warning state */ |
969 | else if (http_status >= 400) | 979 | else if (http_status >= 400) { |
970 | die (STATE_WARNING, _("HTTP WARNING: %s\n"), status_line); | 980 | asprintf (&msg, _("%s - "), status_line); |
971 | 981 | result = max_state_alt(STATE_WARNING, result); | |
982 | } | ||
972 | /* check redirected page if specified */ | 983 | /* check redirected page if specified */ |
973 | else if (http_status >= 300) { | 984 | else if (http_status >= 300) { |
974 | 985 | ||
975 | if (onredirect == STATE_DEPENDENT) | 986 | if (onredirect == STATE_DEPENDENT) |
976 | redir (header, status_line); | 987 | redir (header, status_line); |
977 | else if (onredirect == STATE_UNKNOWN) | 988 | else |
978 | printf (_("HTTP UNKNOWN")); | 989 | result = max_state_alt(onredirect, result); |
979 | else if (onredirect == STATE_OK) | 990 | asprintf (&msg, _("%s - "), status_line); |
980 | printf (_("HTTP OK")); | ||
981 | else if (onredirect == STATE_WARNING) | ||
982 | printf (_("HTTP WARNING")); | ||
983 | else if (onredirect == STATE_CRITICAL) | ||
984 | printf (_("HTTP CRITICAL")); | ||
985 | microsec = deltime (tv); | ||
986 | elapsed_time = (double)microsec / 1.0e6; | ||
987 | die (onredirect, | ||
988 | _(" - %s - %.3f second response time %s|%s %s\n"), | ||
989 | status_line, elapsed_time, | ||
990 | (display_html ? "</A>" : ""), | ||
991 | perfd_time (elapsed_time), perfd_size (pagesize)); | ||
992 | } /* end if (http_status >= 300) */ | 991 | } /* end if (http_status >= 300) */ |
992 | else { | ||
993 | /* Print OK status anyway */ | ||
994 | asprintf (&msg, _("%s - "), status_line); | ||
995 | } | ||
993 | 996 | ||
994 | } /* end else (server_expect_yn) */ | 997 | } /* end else (server_expect_yn) */ |
995 | 998 | ||
996 | if (maximum_age >= 0) { | 999 | if (maximum_age >= 0) { |
997 | check_document_dates (header); | 1000 | result = max_state_alt(check_document_dates(header, &msg), result); |
998 | } | 1001 | } |
999 | |||
1000 | /* check elapsed time */ | ||
1001 | microsec = deltime (tv); | ||
1002 | elapsed_time = (double)microsec / 1.0e6; | ||
1003 | asprintf (&msg, | ||
1004 | _(" - %s - %.3f second response time %s|%s %s\n"), | ||
1005 | status_line, elapsed_time, | ||
1006 | (display_html ? "</A>" : ""), | ||
1007 | perfd_time (elapsed_time), perfd_size (pagesize)); | ||
1008 | if (check_critical_time == TRUE && elapsed_time > critical_time) | ||
1009 | die (STATE_CRITICAL, "HTTP %s: %s", _("CRITICAL"), msg); | ||
1010 | if (check_warning_time == TRUE && elapsed_time > warning_time) | ||
1011 | die (STATE_WARNING, "HTTP %s: %s", _("WARNING"), msg); | ||
1012 | 1002 | ||
1013 | /* Page and Header content checks go here */ | 1003 | /* Page and Header content checks go here */ |
1014 | /* these checks should be last */ | ||
1015 | 1004 | ||
1016 | if (strlen (string_expect)) { | 1005 | if (strlen (string_expect)) { |
1017 | if (strstr (page, string_expect)) { | 1006 | if (!strstr (page, string_expect)) { |
1018 | printf (_("HTTP OK %s - %.3f second response time %s|%s %s\n"), | 1007 | asprintf (&msg, _("%sstring not found, "), msg); |
1019 | status_line, elapsed_time, | 1008 | result = STATE_CRITICAL; |
1020 | (display_html ? "</A>" : ""), | ||
1021 | perfd_time (elapsed_time), perfd_size (pagesize)); | ||
1022 | exit (STATE_OK); | ||
1023 | } | ||
1024 | else { | ||
1025 | printf (_("HTTP CRITICAL - string not found%s|%s %s\n"), | ||
1026 | (display_html ? "</A>" : ""), | ||
1027 | perfd_time (elapsed_time), perfd_size (pagesize)); | ||
1028 | exit (STATE_CRITICAL); | ||
1029 | } | 1009 | } |
1030 | } | 1010 | } |
1031 | 1011 | ||
1032 | if (strlen (regexp)) { | 1012 | if (strlen (regexp)) { |
1033 | errcode = regexec (&preg, page, REGS, pmatch, 0); | 1013 | errcode = regexec (&preg, page, REGS, pmatch, 0); |
1034 | if ((errcode == 0 && invert_regex == 0) || (errcode == REG_NOMATCH && invert_regex == 1)) { | 1014 | if ((errcode == 0 && invert_regex == 0) || (errcode == REG_NOMATCH && invert_regex == 1)) { |
1035 | printf (_("HTTP OK %s - %.3f second response time %s|%s %s\n"), | 1015 | /* OK - No-op to avoid changing the logic around it */ |
1036 | status_line, elapsed_time, | 1016 | result = max_state_alt(STATE_OK, result); |
1037 | (display_html ? "</A>" : ""), | ||
1038 | perfd_time (elapsed_time), perfd_size (pagesize)); | ||
1039 | exit (STATE_OK); | ||
1040 | } | 1017 | } |
1041 | else if ((errcode == REG_NOMATCH && invert_regex == 0) || (errcode == 0 && invert_regex == 1)) { | 1018 | else if ((errcode == REG_NOMATCH && invert_regex == 0) || (errcode == 0 && invert_regex == 1)) { |
1042 | if (invert_regex == 0) | 1019 | if (invert_regex == 0) |
1043 | msg = strdup(_("pattern not found")); | 1020 | asprintf (&msg, _("%spattern not found, "), msg); |
1044 | else | 1021 | else |
1045 | msg = strdup(_("pattern found")); | 1022 | asprintf (&msg, _("%spattern found, "), msg); |
1046 | printf (("%s - %s%s|%s %s\n"), | 1023 | result = STATE_CRITICAL; |
1047 | _("HTTP CRITICAL"), | ||
1048 | msg, | ||
1049 | (display_html ? "</A>" : ""), | ||
1050 | perfd_time (elapsed_time), perfd_size (pagesize)); | ||
1051 | exit (STATE_CRITICAL); | ||
1052 | } | 1024 | } |
1053 | else { | 1025 | else { |
1026 | /* FIXME: Shouldn't that be UNKNOWN? */ | ||
1054 | regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); | 1027 | regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); |
1055 | printf (_("HTTP CRITICAL - Execute Error: %s\n"), errbuf); | 1028 | asprintf (&msg, _("%sExecute Error: %s, "), msg, errbuf); |
1056 | exit (STATE_CRITICAL); | 1029 | result = STATE_CRITICAL; |
1057 | } | 1030 | } |
1058 | } | 1031 | } |
1059 | 1032 | ||
1060 | /* make sure the page is of an appropriate size */ | 1033 | /* make sure the page is of an appropriate size */ |
1061 | /* page_len = get_content_length(header); */ | 1034 | /* page_len = get_content_length(header); */ |
1035 | /* FIXME: Will this work with -N ? IMHO we should use | ||
1036 | * get_content_length(header) and always check if it's different than the | ||
1037 | * returned pagesize | ||
1038 | */ | ||
1039 | /* FIXME: IIRC pagesize returns headers - shouldn't we make | ||
1040 | * it == get_content_length(header) ?? | ||
1041 | */ | ||
1062 | page_len = pagesize; | 1042 | page_len = pagesize; |
1063 | if ((max_page_len > 0) && (page_len > max_page_len)) { | 1043 | if ((max_page_len > 0) && (page_len > max_page_len)) { |
1064 | printf (_("HTTP WARNING: page size %d too large%s|%s\n"), | 1044 | asprintf (&msg, _("%spage size %d too large, "), msg, page_len); |
1065 | page_len, (display_html ? "</A>" : ""), perfd_size (page_len) ); | 1045 | result = max_state_alt(STATE_WARNING, result); |
1066 | exit (STATE_WARNING); | ||
1067 | } else if ((min_page_len > 0) && (page_len < min_page_len)) { | 1046 | } else if ((min_page_len > 0) && (page_len < min_page_len)) { |
1068 | printf (_("HTTP WARNING: page size %d too small%s|%s\n"), | 1047 | asprintf (&msg, _("%spage size %d too small, "), msg, page_len); |
1069 | page_len, (display_html ? "</A>" : ""), perfd_size (page_len) ); | 1048 | result = max_state_alt(STATE_WARNING, result); |
1070 | exit (STATE_WARNING); | ||
1071 | } | 1049 | } |
1072 | /* We only get here if all tests have been passed */ | 1050 | |
1073 | asprintf (&msg, _("HTTP OK %s - %d bytes in %.3f seconds %s|%s %s\n"), | 1051 | /* Cut-off trailing characters */ |
1074 | status_line, page_len, elapsed_time, | 1052 | if(msg[strlen(msg)-2] == ',') |
1053 | msg[strlen(msg)-2] = '\0'; | ||
1054 | else | ||
1055 | msg[strlen(msg)-3] = '\0'; | ||
1056 | |||
1057 | /* check elapsed time */ | ||
1058 | asprintf (&msg, | ||
1059 | _("%s - %.3f second response time %s|%s %s"), | ||
1060 | msg, elapsed_time, | ||
1075 | (display_html ? "</A>" : ""), | 1061 | (display_html ? "</A>" : ""), |
1076 | perfd_time (elapsed_time), perfd_size (page_len)); | 1062 | perfd_time (elapsed_time), perfd_size (page_len)); |
1077 | die (STATE_OK, "%s", msg); | 1063 | |
1064 | if (check_critical_time == TRUE && elapsed_time > critical_time) | ||
1065 | result = STATE_CRITICAL; | ||
1066 | if (check_warning_time == TRUE && elapsed_time > warning_time) | ||
1067 | result = max_state_alt(STATE_WARNING, result); | ||
1068 | |||
1069 | die (result, "HTTP %s: %s\n", state_text(result), msg); | ||
1070 | /* die failed? */ | ||
1078 | return STATE_UNKNOWN; | 1071 | return STATE_UNKNOWN; |
1079 | } | 1072 | } |
1080 | 1073 | ||
@@ -1227,7 +1220,6 @@ redir (char *pos, char *status_line) | |||
1227 | } | 1220 | } |
1228 | 1221 | ||
1229 | 1222 | ||
1230 | |||
1231 | int | 1223 | int |
1232 | server_type_check (const char *type) | 1224 | server_type_check (const char *type) |
1233 | { | 1225 | { |
@@ -1294,7 +1286,7 @@ print_help (void) | |||
1294 | printf (" %s\n", "-I, --IP-address=ADDRESS"); | 1286 | printf (" %s\n", "-I, --IP-address=ADDRESS"); |
1295 | printf (" %s\n", _("IP address or name (use numeric address if possible to bypass DNS lookup).")); | 1287 | printf (" %s\n", _("IP address or name (use numeric address if possible to bypass DNS lookup).")); |
1296 | printf (" %s\n", "-p, --port=INTEGER"); | 1288 | printf (" %s\n", "-p, --port=INTEGER"); |
1297 | printf (" %s", _("Port number (default: ")); | 1289 | printf (" %s", _("Port number (default: ")); |
1298 | printf ("%d)\n", HTTP_PORT); | 1290 | printf ("%d)\n", HTTP_PORT); |
1299 | 1291 | ||
1300 | printf (_(UT_IPv46)); | 1292 | printf (_(UT_IPv46)); |