Plugins using libcurl: Enable the ‘CURLOPT_FOLLOWLOCATION’ option.
[collectd.git] / src / apache.c
index 2365d1f..6489bce 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * collectd - src/apache.c
- * Copyright (C) 2006,2007  Florian octo Forster
+ * Copyright (C) 2006-2008  Florian octo Forster
  * Copyright (C) 2007  Florent EppO Monbillard
  *
  * This program is free software; you can redistribute it and/or modify it
 
 #include <curl/curl.h>
 
-static char *url    = NULL;
-static char *user   = NULL;
-static char *pass   = NULL;
-static char *cacert = NULL;
+static char *url         = NULL;
+static char *user        = NULL;
+static char *pass        = NULL;
+static char *verify_peer = NULL;
+static char *verify_host = NULL;
+static char *cacert      = NULL;
 
 static CURL *curl = NULL;
 
-#define ABUFFER_SIZE 16384
-static char apache_buffer[ABUFFER_SIZE];
-static int  apache_buffer_len = 0;
-static char apache_curl_error[CURL_ERROR_SIZE];
+static char  *apache_buffer = NULL;
+static size_t apache_buffer_size = 0;
+static size_t apache_buffer_fill = 0;
+static char   apache_curl_error[CURL_ERROR_SIZE];
 
 static const char *config_keys[] =
 {
        "URL",
        "User",
        "Password",
-       "CACert",
-       NULL
+       "VerifyPeer",
+       "VerifyHost",
+       "CACert"
 };
-static int config_keys_num = 4;
+static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
 
-static size_t apache_curl_callback (void *buf, size_t size, size_t nmemb, void *stream)
+static size_t apache_curl_callback (void *buf, size_t size, size_t nmemb,
+               void __attribute__((unused)) *stream)
 {
        size_t len = size * nmemb;
 
-       if ((apache_buffer_len + len) >= ABUFFER_SIZE)
-       {
-               len = (ABUFFER_SIZE - 1) - apache_buffer_len;
-       }
-
        if (len <= 0)
                return (len);
 
-       memcpy (apache_buffer + apache_buffer_len, (char *) buf, len);
-       apache_buffer_len += len;
-       apache_buffer[apache_buffer_len] = '\0';
+       if ((apache_buffer_fill + len) >= apache_buffer_size)
+       {
+               char *temp;
+
+               temp = (char *) realloc (apache_buffer,
+                               apache_buffer_fill + len + 1);
+               if (temp == NULL)
+               {
+                       ERROR ("apache plugin: realloc failed.");
+                       return (0);
+               }
+               apache_buffer = temp;
+               apache_buffer_size = apache_buffer_fill + len + 1;
+       }
+
+       memcpy (apache_buffer + apache_buffer_fill, (char *) buf, len);
+       apache_buffer_fill += len;
+       apache_buffer[apache_buffer_fill] = 0;
 
        return (len);
 }
@@ -92,6 +106,10 @@ static int config (const char *key, const char *value)
                return (config_set (&user, value));
        else if (strcasecmp (key, "password") == 0)
                return (config_set (&pass, value));
+       else if (strcasecmp (key, "verifypeer") == 0)
+               return (config_set (&verify_peer, value));
+       else if (strcasecmp (key, "verifyhost") == 0)
+               return (config_set (&verify_host, value));
        else if (strcasecmp (key, "cacert") == 0)
                return (config_set (&cacert, value));
        else
