[Nagiosplug-checkins] CVS: nagiosplug/plugins check_http.c,1.60,1.61

Ton Voon tonvoon at users.sourceforge.net
Wed Nov 17 15:24:02 CET 2004


Update of /cvsroot/nagiosplug/nagiosplug/plugins
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23899

Modified Files:
	check_http.c 
Log Message:
--no-body and --max-age options (949521 - Jamie Zawinski)


Index: check_http.c
===================================================================
RCS file: /cvsroot/nagiosplug/nagiosplug/plugins/check_http.c,v
retrieving revision 1.60
retrieving revision 1.61
diff -C2 -r1.60 -r1.61
*** check_http.c	22 Mar 2004 07:19:58 -0000	1.60
--- check_http.c	17 Nov 2004 23:22:54 -0000	1.61
***************
*** 64,67 ****
--- 64,69 ----
  int check_certificate (X509 **);
  #endif
+ int no_body = FALSE;
+ int maximum_age = -1;
  
  #ifdef HAVE_REGEX_H
***************
*** 210,213 ****
--- 212,217 ----
  		{"onredirect", required_argument, 0, 'f'},
  		{"certificate", required_argument, 0, 'C'},
+ 		{"no-body", no_argument, 0, 'N'},
+ 		{"max-age", required_argument, 0, 'M'},
  		{"content-type", required_argument, 0, 'T'},
  		{"min", required_argument, 0, 'm'},
***************
*** 234,238 ****
  
  	while (1) {
! 		c = getopt_long (argc, argv, "Vvh46t:c:w:H:P:T:I:a:e:p:s:R:r:u:f:C:nlLSm:", longopts, &option);
  		if (c == -1 || c == EOF)
  			break;
--- 238,242 ----
  
  	while (1) {
! 		c = getopt_long (argc, argv, "Vvh46t:c:w:H:P:T:I:a:e:p:s:R:r:u:f:C:nlLSm:M:N", longopts, &option);
  		if (c == -1 || c == EOF)
  			break;
***************
*** 391,394 ****
--- 395,419 ----
  			min_page_len = atoi (optarg);
  			break;
+ 		case 'N': /* no-body */
+ 			no_body = TRUE;
+ 			break;
+ 		case 'M': /* max-age */
+                   {
+                     int L = strlen(optarg);
+                     if (L && optarg[L-1] == 'm')
+                       maximum_age = atoi (optarg) * 60;
+                     else if (L && optarg[L-1] == 'h')
+                       maximum_age = atoi (optarg) * 60 * 60;
+                     else if (L && optarg[L-1] == 'd')
+                       maximum_age = atoi (optarg) * 60 * 60 * 24;
+                     else if (L && (optarg[L-1] == 's' ||
+                                    isdigit (optarg[L-1])))
+                       maximum_age = atoi (optarg);
+                     else {
+                       fprintf (stderr, "unparsable max-age: %s\n", optarg);
+                       exit (1);
+                     }
+                   }
+                   break;
  		}
  	}
