/*!\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;
}
Exemple #2
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(&params, "&"))) {
			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;
}
Exemple #7
0
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;
}