summaryrefslogtreecommitdiffstats
path: root/plugins/check_http.c
diff options
context:
space:
mode:
authorThomas Guyot-Sionnest <dermoth@aei.ca>2009-02-03 04:20:29 -0500
committerThomas Guyot-Sionnest <dermoth@aei.ca>2009-02-03 04:50:47 -0500
commit0d781712d7c8405460ab9f2bd9e262d49fe42a3f (patch)
tree6944e65436a2be94ab198a239f0945c8334facb9 /plugins/check_http.c
parentba132e9e521218efc5d35aa5f7a024cba93f5e29 (diff)
downloadmonitoring-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.c202
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
599static void 599static int
600check_document_dates (const char *headers) 600check_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
688int 693int
@@ -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
1231int 1223int
1232server_type_check (const char *type) 1224server_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));