***************
*** 465,468 ****
--- 490,692 ----
  
  
+ /* Returns 1 if we're done processing the document body; 0 to keep going */
+ static int
+ document_headers_done (char *full_page)
+ {
+ 	const char *body, *s;
+ 	const char *end;
+ 
+ 	for (body = full_page; *body; body++) {
+ 		if (!strncmp (body, "\n\n", 2) || !strncmp (body, "\n\r\n", 3))
+ 			break;
+ 	}
+ 
+ 	if (!*body)
+ 		return 0;  /* haven't read end of headers yet */
+ 
+ 	full_page[body - full_page] = 0;
+ 	return 1;
+ }
+ 
+ static time_t
+ parse_time_string (const char *string)
+ {
+ 	struct tm tm;
+ 	time_t t;
+ 	memset (&tm, 0, sizeof(tm));
+ 
+ 	/* Like this: Tue, 25 Dec 2001 02:59:03 GMT */
+ 
+ 	if (isupper (string[0])  &&  /* Tue */
+ 		islower (string[1])  &&
+ 		islower (string[2])  &&
+ 		',' ==   string[3]   &&
+ 		' ' ==   string[4]   &&
+ 		(isdigit(string[5]) || string[5] == ' ') &&   /* 25 */
+ 		isdigit (string[6])  &&
+ 		' ' ==   string[7]   &&
+ 		isupper (string[8])  &&  /* Dec */
+ 		islower (string[9])  &&
+ 		islower (string[10]) &&
+ 		' ' ==   string[11]  &&
+ 		isdigit (string[12]) &&  /* 2001 */
+ 		isdigit (string[13]) &&
+ 		isdigit (string[14]) &&
+ 		isdigit (string[15]) &&
+ 		' ' ==   string[16]  &&
+ 		isdigit (string[17]) &&  /* 02: */
+ 		isdigit (string[18]) &&
+ 		':' ==   string[19]  &&
+ 		isdigit (string[20]) &&  /* 59: */
+ 		isdigit (string[21]) &&
+ 		':' ==   string[22]  &&
+ 		isdigit (string[23]) &&  /* 03 */
+ 		isdigit (string[24]) &&
+ 		' ' ==   string[25]  &&
+ 		'G' ==   string[26]  &&  /* GMT */
+ 		'M' ==   string[27]  &&  /* GMT */
+ 		'T' ==   string[28]) {
+ 
+ 		tm.tm_sec  = 10 * (string[23]-'0') + (string[24]-'0');
+ 		tm.tm_min  = 10 * (string[20]-'0') + (string[21]-'0');
+ 		tm.tm_hour = 10 * (string[17]-'0') + (string[18]-'0');
+ 		tm.tm_mday = 10 * (string[5] == ' ' ? 0 : string[5]-'0') + (string[6]-'0');
+ 		tm.tm_mon = (!strncmp (string+8, "Jan", 3) ? 0 :
+ 			!strncmp (string+8, "Feb", 3) ? 1 :
+ 			!strncmp (string+8, "Mar", 3) ? 2 :
+ 			!strncmp (string+8, "Apr", 3) ? 3 :
+ 			!strncmp (string+8, "May", 3) ? 4 :
+ 			!strncmp (string+8, "Jun", 3) ? 5 :
+ 			!strncmp (string+8, "Jul", 3) ? 6 :
+ 			!strncmp (string+8, "Aug", 3) ? 7 :
+ 			!strncmp (string+8, "Sep", 3) ? 8 :
+ 			!strncmp (string+8, "Oct", 3) ? 9 :
+ 			!strncmp (string+8, "Nov", 3) ? 10 :
+ 			!strncmp (string+8, "Dec", 3) ? 11 :
+ 			-1);
+ 		tm.tm_year = ((1000 * (string[12]-'0') +
+ 			100 * (string[13]-'0') +
+ 			10 * (string[14]-'0') +
+ 			(string[15]-'0'))
+ 			- 1900);
+ 
+ 		tm.tm_isdst = 0;  /* GMT is never in DST, right? */
+ 
+ 		if (tm.tm_mon < 0 || tm.tm_mday < 1 || tm.tm_mday > 31)
+ 			return 0;
+ 
+ 		/* 
+ 		This is actually wrong: we need to subtract the local timezone
+ 		offset from GMT from this value.  But, that's ok in this usage,
+ 		because we only comparing these two GMT dates against each other,
+ 		so it doesn't matter what time zone we parse them in.
+ 		*/
+ 
+ 		t = mktime (&tm);
+ 		if (t == (time_t) -1) t = 0;
+ 
+ 		if (verbose) {
+ 			const char *s = string;
+ 			while (*s && *s != '\r' && *s != '\n')
+ 			fputc (*s++, stdout);
+ 			printf (" ==> %lu\n", (unsigned long) t);
+ 		}
+ 
+ 		return t;
+ 
+ 	} else {
+ 		return 0;
+ 	}
+ }
+ 
+ 
+ static void
+ check_document_dates (const char *headers)
+ {
+ 	const char *s;
+ 	char *server_date = 0;
+ 	char *document_date = 0;
+ 
+ 	s = headers;
+ 	while (*s) {
+ 		const char *field = s;
+ 		const char *value = 0;
+ 
+ 		/* Find the end of the header field */
+ 		while (*s && !isspace(*s) && *s != ':')
+ 			s++;
+ 
+ 		/* Remember the header value, if any. */
+ 		if (*s == ':')
+ 			value = ++s;
+ 
+ 		/* Skip to the end of the header, including continuation lines. */
+ 		while (*s && !(*s == '\n' && (s[1] != ' ' && s[1] != '\t')))
+ 			s++;
+ 		s++;
+ 
+ 		/* Process this header. */
+ 		if (value && value > field+2) {
+ 			char *ff = (char *) malloc (value-field);
+ 			char *ss = ff;
+ 			while (field < value-1)
+ 				*ss++ = tolower(*field++);
+ 			*ss++ = 0;
+ 
+ 			if (!strcmp (ff, "date") || !strcmp (ff, "last-modified")) {
+ 				const char *e;
+ 				while (*value && isspace (*value))
+ 					value++;
+ 				for (e = value; *e && *e != '\r' && *e != '\n'; e++)
+ 					;
+ 				ss = (char *) malloc (e - value + 1);
+ 				strncpy (ss, value, e - value);
+ 				ss[e - value] = 0;
+ 				if (!strcmp (ff, "date")) {
+ 					if (server_date) free (server_date);
+ 					server_date = ss;
+ 				} else {
+ 					if (document_date) free (document_date);
+ 					document_date = ss;
+ 				}
+ 			}
+ 			free (ff);
+ 		}
+ 	}
+ 
+ 	/* Done parsing the body.  Now check the dates we (hopefully) parsed.  */
+ 	if (!server_date || !*server_date) {
+ 		die (STATE_UNKNOWN, _("Server date unknown\n"));
+ 	} else if (!document_date || !*document_date) {
+ 		die (STATE_CRITICAL, _("Document modification date unknown\n"));
+ 	} else {
+ 		time_t sd = parse_time_string (server_date);
+ 		time_t dd = parse_time_string (document_date);
+ 
+ 		if (sd <= 0) {
+ 			die (STATE_CRITICAL, _("CRITICAL - Server date \"%100s\" unparsable"), server_date);
+ 		} else if (dd <= 0) {
+ 			die (STATE_CRITICAL, _("CRITICAL - Document date \"%100s\" unparsable"), document_date);
+ 		} else if (dd > sd + 30) {
+ 			die (STATE_CRITICAL, _("CRITICAL - Document is %d seconds in the future\n"), dd - sd);
+ 		} else if (dd < sd - maximum_age) {
+ 		int n = (sd - dd);
+ 		if (n > (60 * 60 * 24 * 2))
+ 			die (STATE_CRITICAL,
+ 			  _("CRITICAL - Last modified %.1f days ago\n"),
+ 			  ((float) n) / (60 * 60 * 24));
+ 	else
+ 		die (STATE_CRITICAL,
+ 		    _("CRITICAL - Last modified %d:%02d:%02d ago\n"),
+ 		    n / (60 * 60), (n / 60) % 60, n % 60);
+     }
+ 
+     free (server_date);
+     free (document_date);
+   }
+ }
+ 
+ 
+ 
  int
  check_http (void)
