Asterisk - The Open Source Telephony Project GIT-master-5467495
Loading...
Searching...
No Matches
Data Structures | Typedefs | Enumerations | Functions
ari.h File Reference

Asterisk RESTful API hooks. More...

#include "asterisk/http.h"
#include "asterisk/json.h"
Include dependency graph for ari.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ast_ari_response
 
struct  stasis_rest_handlers
 Handler for a single RESTful path segment. More...
 

Typedefs

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_json *body, struct ast_ari_response *response)
 Callback type for RESTful method handlers.
 

Enumerations

enum  ast_ari_invoke_result { ARI_INVOKE_RESULT_SUCCESS = 0 , ARI_INVOKE_RESULT_ERROR_CONTINUE = -1 , ARI_INVOKE_RESULT_ERROR_CLOSE = -2 }
 
enum  ast_ari_invoke_source { ARI_INVOKE_SOURCE_REST = 0 , ARI_INVOKE_SOURCE_WEBSOCKET , ARI_INVOKE_SOURCE_TEST }
 

Functions

int ast_ari_add_handler (struct stasis_rest_handlers *handler)
 
void ast_ari_close_per_call_websocket (char *app_id)
 Close a per-call outbound websocket connection.
 
char * ast_ari_create_per_call_websocket (const char *app_name, struct ast_channel *channel)
 Create a per-call outbound websocket connection.
 
void ast_ari_get_docs (const char *uri, const char *prefix, struct ast_variable *headers, struct ast_ari_response *response)
 
enum ast_ari_invoke_result ast_ari_invoke (struct ast_tcptls_session_instance *ser, enum ast_ari_invoke_source source, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
 
enum ast_json_encoding_format ast_ari_json_format (void)
 Configured encoding format for JSON output.
 
struct ast_jsonast_ari_oom_json (void)
 The stock message to return when out of memory.
 
int ast_ari_remove_handler (struct stasis_rest_handlers *handler)
 
void ast_ari_response_accepted (struct ast_ari_response *response)
 Fill in a Accepted (202) ast_ari_response.
 
void ast_ari_response_alloc_failed (struct ast_ari_response *response)
 Fill in response with a 500 message for allocation failures.
 
void ast_ari_response_created (struct ast_ari_response *response, const char *url, struct ast_json *message)
 Fill in a Created (201) ast_ari_response.
 
void ast_ari_response_error (struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
 Fill in an error ast_ari_response.
 
void ast_ari_response_no_content (struct ast_ari_response *response)
 Fill in a No Content (204) ast_ari_response.
 
void ast_ari_response_ok (struct ast_ari_response *response, struct ast_json *message)
 Fill in an OK (200) ast_ari_response.
 

Detailed Description

Asterisk RESTful API hooks.

This header file is used mostly as glue code between generated declarations and res_ari.c.

Author
David M. Lee, II dlee@.nosp@m.digi.nosp@m.um.co.nosp@m.m

Definition in file ari.h.

Typedef Documentation

◆ stasis_rest_callback

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_json *body, struct ast_ari_response *response)

Callback type for RESTful method handlers.

Parameters
serTCP/TLS session object (Maybe NULL if not available).
get_paramsGET parameters from the HTTP request.
path_varsPath variables from any wildcard path segments.
headersHTTP headers from the HTTP requiest.
body
[out]responseThe RESTful response.

Definition at line 60 of file ari.h.

Enumeration Type Documentation

◆ ast_ari_invoke_result

Enumerator
ARI_INVOKE_RESULT_SUCCESS 
ARI_INVOKE_RESULT_ERROR_CONTINUE 
ARI_INVOKE_RESULT_ERROR_CLOSE 

Definition at line 137 of file ari.h.

137 {
141};
@ ARI_INVOKE_RESULT_SUCCESS
Definition ari.h:138
@ ARI_INVOKE_RESULT_ERROR_CLOSE
Definition ari.h:140
@ ARI_INVOKE_RESULT_ERROR_CONTINUE
Definition ari.h:139

◆ ast_ari_invoke_source

Enumerator
ARI_INVOKE_SOURCE_REST 
ARI_INVOKE_SOURCE_WEBSOCKET 
ARI_INVOKE_SOURCE_TEST 

Definition at line 147 of file ari.h.

147 {
151};
@ ARI_INVOKE_SOURCE_REST
Definition ari.h:148
@ ARI_INVOKE_SOURCE_TEST
Definition ari.h:150
@ ARI_INVOKE_SOURCE_WEBSOCKET
Definition ari.h:149

Function Documentation

◆ ast_ari_add_handler()

int ast_ari_add_handler ( struct stasis_rest_handlers handler)

Add a resource for REST handling.

Parameters
handlerHandler to add.
Return values
0on success.
non-zeroon failure.

Definition at line 132 of file res_ari.c.

133{
134 RAII_VAR(struct stasis_rest_handlers *, new_handler, NULL, ao2_cleanup);
135 size_t old_size, new_size;
136
138
139 old_size = sizeof(*new_handler) + root_handler->num_children * sizeof(handler);
140 new_size = old_size + sizeof(handler);
141
142 new_handler = ao2_alloc(new_size, NULL);
143 if (!new_handler) {
144 return -1;
145 }
146 memcpy(new_handler, root_handler, old_size);
147 new_handler->children[new_handler->num_children++] = handler;
148
150 ao2_ref(new_handler, +1);
151 root_handler = new_handler;
152 return 0;
153}
ast_mutex_t lock
Definition app_sla.c:337
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
#define ao2_alloc(data_size, destructor_fn)
Definition astobj2.h:409
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition lock.h:596
static struct stasis_rest_handlers * root_handler
Definition res_ari.c:106
static ast_mutex_t root_handler_lock
Definition res_ari.c:103
#define NULL
Definition resample.c:96
Handler for a single RESTful path segment.
Definition ari.h:69
size_t num_children
Definition ari.h:93
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition test_ari.c:59
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition utils.h:981

References ao2_alloc, ao2_cleanup, ao2_ref, handler(), lock, NULL, stasis_rest_handlers::num_children, RAII_VAR, root_handler, root_handler_lock, and SCOPED_MUTEX.

Referenced by load_module(), load_module(), load_module(), load_module(), load_module(), load_module(), load_module(), load_module(), load_module(), load_module(), load_module(), and setup_invocation_test().

◆ ast_ari_close_per_call_websocket()

void ast_ari_close_per_call_websocket ( char *  app_name)

Close a per-call outbound websocket connection.

Parameters
app_idThe ephemeral application id returned by ast_ari_create_per_call_websocket().

This function should really only be called by app_stasis.

Note
This call will block until all messages for the channel have been sent or 5 seconds has elapsed. After that, the websocket will be closed.

Close a per-call outbound websocket connection.

Definition at line 1339 of file ari_websockets.c.

1340{
1341 struct ari_ws_session *session = NULL;
1342 pthread_t thread;
1343 struct timeval tv_start;
1344
1346 if (!session) {
1347 ast_debug(3, "%s: Per call websocket not found\n", app_name);
1349 return;
1350 }
1352
1353 /*
1354 * When stasis_app_exec() returns, the StasisEnd event for the
1355 * channel has been queued but since actually sending it is done
1356 * in a separate thread, it probably won't have been sent yet.
1357 * We need to wait for it to go out on the wire before we close the
1358 * websocket. ari_websocket_send_event will set a flag on the session
1359 * when a StasisEnd event is sent for the channel that originally
1360 * triggered the connection. We'll wait for that but we don't want
1361 * to wait forever so there's a fail-safe timeout in case a thread
1362 * got cancelled or we missed the StasisEnd event somehow.
1363 */
1364 ast_debug(3, "%s: Waiting for StasisEnd event to be sent RC: %d\n",
1365 session->session_id, (int)ao2_ref(session, 0));
1366
1367 tv_start = ast_tvnow();
1368 while (session->thread > 0 && !session->stasis_end_sent) {
1369 struct timeval tv_now = ast_tvnow();
1370 int64_t diff = ast_tvdiff_ms(tv_now, tv_start);
1371 ast_debug(3, "%s: Waiting for StasisEnd event %lu %d %ld\n",
1372 session->session_id, (unsigned long)session->thread,
1373 session->stasis_end_sent, diff);
1374 if (diff > STASIS_END_MAX_WAIT_MS) {
1375 break;
1376 }
1377 /* Sleep for 500ms before checking again. */
1378 usleep(500 * 1000);
1379 }
1380 ast_debug(3, "%s: StasisEnd event sent. Scheduling websocket close. RC: %d\n",
1381 session->session_id, (int)ao2_ref(session, 0));
1382
1383 /*
1384 * We can continue to send events like ChannelVarset and ChannelDestroyed
1385 * to the websocket after the StasisEnd event but those events won't be
1386 * generated until after the Stasis() dialplan app returns. We don't want
1387 * to hold up the dialplan while we wait so we'll create a thread that waits
1388 * a few seconds more before closing the websocket.
1389 *
1390 * We transferring ownership of the session to the thread.
1391 */
1394 ast_log(LOG_WARNING, "%s: Failed to create websocket close thread\n",
1395 session->session_id);
1397 }
1398 ast_debug(3, "%s: Scheduled websocket close RC: %d\n",
1399 session->session_id, (int)ao2_ref(session, 0));
1400
1401 return;
1402}
pthread_t thread
Definition app_sla.c:335
static struct ari_ws_session * session_find_by_app(const char *app_name, unsigned int ws_type)
static void session_unref(struct ari_ws_session *session)
#define STASIS_END_MAX_WAIT_MS
static void * outbound_session_pc_close_thread(void *data)
static struct ast_mansession session
#define ast_free(a)
Definition astmm.h:180
#define ast_log
Definition astobj2.c:42
@ AST_WS_TYPE_CLIENT_PER_CALL
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
const char * app_name(struct ast_app *app)
Definition pbx_app.c:475
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition time.h:107
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition time.h:159
#define ast_pthread_create_detached_background(a, b, c, d)
Definition utils.h:637

