summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Nierlein <sven@nierlein.de>2017-03-18 22:43:51 (GMT)
committerSven Nierlein <sven@nierlein.de>2018-10-22 14:30:31 (GMT)
commitc6c90a5bfae1e6af90af52756da86c4d839e8bc6 (patch)
treed8fe80ce7f5f3769104b9ca442a834091fe98b7d
parenta793540bbb9029069eab3c63fbb82971e2cb9fef (diff)
downloadmonitoring-plugins-c6c90a5bfae1e6af90af52756da86c4d839e8bc6.tar.gz
check_curl: implement -e/--expect
-rw-r--r--plugins/check_curl.c97
1 files changed, 75 insertions, 22 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c
index ccbc6a8..57b6e12 100644
--- a/plugins/check_curl.c
+++ b/plugins/check_curl.c
@@ -49,6 +49,7 @@ const char *email = "devel@monitoring-plugins.org";
49 49
50#define DEFAULT_BUFFER_SIZE 2048 50#define DEFAULT_BUFFER_SIZE 2048
51#define DEFAULT_SERVER_URL "/" 51#define DEFAULT_SERVER_URL "/"
52#define HTTP_EXPECT "HTTP/1."
52enum { 53enum {
53 HTTP_PORT = 80, 54 HTTP_PORT = 80,
54 HTTPS_PORT = 443, 55 HTTPS_PORT = 443,
@@ -122,6 +123,8 @@ char url[DEFAULT_BUFFER_SIZE];
122char msg[DEFAULT_BUFFER_SIZE]; 123char msg[DEFAULT_BUFFER_SIZE];
123char perfstring[DEFAULT_BUFFER_SIZE]; 124char perfstring[DEFAULT_BUFFER_SIZE];
124char string_expect[MAX_INPUT_BUFFER] = ""; 125char string_expect[MAX_INPUT_BUFFER] = "";
126char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT;
127int server_expect_yn = 0;
125char user_auth[MAX_INPUT_BUFFER] = ""; 128char user_auth[MAX_INPUT_BUFFER] = "";
126int onredirect = STATE_OK; 129int onredirect = STATE_OK;
127int use_ssl = FALSE; 130int use_ssl = FALSE;
@@ -188,6 +191,26 @@ CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm)
188 return CURLE_OK; 191 return CURLE_OK;
189} 192}
190 193
194/* Checks if the server 'reply' is one of the expected 'statuscodes' */
195static int
196expected_statuscode (const char *reply, const char *statuscodes)
197{
198 char *expected, *code;
199 int result = 0;
200
201 if ((expected = strdup (statuscodes)) == NULL)
202 die (STATE_UNKNOWN, _("HTTP UNKNOWN - Memory allocation error\n"));
203
204 for (code = strtok (expected, ","); code != NULL; code = strtok (NULL, ","))
205 if (strstr (reply, code) != NULL) {
206 result = 1;
207 break;
208 }
209
210 free (expected);
211 return result;
212}
213
191int 214int
192check_http (void) 215check_http (void)
193{ 216{
@@ -416,28 +439,47 @@ check_http (void)
416 (no_body ? " [[ skipped ]]" : body_buf.buf)); 439 (no_body ? " [[ skipped ]]" : body_buf.buf));
417 } 440 }
418 441
419 /* illegal return codes result in a critical state */ 442 /* make sure the status line matches the response we are looking for */
420 if (code >= 600 || code < 100) { 443 if (!expected_statuscode(header_buf.buf, server_expect)) {
421 die (STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status (%d, %.40s)\n"), status_line.http_code, status_line.msg); 444 /* TODO: fix first_line being cut off */
422 /* server errors result in a critical state */ 445 if (server_port == HTTP_PORT)
423 } else if (code >= 500) { 446 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host: %s\n"), status_line.first_line);
424 result = STATE_CRITICAL; 447 else
425 /* client errors result in a warning state */ 448 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: %s\n"), server_port, status_line.first_line);
426 } else if (code >= 400) { 449 die (STATE_CRITICAL, "HTTP CRITICAL - %s", msg);
427 result = STATE_WARNING; 450 }
428 /* check redirected page if specified */ 451
429 } else if (code >= 300) { 452 /* TODO: implement -d header tests */
430 if (onredirect == STATE_DEPENDENT) { 453 if( server_expect_yn ) {
431 code = status_line.http_code; 454 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Status line output matched \"%s\" - "), server_expect);
432 } 455 if (verbose)
433 result = max_state_alt (onredirect, result); 456 printf ("%s\n",msg);
434 /* TODO: make sure the last status line has been
435 parsed into the status_line structure
436 */
437 /* all other codes are considered ok */
438 } else {
439 result = STATE_OK; 457 result = STATE_OK;
440 } 458 }
459 else {
460 /* illegal return codes result in a critical state */
461 if (code >= 600 || code < 100) {
462 die (STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status (%d, %.40s)\n"), status_line.http_code, status_line.msg);
463 /* server errors result in a critical state */
464 } else if (code >= 500) {
465 result = STATE_CRITICAL;
466 /* client errors result in a warning state */
467 } else if (code >= 400) {
468 result = STATE_WARNING;
469 /* check redirected page if specified */
470 } else if (code >= 300) {
471 if (onredirect == STATE_DEPENDENT) {
472 code = status_line.http_code;
473 }
474 result = max_state_alt (onredirect, result);
475 /* TODO: make sure the last status line has been
476 parsed into the status_line structure
477 */
478 /* all other codes are considered ok */
479 } else {
480 result = STATE_OK;
481 }
482 }
441 483
442 /* check status codes, set exit status accordingly */ 484 /* check status codes, set exit status accordingly */
443 if( status_line.http_code != code ) { 485 if( status_line.http_code != code ) {
@@ -551,6 +593,7 @@ process_arguments (int argc, char **argv)
551 {"port", required_argument, 0, 'p'}, 593 {"port", required_argument, 0, 'p'},
552 {"authorization", required_argument, 0, 'a'}, 594 {"authorization", required_argument, 0, 'a'},
553 {"string", required_argument, 0, 's'}, 595 {"string", required_argument, 0, 's'},
596 {"expect", required_argument, 0, 'e'},
554 {"regex", required_argument, 0, 'r'}, 597 {"regex", required_argument, 0, 'r'},
555 {"ereg", required_argument, 0, 'r'}, 598 {"ereg", required_argument, 0, 'r'},
556 {"eregi", required_argument, 0, 'R'}, 599 {"eregi", required_argument, 0, 'R'},
@@ -588,7 +631,7 @@ process_arguments (int argc, char **argv)
588 } 631 }
589 632
590 while (1) { 633 while (1) {
591 c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:j:I:a:p:s:R:r:u:f:C:J:K:S::m:NE", longopts, &option); 634 c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:j:I:a:p:e:s:R:r:u:f:C:J:K:S::m:NE", longopts, &option);
592 if (c == -1 || c == EOF || c == 1) 635 if (c == -1 || c == EOF || c == 1)
593 break; 636 break;
594 637
@@ -758,6 +801,11 @@ process_arguments (int argc, char **argv)
758 strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1); 801 strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1);
759 string_expect[MAX_INPUT_BUFFER - 1] = 0; 802 string_expect[MAX_INPUT_BUFFER - 1] = 0;
760 break; 803 break;
804 case 'e': /* string or substring */
805 strncpy (server_expect, optarg, MAX_INPUT_BUFFER - 1);
806 server_expect[MAX_INPUT_BUFFER - 1] = 0;
807 server_expect_yn = 1;
808 break;
761 case 'R': /* regex */ 809 case 'R': /* regex */
762 cflags |= REG_ICASE; 810 cflags |= REG_ICASE;
763 case 'r': /* regex */ 811 case 'r': /* regex */
@@ -917,6 +965,11 @@ print_help (void)
917 printf (" %s\n", _("CA certificate file to verify peer against")); 965 printf (" %s\n", _("CA certificate file to verify peer against"));
918#endif 966#endif
919 967
968 printf (" %s\n", "-e, --expect=STRING");
969 printf (" %s\n", _("Comma-delimited list of strings, at least one of them is expected in"));
970 printf (" %s", _("the first (status) line of the server response (default: "));
971 printf ("%s)\n", HTTP_EXPECT);
972 printf (" %s\n", _("If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)"));
920 printf (" %s\n", "-s, --string=STRING"); 973 printf (" %s\n", "-s, --string=STRING");
921 printf (" %s\n", _("String to expect in the content")); 974 printf (" %s\n", _("String to expect in the content"));
922 printf (" %s\n", "-u, --url=PATH"); 975 printf (" %s\n", "-u, --url=PATH");
@@ -1012,7 +1065,7 @@ print_usage (void)
1012 printf (" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate file>]\n"); 1065 printf (" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate file>]\n");
1013 printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-E] [-a auth]\n"); 1066 printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-E] [-a auth]\n");
1014 printf (" [-f <ok|warning|critcal|follow>]\n"); 1067 printf (" [-f <ok|warning|critcal|follow>]\n");
1015 printf (" [-s string] [-r <regex> | -R <case-insensitive regex>]\n"); 1068 printf (" [-e <expect>] [-s string] [-r <regex> | -R <case-insensitive regex>]\n");
1016 printf (" [-m <min_pg_size>:<max_pg_size>] [-N]\n"); 1069 printf (" [-m <min_pg_size>:<max_pg_size>] [-N]\n");
1017 printf (" [-4|-6] [-N]\n"); 1070 printf (" [-4|-6] [-N]\n");
1018 printf (" [-A string] [-k string] [-S <version>] [-C]\n"); 1071 printf (" [-A string] [-k string] [-S <version>] [-C]\n");