diff options
Diffstat (limited to 'rest-api-templates')
-rw-r--r-- | rest-api-templates/ari_resource.h.mustache | 12 | ||||
-rw-r--r-- | rest-api-templates/param_cleanup.mustache | 26 | ||||
-rw-r--r-- | rest-api-templates/param_parsing.mustache | 42 | ||||
-rw-r--r-- | rest-api-templates/res_ari_resource.c.mustache | 50 |
4 files changed, 123 insertions, 7 deletions
diff --git a/rest-api-templates/ari_resource.h.mustache b/rest-api-templates/ari_resource.h.mustache index 6396e2b73..8b4b0acec 100644 --- a/rest-api-templates/ari_resource.h.mustache +++ b/rest-api-templates/ari_resource.h.mustache @@ -44,9 +44,21 @@ struct ast_{{c_nickname}}_args { {{#parameters}} {{#description}} +{{/description}} +{{^allow_multiple}} +{{#description}} /*! \brief {{{description}}} */ {{/description}} {{c_data_type}}{{c_space}}{{c_name}}; +{{/allow_multiple}} +{{#allow_multiple}} + /*! \brief Array of {{{description}}} */ + {{c_data_type}}{{c_space}}*{{c_name}}; + /*! \brief Length of {{c_name}} array. */ + size_t {{c_name}}_count; + /*! \brief Parsing context for {{c_name}}. */ + char *{{c_name}}_parse; +{{/allow_multiple}} {{/parameters}} }; {{#is_req}} diff --git a/rest-api-templates/param_cleanup.mustache b/rest-api-templates/param_cleanup.mustache new file mode 100644 index 000000000..46edb417c --- /dev/null +++ b/rest-api-templates/param_cleanup.mustache @@ -0,0 +1,26 @@ +{{! + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2013, Digium, Inc. + * + * David M. Lee, II <dlee@digium.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. +}} +{{! + * Snippet for cleaning up an _args struct. +}} +{{#query_parameters}} +{{#allow_multiple}} + ast_free(args.{{c_name}}_parse); + ast_free(args.{{c_name}}); +{{/allow_multiple}} +{{/query_parameters}} diff --git a/rest-api-templates/param_parsing.mustache b/rest-api-templates/param_parsing.mustache index d43dcdce2..59c59e958 100644 --- a/rest-api-templates/param_parsing.mustache +++ b/rest-api-templates/param_parsing.mustache @@ -18,15 +18,48 @@ {{! * Snippet for decoding parameters into an _args struct. }} - struct ast_{{c_nickname}}_args args = {}; -{{#has_parameters}} - struct ast_variable *i; - {{#has_query_parameters}} for (i = get_params; i; i = i->next) { {{#query_parameters}} if (strcmp(i->name, "{{name}}") == 0) { +{{^allow_multiple}} args.{{c_name}} = {{c_convert}}(i->value); +{{/allow_multiple}} +{{#allow_multiple}} + /* Parse comma separated list */ + char *vals[MAX_VALS]; + size_t j; + + args.{{c_name}}_parse = ast_strdup(i->value); + if (!args.{{c_name}}_parse) { + ast_ari_response_alloc_failed(response); + goto fin; + } + + args.{{c_name}}_count = ast_app_separate_args( + args.{{c_name}}_parse, ',', vals, ARRAY_LEN(vals)); + if (args.{{c_name}}_count == 0) { + ast_ari_response_alloc_failed(response); + goto fin; + } + + if (args.{{c_name}}_count >= MAX_VALS) { + ast_ari_response_error(response, 400, + "Bad Request", + "Too many values for {{c_name}}"); + goto fin; + } + + 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 (j = 0; j < args.{{c_name}}_count; ++j) { + args.{{c_name}}[j] = {{c_convert}}(vals[j]); + } +{{/allow_multiple}} } else {{/query_parameters}} {} @@ -42,4 +75,3 @@ {} } {{/has_path_parameters}} -{{/has_parameters}} diff --git a/rest-api-templates/res_ari_resource.c.mustache b/rest-api-templates/res_ari_resource.c.mustache index 4f1986c7d..906d55f0d 100644 --- a/rest-api-templates/res_ari_resource.c.mustache +++ b/rest-api-templates/res_ari_resource.c.mustache @@ -46,6 +46,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") +#include "asterisk/app.h" #include "asterisk/module.h" #include "asterisk/stasis_app.h" #include "ari/resource_{{name}}.h" @@ -53,6 +54,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "ari/ari_model_validators.h" #endif +#define MAX_VALS 128 + {{#apis}} {{#operations}} {{#is_req}} @@ -67,6 +70,10 @@ static void ast_ari_{{c_nickname}}_cb( struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_ari_response *response) { + struct ast_{{c_nickname}}_args args = {}; +{{#has_parameters}} + struct ast_variable *i; +{{/has_parameters}} #if defined(AST_DEVMODE) int is_valid; int code; @@ -112,12 +119,21 @@ static void ast_ari_{{c_nickname}}_cb( "Internal Server Error", "Response validation failed"); } #endif /* AST_DEVMODE */ + +fin: __attribute__((unused)) +{{> param_cleanup}} + return; } {{/is_req}} {{#is_websocket}} static void ast_ari_{{c_nickname}}_ws_cb(struct ast_websocket *ws_session, struct ast_variable *get_params, struct ast_variable *headers) { + struct ast_{{c_nickname}}_args args = {}; +{{#has_parameters}} + RAII_VAR(struct ast_ari_response *, response, NULL, ast_free); + struct ast_variable *i; +{{/has_parameters}} RAII_VAR(struct ast_websocket *, s, ws_session, ast_websocket_unref); RAII_VAR(struct ast_ari_websocket_session *, session, NULL, ao2_cleanup); {{#has_path_parameters}} @@ -126,7 +142,15 @@ static void ast_ari_{{c_nickname}}_ws_cb(struct ast_websocket *ws_session, * just punt. */ struct ast_variable *path_vars = NULL; {{/has_path_parameters}} -{{> param_parsing}} + +{{#has_parameters}} + response = ast_calloc(1, sizeof(*response)); + if (!response) { + ast_log(LOG_ERROR, "Failed to create response.\n"); + goto fin; + } +{{/has_parameters}} + #if defined(AST_DEVMODE) session = ast_ari_websocket_session_create(ws_session, ast_ari_validate_{{response_class.c_name}}_fn()); @@ -135,9 +159,31 @@ static void ast_ari_{{c_nickname}}_ws_cb(struct ast_websocket *ws_session, #endif if (!session) { ast_log(LOG_ERROR, "Failed to create ARI session\n"); - return; + goto fin; } + +{{> param_parsing}} + ast_ari_websocket_{{c_nickname}}(session, headers, &args); + +fin: __attribute__((unused)) + if (response && response->response_code != 0) { + /* Param parsing failure */ + /* TODO - ideally, this would return the error code to the + * HTTP client; but we've already done the WebSocket + * negotiation. Param parsing should happen earlier, but we + * need a way to pass it through the WebSocket code to the + * callback */ + RAII_VAR(char *, msg, NULL, ast_free); + if (response->message) { + msg = ast_json_dump_string(response->message); + } else { + msg = ast_strdup("?"); + } + ast_websocket_write(ws_session, AST_WEBSOCKET_OPCODE_TEXT, msg, + strlen(msg)); + } +{{> param_cleanup}} } {{/is_websocket}} {{/operations}} |