References ao2_ref, app_name(), ast_debug, ast_free, ast_log, ast_pthread_create_detached_background, ast_tvdiff_ms(), ast_tvnow(), AST_WS_TYPE_CLIENT_PER_CALL, LOG_WARNING, NULL, outbound_session_pc_close_thread(), session, session_find_by_app(), session_unref(), STASIS_END_MAX_WAIT_MS, and thread.

Referenced by app_exec().

◆ ast_ari_create_per_call_websocket()

char * ast_ari_create_per_call_websocket ( const char *  app_name,
struct ast_channel chan 
)

Create a per-call outbound websocket connection.

Parameters
app_nameThe app name.
channelThe channel to create the websocket for.

This function should really only be called by app_stasis.

A "per_call" websocket configuration must already exist in ari.conf that has 'app_name' in its 'apps' parameter.

The channel uniqueid is used to create a unique app_id composed of "<app_name>-<channel_uniqueid>" which will be returned from this call. This ID will be used to register an ephemeral Stasis application and should be used as the app_name for the call to stasis_app_exec(). When stasis_app_exec() returns, ast_ari_close_per_call_websocket() must be called with the app_id to close the websocket.

The channel unique id is also used to detect when the StasisEnd event is sent for the channel. It's how ast_ari_close_per_call_websocket() knows that all messages for the channel have been sent and it's safe to close the websocket.

Return values
Theephemeral application id or NULL if one could not be created. This pointer will be freed by ast_ari_close_per_call_websocket(). Do not free it yourself.

Create a per-call outbound websocket connection.

Definition at line 1201 of file ari_websockets.c.

