diff --git a/plugins/check_http.c b/plugins/check_http.c
index 82cd1d9c7ec703d5f6b3413ade492321000627ee..69ed2fa91031f0bf89eccd15734661e69cba45da 100644 (file)
--- a/plugins/check_http.c
+++ b/plugins/check_http.c
asprintf (&user_agent, "User-Agent: check_http/%s (nagios-plugins %s)",
clean_revstring (revision), VERSION);
+ /* Parse extra opts if any */
+ argv=np_extra_opts (&argc, argv, progname);
+
if (process_arguments (argc, argv) == ERROR)
usage4 (_("Could not parse arguments"));
}
}
+/* Checks if the server 'reply' is one of the expected 'statuscodes' */
+static int
+expected_statuscode (const char *reply, const char *statuscodes)
+{
+ char *expected, *code;
+ int result = 0;
+
+ if ((expected = strdup (statuscodes)) == NULL)
+ die (STATE_UNKNOWN, _("HTTP UNKNOWN - Memory allocation error\n"));
+ for (code = strtok (expected, ","); code != NULL; code = strtok (NULL, ","))
+ if (strstr (reply, code) != NULL) {
+ result = 1;
+ break;
+ }
+
+ free (expected);
+ return result;
+}
static void
check_document_dates (const char *headers)
/* Skip to the end of the header, including continuation lines. */
while (*s && !(*s == '\n' && (s[1] != ' ' && s[1] != '\t')))
s++;
- s++;
+
+ /* Avoid stepping over end-of-string marker */
+ if (*s)
+ s++;
/* Process this header. */
if (value && value > field+2) {
return (content_length);
}
+char *
+prepend_slash (char *path)
+{
+ char *newpath;
+
+ if (path[0] == '/')
+ return path;
+
+ if ((newpath = malloc (strlen(path) + 2)) == NULL)
+ die (STATE_UNKNOWN, _("HTTP UNKNOWN - Memory allocation error\n"));
+ newpath[0] = '/';
+ strcpy (newpath + 1, path);
+ free (path);
+ return newpath;
+}
+
int
check_http (void)
{
if (check_cert == TRUE) {
result = np_net_ssl_check_cert(days_till_exp);
np_net_ssl_cleanup();
- if(sd) close(sd);
+ if (sd) close(sd);
return result;
}
}
asprintf (&buf, "%sConnection: close\r\n", buf);
/* optionally send the host header info */
- if (host_name)
- asprintf (&buf, "%sHost: %s:%d\r\n", buf, host_name, server_port);
+ if (host_name) {
+ /*
+ * Specify the port only if we're using a non-default port (see RFC 2616,
+ * 14.23). Some server applications/configurations cause trouble if the
+ * (default) port is explicitly specified in the "Host:" header line.
+ */
+ if ((use_ssl == FALSE && server_port == HTTP_PORT) ||
+ (use_ssl == TRUE && server_port == HTTPS_PORT))
+ asprintf (&buf, "%sHost: %s\r\n", buf, host_name);
+ else
+ asprintf (&buf, "%sHost: %s:%d\r\n", buf, host_name, server_port);
+ }
/* optionally send any other header tag */
if (http_opt_headers_count) {
} else {
asprintf (&buf, "%sContent-Type: application/x-www-form-urlencoded\r\n", buf);
}
-
+
asprintf (&buf, "%sContent-Length: %i\r\n\r\n", buf, (int)strlen (http_post_data));
asprintf (&buf, "%s%s%s", buf, http_post_data, CRLF);
}
#ifdef HAVE_SSL
np_net_ssl_cleanup();
#endif
- if(sd) close(sd);
+ if (sd) close(sd);
/* reset the alarm */
alarm (0);
(no_body ? " [[ skipped ]]" : page));
/* make sure the status line matches the response we are looking for */
- if (!strstr (status_line, server_expect)) {
+ if (!expected_statuscode (status_line, server_expect)) {
if (server_port == HTTP_PORT)
asprintf (&msg,
- _("Invalid HTTP response received from host\n"));
+ _("Invalid HTTP response received from host: %s\n"),
+ status_line);
else
asprintf (&msg,
- _("Invalid HTTP response received from host on port %d\n"),
- server_port);
+ _("Invalid HTTP response received from host on port %d: %s\n"),
+ server_port, status_line);
die (STATE_CRITICAL, "HTTP CRITICAL - %s", msg);
}
} /* end if (http_status >= 300) */
} /* end else (server_expect_yn) */
-
+
if (maximum_age >= 0) {
check_document_dates (header);
}
addr = malloc (MAX_IPV4_HOSTLENGTH + 1);
if (addr == NULL)
die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate addr\n"));
-
+
url = malloc (strcspn (pos, "\r\n"));
if (url == NULL)
die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate url\n"));
die (STATE_UNKNOWN, _("HTTP UNKNOWN - could not allocate url\n"));
/* URI_HTTP, URI_HOST, URI_PORT, URI_PATH */
- if (sscanf (pos, HD1, type, addr, &i, url) == 4)
+ if (sscanf (pos, HD1, type, addr, &i, url) == 4) {
+ url = prepend_slash (url);
use_ssl = server_type_check (type);
+ }
/* URI_HTTP URI_HOST URI_PATH */
else if (sscanf (pos, HD2, type, addr, url) == 3 ) {
+ url = prepend_slash (url);
use_ssl = server_type_check (type);
i = server_port_check (use_ssl);
}
/* URI_HTTP URI_HOST URI_PORT */
- else if(sscanf (pos, HD3, type, addr, &i) == 3) {
+ else if (sscanf (pos, HD3, type, addr, &i) == 3) {
strcpy (url, HTTP_URL);
use_ssl = server_type_check (type);
}
/* URI_HTTP URI_HOST */
- else if(sscanf (pos, HD4, type, addr) == 2) {
+ else if (sscanf (pos, HD4, type, addr) == 2) {
strcpy (url, HTTP_URL);
use_ssl = server_type_check (type);
i = server_port_check (use_ssl);
server_address = strdup (addr);
free (server_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);
+ server_url = url;
if ((server_port = i) > MAX_PORT)
die (STATE_UNKNOWN,
printf ("\n");
printf (_(UT_HELP_VRSN));
+ printf (_(UT_EXTRA_OPTS));
printf (" %s\n", "-H, --hostname=ADDRESS");
printf (" %s\n", _("Host name argument for servers using host headers (virtual host)"));
#endif
printf (" %s\n", "-e, --expect=STRING");
- printf (" %s\n", _("String to expect in first (status) line of server response (default: "));
+ printf (" %s\n", _("Comma-delimited list of strings, at least one of them is expected in"));
+ printf (" %s", _("the first (status) line of the server response (default: "));
printf ("%s)\n", HTTP_EXPECT);
printf (" %s\n", _("If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)"));
printf (" %s\n", "-s, --string=STRING");
printf (_(UT_VERBOSE));
- printf (_("Notes:"));
+ printf ("\n");
+ printf ("%s\n", _("Notes:"));
printf (" %s\n", _("This plugin will attempt to open an HTTP connection with the host."));
printf (" %s\n", _("Successful connects return STATE_OK, refusals and timeouts return STATE_CRITICAL"));
printf (" %s\n", _("other errors return STATE_UNKNOWN. Successful connects, but incorrect reponse"));
printf (" %s\n", _("messages from the host result in STATE_WARNING return values. If you are"));
printf (" %s\n", _("checking a virtual server that uses 'host headers' you must supply the FQDN"));
printf (" %s\n", _("(fully qualified domain name) as the [host_name] argument."));
+ printf ("\n");
+ printf (_(UT_EXTRA_OPTS_NOTES));
#ifdef HAVE_SSL
+ printf ("\n");
printf (" %s\n", _("This plugin can also check whether an SSL enabled web server is able to"));
printf (" %s\n", _("serve content (optionally within a specified time) or whether the X509 "));
printf (" %s\n", _("certificate is still valid for the specified number of days."));
- printf (_("Examples:"));
+ printf ("\n");
+ printf ("%s\n", _("Examples:"));
printf (" %s\n\n", "CHECK CONTENT: check_http -w 5 -c 10 --ssl -H www.verisign.com");
printf (" %s\n", _("When the 'www.verisign.com' server returns its content within 5 seconds,"));
printf (" %s\n", _("a STATE_OK will be returned. When the server returns its content but exceeds"));
printf (" %s\n", _("When the certificate of 'www.verisign.com' is valid for more than 14 days,"));
printf (" %s\n", _("a STATE_OK is returned. When the certificate is still valid, but for less than"));
printf (" %s\n", _("14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when"));
- printf (" %s\n\n", _("the certificate is expired."));
+ printf (" %s\n", _("the certificate is expired."));
#endif
printf (_(UT_SUPPORT));