diff options
Diffstat (limited to 'res/res_ari_events.c')
-rw-r--r-- | res/res_ari_events.c | 110 |
1 files changed, 100 insertions, 10 deletions
diff --git a/res/res_ari_events.c b/res/res_ari_events.c index aea318d68..454233945 100644 --- a/res/res_ari_events.c +++ b/res/res_ari_events.c @@ -53,7 +53,92 @@ ASTERISK_REGISTER_FILE() #define MAX_VALS 128 -static void ast_ari_events_event_websocket_ws_cb(struct ast_websocket *ws_session, +static int ast_ari_events_event_websocket_ws_attempted_cb(struct ast_tcptls_session_instance *ser, struct ast_variable *get_params, struct ast_variable *headers) +{ + struct ast_ari_events_event_websocket_args args = {}; + int res = 0; + RAII_VAR(struct ast_ari_response *, response, NULL, ast_free); + struct ast_variable *i; + + response = ast_calloc(1, sizeof(*response)); + if (!response) { + ast_log(LOG_ERROR, "Failed to create response.\n"); + goto fin; + } + + for (i = get_params; i; i = i->next) { + if (strcmp(i->name, "app") == 0) { + /* Parse comma separated list */ + char *vals[MAX_VALS]; + size_t j; + + args.app_parse = ast_strdup(i->value); + if (!args.app_parse) { + ast_ari_response_alloc_failed(response); + goto fin; + } + + if (strlen(args.app_parse) == 0) { + /* ast_app_separate_args can't handle "" */ + args.app_count = 1; + vals[0] = args.app_parse; + } else { + args.app_count = ast_app_separate_args( + args.app_parse, ',', vals, + ARRAY_LEN(vals)); + } + + if (args.app_count == 0) { + ast_ari_response_alloc_failed(response); + goto fin; + } + + if (args.app_count >= MAX_VALS) { + ast_ari_response_error(response, 400, + "Bad Request", + "Too many values for app"); + goto fin; + } + + args.app = ast_malloc(sizeof(*args.app) * args.app_count); + if (!args.app) { + ast_ari_response_alloc_failed(response); + goto fin; + } + + for (j = 0; j < args.app_count; ++j) { + args.app[j] = (vals[j]); + } + } else + {} + } + + res = ast_ari_websocket_events_event_websocket_attempted(ser, headers, &args); + +fin: __attribute__((unused)) + if (!response) { + ast_http_error(ser, 500, "Server Error", "Memory allocation error"); + res = -1; + } else if (response->response_code != 0) { + /* Param parsing failure */ + RAII_VAR(char *, msg, NULL, ast_json_free); + if (response->message) { + msg = ast_json_dump_string(response->message); + } else { + ast_log(LOG_ERROR, "Missing response message\n"); + } + + if (msg) { + ast_http_error(ser, response->response_code, response->response_text, msg); + } + res = -1; + } + ast_free(args.app_parse); + ast_free(args.app); + return res; +} + +static void ast_ari_events_event_websocket_ws_established_cb(struct ast_websocket *ws_session, struct ast_variable *get_params, struct ast_variable *headers) { struct ast_ari_events_event_websocket_args args = {}; @@ -126,16 +211,11 @@ static void ast_ari_events_event_websocket_ws_cb(struct ast_websocket *ws_sessio {} } - ast_ari_websocket_events_event_websocket(session, headers, &args); + ast_ari_websocket_events_event_websocket_established(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_json_free); if (response->message) { msg = ast_json_dump_string(response->message); @@ -351,12 +431,22 @@ static struct stasis_rest_handlers events = { static int load_module(void) { int res = 0; + struct ast_websocket_protocol *protocol; + events.ws_server = ast_websocket_server_create(); if (!events.ws_server) { return AST_MODULE_LOAD_FAILURE; } - res |= ast_websocket_server_add_protocol(events.ws_server, - "ari", ast_ari_events_event_websocket_ws_cb); + + protocol = ast_websocket_sub_protocol_alloc("ari"); + if (!protocol) { + ao2_ref(events.ws_server, -1); + events.ws_server = NULL; + return AST_MODULE_LOAD_FAILURE; + } + protocol->session_attempted = ast_ari_events_event_websocket_ws_attempted_cb; + protocol->session_established = ast_ari_events_event_websocket_ws_established_cb; + res |= ast_websocket_server_add_protocol2(events.ws_server, protocol); stasis_app_ref(); res |= ast_ari_add_handler(&events); return res; @@ -376,4 +466,4 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Web .load = load_module, .unload = unload_module, .nonoptreq = "res_ari,res_stasis", - ); +); |