1203{
1206 RAII_VAR(char *, session_id, NULL, ast_free);
1207 RAII_VAR(char *, app_id, NULL, ast_free);
1208 enum ari_conf_owc_fields invalid_fields;
1209 const char *owc_id = NULL;
1210 char *app_id_rtn = NULL;
1211 struct timeval tv_start;
1212 int res = 0;
1213
1215 if (!owc) {
1216 ast_log(LOG_WARNING, "%s: Failed to find outbound websocket per-call config for app '%s'\n",
1217 ast_channel_name(chan), app_name);
1218 return NULL;
1219 }
1220 owc_id = ast_sorcery_object_get_id(owc);
1221 invalid_fields = ari_conf_owc_get_invalid_fields(owc_id);
1222
1223 if (invalid_fields) {
1224 ast_log(LOG_WARNING, "%s: Unable to create per-call websocket. Outbound websocket config is invalid\n",
1225 owc_id);
1226 return NULL;
1227 }
1228
1229 res = ast_asprintf(&session_id, "%s:%s", owc_id, ast_channel_name(chan));
1230 if (res < 0) {
1231 return NULL;
1232 }
1233 res = ast_asprintf(&app_id, "%s:%s", app_name, ast_channel_name(chan));
1234 if (res < 0) {
1235 ast_free(app_id);
1236 return NULL;
1237 }
1238
1239 session = session_create(NULL, app_id, owc->subscribe_all,
1240 session_id, owc, AST_WS_TYPE_CLIENT_PER_CALL);
1241 if (!session) {
1242 ast_log(LOG_WARNING, "%s: Failed to create websocket session\n", session_id);
1243 return NULL;
1244 }
1245
1246 session->channel_id = ast_strdup(ast_channel_uniqueid(chan));
1247 session->channel_name = ast_strdup(ast_channel_name(chan));
1248
1249 /*
1250 * We have to bump the session reference count here because
1251 * we need to check that the session is connected before we return.
1252 * If it didn't connect, then the thread will have cleaned up the
1253 * session while we're in the loop checking for the connection
1254 * which will result in a SEGV or FRACK.
1255 * RAII will clean up this bump.
1256 */
1258 ast_debug(2, "%s: Starting thread RC: %d\n", session->session_id,
1259 (int)ao2_ref(session, 0));
1260
1264 ast_log(LOG_WARNING, "%s: Failed to create thread.\n", session->session_id);
1265 return NULL;
1266 }
1267
1268 /*
1269 * We need to make sure the session connected and is processing
1270 * requests before we return but we don't want to block forever
1271 * in case the thread never starts or gets cancelled so we have
1272 * a fail-safe timeout.
1273 */
1274 tv_start = ast_tvnow();
1275 while (session->thread > 0 && !session->connected) {
1276 struct timeval tv_now = ast_tvnow();
1277 if (ast_tvdiff_ms(tv_now, tv_start) > PER_CALL_FAIL_SAFE_TIMEOUT(owc)) {
1278 break;
1279 }
1280 /* Sleep for 500ms before checking again. */
1281 usleep(500 * 1000);
1282 }
1283
1284 if (session->thread <= 0 || !session->connected) {
1285 ast_log(LOG_WARNING, "%s: Failed to create per call websocket thread\n",
1286 session_id);
1287 return NULL;
1288 }
1289
1290 ast_debug(3, "%s: Created per call websocket for app '%s'\n",
1291 session_id, app_id);
1292
1293 /*
1294 * We now need to prevent RAII from freeing the app_id.
1295 */
1296 app_id_rtn = app_id;
1297 app_id = NULL;
1298 return app_id_rtn;
1299}
static struct ari_ws_session * session_create(struct ast_tcptls_session_instance *ser, const char *apps, int subscribe_all, const char *session_id, struct ari_conf_outbound_websocket *ows, enum ast_websocket_type ws_type)
static void * outbound_session_handler_thread(void *obj)
static void session_cleanup(void *obj)
#define PER_CALL_FAIL_SAFE_TIMEOUT(owc)
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition astmm.h:267
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition astobj2.h:480
const char * ast_channel_name(const struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
@ AST_WS_TYPE_CLIENT_PER_CALL_CONFIG
ari_conf_owc_fields
Definition internal.h:103
struct ari_conf_outbound_websocket * ari_conf_get_owc_for_app(const char *app_name, unsigned int ws_type)
Get the outbound websocket configuration for a Stasis app.
enum ari_conf_owc_fields ari_conf_owc_get_invalid_fields(const char *id)
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition sorcery.c:2381

References ao2_bump, ao2_cleanup, ao2_ref, app_name(), ari_conf_get_owc_for_app(), ari_conf_owc_get_invalid_fields(), ast_asprintf, ast_channel_name(), ast_channel_uniqueid(), ast_debug, ast_free, ast_log, ast_pthread_create_detached_background, ast_sorcery_object_get_id(), ast_strdup, ast_tvdiff_ms(), ast_tvnow(), AST_WS_TYPE_CLIENT_PER_CALL, AST_WS_TYPE_CLIENT_PER_CALL_CONFIG, LOG_WARNING, NULL, outbound_session_handler_thread(), PER_CALL_FAIL_SAFE_TIMEOUT, RAII_VAR, session, session_cleanup(), session_create(), and session_unref().

Referenced by app_exec().

◆ ast_ari_get_docs()

void ast_ari_get_docs ( const char *  uri,
const char *  prefix,
struct ast_variable headers,
struct ast_ari_response response 
)

Definition at line 818 of file res_ari.c.

820{
821 RAII_VAR(struct ast_str *, absolute_path_builder, NULL, ast_free);
822 RAII_VAR(char *, absolute_api_dirname, NULL, ast_std_free);
823 RAII_VAR(char *, absolute_filename, NULL, ast_std_free);
824 struct ast_json *obj = NULL;
825 struct ast_variable *host = NULL;
826 struct ast_json_error error = {};
827 struct stat file_stat;
828
829 ast_debug(3, "%s(%s)\n", __func__, uri);
830
831 absolute_path_builder = ast_str_create(80);
832 if (absolute_path_builder == NULL) {
834 return;
835 }
836
837 /* absolute path to the rest-api directory */
838 ast_str_append(&absolute_path_builder, 0, "%s", ast_config_AST_DATA_DIR);
839 ast_str_append(&absolute_path_builder, 0, "/rest-api/");
840 absolute_api_dirname = realpath(ast_str_buffer(absolute_path_builder), NULL);
841 if (absolute_api_dirname == NULL) {
842 ast_log(LOG_ERROR, "Error determining real directory for rest-api\n");
844 response, 500, "Internal Server Error",
845 "Cannot find rest-api directory");
846 return;
847 }
848
849 /* absolute path to the requested file */
850 ast_str_append(&absolute_path_builder, 0, "%s", uri);
851 absolute_filename = realpath(ast_str_buffer(absolute_path_builder), NULL);
852 if (absolute_filename == NULL) {
853 switch (errno) {
854 case ENAMETOOLONG:
855 case ENOENT:
856 case ENOTDIR:
858 response, 404, "Not Found",
859 "Resource not found");
860 break;
861 case EACCES:
863 response, 403, "Forbidden",
864 "Permission denied");
865 break;
866 default:
868 "Error determining real path for uri '%s': %s\n",
869 uri, strerror(errno));
871 response, 500, "Internal Server Error",
872 "Cannot find file");
873 break;
874 }
875 return;
876 }
877
878 if (!ast_begins_with(absolute_filename, absolute_api_dirname)) {
879 /* HACKERZ! */
881 "Invalid attempt to access '%s' (not in %s)\n",
882 absolute_filename, absolute_api_dirname);
884 response, 404, "Not Found",
885 "Resource not found");
886 return;
887 }
888
889 if (stat(absolute_filename, &file_stat) == 0) {
890 if (!(file_stat.st_mode & S_IFREG)) {
891 /* Not a file */
893 response, 403, "Forbidden",
894 "Invalid access");
895 return;
896 }
897 } else {
898 /* Does not exist */
900 response, 404, "Not Found",
901 "Resource not found");
902 return;
903 }
904
905 /* Load resource object from file */
906 obj = ast_json_load_new_file(absolute_filename, &error);
907 if (obj == NULL) {
908 ast_log(LOG_ERROR, "Error parsing resource file: %s:%d(%d) %s\n",
909 error.source, error.line, error.column, error.text);
911 response, 500, "Internal Server Error",
912 "Yikes! Cannot parse resource");
913 return;
914 }
915
916 /* Update the basePath properly */
917 if (ast_json_object_get(obj, "basePath") != NULL) {
918 for (host = headers; host; host = host->next) {
919 if (strcasecmp(host->name, "Host") == 0) {
920 break;
921 }
922 }
923 if (host != NULL) {
924 if (prefix != NULL && strlen(prefix) > 0) {
926 obj, "basePath",
927 ast_json_stringf("http://%s%s/ari", host->value,prefix));
928 } else {
930 obj, "basePath",
931 ast_json_stringf("http://%s/ari", host->value));
932 }
933 } else {
934 /* Without the host, we don't have the basePath */
935 ast_json_object_del(obj, "basePath");
936 }
937 }
938
939 ast_ari_response_ok(response, obj);
940}
void ast_std_free(void *ptr)
Definition astmm.c:1734
static char prefix[MAX_PREFIX]
Definition http.c:145
#define LOG_ERROR
struct ast_json * ast_json_stringf(const char *format,...)
Create a JSON string, printf style.
Definition json.c:293
int ast_json_object_del(struct ast_json *object, const char *key)
Delete a field from a JSON object.
Definition json.c:418
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
Definition json.c:414
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition json.c:407
struct ast_json * ast_json_load_new_file(const char *path, struct ast_json_error *error)
Parse file at path into JSON object or array.
Definition json.c:604
int errno
const char * ast_config_AST_DATA_DIR
Definition options.c:159
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition res_ari.c:212
void ast_ari_response_ok(struct ast_ari_response *response, struct ast_json *message)
Fill in an OK (200) ast_ari_response.
Definition res_ari.c:229
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition res_ari.c:251
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition strings.h:1139
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition strings.h:659
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Definition strings.h:97
JSON parsing error information.
Definition json.h:887
Abstract JSON element (object, array, string, int, ...).
Support for dynamic strings.
Definition strings.h:623
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
int error(const char *format,...)

