diff options
Diffstat (limited to 'plugins')
| -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)); |