@@ -102,6 +120,13 @@ static int init (void)
 {
        static char credentials[1024];
 
+       if (url == NULL)
+       {
+               WARNING ("apache plugin: init: No URL configured, returning "
+                               "an error.");
+               return (-1);
+       }
+
        if (curl != NULL)
        {
                curl_easy_cleanup (curl);
@@ -109,7 +134,7 @@ static int init (void)
 
        if ((curl = curl_easy_init ()) == NULL)
        {
-               ERROR ("apache: `curl_easy_init' failed.");
+               ERROR ("apache plugin: init: `curl_easy_init' failed.");
                return (-1);
        }
 
@@ -119,18 +144,40 @@ static int init (void)
 
        if (user != NULL)
        {
-               if (snprintf (credentials, 1024, "%s:%s", user, pass == NULL ? "" : pass) >= 1024)
+               int status;
+
+               status = ssnprintf (credentials, sizeof (credentials), "%s:%s",
+                               user, (pass == NULL) ? "" : pass);
+               if ((status < 0) || ((size_t) status >= sizeof (credentials)))
                {
-                       ERROR ("apache: Credentials would have been truncated.");
+                       ERROR ("apache plugin: init: Returning an error "
+                                       "because the credentials have been "
+                                       "truncated.");
                        return (-1);
                }
 
                curl_easy_setopt (curl, CURLOPT_USERPWD, credentials);
        }
 
-       if (url != NULL)
+       curl_easy_setopt (curl, CURLOPT_URL, url);
+       curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1);
+
+       if ((verify_peer == NULL) || (strcmp (verify_peer, "true") == 0))
+       {
+               curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 1);
+       }
+       else
        {
-               curl_easy_setopt (curl, CURLOPT_URL, url);
+               curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0);
+       }
+
+       if ((verify_host == NULL) || (strcmp (verify_host, "true") == 0))
+       {
+               curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 2);
+       }
+       else
+       {
+               curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0);
        }
 
        if (cacert != NULL)
@@ -142,50 +189,47 @@ static int init (void)
 } /* int init */
 
 static void submit_counter (const char *type, const char *type_instance,
-               unsigned long long value)
+               counter_t value)
 {
        value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       DEBUG ("type = %s; type_instance = %s; value = %llu;",
-                       type, type_instance, value);
-
        values[0].counter = value;
 
        vl.values = values;
        vl.values_len = 1;
-       vl.time = time (NULL);
-       strcpy (vl.host, hostname_g);
-       strcpy (vl.plugin, "apache");
-       strcpy (vl.plugin_instance, "");
-       strncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
+       sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+       sstrncpy (vl.plugin, "apache", sizeof (vl.plugin));
+       sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance));
+       sstrncpy (vl.type, type, sizeof (vl.type));
 
-       plugin_dispatch_values (type, &vl);
+       if (type_instance != NULL)
+               sstrncpy (vl.type_instance, type_instance,
+                               sizeof (vl.type_instance));
+
+       plugin_dispatch_values (&vl);
 } /* void submit_counter */
 
 static void submit_gauge (const char *type, const char *type_instance,
-               double value)
+               gauge_t value)
 {
        value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       DEBUG ("type = %s; type_instance = %s; value = %lf;",
-                       type, type_instance, value);
-
        values[0].gauge = value;
 
        vl.values = values;
        vl.values_len = 1;
-       vl.time = time (NULL);
-       strcpy (vl.host, hostname_g);
-       strcpy (vl.plugin, "apache");
-       strcpy (vl.plugin_instance, "");
+       sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+       sstrncpy (vl.plugin, "apache", sizeof (vl.plugin));
+       sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance));
+       sstrncpy (vl.type, type, sizeof (vl.type));
 
        if (type_instance != NULL)
-               strncpy (vl.type_instance, type_instance,
+               sstrncpy (vl.type_instance, type_instance,
                                sizeof (vl.type_instance));
 
-       plugin_dispatch_values (type, &vl);
+       plugin_dispatch_values (&vl);
 } /* void submit_counter */
 
 static void submit_scoreboard (char *buf)
@@ -256,7 +300,7 @@ static int apache_read (void)
        if (url == NULL)
                return (-1);
 
-       apache_buffer_len = 0;
+       apache_buffer_fill = 0;
        if (curl_easy_perform (curl) != 0)
        {
                ERROR ("apache: curl_easy_perform failed: %s",
@@ -299,7 +343,7 @@ static int apache_read (void)
                }
        }
 
-       apache_buffer_len = 0;
+       apache_buffer_fill = 0;
 
        return (0);
 } /* int apache_read */