References ast_ari_response_alloc_failed(), ast_ari_response_error(), ast_ari_response_ok(), ast_begins_with(), ast_config_AST_DATA_DIR, ast_debug, ast_free, ast_json_load_new_file(), ast_json_object_del(), ast_json_object_get(), ast_json_object_set(), ast_json_stringf(), ast_log, ast_std_free(), ast_str_append(), ast_str_buffer(), ast_str_create, errno, error(), LOG_ERROR, ast_variable::name, ast_variable::next, NULL, prefix, RAII_VAR, and ast_variable::value.

Referenced by ast_ari_invoke(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), and AST_TEST_DEFINE().

◆ ast_ari_invoke()

enum ast_ari_invoke_result ast_ari_invoke ( struct ast_tcptls_session_instance ser,
enum ast_ari_invoke_source  source,
const struct ast_http_uri urih,
const char *  uri,
enum ast_http_method  method,
struct ast_variable get_params,
struct ast_variable headers,
struct ast_json body,
struct ast_ari_response response 
)

Definition at line 612 of file res_ari.c.

617{
620 struct stasis_rest_handlers *wildcard_handler = NULL;
621 RAII_VAR(struct ast_variable *, path_vars, NULL, ast_variables_destroy);
624
625 char *path = ast_strdupa(uri);
626 char *path_segment = NULL;
628 SCOPE_ENTER(3, "Request: %s %s, path:%s\n", ast_get_http_method(method), uri, path);
629
630
631 if (!general) {
632 if (ser && source == ARI_INVOKE_SOURCE_REST) {
634 }
635 ast_ari_response_error(response, 500, "Server Error", "URI handler config missing");
637 response->response_code, response->response_text);
638 }
639
640 user = authenticate_user(get_params, headers, source);
641 if (!user) {
642 ast_ari_response_error(response, 401, "Unauthorized", "Authentication required");
643 if (source == ARI_INVOKE_SOURCE_REST) {
644 /* Per RFC 2617, section 1.2: The 401 (Unauthorized) response
645 * message is used by an origin server to challenge the
646 * authorization of a user agent. This response MUST include a
647 * WWW-Authenticate header field containing at least one
648 * challenge applicable to the requested resource.
649 */
650
651 /* Section 1.2:
652 * realm = "realm" "=" realm-value
653 * realm-value = quoted-string
654 * Section 2:
655 * challenge = "Basic" realm
656 */
657 ast_str_append(&response->headers, 0,
658 "WWW-Authenticate: Basic realm=\"%s\"\r\n",
659 general->auth_realm);
660 }
662 response->response_code, response->response_text);
663 }
664
665 if (source == ARI_INVOKE_SOURCE_REST && ser && user->acl && !ast_acl_list_is_empty(user->acl) &&
666 ast_apply_acl(user->acl, &ser->remote_address, "ARI User ACL") == AST_SENSE_DENY) {
667 ast_ari_response_error(response, 403, "Forbidden", "Access denied by ACL");
669 response->response_code, response->response_text);
670 } else if (!ast_fully_booted) {
671 ast_ari_response_error(response, 503, "Service Unavailable", "Asterisk not booted");
673 response->response_code, response->response_text);
674 } else if (user->read_only && method != AST_HTTP_GET && method != AST_HTTP_OPTIONS) {
675 ast_ari_response_error(response, 403, "Forbidden", "Write access denied");
677 response->response_code, response->response_text);
678 } else if (ast_ends_with(uri, "/")) {
679 remove_trailing_slash(uri, response);
681 response->response_code, response->response_text);
682 } else if (ast_begins_with(uri, "api-docs/")) {
683 /* Serving up API docs */
684 if (method != AST_HTTP_GET) {
685 ast_ari_response_error(response, 405, "Method Not Allowed", "Unsupported method");
686 } else {
687 if (urih) {
688 /* Skip the api-docs prefix */
689 ast_ari_get_docs(strchr(uri, '/') + 1, urih->prefix, headers, response);
690 } else {
691 /*
692 * If we were invoked without a urih, we're probably
693 * being called from the websocket so just use the
694 * default prefix. It's filled in by ast_http_uri_link().
695 */
696 ast_ari_get_docs(strchr(uri, '/') + 1, http_uri.prefix, headers, response);
697 }
698 }
700 response->response_code, response->response_text);
701 }
702
703 root = handler = get_root_handler();
704 ast_assert(root != NULL);
705
706 while ((path_segment = strsep(&path, "/")) && (strlen(path_segment) > 0)) {
707 struct stasis_rest_handlers *found_handler = NULL;
708 int i;
709 SCOPE_ENTER(4, "Finding handler for path segment %s\n", path_segment);
710
712
713 for (i = 0; found_handler == NULL && i < handler->num_children; ++i) {
714 struct stasis_rest_handlers *child = handler->children[i];
715 SCOPE_ENTER(5, "Checking handler path segment %s\n", child->path_segment);
716
717 if (child->is_wildcard) {
718 /* Record the path variable */
719 struct ast_variable *path_var = ast_variable_new(child->path_segment, path_segment, __FILE__);
720 path_var->next = path_vars;
721 path_vars = path_var;
722 wildcard_handler = child;
723 ast_trace(-1, " Checking %s %s: Matched wildcard.\n", handler->path_segment, child->path_segment);
724
725 } else if (strcmp(child->path_segment, path_segment) == 0) {
726 found_handler = child;
727 ast_trace(-1, " Checking %s %s: Explicit match with %s\n", handler->path_segment, child->path_segment, path_segment);
728 } else {
729 ast_trace(-1, " Checking %s %s: Didn't match %s\n", handler->path_segment, child->path_segment, path_segment);
730 }
731 SCOPE_EXIT("Done checking %s\n", child->path_segment);
732 }
733
734 if (!found_handler && wildcard_handler) {
735 ast_trace(-1, " No explicit handler found for %s. Using wildcard %s.\n",
736 path_segment, wildcard_handler->path_segment);
737 found_handler = wildcard_handler;
738 wildcard_handler = NULL;
739 }
740
741 if (found_handler == NULL) {
742 /* resource not found */
744 response, 404, "Not Found",
745 "Resource not found");
746 SCOPE_EXIT_EXPR(break, "Handler not found for %s\n", path_segment);
747 } else {
748 handler = found_handler;
749 }
750 SCOPE_EXIT("Done checking %s\n", path_segment);
751 }
752
753 if (handler == NULL || response->response_code == 404) {
754 /* resource not found */
756 response->response_code, response->response_text, uri);
757 }
758
760 if (method == AST_HTTP_OPTIONS) {
761 handle_options(handler, headers, response);
763 }
764
765 if (method < 0 || method >= AST_HTTP_MAX_METHOD) {
766 add_allow_header(handler, response);
768 response, 405, "Method Not Allowed",
769 "Invalid method");
771 response->response_code, response->response_text);
772 }
773
774 if (handler->is_websocket && method == AST_HTTP_GET) {
775 if (source == ARI_INVOKE_SOURCE_WEBSOCKET) {
777 response, 400, "Bad request",
778 "Can't upgrade to websocket from a websocket");
780 response->response_code, response->response_text);
781 }
782 /* WebSocket! */
783 ast_trace(-1, "Handling websocket %s\n", uri);
785 get_params, headers);
786 /* Since the WebSocket code handles the connection, we shouldn't
787 * do anything else; setting no_response */
788 response->no_response = 1;
790 }
791
792 callback = handler->callbacks[method];
793 if (callback == NULL) {
794 add_allow_header(handler, response);
796 response, 405, "Method Not Allowed",
797 "Invalid method");
799 response->response_code, response->response_text);
800 }
801
802 ast_trace(-1, "Running callback: %s\n", uri);
803 callback(ser, get_params, path_vars, headers, body, response);
804 if (response->message == NULL && response->response_code == 0) {
805 /* Really should not happen */
806 ast_log(LOG_ERROR, "ARI %s %s not implemented\n",
809 response, 501, "Not Implemented",
810 "Method not implemented");
812 response->response_code, response->response_text);
813 }
814 SCOPE_EXIT_RTN_VALUE(ARI_INVOKE_RESULT_SUCCESS, "Response: %d : %s\n",
815 response->response_code, response->response_text);
816}
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
Definition acl.c:799
@ AST_SENSE_DENY
Definition acl.h:37
int ast_acl_list_is_empty(struct ast_acl_list *acl_list)
Determines if an ACL is empty or if it contains entries.
Definition acl.c:540
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_json *body, struct ast_ari_response *response)
Callback type for RESTful method handlers.
Definition ari.h:60
void ari_handle_websocket(struct ast_tcptls_session_instance *ser, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers)
Wrapper for invoking the websocket code for an incoming connection.
char * strsep(char **str, const char *delims)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition astmm.h:298
static struct ast_channel * callback(struct ast_channelstorage_instance *driver, ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags, int rdlock)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_ENTER(level,...)
#define SCOPE_EXIT_EXPR(__expr,...)
#define SCOPE_EXIT(...)
#define ast_trace(level,...)
@ AST_HTTP_GET
Definition http.h:60
@ AST_HTTP_MAX_METHOD
Definition http.h:66
@ AST_HTTP_OPTIONS
Definition http.h:65
const char * ast_get_http_method(enum ast_http_method method) attribute_pure
Return http method name string.
Definition http.c:207
void ast_http_request_close_on_completion(struct ast_tcptls_session_instance *ser)
Request the HTTP connection be closed after this HTTP request.
Definition http.c:911
#define ast_variable_new(name, value, filename)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition extconf.c:1260
#define ast_fully_booted
Definition options.h:127
struct ari_conf_general * ari_conf_get_general(void)
static void remove_trailing_slash(const char *uri, struct ast_ari_response *response)
Definition res_ari.c:586
static void add_allow_header(struct stasis_rest_handlers *handler, struct ast_ari_response *response)
Definition res_ari.c:268
static struct ast_http_uri http_uri
Definition res_ari.c:117
static struct ari_conf_user * authenticate_user(struct ast_variable *get_params, struct ast_variable *headers, enum ast_ari_invoke_source source)
Authenticate an HTTP request.
Definition res_ari.c:521
static void handle_options(struct stasis_rest_handlers *handler, struct ast_variable *headers, struct ast_ari_response *response)
Handle OPTIONS request, mainly for CORS preflight requests.
Definition res_ari.c:314
void ast_ari_get_docs(const char *uri, const char *prefix, struct ast_variable *headers, struct ast_ari_response *response)
Definition res_ari.c:818
static struct stasis_rest_handlers * get_root_handler(void)
Definition res_ari.c:191
const char * method
Definition res_pjsip.c:1277
static int force_inline attribute_pure ast_ends_with(const char *str, const char *suffix)
Checks whether a string ends with another.
Definition strings.h:116
Global configuration options for ARI.
Definition internal.h:58
Per-user configuration options.
Definition internal.h:85
struct ast_str * headers
Definition ari.h:105
struct ast_json * message
Definition ari.h:103
int response_code
Definition ari.h:108
const char * response_text
Definition ari.h:112
unsigned int no_response
Definition ari.h:114
const char * prefix
Definition http.h:106
struct ast_sockaddr remote_address
Definition tcptls.h:153
const char * path_segment
Definition ari.h:71
struct stasis_rest_handlers * children[]
Definition ari.h:95
structure to hold users read from phoneprov_users.conf
#define ast_assert(a)
Definition utils.h:779
void ast_uri_decode(char *s, struct ast_flags spec)
Decode URI, URN, URL (overwrite string)
Definition utils.c:760
const struct ast_flags ast_uri_http_legacy
Definition utils.c:718

