Code

Fixed help output (Christian Mies)
[nagiosplug.git] / plugins / check_http.c
index 5e33ec86113e485a55a24b1750e3ef6aea799bab..bec02e1af5af67ce2a16d32604b3ba759cc27921 100644 (file)
@@ -43,9 +43,12 @@ const char *revision = "$Revision$";
 const char *copyright = "1999-2006";
 const char *email = "nagiosplug-devel@lists.sourceforge.net";
 
+#include <ctype.h>
+
 #include "common.h"
 #include "netutils.h"
 #include "utils.h"
+#include "base64.h"
 
 #define INPUT_DELIMITER ";"
 
@@ -53,7 +56,8 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
 enum {
   MAX_IPV4_HOSTLENGTH = 255,
   HTTP_PORT = 80,
-  HTTPS_PORT = 443
+  HTTPS_PORT = 443,
+  MAX_PORT = 65535
 };
 
 #ifdef HAVE_SSL
@@ -122,7 +126,6 @@ char *http_content_type;
 char buffer[MAX_INPUT_BUFFER];
 
 int process_arguments (int, char **);
-static char *base64 (const char *bin, size_t len);
 int check_http (void);
 void redir (char *pos, char *status_line);
 int server_type_check(const char *type);
@@ -137,6 +140,10 @@ main (int argc, char **argv)
 {
   int result = STATE_UNKNOWN;
 
+       setlocale (LC_ALL, "");
+       bindtextdomain (PACKAGE, LOCALEDIR);
+       textdomain (PACKAGE);
+
   /* Set default URL. Must be malloced for subsequent realloc if --onredirect=follow */
   server_url = strdup(HTTP_URL);
   server_url_length = strlen(server_url);
@@ -148,7 +155,7 @@ main (int argc, char **argv)
 
   if (display_html == TRUE)
     printf ("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">", 
-      use_ssl ? "https" : "http", host_name,
+      use_ssl ? "https" : "http", host_name ? host_name : server_address,
       server_port, server_url);
 
   /* initialize alarm signal handling, set socket timeout, start timer */
@@ -452,49 +459,6 @@ process_arguments (int argc, char **argv)
 
 
 
-/* written by lauri alanko */
-static char *
-base64 (const char *bin, size_t len)
-{
-
-  char *buf = (char *) malloc ((len + 2) / 3 * 4 + 1);
-  size_t i = 0, j = 0;
-
-  char BASE64_END = '=';
-  char base64_table[64];
-  strncpy (base64_table, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 64);
-
-  while (j < len - 2) {
-    buf[i++] = base64_table[bin[j] >> 2];
-    buf[i++] = base64_table[((bin[j] & 3) << 4) | (bin[j + 1] >> 4)];
-    buf[i++] = base64_table[((bin[j + 1] & 15) << 2) | (bin[j + 2] >> 6)];
-    buf[i++] = base64_table[bin[j + 2] & 63];
-    j += 3;
-  }
-
-  switch (len - j) {
-  case 1:
-    buf[i++] = base64_table[bin[j] >> 2];
-    buf[i++] = base64_table[(bin[j] & 3) << 4];
-    buf[i++] = BASE64_END;
-    buf[i++] = BASE64_END;
-    break;
-  case 2:
-    buf[i++] = base64_table[bin[j] >> 2];
-    buf[i++] = base64_table[((bin[j] & 3) << 4) | (bin[j + 1] >> 4)];
-    buf[i++] = base64_table[(bin[j + 1] & 15) << 2];
-    buf[i++] = BASE64_END;
-    break;
-  case 0:
-    break;
-  }
-
-  buf[i] = '\0';
-  return buf;
-}
-
-
-
 /* Returns 1 if we're done processing the document body; 0 to keep going */
 static int
 document_headers_done (char *full_page)
@@ -779,6 +743,9 @@ check_http (void)
 
   asprintf (&buf, "%s %s HTTP/1.0\r\n%s\r\n", http_method, server_url, user_agent);
 
+  /* tell HTTP/1.1 servers not to keep the connection alive */
+  asprintf (&buf, "%sConnection: close\r\n", buf);
+
   /* optionally send the host header info */
   if (host_name)
     asprintf (&buf, "%sHost: %s\r\n", buf, host_name);
@@ -976,14 +943,14 @@ check_http (void)
   microsec = deltime (tv);
   elapsed_time = (double)microsec / 1.0e6;
   asprintf (&msg,
-            _("HTTP WARNING: %s - %.3f second response time %s|%s %s\n"),
+            _(" - %s - %.3f second response time %s|%s %s\n"),
             status_line, elapsed_time, 
             (display_html ? "</A>" : ""),
             perfd_time (elapsed_time), perfd_size (pagesize));
   if (check_critical_time == TRUE && elapsed_time > critical_time)
-    die (STATE_CRITICAL, "%s", msg);
+    die (STATE_CRITICAL, "HTTP %s: %s", _("CRITICAL"), msg);
   if (check_warning_time == TRUE && elapsed_time > warning_time)
-    die (STATE_WARNING, "%s", msg);
+    die (STATE_WARNING, "HTTP %s: %s", _("WARNING"), msg);
 
   /* Page and Header content checks go here */
   /* these checks should be last */
@@ -1056,15 +1023,14 @@ check_http (void)
 
 
 /* per RFC 2396 */
-#define HDR_LOCATION "%*[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]: "
-#define URI_HTTP "%[HTPShtps]://"
-#define URI_HOST "%[-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]"
-#define URI_PORT ":%[0123456789]"
+#define URI_HTTP "%5[HTPShtps]"
+#define URI_HOST "%255[-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]"
+#define URI_PORT "%6d" /* MAX_PORT's width is 5 chars, 6 to detect overflow */
 #define URI_PATH "%[-_.!~*'();/?:@&=+$,%#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]"
-#define HD1 URI_HTTP URI_HOST URI_PORT URI_PATH
-#define HD2 URI_HTTP URI_HOST URI_PATH
-#define HD3 URI_HTTP URI_HOST URI_PORT
-#define HD4 URI_HTTP URI_HOST
+#define HD1 URI_HTTP "://" URI_HOST ":" URI_PORT "/" URI_PATH
+#define HD2 URI_HTTP "://" URI_HOST "/" URI_PATH
+#define HD3 URI_HTTP "://" URI_HOST ":" URI_PORT
+#define HD4 URI_HTTP "://" URI_HOST
 #define HD5 URI_PATH
 
 void
@@ -1075,7 +1041,6 @@ redir (char *pos, char *status_line)
   char xx[2];
   char type[6];
   char *addr;
-  char port[6];
   char *url;
 
   addr = malloc (MAX_IPV4_HOSTLENGTH + 1);
@@ -1087,7 +1052,7 @@ redir (char *pos, char *status_line)
     die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate url\n"));
 
   while (pos) {
-    sscanf (pos, "%[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]:%n", xx, &i);
+    sscanf (pos, "%1[Ll]%*1[Oo]%*1[Cc]%*1[Aa]%*1[Tt]%*1[Ii]%*1[Oo]%*1[Nn]:%n", xx, &i);
     if (i == 0) {
       pos += (size_t) strcspn (pos, "\r\n");
       pos += (size_t) strspn (pos, "\r\n");
@@ -1099,17 +1064,27 @@ redir (char *pos, char *status_line)
     }
 
     pos += i;
-    pos += strspn (pos, " \t\r\n");
+    pos += strspn (pos, " \t");
+
+    /*
+     * RFC 2616 (4.2):  ``Header fields can be extended over multiple lines by
+     * preceding each extra line with at least one SP or HT.''
+     */
+    for (; (i = strspn (pos, "\r\n")); pos += i) {
+      pos += i;
+      if (!(i = strspn (pos, " \t"))) {
+        die (STATE_UNKNOWN, _("HTTP UNKNOWN - Empty redirect location%s\n"),
+             display_html ? "</A>" : "");
+      }
+    }
 
-    url = realloc (url, strcspn (pos, "\r\n"));
+    url = realloc (url, strcspn (pos, "\r\n") + 1);
     if (url == NULL)
       die (STATE_UNKNOWN, _("HTTP UNKNOWN - could not allocate url\n"));
 
     /* URI_HTTP, URI_HOST, URI_PORT, URI_PATH */
-    if (sscanf (pos, HD1, type, addr, port, url) == 4) {
+    if (sscanf (pos, HD1, type, addr, &i, url) == 4)
       use_ssl = server_type_check (type);
-      i = atoi (port);
-    }
 
     /* URI_HTTP URI_HOST URI_PATH */
     else if (sscanf (pos, HD2, type, addr, url) == 3 ) { 
@@ -1118,10 +1093,9 @@ redir (char *pos, char *status_line)
     }
 
     /* URI_HTTP URI_HOST URI_PORT */
-    else if(sscanf (pos, HD3, type, addr, port) == 3) {
+    else if(sscanf (pos, HD3, type, addr, &i) == 3) {
       strcpy (url, HTTP_URL);
       use_ssl = server_type_check (type);
-      i = atoi (port);
     }
 
     /* URI_HTTP URI_HOST */
@@ -1141,7 +1115,7 @@ redir (char *pos, char *status_line)
       }
       i = server_port;
       strcpy (type, server_type);
-      strcpy (addr, host_name);
+      strcpy (addr, host_name ? host_name : server_address);
     }           
 
     else {
@@ -1167,7 +1141,6 @@ redir (char *pos, char *status_line)
          _("HTTP WARNING - redirection creates an infinite loop - %s://%s:%d%s%s\n"),
          type, addr, i, url, (display_html ? "</A>" : ""));
 
-  server_port = i;
   strcpy (server_type, type);
 
   free (host_name);
@@ -1177,7 +1150,22 @@ redir (char *pos, char *status_line)
   server_address = strdup (addr);
 
   free (server_url);
-  server_url = strdup (url);
+  if ((url[0] == '/'))
+    server_url = strdup (url);
+  else if (asprintf(&server_url, "/%s", url) == -1)
+    die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate server_url%s\n"),
+         display_html ? "</A>" : "");
+  free(url);
+
+  if ((server_port = i) > MAX_PORT)
+    die (STATE_UNKNOWN,
+         _("HTTP UNKNOWN - Redirection to port above %d - %s://%s:%d%s%s\n"),
+         MAX_PORT, server_type, server_address, server_port, server_url,
+         display_html ? "</A>" : "");
+
+  if (verbose)
+    printf (_("Redirection to %s://%s:%d%s\n"), server_type,
+            host_name ? host_name : server_address, server_port, server_url);
 
   check_http ();
 }