#define MAX_POST_CONTENT 1025
-static const char *get_content_type(struct ast_variable *headers)
+/*!
+ * \brief Retrieves the content type specified in the "Content-Type" header.
+ *
+ * This function only returns the "type/subtype" and any trailing parameter is
+ * not included.
+ *
+ * \note the return value is an allocated string that needs to be freed.
+ *
+ * \retval the content type/subtype or NULL if the header is not found.
+ */
+static char *get_content_type(struct ast_variable *headers)
{
struct ast_variable *v;
for (v = headers; v; v = v->next) {
if (strcasecmp(v->name, "Content-Type") == 0) {
- return v->value;
+ const char *param = strchr(v->value, ';');
+ size_t size = (param ? param - v->value :
+ strlen(v->value)) + 1;
+ return ast_strndup(v->value, size);
}
}
- /* Missing content type; assume empty string */
- return "";
+ return NULL;
}
static int get_content_length(struct ast_variable *headers)
int res;
struct ast_json *body;
RAII_VAR(char *, buf, NULL, ast_free);
+ RAII_VAR(char *, type, get_content_type(headers), ast_free);
/* Use errno to distinguish errors from no body */
errno = 0;
- if (strcasecmp(get_content_type(headers), "application/json") != 0) {
+ if (ast_strlen_zero(type) || strcasecmp(type, "application/json")) {
/* Content type is not JSON */
return NULL;
}
struct ast_variable *v, *post_vars=NULL, *prev = NULL;
char *var, *val;
RAII_VAR(char *, buf, NULL, ast_free_ptr);
+ RAII_VAR(char *, type, get_content_type(headers), ast_free);
int res;
/* Use errno to distinguish errors from no params */
errno = 0;
- if (strcasecmp(get_content_type(headers), "application/x-www-form-urlencoded") != 0) {
+ if (ast_strlen_zero(type) ||
+ strcasecmp(type, "application/x-www-form-urlencoded")) {
/* Content type is not form data */
return NULL;
}
ast_ari_response_ok(response, ast_json_ref(json));
}
+static int ari_channels_set_channel_var(struct ast_channel *chan,
+ const char *variable, const char *value, struct ast_ari_response *response)
+{
+ if (pbx_builtin_setvar_helper(chan, variable, value)) {
+ ast_ari_response_error(
+ response, 400, "Bad Request",
+ "Unable to set channel variable %s=%s", variable, value);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int ari_channels_set_channel_vars(struct ast_channel *chan,
+ struct ast_json *variables, struct ast_ari_response *response)
+{
+ struct ast_json_iter *i;
+
+ if (!variables) {
+ /* nothing to do */
+ return 0;
+ }
+
+ for (i = ast_json_object_iter(variables); i;
+ i = ast_json_object_iter_next(variables, i)) {
+ if (ari_channels_set_channel_var(
+ chan, ast_json_object_iter_key(i),
+ ast_json_string_get(ast_json_object_iter_value(i)),
+ response)) {
+ /* response filled in by called function */
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
void ast_ari_channels_originate(struct ast_variable *headers,
struct ast_ari_channels_originate_args *args,
struct ast_ari_response *response)
return;
}
+ if (ari_channels_set_channel_vars(chan, args->variables, response)) {
+ /* response filled in by called function */
+ return;
+ }
+
snapshot = ast_channel_snapshot_create(chan);
ast_channel_unlock(chan);
snapshot = ast_channel_snapshot_create(snoop);
ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL));
-}
\ No newline at end of file
+}
const char *caller_id;
/*! \brief Timeout (in seconds) before giving up dialing, or -1 for no timeout. */
int timeout;
+ /*! \brief Variables to be set on the channel. */
+ struct ast_json *variables;
};
/*!
* \brief Create a new channel (originate).
struct ast_ari_channels_originate_args args = {};
struct ast_variable *i;
RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
- struct ast_json *field;
#if defined(AST_DEVMODE)
int is_valid;
int code;
goto fin;
}
}
- /* Parse query parameters out of it */
- field = ast_json_object_get(body, "endpoint");
- if (field) {
- args.endpoint = ast_json_string_get(field);
- }
- field = ast_json_object_get(body, "extension");
- if (field) {
- args.extension = ast_json_string_get(field);
- }
- field = ast_json_object_get(body, "context");
- if (field) {
- args.context = ast_json_string_get(field);
- }
- field = ast_json_object_get(body, "priority");
- if (field) {
- args.priority = ast_json_integer_get(field);
- }
- field = ast_json_object_get(body, "app");
- if (field) {
- args.app = ast_json_string_get(field);
- }
- field = ast_json_object_get(body, "appArgs");
- if (field) {
- args.app_args = ast_json_string_get(field);
- }
- field = ast_json_object_get(body, "callerId");
- if (field) {
- args.caller_id = ast_json_string_get(field);
- }
- field = ast_json_object_get(body, "timeout");
- if (field) {
- args.timeout = ast_json_integer_get(field);
- }
+ args.variables = ast_json_ref(body);
ast_ari_channels_originate(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
"allowMultiple": false,
"dataType": "int",
"defaultValue": 30
+ },
+ {
+ "name": "variables",
+ "description": "Variables to be set on the channel.",
+ "paramType": "body",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "containers"
}
],
"errorResponses": [