References add_allow_header(), ao2_cleanup, ari_conf_get_general(), ari_handle_websocket(), ARI_INVOKE_RESULT_ERROR_CLOSE, ARI_INVOKE_RESULT_ERROR_CONTINUE, ARI_INVOKE_RESULT_SUCCESS, ARI_INVOKE_SOURCE_REST, ARI_INVOKE_SOURCE_WEBSOCKET, ast_acl_list_is_empty(), ast_apply_acl(), ast_ari_get_docs(), ast_ari_response_error(), ast_assert, ast_begins_with(), ast_ends_with(), ast_fully_booted, ast_get_http_method(), AST_HTTP_GET, AST_HTTP_MAX_METHOD, AST_HTTP_OPTIONS, ast_http_request_close_on_completion(), ast_log, AST_SENSE_DENY, ast_str_append(), ast_strdupa, ast_trace, ast_uri_decode(), ast_uri_http_legacy, ast_variable_new, ast_variables_destroy(), authenticate_user(), callback(), stasis_rest_handlers::children, get_root_handler(), handle_options(), handler(), ast_ari_response::headers, http_uri, stasis_rest_handlers::is_wildcard, LOG_ERROR, ast_ari_response::message, method, ast_variable::next, ast_ari_response::no_response, NULL, stasis_rest_handlers::num_children, stasis_rest_handlers::path_segment, ast_http_uri::prefix, RAII_VAR, ast_tcptls_session_instance::remote_address, remove_trailing_slash(), ast_ari_response::response_code, ast_ari_response::response_text, SCOPE_ENTER, SCOPE_EXIT, SCOPE_EXIT_EXPR, SCOPE_EXIT_RTN_VALUE, and strsep().

Referenced by ari_websocket_process_request(), ast_ari_callback(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), and invoke_delete_common().

◆ ast_ari_json_format()

enum ast_json_encoding_format ast_ari_json_format ( void  )

Configured encoding format for JSON output.

Returns
JSON output encoding (compact, pretty, etc.)

