X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fcurl_json.c;h=98ba0bb2ed9db58462fe465a6f8dbe902c17e6ae;hb=0657d95eaa686d64efe6bbccda346ebd6467bd0b;hp=8a084fed6fb9bb3bbb3d4c619579f9a83317b97d;hpb=f2389f97fbec15f49dcd1d9b06b3b6bbd0837e8a;p=collectd.git diff --git a/src/curl_json.c b/src/curl_json.c index 8a084fed..98ba0bb2 100644 --- a/src/curl_json.c +++ b/src/curl_json.c @@ -78,6 +78,7 @@ struct cj_s /* {{{ */ struct curl_slist *headers; char *post_body; cdtime_t interval; + int timeout; CURL *curl; char curl_errbuf[CURL_ERROR_SIZE]; @@ -231,12 +232,17 @@ static int cj_cb_number (void *ctx, buffer[sizeof (buffer) - 1] = 0; if ((key == NULL) || !CJ_IS_KEY (key)) { - if (key != NULL) + if (key != NULL && !db->state[db->depth].in_array/*can be inhomogeneous*/) NOTICE ("curl_json plugin: Found \"%s\", but the configuration expects" " a map.", buffer); - cj_cb_inc_array_index (ctx, /* update_key = */ 0); - return (CJ_CB_CONTINUE); - } else { + cj_cb_inc_array_index (ctx, /* update_key = */ 1); + key = db->state[db->depth].key; + if (key == NULL) { + return (CJ_CB_CONTINUE); + } + } + else + { cj_cb_inc_array_index (ctx, /* update_key = */ 1); } @@ -276,10 +282,21 @@ static int cj_cb_map_key (void *ctx, memcpy (name, in_name, name_len); name[name_len] = 0; - if (c_avl_get (tree, name, (void *) &value) == 0) - db->state[db->depth].key = value; + if (c_avl_get (tree, name, (void *) &value) == 0) { + if (CJ_IS_KEY((cj_key_t*)value)) { + db->state[db->depth].key = value; + } + else { + db->state[db->depth].tree = (c_avl_tree_t*) value; + } + } else if (c_avl_get (tree, CJ_ANY, (void *) &value) == 0) - db->state[db->depth].key = value; + if (CJ_IS_KEY((cj_key_t*)value)) { + db->state[db->depth].key = value; + } + else { + db->state[db->depth].tree = (c_avl_tree_t*) value; + } else db->state[db->depth].key = NULL; } @@ -486,6 +503,7 @@ static int cj_config_add_key (cj_t *db, /* {{{ */ { ERROR ("curl_json plugin: cj_config: " "Invalid key: %s", ci->key); + cj_key_free (key); return (-1); } @@ -508,72 +526,68 @@ static int cj_config_add_key (cj_t *db, /* {{{ */ break; } /* for (i = 0; i < ci->children_num; i++) */ - while (status == 0) + if (status != 0) { - if (key->type == NULL) - { - WARNING ("curl_json plugin: `Type' missing in `Key' block."); - status = -1; - } + cj_key_free (key); + return (-1); + } - break; - } /* while (status == 0) */ + if (key->type == NULL) + { + WARNING ("curl_json plugin: `Type' missing in `Key' block."); + cj_key_free (key); + return (-1); + } /* store path in a tree that will match the json map structure, example: * "httpd/requests/count", * "httpd/requests/current" -> * { "httpd": { "requests": { "count": $key, "current": $key } } } */ - if (status == 0) + char *ptr; + char *name; + c_avl_tree_t *tree; + + if (db->tree == NULL) + db->tree = cj_avl_create(); + + tree = db->tree; + ptr = key->path; + if (*ptr == '/') + ++ptr; + + name = ptr; + while ((ptr = strchr (name, '/')) != NULL) { - char *ptr; - char *name; char ent[PATH_MAX]; - c_avl_tree_t *tree; + c_avl_tree_t *value; + size_t len; - if (db->tree == NULL) - db->tree = cj_avl_create(); + len = ptr - name; + if (len == 0) + break; - tree = db->tree; - name = key->path; - ptr = key->path; - if (*ptr == '/') - ++ptr; + len = COUCH_MIN(len, sizeof (ent)-1); + sstrncpy (ent, name, len+1); - name = ptr; - while (*ptr) - { - if (*ptr == '/') - { - c_avl_tree_t *value; - int len; - - len = ptr-name; - if (len == 0) - break; - len = COUCH_MIN(len, sizeof (ent)-1); - sstrncpy (ent, name, len+1); - - if (c_avl_get (tree, ent, (void *) &value) != 0) - { - value = cj_avl_create (); - c_avl_insert (tree, strdup (ent), value); - } - - tree = value; - name = ptr+1; - } - ++ptr; - } - if (*name) - c_avl_insert (tree, strdup(name), key); - else + if (c_avl_get (tree, ent, (void *) &value) != 0) { - ERROR ("curl_json plugin: invalid key: %s", key->path); - status = -1; + value = cj_avl_create (); + c_avl_insert (tree, strdup (ent), value); } + + tree = value; + name = ptr + 1; + } + + if (strlen (name) == 0) + { + ERROR ("curl_json plugin: invalid key: %s", key->path); + cj_key_free (key); + return (-1); } + c_avl_insert (tree, strdup (name), key); return (status); } /* }}} int cj_config_add_key */ @@ -592,6 +606,8 @@ static int cj_init_curl (cj_t *db) /* {{{ */ curl_easy_setopt (db->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); curl_easy_setopt (db->curl, CURLOPT_ERRORBUFFER, db->curl_errbuf); curl_easy_setopt (db->curl, CURLOPT_URL, db->url); + curl_easy_setopt (db->curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt (db->curl, CURLOPT_MAXREDIRS, 50L); if (db->user != NULL) { @@ -632,6 +648,17 @@ static int cj_init_curl (cj_t *db) /* {{{ */ if (db->post_body != NULL) curl_easy_setopt (db->curl, CURLOPT_POSTFIELDS, db->post_body); +#ifdef HAVE_CURLOPT_TIMEOUT_MS + if (db->timeout >= 0) + curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) db->timeout); + else if (db->interval > 0) + curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, + CDTIME_T_TO_MS(db->timeout)); + else + curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, + CDTIME_T_TO_MS(plugin_get_interval())); +#endif + return (0); } /* }}} int cj_init_curl */ @@ -657,6 +684,8 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */ } memset (db, 0, sizeof (*db)); + db->timeout = -1; + if (strcasecmp ("URL", ci->key) == 0) status = cf_util_get_string (ci, &db->url); else if (strcasecmp ("Sock", ci->key) == 0) @@ -665,6 +694,7 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */ { ERROR ("curl_json plugin: cj_config: " "Invalid key: %s", ci->key); + cj_free (db); return (-1); } if (status != 0) @@ -702,6 +732,8 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */ status = cj_config_add_key (db, child); else if (strcasecmp ("Interval", child->key) == 0) status = cf_util_get_cdtime(child, &db->interval); + else if (strcasecmp ("Timeout", child->key) == 0) + status = cf_util_get_int (child, &db->timeout); else { WARNING ("curl_json plugin: Option `%s' not allowed here.", child->key);