/*!\brief uridecode: Decode URI according to RFC 2396 */ static int uridecode(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) { if (ast_strlen_zero(data)) { ast_log(LOG_WARNING, "Syntax: URIDECODE(<data>) - missing argument!\n"); return -1; } ast_copy_string(buf, data, len); ast_uri_decode(buf); return 0; }
/*!\brief uridecode: Decode URI according to RFC 2396 */ static int uridecode(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) { if (ast_strlen_zero(data)) { buf[0] = '\0'; return 0; } ast_copy_string(buf, data, len); ast_uri_decode(buf, ast_uri_http); return 0; }
/*! * \brief Execute a curl query and return ast_variable list * \param url The base URL from which to retrieve data * \param unused Not currently used * \param fields list containing one or more field/operator/value set. * * \retval var on success * \retval NULL on failure */ static struct ast_variable *realtime_curl(const char *url, const char *unused, const struct ast_variable *fields) { struct ast_str *query, *buffer; char buf1[256], buf2[256]; const struct ast_variable *field; char *stringp, *pair, *key; unsigned int start = 1; struct ast_variable *var = NULL, *prev = 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_thread_get(&query_buf, 16))) { return NULL; } if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return NULL; } ast_str_set(&query, 0, "${CURL(%s/single,", url); for (field = fields; field; field = field->next) { ast_uri_encode(field->name, buf1, sizeof(buf1), ast_uri_http); ast_uri_encode(field->value, buf2, sizeof(buf2), ast_uri_http); ast_str_append(&query, 0, "%s%s=%s", !start ? "&" : "", buf1, buf2); start = 0; } ast_str_append(&query, 0, ")}"); ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); /* Remove any trailing newline characters */ if ((stringp = strchr(ast_str_buffer(buffer), '\r')) || (stringp = strchr(ast_str_buffer(buffer), '\n'))) { *stringp = '\0'; } stringp = ast_str_buffer(buffer); while ((pair = strsep(&stringp, "&"))) { key = strsep(&pair, "="); ast_uri_decode(key, ast_uri_http); if (pair) { ast_uri_decode(pair, ast_uri_http); } if (!ast_strlen_zero(key)) { if (prev) { prev->next = ast_variable_new(key, S_OR(pair, ""), ""); if (prev->next) { prev = prev->next; } } else { prev = var = ast_variable_new(key, S_OR(pair, ""), ""); } } } return var; }
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, *buffer; char buf1[200]; char *stringp, *line, *pair, *key; int last_cat_metric = -1, cat_metric = -1; struct ast_category *cat = NULL; char *cur_cat = ""; char *category = "", *var_name = "", *var_val = ""; struct ast_flags loader_flags = { 0 }; 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_thread_get(&query_buf, 100))) { return NULL; } if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return NULL; } ast_uri_encode(file, buf1, sizeof(buf1), ast_uri_http); ast_str_set(&query, 0, "${CURL(%s/static?file=%s)}", url, buf1); /* Do the CURL query */ ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); /* Line oriented output */ stringp = ast_str_buffer(buffer); cat = ast_config_get_current_category(cfg); while ((line = strsep(&stringp, "\r\n"))) { if (ast_strlen_zero(line)) { continue; } while ((pair = strsep(&line, "&"))) { key = strsep(&pair, "="); ast_uri_decode(key, ast_uri_http); if (pair) { ast_uri_decode(pair, ast_uri_http); } if (!strcasecmp(key, "category")) { category = S_OR(pair, ""); } else if (!strcasecmp(key, "var_name")) { var_name = S_OR(pair, ""); } else if (!strcasecmp(key, "var_val")) { var_val = S_OR(pair, ""); } else if (!strcasecmp(key, "cat_metric")) { cat_metric = pair ? atoi(pair) : 0; } } if (!strcmp(var_name, "#include")) { if (!ast_config_internal_load(var_val, cfg, loader_flags, "", who_asked)) return NULL; } if (!cat || strcmp(category, cur_cat) || last_cat_metric != cat_metric) { if (!(cat = ast_category_new(category, "", 99999))) break; cur_cat = category; last_cat_metric = cat_metric; ast_category_append(cfg, cat); } ast_variable_append(cat, ast_variable_new(var_name, var_val, "")); } return cfg; }
/*! * \brief Excute an Select query and return ast_config list * \param url * \param unused * \param fields list containing one or more field/operator/value set. * * \retval struct ast_config pointer on success * \retval NULL on failure */ static struct ast_config *realtime_multi_curl(const char *url, const char *unused, const struct ast_variable *fields) { struct ast_str *query, *buffer; char buf1[256], buf2[256]; const struct ast_variable *field; char *stringp, *line, *pair, *key, *initfield = NULL; int start = 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_thread_get(&query_buf, 16))) { return NULL; } if (!(buffer = ast_str_thread_get(&result_buf, 16))) { return NULL; } ast_str_set(&query, 0, "${CURL(%s/multi,", url); for (field = fields; field; field = field->next) { if (start) { char *op; initfield = ast_strdupa(field->name); if ((op = strchr(initfield, ' '))) *op = '\0'; } ast_uri_encode(field->name, buf1, sizeof(buf1), ast_uri_http); ast_uri_encode(field->value, buf2, sizeof(buf2), ast_uri_http); ast_str_append(&query, 0, "%s%s=%s", !start ? "&" : "", buf1, buf2); start = 0; } ast_str_append(&query, 0, ")}"); /* Do the CURL query */ ast_str_substitute_variables(&buffer, 0, NULL, ast_str_buffer(query)); if (!(cfg = ast_config_new())) { return NULL; } /* Line oriented output */ stringp = ast_str_buffer(buffer); while ((line = strsep(&stringp, "\r\n"))) { if (ast_strlen_zero(line)) { continue; } if (!(cat = ast_category_new("", "", 99999))) { continue; } while ((pair = strsep(&line, "&"))) { key = strsep(&pair, "="); ast_uri_decode(key, ast_uri_http); if (pair) { ast_uri_decode(pair, ast_uri_http); } if (!strcasecmp(key, initfield) && pair) { ast_category_rename(cat, pair); } if (!ast_strlen_zero(key)) { var = ast_variable_new(key, S_OR(pair, ""), ""); ast_variable_append(cat, var); } } ast_category_append(cfg, cat); } return cfg; }
static char *handle_uri(struct sockaddr_in *sin, char *uri, int *status, char **title, int *contentlength, struct ast_variable **cookies, unsigned int *static_content) { char *c; char *turi; char *params; char *var; char *val; struct ast_http_uri *urih=NULL; int len; struct ast_variable *vars=NULL, *v, *prev = NULL; params = strchr(uri, '?'); if (params) { *params = '\0'; params++; while ((var = strsep(¶ms, "&"))) { val = strchr(var, '='); if (val) { *val = '\0'; val++; ast_uri_decode(val); } else val = ""; ast_uri_decode(var); if ((v = ast_variable_new(var, val))) { if (vars) prev->next = v; else vars = v; prev = v; } } } if (prev) prev->next = *cookies; else vars = *cookies; *cookies = NULL; ast_uri_decode(uri); if (!strncasecmp(uri, prefix, prefix_len)) { uri += prefix_len; if (!*uri || (*uri == '/')) { if (*uri == '/') uri++; ast_rwlock_rdlock(&uris_lock); urih = uris; while(urih) { len = strlen(urih->uri); if (!strncasecmp(urih->uri, uri, len)) { if (!uri[len] || uri[len] == '/') { turi = uri + len; if (*turi == '/') turi++; if (!*turi || urih->has_subtree) { uri = turi; break; } } } urih = urih->next; } if (!urih) ast_rwlock_unlock(&uris_lock); } } if (urih) { if (urih->static_content) *static_content = 1; c = urih->callback(sin, uri, vars, status, title, contentlength); ast_rwlock_unlock(&uris_lock); } else if (ast_strlen_zero(uri) && ast_strlen_zero(prefix)) { /* Special case: If no prefix, and no URI, send to /static/index.html */ c = ast_http_error(302, "Moved Temporarily", "Location: /static/index.html\r\n", "Redirecting to /static/index.html."); *status = 302; *title = strdup("Moved Temporarily"); } else { c = ast_http_error(404, "Not Found", NULL, "The requested URL was not found on this server."); *status = 404; *title = strdup("Not Found"); } ast_variables_destroy(vars); return c; }
void ast_ari_invoke(struct ast_tcptls_session_instance *ser, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers, struct ast_ari_response *response) { RAII_VAR(struct stasis_rest_handlers *, root, NULL, ao2_cleanup); struct stasis_rest_handlers *handler; RAII_VAR(struct ast_variable *, path_vars, NULL, ast_variables_destroy); char *path = ast_strdupa(uri); char *path_segment; stasis_rest_callback callback; root = handler = get_root_handler(); ast_assert(root != NULL); while ((path_segment = strsep(&path, "/")) && (strlen(path_segment) > 0)) { struct stasis_rest_handlers *found_handler = NULL; int i; ast_uri_decode(path_segment, ast_uri_http_legacy); ast_debug(3, "Finding handler for %s\n", path_segment); for (i = 0; found_handler == NULL && i < handler->num_children; ++i) { struct stasis_rest_handlers *child = handler->children[i]; ast_debug(3, " Checking %s\n", child->path_segment); if (child->is_wildcard) { /* Record the path variable */ struct ast_variable *path_var = ast_variable_new(child->path_segment, path_segment, __FILE__); path_var->next = path_vars; path_vars = path_var; found_handler = child; } else if (strcmp(child->path_segment, path_segment) == 0) { found_handler = child; } } if (found_handler == NULL) { /* resource not found */ ast_debug(3, " Handler not found\n"); ast_ari_response_error( response, 404, "Not Found", "Resource not found"); return; } else { ast_debug(3, " Got it!\n"); handler = found_handler; } } ast_assert(handler != NULL); if (method == AST_HTTP_OPTIONS) { handle_options(handler, headers, response); return; } if (method < 0 || method >= AST_HTTP_MAX_METHOD) { add_allow_header(handler, response); ast_ari_response_error( response, 405, "Method Not Allowed", "Invalid method"); return; } if (handler->ws_server && method == AST_HTTP_GET) { /* WebSocket! */ ari_handle_websocket(handler->ws_server, ser, uri, method, get_params, headers); /* Since the WebSocket code handles the connection, we shouldn't * do anything else; setting no_response */ response->no_response = 1; return; } callback = handler->callbacks[method]; if (callback == NULL) { add_allow_header(handler, response); ast_ari_response_error( response, 405, "Method Not Allowed", "Invalid method"); return; } callback(ser, get_params, path_vars, headers, response); if (response->message == NULL && response->response_code == 0) { /* Really should not happen */ ast_log(LOG_ERROR, "ARI %s %s not implemented\n", ast_get_http_method(method), uri); ast_ari_response_error( response, 501, "Not Implemented", "Method not implemented"); } }
/*! * \brief Execute a curl query and return ast_variable list * \param url The base URL from which to retrieve data * \param unused Not currently used * \param ap list containing one or more field/operator/value set. * * \retval var on success * \retval NULL on failure */ static struct ast_variable *realtime_curl(const char *url, const char *unused, va_list ap) { struct ast_str *query; char buf1[200], buf2[200]; 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; 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))) return NULL; if (!(buffer = ast_malloc(bufsize))) { ast_free(query); return NULL; } ast_str_set(&query, 0, "${CURL(%s/single,", url); for (i = 0; (newparam = va_arg(ap, const char *)); i++) { newval = va_arg(ap, const char *); ast_uri_encode(newparam, buf1, sizeof(buf1), EncodeSpecialChars); ast_uri_encode(newval, buf2, sizeof(buf2), EncodeSpecialChars); ast_str_append(&query, 0, "%s%s=%s", i > 0 ? "&" : "", buf1, buf2); } va_end(ap); ast_str_append(&query, 0, ")}"); pbx_substitute_variables_helper(NULL, query->str, buffer, bufsize); /* Remove any trailing newline characters */ if ((stringp = strchr(buffer, '\r')) || (stringp = strchr(buffer, '\n'))) *stringp = '\0'; stringp = buffer; while ((pair = strsep(&stringp, "&"))) { key = strsep(&pair, "="); ast_uri_decode(key); 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) prev = prev->next; } else prev = var = ast_variable_new(key, S_OR(pair, ""), ""); } } ast_free(buffer); ast_free(query); return var; }
/*! * \brief Excute an Select query and return ast_config list * \param url * \param unused * \param ap list containing one or more field/operator/value set. * * \retval struct ast_config pointer on success * \retval NULL on failure */ 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]; 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; 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))) return NULL; if (!(buffer = ast_malloc(bufsize))) { ast_free(query); return NULL; } ast_str_set(&query, 0, "${CURL(%s/multi,", url); for (i = 0; (newparam = va_arg(ap, const char *)); i++) { newval = va_arg(ap, const char *); if (i == 0) { char *op; initfield = ast_strdupa(newparam); if ((op = strchr(initfield, ' '))) *op = '\0'; } ast_uri_encode(newparam, buf1, sizeof(buf1), EncodeSpecialChars); ast_uri_encode(newval, buf2, sizeof(buf2), EncodeSpecialChars); ast_str_append(&query, 0, "%s%s=%s", i > 0 ? "&" : "", buf1, buf2); } va_end(ap); ast_str_append(&query, 0, ")}"); /* Do the CURL query */ pbx_substitute_variables_helper(NULL, query->str, buffer, bufsize); if (!(cfg = ast_config_new())) goto exit_multi; /* Line oriented output */ stringp = buffer; while ((line = strsep(&stringp, "\r\n"))) { if (ast_strlen_zero(line)) continue; if (!(cat = ast_category_new("", "", 99999))) continue; while ((pair = strsep(&line, "&"))) { key = strsep(&pair, "="); ast_uri_decode(key); if (pair) ast_uri_decode(pair); if (!strcasecmp(key, initfield) && pair) ast_category_rename(cat, pair); if (!ast_strlen_zero(key)) { var = ast_variable_new(key, S_OR(pair, ""), ""); ast_variable_append(cat, var); } } ast_category_append(cfg, cat); } exit_multi: ast_free(buffer); ast_free(query); return cfg; }