Definition at line 1000 of file res_ari.c.

1001{
1003 return general ? general->format : AST_JSON_COMPACT;
1004}
@ AST_JSON_COMPACT
Definition json.h:793

References ao2_cleanup, ari_conf_get_general(), AST_JSON_COMPACT, and RAII_VAR.

Referenced by ast_ari_callback(), and session_write().

◆ ast_ari_oom_json()

struct ast_json * ast_ari_oom_json ( void  )

The stock message to return when out of memory.

The refcount is NOT bumped on this object, so ast_json_ref() if you want to keep the reference.

Returns
JSON message specifying an out-of-memory error.

Definition at line 127 of file res_ari.c.

128{
129 return oom_json;
130}
static struct ast_json * oom_json
Definition res_ari.c:109

References oom_json.

◆ ast_ari_remove_handler()

int ast_ari_remove_handler ( struct stasis_rest_handlers handler)

Remove a resource for REST handling.

Parameters
handlerHandler to add.
Return values
0on success.
non-zeroon failure.

Definition at line 155 of file res_ari.c.

156{
157 struct stasis_rest_handlers *new_handler;
158 size_t size;
159 size_t i;
160 size_t j;
161
163
165 size = sizeof(*new_handler) + root_handler->num_children * sizeof(handler);
166
167 new_handler = ao2_alloc(size, NULL);
168 if (!new_handler) {
170 return -1;
171 }
172
173 /* Create replacement root_handler less the handler to remove. */
174 memcpy(new_handler, root_handler, sizeof(*new_handler));
175 for (i = 0, j = 0; i < root_handler->num_children; ++i) {
176 if (root_handler->children[i] == handler) {
177 continue;
178 }
179 new_handler->children[j++] = root_handler->children[i];
180 }
181 new_handler->num_children = j;
182
183 /* Replace the old root_handler with the new. */
185 root_handler = new_handler;
186
188 return 0;
189}
#define ast_mutex_unlock(a)
Definition lock.h:197
#define ast_mutex_lock(a)
Definition lock.h:196

References ao2_alloc, ao2_cleanup, ast_assert, ast_mutex_lock, ast_mutex_unlock, stasis_rest_handlers::children, handler(), NULL, stasis_rest_handlers::num_children, root_handler, and root_handler_lock.

Referenced by tear_down_invocation_test(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), and unload_module().

◆ ast_ari_response_accepted()

void ast_ari_response_accepted ( struct ast_ari_response response)

Fill in a Accepted (202) ast_ari_response.

Definition at line 244 of file res_ari.c.

245{
246 response->message = ast_json_null();
247 response->response_code = 202;
248 response->response_text = "Accepted";
249}
struct ast_json * ast_json_null(void)
Get the JSON null value.
Definition json.c:248

References ast_json_null(), ast_ari_response::message, ast_ari_response::response_code, and ast_ari_response::response_text.

Referenced by ast_ari_asterisk_reload_module().

◆ ast_ari_response_alloc_failed()

void ast_ari_response_alloc_failed ( struct ast_ari_response response)

Fill in response with a 500 message for allocation failures.

Parameters
responseResponse to fill in.

Definition at line 251 of file res_ari.c.

252{
253 response->message = ast_json_ref(oom_json);
254 response->response_code = 500;
255 response->response_text = "Internal Server Error";
256}
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition json.c:67

References ast_json_ref(), ast_ari_response::message, oom_json, ast_ari_response::response_code, and ast_ari_response::response_text.

Referenced by ari_bridges_play_helper(), ari_bridges_play_new(), ari_channels_handle_originate_with_id(), ast_ari_applications_subscribe_cb(), ast_ari_applications_unsubscribe_cb(), ast_ari_asterisk_add_log_cb(), ast_ari_asterisk_get_global_var(), ast_ari_asterisk_get_global_var_cb(), ast_ari_asterisk_get_info(), ast_ari_asterisk_get_info_cb(), ast_ari_asterisk_get_module(), ast_ari_asterisk_list_modules(), ast_ari_asterisk_set_global_var_cb(), ast_ari_asterisk_update_object(), ast_ari_bridges_add_channel(), ast_ari_bridges_add_channel_cb(), ast_ari_bridges_create(), ast_ari_bridges_create_with_id(), ast_ari_bridges_get_bridge_var(), ast_ari_bridges_get_bridge_var_cb(), ast_ari_bridges_get_bridge_vars(), ast_ari_bridges_get_bridge_vars_cb(), ast_ari_bridges_list(), ast_ari_bridges_play_cb(), ast_ari_bridges_play_with_id_cb(), ast_ari_bridges_record(), ast_ari_bridges_record_cb(), ast_ari_bridges_remove_channel_cb(), ast_ari_bridges_set_bridge_var_cb(), ast_ari_bridges_start_moh(), ast_ari_bridges_start_moh_cb(), ast_ari_channels_continue_in_dialplan(), ast_ari_channels_continue_in_dialplan_cb(), ast_ari_channels_create(), ast_ari_channels_dial(), ast_ari_channels_dial_cb(), ast_ari_channels_get_channel_var(), ast_ari_channels_get_channel_var_cb(), ast_ari_channels_get_channel_vars(), ast_ari_channels_get_channel_vars_cb(), ast_ari_channels_hangup_cb(), ast_ari_channels_list(), ast_ari_channels_move_cb(), ast_ari_channels_mute_cb(), ast_ari_channels_play_cb(), ast_ari_channels_play_with_id_cb(), ast_ari_channels_record_cb(), ast_ari_channels_redirect_cb(), ast_ari_channels_send_dtmf_cb(), ast_ari_channels_set_channel_var_cb(), ast_ari_channels_snoop_channel_cb(), ast_ari_channels_snoop_channel_with_id_cb(), ast_ari_channels_start_moh_cb(), ast_ari_channels_transfer_progress_cb(), ast_ari_channels_unmute_cb(), ast_ari_device_states_update_cb(), ast_ari_endpoints_get(), ast_ari_endpoints_list(), ast_ari_endpoints_list_by_tech(), ast_ari_events_claim_channel_cb(), ast_ari_events_user_event_cb(), ast_ari_get_docs(), ast_ari_mailboxes_update_cb(), ast_ari_playbacks_control_cb(), ast_ari_recordings_copy_stored_cb(), ast_ari_recordings_list_stored(), ast_ari_sounds_list_cb(), control_list_create(), handle_options(), json_to_ast_variables(), json_to_ast_variables(), json_to_ast_variables(), return_sorcery_object(), send_message(), and send_refer().

◆ ast_ari_response_created()

void ast_ari_response_created ( struct ast_ari_response response,
const char *  url,
struct ast_json message 
)

Fill in a Created (201) ast_ari_response.

Parameters
responseResponse to fill in.
urlURL to the created resource.
messageJSON response. This reference is stolen, so just ast_json_ref if you need to keep a reference to it.

Definition at line 258 of file res_ari.c.

260{
262 response->message = message;
263 response->response_code = 201;
264 response->response_text = "Created";
265 ast_str_append(&response->headers, 0, "Location: /%s%s\r\n", root->path_segment, url);
266}
static char url[512]

