[asterisk-commits] kharwell: branch 12 r403752 - in /branches/12: main/ res/ res/ari/ rest-api/a...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Dec 13 11:17:52 CST 2013


Author: kharwell
Date: Fri Dec 13 11:17:48 2013
New Revision: 403752

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=403752
Log:
ARI: Allow specifying channel variables during a POST /channels

Added the ability to specify channel variables when creating/originating a
channel in ARI.  The variables are sent in the body of the request and should
be formatted as a single level JSON object.  No nested objects allowed.
For example: {"variable1": "foo", "variable2": "bar"}.

(closes issue ASTERISK-22872)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/3052/


Modified:
    branches/12/main/http.c
    branches/12/res/ari/resource_channels.c
    branches/12/res/ari/resource_channels.h
    branches/12/res/res_ari_channels.c
    branches/12/rest-api/api-docs/channels.json

Modified: branches/12/main/http.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/main/http.c?view=diff&rev=403752&r1=403751&r2=403752
==============================================================================
--- branches/12/main/http.c (original)
+++ branches/12/main/http.c Fri Dec 13 11:17:48 2013
@@ -608,18 +608,30 @@
 
 #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;
-		}
-	}
-
-	/* Missing content type; assume empty string */
-	return "";
+			const char *param = strchr(v->value, ';');
+			size_t size = (param ? param - v->value :
+				       strlen(v->value)) + 1;
+			return ast_strndup(v->value, size);
+		}
+	}
+
+	return NULL;
 }
 
 static int get_content_length(struct ast_variable *headers)
@@ -643,11 +655,12 @@
 	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;
 	}
@@ -704,12 +717,14 @@
 	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;
 	}

Modified: branches/12/res/ari/resource_channels.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari/resource_channels.c?view=diff&rev=403752&r1=403751&r2=403752
==============================================================================
--- branches/12/res/ari/resource_channels.c (original)
+++ branches/12/res/ari/resource_channels.c Fri Dec 13 11:17:48 2013
@@ -688,6 +688,43 @@
 	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)
@@ -768,6 +805,11 @@
 		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);
 
@@ -917,4 +959,4 @@
 
 	snapshot = ast_channel_snapshot_create(snoop);
 	ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL));
-}
+}

Modified: branches/12/res/ari/resource_channels.h
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/ari/resource_channels.h?view=diff&rev=403752&r1=403751&r2=403752
==============================================================================
--- branches/12/res/ari/resource_channels.h (original)
+++ branches/12/res/ari/resource_channels.h Fri Dec 13 11:17:48 2013
@@ -68,6 +68,8 @@
 	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).

Modified: branches/12/res/res_ari_channels.c
URL: http://svnview.digium.com/svn/asterisk/branches/12/res/res_ari_channels.c?view=diff&rev=403752&r1=403751&r2=403752
==============================================================================
--- branches/12/res/res_ari_channels.c (original)
+++ branches/12/res/res_ari_channels.c Fri Dec 13 11:17:48 2013
@@ -117,7 +117,6 @@
 	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;
@@ -165,39 +164,7 @@
 			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;

Modified: branches/12/rest-api/api-docs/channels.json
URL: http://svnview.digium.com/svn/asterisk/branches/12/rest-api/api-docs/channels.json?view=diff&rev=403752&r1=403751&r2=403752
==============================================================================
--- branches/12/rest-api/api-docs/channels.json (original)
+++ branches/12/rest-api/api-docs/channels.json Fri Dec 13 11:17:48 2013
@@ -88,6 +88,14 @@
 							"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": [




More information about the asterisk-commits mailing list