***************
*** 562,565 ****
--- 786,794 ----
  		asprintf (&full_page, "%s%s", full_page, buffer);
  		pagesize += i;
+ 
+                 if (no_body && document_headers_done (full_page)) {
+                   i = 0;
+                   break;
+                 }
  	}
  
***************
*** 622,626 ****
  	header[pos - header] = 0;
  	if (verbose)
! 		printf ("**** HEADER ****\n%s\n**** CONTENT ****\n%s\n", header, page);
  
  	/* make sure the status line matches the response we are looking for */
--- 851,856 ----
  	header[pos - header] = 0;
  	if (verbose)
! 		printf ("**** HEADER ****\n%s\n**** CONTENT ****\n%s\n", header,
!                 (no_body ? "  [[ skipped ]]" : page));
  
  	/* make sure the status line matches the response we are looking for */
***************
*** 692,695 ****
--- 922,929 ----
  	} /* end else (server_expect_yn)  */
  		
+         if (maximum_age >= 0) {
+           check_document_dates (header);
+         }
+ 
  	/* check elapsed time */
  	microsec = deltime (tv);
***************
*** 1155,1158 ****
--- 1389,1398 ----
   -P, --post=STRING\n\
     URL encoded http POST data\n\
+  -N, --no-body\n\
+    Don't wait for document body: stop reading after headers.\n\
+    (Note that this still does an HTTP GET or POST, not a HEAD.)\n\
+  -M, --max-age=SECONDS\n\
+    Warn if document is more than SECONDS old. the number can also be of \n\
+    the form \"10m\" for minutes, \"10h\" for hours, or \"10d\" for days.\n\
   -T, --content-type=STRING\n\
     specify Content-Type header media type when POSTing\n"), HTTP_EXPECT);
***************
*** 1227,1231 ****
    [-a auth] [-f <ok | warn | critcal | follow>] [-e <expect>]\n\
    [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n\
!   [-P string] [-m min_pg_size] [-4|-6]\n"), progname);
  	printf (_(UT_HLP_VRS), progname, progname);
  }
--- 1467,1471 ----
    [-a auth] [-f <ok | warn | critcal | follow>] [-e <expect>]\n\
    [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n\
!   [-P string] [-m min_pg_size] [-4|-6] [-N] [-M <age>]\n"), progname);
  	printf (_(UT_HLP_VRS), progname, progname);
  }





More information about the Commits mailing list