References ao2_cleanup, ast_str_append(), get_root_handler(), ast_ari_response::headers, ast_ari_response::message, RAII_VAR, ast_ari_response::response_code, ast_ari_response::response_text, and url.

Referenced by ari_bridges_play_found(), ari_bridges_play_new(), ari_channels_handle_play(), ast_ari_bridges_record(), and ast_ari_channels_record().

◆ ast_ari_response_error()

void ast_ari_response_error ( struct ast_ari_response response,
int  response_code,
const char *  response_text,
const char *  message_fmt,
  ... 
)

Fill in an error ast_ari_response.

Parameters
responseResponse to fill in.
response_codeHTTP response code.
response_textText corresponding to the HTTP response code.
message_fmtError message format string.

Definition at line 212 of file res_ari.c.

216{
218 va_list ap;
219
220 va_start(ap, message_fmt);
221 message = ast_json_vstringf(message_fmt, ap);
222 va_end(ap);
223 response->message = ast_json_pack("{s: o}",
224 "message", ast_json_ref(message));
225 response->response_code = response_code;
226 response->response_text = response_text;
227}
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition json.c:73
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition json.c:612
struct ast_json * ast_json_vstringf(const char *format, va_list args)
Create a JSON string, vprintf style.
Definition json.c:303

References ast_json_pack(), ast_json_ref(), ast_json_unref(), ast_json_vstringf(), ast_ari_response::message, NULL, RAII_VAR, ast_ari_response::response_code, and ast_ari_response::response_text.

Referenced by ari_bridges_play_helper(), ari_bridges_play_new(), ari_channels_handle_originate_with_id(), ari_channels_handle_play(), ari_channels_handle_snoop_channel(), ast_ari_applications_filter(), ast_ari_applications_filter_cb(), ast_ari_applications_get(), ast_ari_applications_get_cb(), ast_ari_applications_list(), ast_ari_applications_list_cb(), ast_ari_applications_subscribe(), ast_ari_applications_subscribe_cb(), ast_ari_applications_unsubscribe(), ast_ari_applications_unsubscribe_cb(), ast_ari_asterisk_add_log(), ast_ari_asterisk_add_log_cb(), ast_ari_asterisk_delete_log(), ast_ari_asterisk_delete_log_cb(), ast_ari_asterisk_delete_object(), ast_ari_asterisk_delete_object_cb(), ast_ari_asterisk_get_global_var(), ast_ari_asterisk_get_global_var_cb(), ast_ari_asterisk_get_info_cb(), ast_ari_asterisk_get_module(), ast_ari_asterisk_get_module_cb(), ast_ari_asterisk_get_object(), ast_ari_asterisk_get_object_cb(), ast_ari_asterisk_list_log_channels(), ast_ari_asterisk_list_log_channels_cb(), ast_ari_asterisk_list_modules_cb(), ast_ari_asterisk_load_module(), ast_ari_asterisk_load_module_cb(), ast_ari_asterisk_ping_cb(), ast_ari_asterisk_reload_module(), ast_ari_asterisk_reload_module_cb(), ast_ari_asterisk_rotate_log(), ast_ari_asterisk_rotate_log_cb(), ast_ari_asterisk_set_global_var(), ast_ari_asterisk_set_global_var_cb(), ast_ari_asterisk_unload_module(), ast_ari_asterisk_unload_module_cb(), ast_ari_asterisk_update_object(), ast_ari_asterisk_update_object_cb(), ast_ari_bridges_add_channel_cb(), ast_ari_bridges_clear_video_source_cb(), ast_ari_bridges_create(), ast_ari_bridges_create_cb(), ast_ari_bridges_create_with_id(), ast_ari_bridges_create_with_id_cb(), ast_ari_bridges_destroy_cb(), ast_ari_bridges_get(), ast_ari_bridges_get_bridge_var(), ast_ari_bridges_get_bridge_var_cb(), ast_ari_bridges_get_bridge_vars(), ast_ari_bridges_get_bridge_vars_cb(), ast_ari_bridges_get_cb(), ast_ari_bridges_list_cb(), ast_ari_bridges_play_cb(), ast_ari_bridges_play_with_id_cb(), ast_ari_bridges_record(), ast_ari_bridges_record_cb(), ast_ari_bridges_remove_channel(), ast_ari_bridges_remove_channel_cb(), ast_ari_bridges_set_bridge_var(), ast_ari_bridges_set_bridge_var_cb(), ast_ari_bridges_set_bridge_vars(), ast_ari_bridges_set_bridge_vars_cb(), ast_ari_bridges_set_video_source(), ast_ari_bridges_set_video_source_cb(), ast_ari_bridges_start_moh_cb(), ast_ari_bridges_stop_moh(), ast_ari_bridges_stop_moh_cb(), ast_ari_callback(), ast_ari_channels_answer(), ast_ari_channels_answer_cb(), ast_ari_channels_continue_in_dialplan(), ast_ari_channels_continue_in_dialplan_cb(), ast_ari_channels_create(), ast_ari_channels_create_cb(), ast_ari_channels_dial(), ast_ari_channels_dial_cb(), ast_ari_channels_external_media(), ast_ari_channels_external_media_cb(), ast_ari_channels_get(), ast_ari_channels_get_cb(), ast_ari_channels_get_channel_var(), ast_ari_channels_get_channel_var_cb(), ast_ari_channels_get_channel_vars(), ast_ari_channels_get_channel_vars_cb(), ast_ari_channels_hangup(), ast_ari_channels_hangup_cb(), ast_ari_channels_hold_cb(), ast_ari_channels_list_cb(), ast_ari_channels_move(), ast_ari_channels_move_cb(), ast_ari_channels_mute(), ast_ari_channels_mute_cb(), ast_ari_channels_originate_cb(), ast_ari_channels_originate_with_id_cb(), ast_ari_channels_play_cb(), ast_ari_channels_play_with_id_cb(), ast_ari_channels_progress_cb(), ast_ari_channels_record(), ast_ari_channels_record_cb(), ast_ari_channels_redirect(), ast_ari_channels_redirect_cb(), ast_ari_channels_ring_cb(), ast_ari_channels_ring_stop_cb(), ast_ari_channels_rtpstatistics(), ast_ari_channels_rtpstatistics_cb(), ast_ari_channels_send_dtmf(), ast_ari_channels_send_dtmf_cb(), ast_ari_channels_set_channel_var(), ast_ari_channels_set_channel_var_cb(), ast_ari_channels_set_channel_vars(), ast_ari_channels_set_channel_vars_cb(), ast_ari_channels_snoop_channel_cb(), ast_ari_channels_snoop_channel_with_id_cb(), ast_ari_channels_start_moh_cb(), ast_ari_channels_start_silence_cb(), ast_ari_channels_stop_moh_cb(), ast_ari_channels_stop_silence_cb(), ast_ari_channels_transfer_progress(), ast_ari_channels_transfer_progress_cb(), ast_ari_channels_unhold_cb(), ast_ari_channels_unmute(), ast_ari_channels_unmute_cb(), ast_ari_device_states_delete(), ast_ari_device_states_delete_cb(), ast_ari_device_states_get(), ast_ari_device_states_get_cb(), ast_ari_device_states_list(), ast_ari_device_states_list_cb(), ast_ari_device_states_update(), ast_ari_device_states_update_cb(), ast_ari_endpoints_get(), ast_ari_endpoints_get_cb(), ast_ari_endpoints_list(), ast_ari_endpoints_list_by_tech(), ast_ari_endpoints_list_by_tech_cb(), ast_ari_endpoints_list_cb(), ast_ari_endpoints_refer_cb(), ast_ari_endpoints_refer_to_endpoint(), ast_ari_endpoints_refer_to_endpoint_cb(), ast_ari_endpoints_send_message_cb(), ast_ari_endpoints_send_message_to_endpoint(), ast_ari_endpoints_send_message_to_endpoint_cb(), ast_ari_events_claim_channel(), ast_ari_events_claim_channel_cb(), ast_ari_events_user_event(), ast_ari_events_user_event_cb(), ast_ari_get_docs(), ast_ari_invoke(), ast_ari_mailboxes_delete(), ast_ari_mailboxes_delete_cb(), ast_ari_mailboxes_get(), ast_ari_mailboxes_get_cb(), ast_ari_mailboxes_list(), ast_ari_mailboxes_list_cb(), ast_ari_mailboxes_update(), ast_ari_mailboxes_update_cb(), ast_ari_playbacks_control(), ast_ari_playbacks_control_cb(), ast_ari_playbacks_get(), ast_ari_playbacks_get_cb(), ast_ari_playbacks_stop(), ast_ari_playbacks_stop_cb(), ast_ari_recordings_cancel_cb(), ast_ari_recordings_copy_stored(), ast_ari_recordings_copy_stored_cb(), ast_ari_recordings_delete_stored(), ast_ari_recordings_delete_stored_cb(), ast_ari_recordings_get_live(), ast_ari_recordings_get_live_cb(), ast_ari_recordings_get_stored(), ast_ari_recordings_get_stored_cb(), ast_ari_recordings_get_stored_file(), ast_ari_recordings_get_stored_file_cb(), ast_ari_recordings_list_stored_cb(), ast_ari_recordings_mute_cb(), ast_ari_recordings_pause_cb(), ast_ari_recordings_stop_cb(), ast_ari_recordings_unmute_cb(), ast_ari_recordings_unpause_cb(), ast_ari_sounds_get(), ast_ari_sounds_get_cb(), ast_ari_sounds_list(), ast_ari_sounds_list_cb(), channel_state_invalid(), check_add_remove_channel(), control_list_create(), control_recording(), find_bridge(), find_channel_control(), find_control(), json_to_ast_variables(), json_to_ast_variables(), json_to_ast_variables(), remove_trailing_slash(), send_message(), and send_refer().

