diff options
author | Tilghman Lesher <tilghman@meg.abyt.es> | 2009-04-29 18:53:01 +0000 |
---|---|---|
committer | Tilghman Lesher <tilghman@meg.abyt.es> | 2009-04-29 18:53:01 +0000 |
commit | a866a7590085a1f635ca92459c3917e5cded257a (patch) | |
tree | 972bdf8f96c18f1b9667469307af69385f4a75f3 /res/res_config_curl.c | |
parent | 0ea83eab4811c8519e4e04bf4c59b1744cf1efc9 (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.c | 236 |
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; } |