summaryrefslogtreecommitdiff
path: root/res/res_config_curl.c
diff options
context:
space:
mode:
authorTilghman Lesher <tilghman@meg.abyt.es>2009-04-29 18:53:01 +0000
committerTilghman Lesher <tilghman@meg.abyt.es>2009-04-29 18:53:01 +0000
commita866a7590085a1f635ca92459c3917e5cded257a (patch)
tree972bdf8f96c18f1b9667469307af69385f4a75f3 /res/res_config_curl.c
parent0ea83eab4811c8519e4e04bf4c59b1744cf1efc9 (diff)
Merge str_substitution branch.
This branch adds additional methods to dialplan functions, whereby the result buffers are now dynamic buffers, which can be expanded to the size of any result. No longer are variable substitutions limited to 4095 bytes of data. In addition, the common case of needing buffers much smaller than that will enable substitution to only take up the amount of memory actually needed. The existing variable substitution routines are still available, but users of those API calls should transition to using the dynamic-buffer APIs. Reviewboard: http://reviewboard.digium.com/r/174/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@191140 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_config_curl.c')
-rw-r--r--res/res_config_curl.c236
1 files changed, 121 insertions, 115 deletions
diff --git a/res/res_config_curl.c b/res/res_config_curl.c
index 1d259c845..928a6ae3b 100644
--- a/res/res_config_curl.c
+++ b/res/res_config_curl.c
@@ -43,6 +43,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
+#include "asterisk/threadstorage.h"
+
+AST_THREADSTORAGE(query_buf);
+AST_THREADSTORAGE(result_buf);
/*!
* \brief Execute a curl query and return ast_variable list
@@ -55,25 +59,24 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
*/
static struct ast_variable *realtime_curl(const char *url, const char *unused, va_list ap)
{
- struct ast_str *query;
- char buf1[200], buf2[200];
+ struct ast_str *query, *buffer;
+ char buf1[256], buf2[256];
const char *newparam, *newval;
char *stringp, *pair, *key;
int i;
- struct ast_variable *var=NULL, *prev=NULL;
- const int EncodeSpecialChars = 1, bufsize = 64000;
- char *buffer;
+ struct ast_variable *var = NULL, *prev = NULL;
+ const int EncodeSpecialChars = 1;
if (!ast_custom_function_find("CURL")) {
ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
return NULL;
}
- if (!(query = ast_str_create(1000)))
+ if (!(query = ast_str_thread_get(&query_buf, 16))) {
return NULL;
+ }
- if (!(buffer = ast_malloc(bufsize))) {
- ast_free(query);
+ if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
return NULL;
}
@@ -88,31 +91,33 @@ static struct ast_variable *realtime_curl(const char *url, const char *unused, v
va_end(ap);
ast_str_append(&query, 0, ")}");
- pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, bufsize);
+ ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
/* Remove any trailing newline characters */
- if ((stringp = strchr(buffer, '\r')) || (stringp = strchr(buffer, '\n')))
+ if ((stringp = strchr(ast_str_buffer(buffer), '\r')) || (stringp = strchr(ast_str_buffer(buffer), '\n'))) {
*stringp = '\0';
+ }
- stringp = buffer;
+ stringp = ast_str_buffer(buffer);
while ((pair = strsep(&stringp, "&"))) {
key = strsep(&pair, "=");
ast_uri_decode(key);
- if (pair)
+ if (pair) {
ast_uri_decode(pair);
+ }
if (!ast_strlen_zero(key)) {
if (prev) {
prev->next = ast_variable_new(key, S_OR(pair, ""), "");
- if (prev->next)
+ if (prev->next) {
prev = prev->next;
- } else
+ }
+ } else {
prev = var = ast_variable_new(key, S_OR(pair, ""), "");
+ }
}
}
- ast_free(buffer);
- ast_free(query);
return var;
}
@@ -127,27 +132,26 @@ static struct ast_variable *realtime_curl(const char *url, const char *unused, v
*/
static struct ast_config *realtime_multi_curl(const char *url, const char *unused, va_list ap)
{
- struct ast_str *query;
- char buf1[200], buf2[200];
+ struct ast_str *query, *buffer;
+ char buf1[256], buf2[256];
const char *newparam, *newval;
char *stringp, *line, *pair, *key, *initfield = NULL;
int i;
- const int EncodeSpecialChars = 1, bufsize = 256000;
- struct ast_variable *var=NULL;
- struct ast_config *cfg=NULL;
- struct ast_category *cat=NULL;
- char *buffer;
+ const int EncodeSpecialChars = 1;
+ struct ast_variable *var = NULL;
+ struct ast_config *cfg = NULL;
+ struct ast_category *cat = NULL;
if (!ast_custom_function_find("CURL")) {
ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
return NULL;
}
- if (!(query = ast_str_create(1000)))
+ if (!(query = ast_str_thread_get(&query_buf, 16))) {
return NULL;
+ }
- if (!(buffer = ast_malloc(bufsize))) {
- ast_free(query);
+ if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
return NULL;
}
@@ -170,28 +174,33 @@ static struct ast_config *realtime_multi_curl(const char *url, const char *unuse
ast_str_append(&query, 0, ")}");
/* Do the CURL query */
- pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, bufsize);
+ ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
- if (!(cfg = ast_config_new()))
- goto exit_multi;
+ if (!(cfg = ast_config_new())) {
+ return NULL;
+ }
/* Line oriented output */
- stringp = buffer;
+ stringp = ast_str_buffer(buffer);
while ((line = strsep(&stringp, "\r\n"))) {
- if (ast_strlen_zero(line))
+ if (ast_strlen_zero(line)) {
continue;
+ }
- if (!(cat = ast_category_new("", "", 99999)))
+ if (!(cat = ast_category_new("", "", 99999))) {
continue;
+ }
while ((pair = strsep(&line, "&"))) {
key = strsep(&pair, "=");
ast_uri_decode(key);
- if (pair)
+ if (pair) {
ast_uri_decode(pair);
+ }
- if (!strcasecmp(key, initfield) && pair)
+ if (!strcasecmp(key, initfield) && pair) {
ast_category_rename(cat, pair);
+ }
if (!ast_strlen_zero(key)) {
var = ast_variable_new(key, S_OR(pair, ""), "");
@@ -201,9 +210,6 @@ static struct ast_config *realtime_multi_curl(const char *url, const char *unuse
ast_category_append(cfg, cat);
}
-exit_multi:
- ast_free(buffer);
- ast_free(query);
return cfg;
}
@@ -224,24 +230,23 @@ exit_multi:
*/
static int update_curl(const char *url, const char *unused, const char *keyfield, const char *lookup, va_list ap)
{
- struct ast_str *query;
- char buf1[200], buf2[200];
+ struct ast_str *query, *buffer;
+ char buf1[256], buf2[256];
const char *newparam, *newval;
char *stringp;
int i, rowcount = -1;
- const int EncodeSpecialChars = 1, bufsize = 100;
- char *buffer;
+ const int EncodeSpecialChars = 1;
if (!ast_custom_function_find("CURL")) {
ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
return -1;
}
- if (!(query = ast_str_create(1000)))
+ if (!(query = ast_str_thread_get(&query_buf, 16))) {
return -1;
+ }
- if (!(buffer = ast_malloc(bufsize))) {
- ast_free(query);
+ if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
return -1;
}
@@ -258,43 +263,40 @@ static int update_curl(const char *url, const char *unused, const char *keyfield
va_end(ap);
ast_str_append(&query, 0, ")}");
- pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, bufsize);
+ ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
/* Line oriented output */
- stringp = buffer;
- while (*stringp <= ' ')
+ stringp = ast_str_buffer(buffer);
+ while (*stringp <= ' ') {
stringp++;
+ }
sscanf(stringp, "%d", &rowcount);
- ast_free(buffer);
- ast_free(query);
-
- if (rowcount >= 0)
+ if (rowcount >= 0) {
return (int)rowcount;
+ }
return -1;
}
static int update2_curl(const char *url, const char *unused, va_list ap)
{
- struct ast_str *query;
+ struct ast_str *query, *buffer;
char buf1[200], buf2[200];
const char *newparam, *newval;
char *stringp;
int rowcount = -1, lookup = 1, first = 1;
- const int EncodeSpecialChars = 1, bufsize = 100;
- char *buffer;
+ const int EncodeSpecialChars = 1;
if (!ast_custom_function_find("CURL")) {
ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
return -1;
}
- if (!(query = ast_str_create(1000)))
+ if (!(query = ast_str_thread_get(&query_buf, 1000)))
return -1;
- if (!(buffer = ast_malloc(bufsize))) {
- ast_free(query);
+ if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
return -1;
}
@@ -316,24 +318,27 @@ static int update2_curl(const char *url, const char *unused, va_list ap)
ast_uri_encode(newparam, buf1, sizeof(buf1), EncodeSpecialChars);
ast_uri_encode(newval, buf2, sizeof(buf2), EncodeSpecialChars);
ast_str_append(&query, 0, "%s%s=%s", first ? "" : "&", buf1, buf2);
+ first = 0;
}
va_end(ap);
ast_str_append(&query, 0, ")}");
- /* TODO: Make proxies work */
- pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, bufsize);
+ /* Proxies work, by setting CURLOPT options in the [globals] section of
+ * extensions.conf. Unfortunately, this means preloading pbx_config.so
+ * so that they have an opportunity to be set prior to startup realtime
+ * queries. */
+ ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
/* Line oriented output */
- stringp = buffer;
- while (*stringp <= ' ')
+ stringp = ast_str_buffer(buffer);
+ while (*stringp <= ' ') {
stringp++;
+ }
sscanf(stringp, "%d", &rowcount);
- ast_free(buffer);
- ast_free(query);
-
- if (rowcount >= 0)
+ if (rowcount >= 0) {
return (int)rowcount;
+ }
return -1;
}
@@ -353,24 +358,23 @@ static int update2_curl(const char *url, const char *unused, va_list ap)
*/
static int store_curl(const char *url, const char *unused, va_list ap)
{
- struct ast_str *query;
- char buf1[200], buf2[200];
+ struct ast_str *query, *buffer;
+ char buf1[256], buf2[256];
const char *newparam, *newval;
char *stringp;
int i, rowcount = -1;
- const int EncodeSpecialChars = 1, bufsize = 100;
- char *buffer;
+ const int EncodeSpecialChars = 1;
if (!ast_custom_function_find("CURL")) {
ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
return -1;
}
- if (!(query = ast_str_create(1000)))
+ if (!(query = ast_str_thread_get(&query_buf, 1000))) {
return -1;
+ }
- if (!(buffer = ast_malloc(bufsize))) {
- ast_free(query);
+ if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
return -1;
}
@@ -385,18 +389,17 @@ static int store_curl(const char *url, const char *unused, va_list ap)
va_end(ap);
ast_str_append(&query, 0, ")}");
- pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, bufsize);
+ ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
- stringp = buffer;
- while (*stringp <= ' ')
+ stringp = ast_str_buffer(buffer);
+ while (*stringp <= ' ') {
stringp++;
+ }
sscanf(stringp, "%d", &rowcount);
- ast_free(buffer);
- ast_free(query);
-
- if (rowcount >= 0)
- return (int)rowcount;
+ if (rowcount >= 0) {
+ return rowcount;
+ }
return -1;
}
@@ -418,24 +421,23 @@ static int store_curl(const char *url, const char *unused, va_list ap)
*/
static int destroy_curl(const char *url, const char *unused, const char *keyfield, const char *lookup, va_list ap)
{
- struct ast_str *query;
+ struct ast_str *query, *buffer;
char buf1[200], buf2[200];
const char *newparam, *newval;
char *stringp;
int i, rowcount = -1;
- const int EncodeSpecialChars = 1, bufsize = 100;
- char *buffer;
+ const int EncodeSpecialChars = 1;
if (!ast_custom_function_find("CURL")) {
ast_log(LOG_ERROR, "func_curl.so must be loaded in order to use res_config_curl.so!!\n");
return -1;
}
- if (!(query = ast_str_create(1000)))
+ if (!(query = ast_str_thread_get(&query_buf, 1000))) {
return -1;
+ }
- if (!(buffer = ast_malloc(bufsize))) {
- ast_free(query);
+ if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
return -1;
}
@@ -452,27 +454,26 @@ static int destroy_curl(const char *url, const char *unused, const char *keyfiel
va_end(ap);
ast_str_append(&query, 0, ")}");
- pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, bufsize);
+ ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
/* Line oriented output */
- stringp = buffer;
- while (*stringp <= ' ')
+ stringp = ast_str_buffer(buffer);
+ while (*stringp <= ' ') {
stringp++;
+ }
sscanf(stringp, "%d", &rowcount);
- ast_free(buffer);
- ast_free(query);
-
- if (rowcount >= 0)
+ if (rowcount >= 0) {
return (int)rowcount;
+ }
return -1;
}
static int require_curl(const char *url, const char *unused, va_list ap)
{
- struct ast_str *query;
- char *elm, field[256], buffer[128];
+ struct ast_str *query, *buffer;
+ char *elm, field[256];
int type, size;
const int EncodeSpecialChars = 1;
@@ -481,7 +482,11 @@ static int require_curl(const char *url, const char *unused, va_list ap)
return -1;
}
- if (!(query = ast_str_create(100))) {
+ if (!(query = ast_str_thread_get(&query_buf, 100))) {
+ return -1;
+ }
+
+ if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
return -1;
}
@@ -511,19 +516,19 @@ static int require_curl(const char *url, const char *unused, va_list ap)
va_end(ap);
ast_str_append(&query, 0, ")}");
- pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, sizeof(buffer));
- return atoi(buffer);
+ ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
+ return atoi(ast_str_buffer(buffer));
}
static struct ast_config *config_curl(const char *url, const char *unused, const char *file, struct ast_config *cfg, struct ast_flags flags, const char *sugg_incl, const char *who_asked)
{
- struct ast_str *query;
+ struct ast_str *query, *buffer;
char buf1[200];
char *stringp, *line, *pair, *key;
- const int EncodeSpecialChars = 1, bufsize = 256000;
+ const int EncodeSpecialChars = 1;
int last_cat_metric = -1, cat_metric = -1;
- struct ast_category *cat=NULL;
- char *buffer, *cur_cat = "";
+ struct ast_category *cat = NULL;
+ char *cur_cat = "";
char *category = "", *var_name = "", *var_val = "";
struct ast_flags loader_flags = { 0 };
@@ -532,11 +537,11 @@ static struct ast_config *config_curl(const char *url, const char *unused, const
return NULL;
}
- if (!(query = ast_str_create(1000)))
+ if (!(query = ast_str_thread_get(&query_buf, 100))) {
return NULL;
+ }
- if (!(buffer = ast_malloc(bufsize))) {
- ast_free(query);
+ if (!(buffer = ast_str_thread_get(&result_buf, 16))) {
return NULL;
}
@@ -544,30 +549,33 @@ static struct ast_config *config_curl(const char *url, const char *unused, const
ast_str_set(&query, 0, "${CURL(%s/static?file=%s)}", url, buf1);
/* Do the CURL query */
- pbx_substitute_variables_helper(NULL, ast_str_buffer(query), buffer, bufsize);
+ ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query));
/* Line oriented output */
- stringp = buffer;
+ stringp = ast_str_buffer(buffer);
cat = ast_config_get_current_category(cfg);
while ((line = strsep(&stringp, "\r\n"))) {
- if (ast_strlen_zero(line))
+ if (ast_strlen_zero(line)) {
continue;
+ }
while ((pair = strsep(&line, "&"))) {
key = strsep(&pair, "=");
ast_uri_decode(key);
- if (pair)
+ if (pair) {
ast_uri_decode(pair);
+ }
- if (!strcasecmp(key, "category"))
+ if (!strcasecmp(key, "category")) {
category = S_OR(pair, "");
- else if (!strcasecmp(key, "var_name"))
+ } else if (!strcasecmp(key, "var_name")) {
var_name = S_OR(pair, "");
- else if (!strcasecmp(key, "var_val"))
+ } else if (!strcasecmp(key, "var_val")) {
var_val = S_OR(pair, "");
- else if (!strcasecmp(key, "cat_metric"))
+ } else if (!strcasecmp(key, "cat_metric")) {
cat_metric = pair ? atoi(pair) : 0;
+ }
}
if (!strcmp(var_name, "#include")) {
@@ -585,8 +593,6 @@ static struct ast_config *config_curl(const char *url, const char *unused, const
ast_variable_append(cat, ast_variable_new(var_name, var_val, ""));
}
- ast_free(buffer);
- ast_free(query);
return cfg;
}