◆ ast_ari_response_no_content()

void ast_ari_response_no_content ( struct ast_ari_response response)

Fill in a No Content (204) ast_ari_response.

Definition at line 237 of file res_ari.c.

238{
239 response->message = ast_json_null();
240 response->response_code = 204;
241 response->response_text = "No Content";
242}

References ast_json_null(), ast_ari_response::message, ast_ari_response::response_code, and ast_ari_response::response_text.

Referenced by ast_ari_asterisk_add_log(), ast_ari_asterisk_delete_log(), ast_ari_asterisk_delete_object(), ast_ari_asterisk_load_module(), ast_ari_asterisk_reload_module(), ast_ari_asterisk_rotate_log(), ast_ari_asterisk_set_global_var(), ast_ari_asterisk_unload_module(), ast_ari_bridges_add_channel(), ast_ari_bridges_clear_video_source(), ast_ari_bridges_destroy(), ast_ari_bridges_remove_channel(), ast_ari_bridges_set_bridge_var(), ast_ari_bridges_set_bridge_vars(), ast_ari_bridges_set_video_source(), ast_ari_bridges_start_moh(), ast_ari_bridges_stop_moh(), ast_ari_channels_answer(), ast_ari_channels_continue_in_dialplan(), ast_ari_channels_dial(), ast_ari_channels_hangup(), ast_ari_channels_hold(), ast_ari_channels_move(), ast_ari_channels_mute(), ast_ari_channels_progress(), ast_ari_channels_redirect(), ast_ari_channels_ring(), ast_ari_channels_ring_stop(), ast_ari_channels_send_dtmf(), ast_ari_channels_set_channel_var(), ast_ari_channels_set_channel_vars(), ast_ari_channels_start_moh(), ast_ari_channels_start_silence(), ast_ari_channels_stop_moh(), ast_ari_channels_stop_silence(), ast_ari_channels_transfer_progress(), ast_ari_channels_unhold(), ast_ari_channels_unmute(), ast_ari_device_states_delete(), ast_ari_device_states_update(), ast_ari_events_claim_channel(), ast_ari_events_user_event(), ast_ari_mailboxes_delete(), ast_ari_mailboxes_update(), ast_ari_playbacks_control(), ast_ari_playbacks_stop(), ast_ari_recordings_delete_stored(), control_recording(), and handle_options().

◆ ast_ari_response_ok()

void ast_ari_response_ok ( struct ast_ari_response response,
struct ast_json message 
)

Fill in an OK (200) ast_ari_response.

Parameters
responseResponse to fill in.
messageJSON response. This reference is stolen, so just ast_json_ref if you need to keep a reference to it.

Definition at line 229 of file res_ari.c.

231{
232 response->message = message;
233 response->response_code = 200;
234 response->response_text = "OK";
235}

References ast_ari_response::message, ast_ari_response::response_code, and ast_ari_response::response_text.

Referenced by ari_channels_handle_originate_with_id(), ari_channels_handle_snoop_channel(), ast_ari_applications_filter(), ast_ari_applications_get(), ast_ari_applications_list(), ast_ari_applications_subscribe(), ast_ari_applications_unsubscribe(), ast_ari_asterisk_get_global_var(), ast_ari_asterisk_get_info(), ast_ari_asterisk_get_module(), ast_ari_asterisk_list_log_channels(), ast_ari_asterisk_list_modules(), ast_ari_asterisk_ping(), ast_ari_bridges_create(), ast_ari_bridges_create_with_id(), ast_ari_bridges_get(), ast_ari_bridges_get_bridge_var(), ast_ari_bridges_get_bridge_vars(), ast_ari_bridges_list(), ast_ari_channels_create(), ast_ari_channels_get(), ast_ari_channels_get_channel_var(), ast_ari_channels_get_channel_vars(), ast_ari_channels_list(), ast_ari_channels_rtpstatistics(), ast_ari_device_states_get(), ast_ari_device_states_list(), ast_ari_endpoints_get(), ast_ari_endpoints_list(), ast_ari_endpoints_list_by_tech(), ast_ari_get_docs(), ast_ari_mailboxes_get(), ast_ari_mailboxes_list(), ast_ari_playbacks_get(), ast_ari_recordings_copy_stored(), ast_ari_recordings_get_live(), ast_ari_recordings_get_stored(), ast_ari_recordings_get_stored_file(), ast_ari_recordings_list_stored(), ast_ari_sounds_get(), ast_ari_sounds_list(), and return_sorcery_object().