[collectd] [PATCH] curl* plugins: Added support for POST and arbitrary headers

Kimo Rosenbaum kimor79 at yahoo.com
Mon Feb 4 23:36:17 CET 2013


Hello Dan,


Would you mind creating a pull request (https://github.com/collectd/collectd/pulls)? (or attach as an attachment)


I would like to try this patch but I think my email client is eating it up.

Thanks
Kimo

>________________________________
> From: Dan Fandrich <dan at coneharvesters.com>
>To: collectd at verplant.org 
>Sent: Monday, February 4, 2013 2:29 PM
>Subject: [collectd] [PATCH] curl* plugins: Added support for POST and arbitrary headers
> 
>These plugins can now be used for things like SOAP or XML-RPC calls.
>---
>src/collectd.conf.pod |   41 ++++++++++++++++++++---------------------
>src/curl.c            |   29 +++++++++++++++++++++++++++++
>src/curl_json.c       |   28 ++++++++++++++++++++++++++++
>src/curl_xml.c        |   28 ++++++++++++++++++++++++++++
>4 files changed, 105 insertions(+), 21 deletions(-)
>
>diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod
>index 70bc997..e70caad 100644
>--- a/src/collectd.conf.pod
>+++ b/src/collectd.conf.pod
>@@ -944,6 +944,19 @@ File that holds one or more SSL certificates. If you want to use HTTPS you will
>possibly need this option. What CA certificates come bundled with C<libcurl>
>and are checked by default depends on the distribution you use.
>
>+=item B<Header> I<Header>
>+
>+A HTTP header to add to the request. Multiple headers are added if this option
>+is specified more than once.
>+
>+=item B<Post> I<Body>
>+
>+Specifies that the HTTP operation should be a POST instead of a GET. The
>+complete data to be posted is given as the argument.  This option will usually
>+need to be accompanied by a B<Header> option to set an appropriate
>+C<Content-Type> for the post body (e.g. to
>+C<application/x-www-form-urlencoded>).
>+
>=item B<MeasureResponseTime> B<true>|B<false>
>
>Measure response time for the request. If this setting is enabled, B<Match>
>@@ -1002,31 +1015,15 @@ The following options are valid within B<URL> blocks:
>Sets the plugin instance to I<Instance>.
>
>=item B<User> I<Name>
>-
>-Username to use if authorization is required to read the page.
>-
>=item B<Password> I<Password>
>-
>-Password to use if authorization is required to read the page.
>-
>=item B<VerifyPeer> B<true>|B<false>
>-
>-Enable or disable peer SSL certificate verification. See
>-L<http://curl.haxx.se/docs/sslcerts.html> for details. Enabled by default.
>-
>=item B<VerifyHost> B<true>|B<false>
>-
>-Enable or disable peer host name verification. If enabled, the plugin checks if
>-the C<Common Name> or a C<Subject Alternate Name> field of the SSL certificate
>-matches the host name provided by the B<URL> option. If this identity check
>-fails, the connection is aborted. Obviously, only works when connecting to a
>-SSL enabled server. Enabled by default.
>-
>=item B<CACert> I<file>
>+=item B<Header> I<Header>
>+=item B<Post> I<Body>
>
>-File that holds one or more SSL certificates. If you want to use HTTPS you will
>-possibly need this option. What CA certificates come bundled with C<libcurl>
>-and are checked by default depends on the distribution you use.
>+These options behave exactly equivalent to the appropriate options of the
>+I<cURL> plugin. Please see there for a detailed description.
>
>=back
>
>@@ -1100,9 +1097,11 @@ empty string (no plugin instance).
>=item B<VerifyPeer> B<true>|B<false>
>=item B<VerifyHost> B<true>|B<false>
>=item B<CACert> I<CA Cert File>
>+=item B<Header> I<Header>
>+=item B<Post> I<Body>
>
>These options behave exactly equivalent to the appropriate options of the
>-I<cURL> and I<cURL-JSON> plugins. Please see there for a detailed description.
>+I<cURL> plugin. Please see there for a detailed description.
>
>=item E<lt>B<XPath> I<XPath-expression>E<gt>
>
>diff --git a/src/curl.c b/src/curl.c
>index 30d6e45..cb352bf 100644
>--- a/src/curl.c
>+++ b/src/curl.c
>@@ -60,6 +60,8 @@ struct web_page_s /* {{{ */
>   int   verify_peer;
>   int   verify_host;
>   char *cacert;
>+  struct curl_slist *headers;
>+  char *post_body;
>   int   response_time;
>
>   CURL *curl;
>@@ -148,6 +150,8 @@ static void cc_web_page_free (web_page_t *wp) /* {{{ */
>   sfree (wp->pass);
>   sfree (wp->credentials);
>   sfree (wp->cacert);
>+  sfree (wp->post_body);
>+  curl_slist_free_all (wp->headers);
>
>   sfree (wp->buffer);
>
>@@ -173,6 +177,23 @@ static int cc_config_add_string (const char *name, char **dest, /* {{{ */
>   return (0);
>} /* }}} int cc_config_add_string */
>
>+static int cc_config_append_string (const char *name, struct curl_slist **dest, /* {{{ */
>+    oconfig_item_t *ci)
>+{
>+  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
>+  {
>+    WARNING ("curl plugin: `%s' needs exactly one string argument.", name);
>+    return (-1);
>+  }
>+
>+  *dest = curl_slist_append(*dest, ci->values[0].value.string);
>+  if (*dest == NULL)
>+    return (-1);
>+
>+  return (0);
>+} /* }}} int cc_config_append_string */
>+
>+
>static int cc_config_set_boolean (const char *name, int *dest, /* {{{ */
>     oconfig_item_t *ci)
>{
>@@ -405,6 +426,10 @@ static int cc_page_init_curl (web_page_t *wp) /* {{{ */
>       wp->verify_host ? 2L : 0L);
>   if (wp->cacert != NULL)
>     curl_easy_setopt (wp->curl, CURLOPT_CAINFO, wp->cacert);
>+  if (wp->headers != NULL)
>+    curl_easy_setopt (wp->curl, CURLOPT_HTTPHEADER, wp->headers);
>+  if (wp->post_body != NULL)
>+    curl_easy_setopt (wp->curl, CURLOPT_POSTFIELDS, wp->post_body);
>
>   return (0);
>} /* }}} int cc_page_init_curl */
>@@ -466,6 +491,10 @@ static int cc_config_add_page (oconfig_item_t *ci) /* {{{ */
>     else if (strcasecmp ("Match", child->key) == 0)
>       /* Be liberal with failing matches => don't set `status'. */
>       cc_config_add_match (page, child);
>+    else if (strcasecmp ("Header", child->key) == 0)
>+      status = cc_config_append_string ("Header", &page->headers, child);
>+    else if (strcasecmp ("Post", child->key) == 0)
>+      status = cc_config_add_string ("Post", &page->post_body, child);
>     else
>     {
>       WARNING ("curl plugin: Option `%s' not allowed here.", child->key);
>diff --git a/src/curl_json.c b/src/curl_json.c
>index 2ddaff3..1494327 100644
>--- a/src/curl_json.c
>+++ b/src/curl_json.c
>@@ -67,6 +67,8 @@ struct cj_s /* {{{ */
>   _Bool verify_peer;
>   _Bool verify_host;
>   char *cacert;
>+  struct curl_slist *headers;
>+  char *post_body;
>
>   CURL *curl;
>   char curl_errbuf[CURL_ERROR_SIZE];
>@@ -374,6 +376,8 @@ static void cj_free (void *arg) /* {{{ */
>   sfree (db->pass);
>   sfree (db->credentials);
>   sfree (db->cacert);
>+  sfree (db->post_body);
>+  curl_slist_free_all (db->headers);
>
>   sfree (db);
>} /* }}} void cj_free */
>@@ -385,6 +389,22 @@ static c_avl_tree_t *cj_avl_create(void)
>   return c_avl_create ((int (*) (const void *, const void *)) strcmp);
>}
>
>+static int cj_config_append_string (const char *name, struct curl_slist **dest, /* {{{ */
>+    oconfig_item_t *ci)
>+{
>+  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
>+  {
>+    WARNING ("curl_json plugin: `%s' needs exactly one string argument.", name);
>+    return (-1);
>+  }
>+
>+  *dest = curl_slist_append(*dest, ci->values[0].value.string);
>+  if (*dest == NULL)
>+    return (-1);
>+
>+  return (0);
>+} /* }}} int cj_config_append_string */
>+
>static int cj_config_add_key (cj_t *db, /* {{{ */
>                                    oconfig_item_t *ci)
>{
>@@ -554,6 +574,10 @@ static int cj_init_curl (cj_t *db) /* {{{ */
>                     db->verify_host ? 2L : 0L);
>   if (db->cacert != NULL)
>     curl_easy_setopt (db->curl, CURLOPT_CAINFO, db->cacert);
>+  if (db->headers != NULL)
>+    curl_easy_setopt (db->curl, CURLOPT_HTTPHEADER, db->headers);
>+  if (db->post_body != NULL)
>+    curl_easy_setopt (db->curl, CURLOPT_POSTFIELDS, db->post_body);
>
>   return (0);
>} /* }}} int cj_init_curl */
>@@ -615,6 +639,10 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */
>       status = cf_util_get_boolean (child, &db->verify_host);
>     else if (strcasecmp ("CACert", child->key) == 0)
>       status = cf_util_get_string (child, &db->cacert);
>+    else if (strcasecmp ("Header", child->key) == 0)
>+      status = cj_config_append_string ("Header", &db->headers, child);
>+    else if (strcasecmp ("Post", child->key) == 0)
>+      status = cf_util_get_string (child, &db->post_body);
>     else if (strcasecmp ("Key", child->key) == 0)
>       status = cj_config_add_key (db, child);
>     else
>diff --git a/src/curl_xml.c b/src/curl_xml.c
>index da90d7c..2a36608 100644
>--- a/src/curl_xml.c
>+++ b/src/curl_xml.c
>@@ -70,6 +70,8 @@ struct cx_s /* {{{ */
>   _Bool verify_peer;
>   _Bool verify_host;
>   char *cacert;
>+  char *post_body;
>+  struct curl_slist *headers;
>
>   CURL *curl;
>   char curl_errbuf[CURL_ERROR_SIZE];
>@@ -184,10 +186,28 @@ static void cx_free (void *arg) /* {{{ */
>   sfree (db->pass);
>   sfree (db->credentials);
>   sfree (db->cacert);
>+  sfree (db->post_body);
>+  curl_slist_free_all (db->headers);
>
>   sfree (db);
>} /* }}} void cx_free */
>
>+static int cx_config_append_string (const char *name, struct curl_slist **dest, /* {{{ */
>+    oconfig_item_t *ci)
>+{
>+  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
>+  {
>+    WARNING ("curl_xml plugin: `%s' needs exactly one string argument.", name);
>+    return (-1);
>+  }
>+
>+  *dest = curl_slist_append(*dest, ci->values[0].value.string);
>+  if (*dest == NULL)
>+    return (-1);
>+
>+  return (0);
>+} /* }}} int cx_config_append_string */
>+
>static int cx_check_type (const data_set_t *ds, cx_xpath_t *xpath) /* {{{ */
>{
>   if (!ds)
>@@ -770,6 +790,10 @@ static int cx_init_curl (cx_t *db) /* {{{ */
>                     db->verify_host ? 2L : 0L);
>   if (db->cacert != NULL)
>     curl_easy_setopt (db->curl, CURLOPT_CAINFO, db->cacert);
>+  if (db->headers != NULL)
>+    curl_easy_setopt (db->curl, CURLOPT_HTTPHEADER, db->headers);
>+  if (db->post_body != NULL)
>+    curl_easy_setopt (db->curl, CURLOPT_POSTFIELDS, db->post_body);
>
>   return (0);
>} /* }}} int cx_init_curl */
>@@ -833,6 +857,10 @@ static int cx_config_add_url (oconfig_item_t *ci) /* {{{ */
>       status = cf_util_get_string (child, &db->cacert);
>     else if (strcasecmp ("xpath", child->key) == 0)
>       status = cx_config_add_xpath (db, child);
>+    else if (strcasecmp ("Header", child->key) == 0)
>+      status = cx_config_append_string ("Header", &db->headers, child);
>+    else if (strcasecmp ("Post", child->key) == 0)
>+      status = cf_util_get_string (child, &db->post_body);
>     else
>     {
>       WARNING ("curl_xml plugin: Option `%s' not allowed here.", child->key);
>-- 
>1.7.10
>
>
>_______________________________________________
>collectd mailing list
>collectd at verplant.org
>http://mailman.verplant.org/listinfo/collectd
>
>
>



More information about the collectd mailing list