summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/asterisk/ari.h9
-rw-r--r--include/asterisk/http.h12
-rw-r--r--main/http.c103
-rw-r--r--res/res_ari.c2
-rw-r--r--res/res_ari_applications.c104
-rw-r--r--res/res_ari_asterisk.c100
-rw-r--r--res/res_ari_bridges.c240
-rw-r--r--res/res_ari_channels.c400
-rw-r--r--res/res_ari_device_states.c29
-rw-r--r--res/res_ari_endpoints.c6
-rw-r--r--res/res_ari_playbacks.c27
-rw-r--r--res/res_ari_recordings.c20
-rw-r--r--res/res_ari_sounds.c29
-rw-r--r--rest-api-templates/asterisk_processor.py26
-rw-r--r--rest-api-templates/param_parsing.mustache63
-rw-r--r--rest-api-templates/res_ari_resource.c.mustache7
-rw-r--r--rest-api-templates/swagger_model.py13
-rw-r--r--tests/test_ari.c9
18 files changed, 1170 insertions, 29 deletions
diff --git a/include/asterisk/ari.h b/include/asterisk/ari.h
index dfeef513c..f5b76f8dc 100644
--- a/include/asterisk/ari.h
+++ b/include/asterisk/ari.h
@@ -50,15 +50,16 @@ struct ast_ari_response;
/*!
* \brief Callback type for RESTful method handlers.
+ * \param ser TCP/TLS session object
* \param get_params GET parameters from the HTTP request.
* \param path_vars Path variables from any wildcard path segments.
* \param headers HTTP headers from the HTTP requiest.
* \param[out] response The RESTful response.
*/
-typedef void (*stasis_rest_callback)(struct ast_variable *get_params,
- struct ast_variable *path_vars,
- struct ast_variable *headers,
- struct ast_ari_response *response);
+typedef void (*stasis_rest_callback)(
+ struct ast_tcptls_session_instance *ser,
+ struct ast_variable *get_params, struct ast_variable *path_vars,
+ struct ast_variable *headers, struct ast_ari_response *response);
/*!
* \brief Handler for a single RESTful path segment.
diff --git a/include/asterisk/http.h b/include/asterisk/http.h
index 59e185a6f..0642cfa9b 100644
--- a/include/asterisk/http.h
+++ b/include/asterisk/http.h
@@ -212,5 +212,17 @@ void ast_http_prefix(char *buf, int len);
*/
struct ast_variable *ast_http_get_post_vars(struct ast_tcptls_session_instance *ser, struct ast_variable *headers);
+struct ast_json;
+
+/*!\brief Get JSON from client Request Entity-Body, if content type is
+ * application/json.
+ * \param ser TCP/TLS session object
+ * \param headers List of HTTP headers
+ * \return Parsed JSON content body
+ * \return \c NULL on error, if no content, or if different content type.
+ * \since 12
+ */
+struct ast_json *ast_http_get_json(
+ struct ast_tcptls_session_instance *ser, struct ast_variable *headers);
#endif /* _ASTERISK_SRV_H */
diff --git a/main/http.c b/main/http.c
index a9c8a3564..0c9b09a90 100644
--- a/main/http.c
+++ b/main/http.c
@@ -65,6 +65,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/_private.h"
#include "asterisk/astobj2.h"
#include "asterisk/netsock2.h"
+#include "asterisk/json.h"
#define MAX_PREFIX 80
#define DEFAULT_PORT 8088
@@ -607,6 +608,91 @@ void ast_http_uri_unlink_all_with_key(const char *key)
#define MAX_POST_CONTENT 1025
+static const 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 "";
+}
+
+static int get_content_length(struct ast_variable *headers)
+{
+ struct ast_variable *v;
+
+ for (v = headers; v; v = v->next) {
+ if (!strcasecmp(v->name, "Content-Length")) {
+ return atoi(v->value);
+ }
+ }
+
+ /* Missing content length; assume zero */
+ return 0;
+}
+
+struct ast_json *ast_http_get_json(
+ struct ast_tcptls_session_instance *ser, struct ast_variable *headers)
+{
+ int content_length = 0;
+ int res;
+ struct ast_json *body;
+ RAII_VAR(char *, buf, NULL, ast_free);
+
+ /* Use errno to distinguish errors from no body */
+ errno = 0;
+
+ if (strcasecmp(get_content_type(headers), "application/json") != 0) {
+ /* Content type is not JSON */
+ return NULL;
+ }
+
+ content_length = get_content_length(headers);
+
+ if (content_length <= 0) {
+ /* No content (or streaming content). */
+ return NULL;
+ }
+
+ if (content_length > MAX_POST_CONTENT - 1) {
+ ast_log(LOG_WARNING,
+ "Excessively long HTTP content. (%d > %d)\n",
+ content_length, MAX_POST_CONTENT);
+ errno = EFBIG;
+ return NULL;
+ }
+
+ buf = ast_malloc(content_length);
+ if (!buf) {
+ /* Malloc sets ENOMEM */
+ return NULL;
+ }
+
+ res = fread(buf, 1, content_length, ser->f);
+ if (res < content_length) {
+ /* Error, distinguishable by ferror() or feof(), but neither
+ * is good. Treat either one as I/O error */
+ ast_log(LOG_WARNING, "Short HTTP request body (%d < %d)\n",
+ res, content_length);
+ errno = EIO;
+ return NULL;
+ }
+
+ body = ast_json_load_buf(buf, content_length, NULL);
+ if (body == NULL) {
+ /* Failed to parse JSON; treat as an I/O error */
+ errno = EIO;
+ return NULL;
+ }
+
+ return body;
+}
+
/*
* get post variables from client Request Entity-Body, if content type is
* application/x-www-form-urlencoded
@@ -623,21 +709,12 @@ struct ast_variable *ast_http_get_post_vars(
/* Use errno to distinguish errors from no params */
errno = 0;
- for (v = headers; v; v = v->next) {
- if (!strcasecmp(v->name, "Content-Type")) {
- if (strcasecmp(v->value, "application/x-www-form-urlencoded")) {
- return NULL;
- }
- break;
- }
+ if (strcasecmp(get_content_type(headers), "application/x-www-form-urlencoded") != 0) {
+ /* Content type is not form data */
+ return NULL;
}
- for (v = headers; v; v = v->next) {
- if (!strcasecmp(v->name, "Content-Length")) {
- content_length = atoi(v->value);
- break;
- }
- }
+ content_length = get_content_length(headers);
if (content_length <= 0) {
return NULL;
diff --git a/res/res_ari.c b/res/res_ari.c
index 4ceb3847e..108f6c7e1 100644
--- a/res/res_ari.c
+++ b/res/res_ari.c
@@ -539,7 +539,7 @@ void ast_ari_invoke(struct ast_tcptls_session_instance *ser,
return;
}
- callback(get_params, path_vars, headers, response);
+ 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",
diff --git a/res/res_ari_applications.c b/res/res_ari_applications.c
index 565e3a7ab..1f021c41d 100644
--- a/res/res_ari_applications.c
+++ b/res/res_ari_applications.c
@@ -59,10 +59,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_applications_list_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_applications_list_args args = {};
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -108,11 +110,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_applications_get_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_applications_get_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -165,11 +169,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_applications_subscribe_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_applications_subscribe_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;
@@ -227,6 +234,53 @@ static void ast_ari_applications_subscribe_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "eventSource");
+ if (field) {
+ /* If they were silly enough to both pass in a query param and a
+ * JSON body, free up the query value.
+ */
+ ast_free(args.event_source);
+ if (ast_json_typeof(field) == AST_JSON_ARRAY) {
+ /* Multiple param passed as array */
+ size_t i;
+ args.event_source_count = ast_json_array_size(field);
+ args.event_source = ast_malloc(sizeof(*args.event_source) * args.event_source_count);
+
+ if (!args.event_source) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ for (i = 0; i < args.event_source_count; ++i) {
+ args.event_source[i] = ast_json_string_get(ast_json_array_get(field, i));
+ }
+ } else {
+ /* Multiple param passed as single value */
+ args.event_source_count = 1;
+ args.event_source = ast_malloc(sizeof(*args.event_source) * args.event_source_count);
+ if (!args.event_source) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+ args.event_source[0] = ast_json_string_get(field);
+ }
+ }
ast_ari_applications_subscribe(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -272,11 +326,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_applications_unsubscribe_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_applications_unsubscribe_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;
@@ -334,6 +391,53 @@ static void ast_ari_applications_unsubscribe_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "eventSource");
+ if (field) {
+ /* If they were silly enough to both pass in a query param and a
+ * JSON body, free up the query value.
+ */
+ ast_free(args.event_source);
+ if (ast_json_typeof(field) == AST_JSON_ARRAY) {
+ /* Multiple param passed as array */
+ size_t i;
+ args.event_source_count = ast_json_array_size(field);
+ args.event_source = ast_malloc(sizeof(*args.event_source) * args.event_source_count);
+
+ if (!args.event_source) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ for (i = 0; i < args.event_source_count; ++i) {
+ args.event_source[i] = ast_json_string_get(ast_json_array_get(field, i));
+ }
+ } else {
+ /* Multiple param passed as single value */
+ args.event_source_count = 1;
+ args.event_source = ast_malloc(sizeof(*args.event_source) * args.event_source_count);
+ if (!args.event_source) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+ args.event_source[0] = ast_json_string_get(field);
+ }
+ }
ast_ari_applications_unsubscribe(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
diff --git a/res/res_ari_asterisk.c b/res/res_ari_asterisk.c
index c83c2f6a3..6d561aca9 100644
--- a/res/res_ari_asterisk.c
+++ b/res/res_ari_asterisk.c
@@ -59,11 +59,14 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_asterisk_get_info_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_asterisk_get_info_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;
@@ -115,6 +118,53 @@ static void ast_ari_asterisk_get_info_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "only");
+ if (field) {
+ /* If they were silly enough to both pass in a query param and a
+ * JSON body, free up the query value.
+ */
+ ast_free(args.only);
+ if (ast_json_typeof(field) == AST_JSON_ARRAY) {
+ /* Multiple param passed as array */
+ size_t i;
+ args.only_count = ast_json_array_size(field);
+ args.only = ast_malloc(sizeof(*args.only) * args.only_count);
+
+ if (!args.only) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ for (i = 0; i < args.only_count; ++i) {
+ args.only[i] = ast_json_string_get(ast_json_array_get(field, i));
+ }
+ } else {
+ /* Multiple param passed as single value */
+ args.only_count = 1;
+ args.only = ast_malloc(sizeof(*args.only) * args.only_count);
+ if (!args.only) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+ args.only[0] = ast_json_string_get(field);
+ }
+ }
ast_ari_asterisk_get_info(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -157,11 +207,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_asterisk_get_global_var_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_asterisk_get_global_var_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;
@@ -173,6 +226,26 @@ static void ast_ari_asterisk_get_global_var_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "variable");
+ if (field) {
+ args.variable = ast_json_string_get(field);
+ }
ast_ari_asterisk_get_global_var(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -214,11 +287,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_asterisk_set_global_var_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_asterisk_set_global_var_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;
@@ -233,6 +309,30 @@ static void ast_ari_asterisk_set_global_var_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "variable");
+ if (field) {
+ args.variable = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "value");
+ if (field) {
+ args.value = ast_json_string_get(field);
+ }
ast_ari_asterisk_set_global_var(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
diff --git a/res/res_ari_bridges.c b/res/res_ari_bridges.c
index 3020c4a62..f72a72805 100644
--- a/res/res_ari_bridges.c
+++ b/res/res_ari_bridges.c
@@ -59,10 +59,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_bridges_list_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_bridges_list_args args = {};
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -108,11 +110,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_bridges_create_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_bridges_create_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;
@@ -124,6 +129,26 @@ static void ast_ari_bridges_create_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "type");
+ if (field) {
+ args.type = ast_json_string_get(field);
+ }
ast_ari_bridges_create(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -164,11 +189,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_bridges_get_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_bridges_get_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -221,11 +248,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_bridges_destroy_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_bridges_destroy_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -278,11 +307,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_bridges_add_channel_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_bridges_add_channel_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;
@@ -343,6 +375,57 @@ static void ast_ari_bridges_add_channel_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "channel");
+ if (field) {
+ /* If they were silly enough to both pass in a query param and a
+ * JSON body, free up the query value.
+ */
+ ast_free(args.channel);
+ if (ast_json_typeof(field) == AST_JSON_ARRAY) {
+ /* Multiple param passed as array */
+ size_t i;
+ args.channel_count = ast_json_array_size(field);
+ args.channel = ast_malloc(sizeof(*args.channel) * args.channel_count);
+
+ if (!args.channel) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ for (i = 0; i < args.channel_count; ++i) {
+ args.channel[i] = ast_json_string_get(ast_json_array_get(field, i));
+ }
+ } else {
+ /* Multiple param passed as single value */
+ args.channel_count = 1;
+ args.channel = ast_malloc(sizeof(*args.channel) * args.channel_count);
+ if (!args.channel) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+ args.channel[0] = ast_json_string_get(field);
+ }
+ }
+ field = ast_json_object_get(body, "role");
+ if (field) {
+ args.role = ast_json_string_get(field);
+ }
ast_ari_bridges_add_channel(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -389,11 +472,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_bridges_remove_channel_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_bridges_remove_channel_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;
@@ -451,6 +537,53 @@ static void ast_ari_bridges_remove_channel_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "channel");
+ if (field) {
+ /* If they were silly enough to both pass in a query param and a
+ * JSON body, free up the query value.
+ */
+ ast_free(args.channel);
+ if (ast_json_typeof(field) == AST_JSON_ARRAY) {
+ /* Multiple param passed as array */
+ size_t i;
+ args.channel_count = ast_json_array_size(field);
+ args.channel = ast_malloc(sizeof(*args.channel) * args.channel_count);
+
+ if (!args.channel) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ for (i = 0; i < args.channel_count; ++i) {
+ args.channel[i] = ast_json_string_get(ast_json_array_get(field, i));
+ }
+ } else {
+ /* Multiple param passed as single value */
+ args.channel_count = 1;
+ args.channel = ast_malloc(sizeof(*args.channel) * args.channel_count);
+ if (!args.channel) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+ args.channel[0] = ast_json_string_get(field);
+ }
+ }
ast_ari_bridges_remove_channel(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -497,11 +630,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_bridges_start_moh_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_bridges_start_moh_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;
@@ -519,6 +655,26 @@ static void ast_ari_bridges_start_moh_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "mohClass");
+ if (field) {
+ args.moh_class = ast_json_string_get(field);
+ }
ast_ari_bridges_start_moh(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -561,11 +717,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_bridges_stop_moh_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_bridges_stop_moh_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -619,11 +777,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_bridges_play_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_bridges_play_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;
@@ -650,6 +811,38 @@ static void ast_ari_bridges_play_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "media");
+ if (field) {
+ args.media = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "lang");
+ if (field) {
+ args.lang = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "offsetms");
+ if (field) {
+ args.offsetms = ast_json_integer_get(field);
+ }
+ field = ast_json_object_get(body, "skipms");
+ if (field) {
+ args.skipms = ast_json_integer_get(field);
+ }
ast_ari_bridges_play(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -692,11 +885,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_bridges_record_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_bridges_record_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;
@@ -732,6 +928,50 @@ static void ast_ari_bridges_record_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "name");
+ if (field) {
+ args.name = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "format");
+ if (field) {
+ args.format = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "maxDurationSeconds");
+ if (field) {
+ args.max_duration_seconds = ast_json_integer_get(field);
+ }
+ field = ast_json_object_get(body, "maxSilenceSeconds");
+ if (field) {
+ args.max_silence_seconds = ast_json_integer_get(field);
+ }
+ field = ast_json_object_get(body, "ifExists");
+ if (field) {
+ args.if_exists = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "beep");
+ if (field) {
+ args.beep = ast_json_is_true(field);
+ }
+ field = ast_json_object_get(body, "terminateOn");
+ if (field) {
+ args.terminate_on = ast_json_string_get(field);
+ }
ast_ari_bridges_record(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
diff --git a/res/res_ari_channels.c b/res/res_ari_channels.c
index 7e7da356f..40ad32b2b 100644
--- a/res/res_ari_channels.c
+++ b/res/res_ari_channels.c
@@ -59,10 +59,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_list_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_list_args args = {};
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -108,11 +110,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_originate_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
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;
@@ -145,6 +150,54 @@ static void ast_ari_channels_originate_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ 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);
+ }
ast_ari_channels_originate(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -186,11 +239,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_get_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_get_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -243,11 +298,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_hangup_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_hangup_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;
@@ -265,6 +323,26 @@ static void ast_ari_channels_hangup_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "reason");
+ if (field) {
+ args.reason = ast_json_string_get(field);
+ }
ast_ari_channels_hangup(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -307,11 +385,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_continue_in_dialplan_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_continue_in_dialplan_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;
@@ -335,6 +416,34 @@ static void ast_ari_channels_continue_in_dialplan_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "context");
+ if (field) {
+ args.context = 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, "priority");
+ if (field) {
+ args.priority = ast_json_integer_get(field);
+ }
ast_ari_channels_continue_in_dialplan(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -377,11 +486,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_answer_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_answer_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -435,11 +546,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_ring_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_ring_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -493,11 +606,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_ring_stop_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_ring_stop_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -551,11 +666,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_send_dtmf_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_send_dtmf_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;
@@ -585,6 +703,42 @@ static void ast_ari_channels_send_dtmf_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "dtmf");
+ if (field) {
+ args.dtmf = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "before");
+ if (field) {
+ args.before = ast_json_integer_get(field);
+ }
+ field = ast_json_object_get(body, "between");
+ if (field) {
+ args.between = ast_json_integer_get(field);
+ }
+ field = ast_json_object_get(body, "duration");
+ if (field) {
+ args.duration = ast_json_integer_get(field);
+ }
+ field = ast_json_object_get(body, "after");
+ if (field) {
+ args.after = ast_json_integer_get(field);
+ }
ast_ari_channels_send_dtmf(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -628,11 +782,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_mute_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_mute_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;
@@ -650,6 +807,26 @@ static void ast_ari_channels_mute_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "direction");
+ if (field) {
+ args.direction = ast_json_string_get(field);
+ }
ast_ari_channels_mute(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -692,11 +869,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_unmute_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_unmute_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;
@@ -714,6 +894,26 @@ static void ast_ari_channels_unmute_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "direction");
+ if (field) {
+ args.direction = ast_json_string_get(field);
+ }
ast_ari_channels_unmute(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -756,11 +956,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_hold_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_hold_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -814,11 +1016,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_unhold_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_unhold_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -872,11 +1076,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_start_moh_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_start_moh_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;
@@ -894,6 +1101,26 @@ static void ast_ari_channels_start_moh_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "mohClass");
+ if (field) {
+ args.moh_class = ast_json_string_get(field);
+ }
ast_ari_channels_start_moh(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -936,11 +1163,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_stop_moh_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_stop_moh_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -994,11 +1223,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_start_silence_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_start_silence_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1052,11 +1283,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_stop_silence_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_stop_silence_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1110,11 +1343,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_play_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_play_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;
@@ -1141,6 +1377,38 @@ static void ast_ari_channels_play_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "media");
+ if (field) {
+ args.media = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "lang");
+ if (field) {
+ args.lang = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "offsetms");
+ if (field) {
+ args.offsetms = ast_json_integer_get(field);
+ }
+ field = ast_json_object_get(body, "skipms");
+ if (field) {
+ args.skipms = ast_json_integer_get(field);
+ }
ast_ari_channels_play(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -1183,11 +1451,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_record_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_record_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;
@@ -1223,6 +1494,50 @@ static void ast_ari_channels_record_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "name");
+ if (field) {
+ args.name = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "format");
+ if (field) {
+ args.format = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "maxDurationSeconds");
+ if (field) {
+ args.max_duration_seconds = ast_json_integer_get(field);
+ }
+ field = ast_json_object_get(body, "maxSilenceSeconds");
+ if (field) {
+ args.max_silence_seconds = ast_json_integer_get(field);
+ }
+ field = ast_json_object_get(body, "ifExists");
+ if (field) {
+ args.if_exists = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "beep");
+ if (field) {
+ args.beep = ast_json_is_true(field);
+ }
+ field = ast_json_object_get(body, "terminateOn");
+ if (field) {
+ args.terminate_on = ast_json_string_get(field);
+ }
ast_ari_channels_record(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -1267,11 +1582,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_get_channel_var_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_get_channel_var_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;
@@ -1289,6 +1607,26 @@ static void ast_ari_channels_get_channel_var_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "variable");
+ if (field) {
+ args.variable = ast_json_string_get(field);
+ }
ast_ari_channels_get_channel_var(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -1332,11 +1670,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_set_channel_var_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_set_channel_var_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;
@@ -1357,6 +1698,30 @@ static void ast_ari_channels_set_channel_var_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "variable");
+ if (field) {
+ args.variable = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "value");
+ if (field) {
+ args.value = ast_json_string_get(field);
+ }
ast_ari_channels_set_channel_var(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -1400,11 +1765,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_channels_snoop_channel_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_channels_snoop_channel_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;
@@ -1431,6 +1799,38 @@ static void ast_ari_channels_snoop_channel_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "spy");
+ if (field) {
+ args.spy = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "whisper");
+ if (field) {
+ args.whisper = ast_json_string_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);
+ }
ast_ari_channels_snoop_channel(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
diff --git a/res/res_ari_device_states.c b/res/res_ari_device_states.c
index 07f51ba3e..a8079f139 100644
--- a/res/res_ari_device_states.c
+++ b/res/res_ari_device_states.c
@@ -59,10 +59,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_device_states_list_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_device_states_list_args args = {};
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -108,11 +110,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_device_states_get_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_device_states_get_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -164,11 +168,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_device_states_update_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_device_states_update_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;
@@ -186,6 +193,26 @@ static void ast_ari_device_states_update_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "deviceState");
+ if (field) {
+ args.device_state = ast_json_string_get(field);
+ }
ast_ari_device_states_update(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -228,11 +255,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_device_states_delete_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_device_states_delete_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
diff --git a/res/res_ari_endpoints.c b/res/res_ari_endpoints.c
index 10accb968..f7995ef4d 100644
--- a/res/res_ari_endpoints.c
+++ b/res/res_ari_endpoints.c
@@ -59,10 +59,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_endpoints_list_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_endpoints_list_args args = {};
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -108,11 +110,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_endpoints_list_by_tech_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_endpoints_list_by_tech_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -165,11 +169,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_endpoints_get_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_endpoints_get_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
diff --git a/res/res_ari_playbacks.c b/res/res_ari_playbacks.c
index 5b6dc919b..429f00dc2 100644
--- a/res/res_ari_playbacks.c
+++ b/res/res_ari_playbacks.c
@@ -59,11 +59,13 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_playbacks_get_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_playbacks_get_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -116,11 +118,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_playbacks_stop_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_playbacks_stop_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -173,11 +177,14 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_playbacks_control_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_playbacks_control_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;
@@ -195,6 +202,26 @@ static void ast_ari_playbacks_control_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "operation");
+ if (field) {
+ args.operation = ast_json_string_get(field);
+ }
ast_ari_playbacks_control(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
diff --git a/res/res_ari_recordings.c b/res/res_ari_recordings.c
index 3a4afdc71..56fb9ecca 100644
--- a/res/res_ari_recordings.c
+++ b/res/res_ari_recordings.c
@@ -59,10 +59,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_recordings_list_stored_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_recordings_list_stored_args args = {};
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -108,11 +110,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_recordings_get_stored_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_recordings_get_stored_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -165,11 +169,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_recordings_delete_stored_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_recordings_delete_stored_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -222,11 +228,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_recordings_get_live_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_recordings_get_live_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -279,11 +287,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_recordings_cancel_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_recordings_cancel_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -336,11 +346,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_recordings_stop_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_recordings_stop_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -393,11 +405,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_recordings_pause_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_recordings_pause_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -451,11 +465,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_recordings_unpause_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_recordings_unpause_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -509,11 +525,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_recordings_mute_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_recordings_mute_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -567,11 +585,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_recordings_unmute_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_recordings_unmute_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
diff --git a/res/res_ari_sounds.c b/res/res_ari_sounds.c
index 62a34364e..a3657d13b 100644
--- a/res/res_ari_sounds.c
+++ b/res/res_ari_sounds.c
@@ -59,11 +59,14 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_sounds_list_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_sounds_list_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;
@@ -78,6 +81,30 @@ static void ast_ari_sounds_list_cb(
} else
{}
}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "lang");
+ if (field) {
+ args.lang = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "format");
+ if (field) {
+ args.format = ast_json_string_get(field);
+ }
ast_ari_sounds_list(headers, &args, response);
#if defined(AST_DEVMODE)
code = response->response_code;
@@ -118,11 +145,13 @@ fin: __attribute__((unused))
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_sounds_get_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
struct ast_ari_sounds_get_args args = {};
struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
diff --git a/rest-api-templates/asterisk_processor.py b/rest-api-templates/asterisk_processor.py
index 18044f57e..7eb5bff6f 100644
--- a/rest-api-templates/asterisk_processor.py
+++ b/rest-api-templates/asterisk_processor.py
@@ -146,6 +146,15 @@ class AsteriskProcessor(SwaggerPostProcessor):
'boolean': 'ast_true',
}
+ #: JSON conversion functions
+ json_convert_mapping = {
+ 'string': 'ast_json_string_get',
+ 'int': 'ast_json_integer_get',
+ 'long': 'ast_json_integer_get',
+ 'double': 'ast_json_real_get',
+ 'boolean': 'ast_json_is_true',
+ }
+
def __init__(self, wiki_prefix):
self.wiki_prefix = wiki_prefix
@@ -190,15 +199,22 @@ class AsteriskProcessor(SwaggerPostProcessor):
raise SwaggerError("Summary should end with .", context)
operation.wiki_summary = wikify(operation.summary or "")
operation.wiki_notes = wikify(operation.notes or "")
+ operation.parse_body = (operation.body_parameter or operation.has_query_parameters) and True
def process_parameter(self, parameter, context):
- if not parameter.data_type in self.type_mapping:
- raise SwaggerError(
- "Invalid parameter type %s" % parameter.data_type, context)
+ if parameter.param_type == 'body':
+ parameter.c_data_type = 'struct ast_json *'
+ else:
+ if not parameter.data_type in self.type_mapping:
+ raise SwaggerError(
+ "Invalid parameter type %s" % parameter.data_type, context)
+ # Type conversions
+ parameter.c_data_type = self.type_mapping[parameter.data_type]
+ parameter.c_convert = self.convert_mapping[parameter.data_type]
+ parameter.json_convert = self.json_convert_mapping[parameter.data_type]
+
# Parameter names are camelcase, Asterisk convention is snake case
parameter.c_name = snakify(parameter.name)
- parameter.c_data_type = self.type_mapping[parameter.data_type]
- parameter.c_convert = self.convert_mapping[parameter.data_type]
# You shouldn't put a space between 'char *' and the variable
if parameter.c_data_type.endswith('*'):
parameter.c_space = ''
diff --git a/rest-api-templates/param_parsing.mustache b/rest-api-templates/param_parsing.mustache
index aabd728fd..9d2073869 100644
--- a/rest-api-templates/param_parsing.mustache
+++ b/rest-api-templates/param_parsing.mustache
@@ -83,3 +83,66 @@
{}
}
{{/has_path_parameters}}
+{{^is_websocket}}
+{{#parse_body}}
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+{{#body_parameter}}
+ args.{{c_name}} = ast_json_ref(body);
+{{/body_parameter}}
+{{^body_parameter}}
+ /* Parse query parameters out of it */
+{{#query_parameters}}
+ field = ast_json_object_get(body, "{{name}}");
+ if (field) {
+{{^allow_multiple}}
+ args.{{c_name}} = {{json_convert}}(field);
+{{/allow_multiple}}
+{{#allow_multiple}}
+ /* If they were silly enough to both pass in a query param and a
+ * JSON body, free up the query value.
+ */
+ ast_free(args.{{c_name}});
+ if (ast_json_typeof(field) == AST_JSON_ARRAY) {
+ /* Multiple param passed as array */
+ size_t i;
+ args.{{c_name}}_count = ast_json_array_size(field);
+ args.{{c_name}} = ast_malloc(sizeof(*args.{{c_name}}) * args.{{c_name}}_count);
+
+ if (!args.{{c_name}}) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+
+ for (i = 0; i < args.{{c_name}}_count; ++i) {
+ args.{{c_name}}[i] = {{json_convert}}(ast_json_array_get(field, i));
+ }
+ } else {
+ /* Multiple param passed as single value */
+ args.{{c_name}}_count = 1;
+ args.{{c_name}} = ast_malloc(sizeof(*args.{{c_name}}) * args.{{c_name}}_count);
+ if (!args.{{c_name}}) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+ args.{{c_name}}[0] = {{json_convert}}(field);
+ }
+{{/allow_multiple}}
+ }
+{{/query_parameters}}
+{{/body_parameter}}
+{{/parse_body}}
+{{/is_websocket}}
diff --git a/rest-api-templates/res_ari_resource.c.mustache b/rest-api-templates/res_ari_resource.c.mustache
index 580ba1944..d2823a877 100644
--- a/rest-api-templates/res_ari_resource.c.mustache
+++ b/rest-api-templates/res_ari_resource.c.mustache
@@ -74,6 +74,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
* \param[out] response Response to the HTTP request.
*/
static void ast_ari_{{c_name}}_{{c_nickname}}_cb(
+ struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
struct ast_variable *headers, struct ast_ari_response *response)
{
@@ -81,6 +82,12 @@ static void ast_ari_{{c_name}}_{{c_nickname}}_cb(
{{#has_parameters}}
struct ast_variable *i;
{{/has_parameters}}
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
+{{^body_parameter}}
+{{#has_query_parameters}}
+ struct ast_json *field;
+{{/has_query_parameters}}
+{{/body_parameter}}
#if defined(AST_DEVMODE)
int is_valid;
int code;
diff --git a/rest-api-templates/swagger_model.py b/rest-api-templates/swagger_model.py
index 144f22bdb..01659d145 100644
--- a/rest-api-templates/swagger_model.py
+++ b/rest-api-templates/swagger_model.py
@@ -377,8 +377,9 @@ class Operation(Stringify):
if self.is_websocket:
self.websocket_protocol = op_json.get('websocketProtocol')
if self.http_method != 'GET':
- raise ValueError(
- "upgrade: websocket is only valid on GET operations")
+ raise SwaggerError(
+ "upgrade: websocket is only valid on GET operations",
+ context)
params_json = op_json.get('parameters') or []
self.parameters = [
@@ -394,6 +395,14 @@ class Operation(Stringify):
self.has_header_parameters = self.header_parameters and True
self.has_parameters = self.has_query_parameters or \
self.has_path_parameters or self.has_header_parameters
+
+ # Body param is different, since there's at most one
+ self.body_parameter = [
+ p for p in self.parameters if p.is_type('body')]
+ if len(self.body_parameter) > 1:
+ raise SwaggerError("Cannot have more than one body param", context)
+ self.body_parameter = self.body_parameter and self.body_parameter[0]
+
self.summary = op_json.get('summary')
self.notes = op_json.get('notes')
err_json = op_json.get('errorResponses') or []
diff --git a/tests/test_ari.c b/tests/test_ari.c
index f984c3d2d..fc74544af 100644
--- a/tests/test_ari.c
+++ b/tests/test_ari.c
@@ -95,10 +95,11 @@ static void handler(const char *name,
* Macro to reduce the handler definition boiler-plate.
*/
#define HANDLER(name, response_code) \
- static void name(struct ast_variable *get_params, \
- struct ast_variable *path_vars, \
- struct ast_variable *headers, \
- struct ast_ari_response *response) \
+ static void name(struct ast_tcptls_session_instance *ser, \
+ struct ast_variable *get_params, \
+ struct ast_variable *path_vars, \
+ struct ast_variable *headers, \
+ struct ast_ari_response *response) \
{ \
handler(#name, response_code, get_params, path_vars, headers, response); \
}