54#define SET_RESPONSE_AND_EXIT(_reponse_code, _reponse_text, \
55 _reponse_msg, _remote_addr, _request, _request_msg) \
57 RAII_VAR(char *, _msg_str, NULL, ast_json_free); \
59 _msg_str = ast_json_dump_string_format(_request_msg, AST_JSON_COMPACT); \
61 response->response_code = 500; \
62 response->response_text = "Server error. Out of memory"; \
65 response->message = ast_json_pack("{ s:s }", \
66 "message", _reponse_msg); \
67 response->response_code = _reponse_code; \
68 response->response_text = _reponse_text; \
69 SCOPE_EXIT_LOG_RTN_VALUE(_request, LOG_WARNING, \
70 "%s: %s Request: %s\n", _remote_addr, _reponse_text, S_OR(_msg_str, "<none>")); \
74 const char *remote_addr,
struct ast_json *request_msg,
80 char *query_string_start =
NULL;
81 SCOPE_ENTER(4,
"%s: Parsing RESTRequest message\n", remote_addr);
88 "Server error",
"No message to parse.",
95 "Server error",
"Out of memory",
102 request_msg,
"transaction_id")));
107 request_msg,
"request_id")));
113 "Bad request",
"No 'type' property.",
114 remote_addr,
request, request_msg);
119 "Bad request",
"Unknown request type.",
120 remote_addr,
request, request_msg);
127 "Bad request",
"Empty or missing 'uri' property.",
128 remote_addr,
request, request_msg);
130 if ((query_string_start = strchr(
request->uri,
'?')))
132 *query_string_start =
'\0';
133 query_string_start++;
135 query_string_start, strlen(query_string_start),
"application/x-www-form-urlencoded");
142 "Bad request",
"Unknown or missing 'method' property.",
143 remote_addr,
request, request_msg);
153 "Bad request",
"Unable to parse 'query_strings' array.",
154 remote_addr,
request, request_msg);
164 "%s: Done parsing RESTRequest message.\n", remote_addr);
173 "Bad request",
"No 'content_type' for 'message_body'.",
174 remote_addr,
request, request_msg);
182 "Bad request",
"Unable to parse 'message_body' as 'application/x-www-form-urlencoded'.",
183 remote_addr,
request, request_msg);
191 "Bad request",
"Unable to parse 'message_body' as 'application/json'.",
192 remote_addr,
request, request_msg);
196 "Bad request",
"Unknown content type.",
197 remote_addr,
request, request_msg);
202 for (; v; v = v->
next) {
208 "%s: Done parsing RESTRequest message.\n", remote_addr);
213 const char *remote_addr,
const char *
app_name,
219 SCOPE_ENTER(4,
"%s: Sending REST response %d:%s for uri %s\n",
223 if (response->
fd >= 0) {
233 "{s:s, s:s*, s:s*, s:i, s:s, s:s, s:s*, s:s* }",
234 "type",
"RESTResponse",
240 "content_type",
message ?
"application/json" :
NULL,
246 "%s: Failed to pack JSON response for request %s\n",
251 app_name, app_resp_json, debug_app);
262 const char *remote_addr,
struct ast_variable *upgrade_headers,
269 SCOPE_ENTER(3,
"%s: New WebSocket Msg\n", remote_addr);
278 ast_verbose(
"<--- Received ARI message from %s --->\n%s\n",
306 upgrade_headers,
request->body, &response);
Asterisk RESTful API hooks.
@ ARI_INVOKE_SOURCE_WEBSOCKET
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)
static struct rest_request_msg * parse_rest_request_msg(const char *remote_addr, struct ast_json *request_msg, struct ast_ari_response *response, int debug_app)
int ari_websocket_process_request(struct ari_ws_session *ari_ws_session, const char *remote_addr, struct ast_variable *upgrade_headers, const char *app_name, struct ast_json *request_msg)
static void request_destroy(struct rest_request_msg *request)
#define SET_RESPONSE_AND_EXIT(_reponse_code, _reponse_text, _reponse_msg, _remote_addr, _request, _request_msg)
static void send_rest_response(struct ari_ws_session *ari_ws_session, const char *remote_addr, const char *app_name, struct rest_request_msg *request, struct ast_ari_response *response, int debug_app)
void ari_websocket_send_event(struct ari_ws_session *ari_ws_session, const char *app_name, struct ast_json *message, int debug_app)
Callback handler for Stasis application messages.
Internal API's for websockets.
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdup(str)
A wrapper for strdup()
#define ast_calloc(num, len)
A wrapper for calloc()
static int request(void *obj)
void ast_verbose(const char *fmt,...)
#define TRACE_ATLEAST(level)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
#define SCOPE_CALL_WITH_RESULT(level, __var, __funcname,...)
#define SCOPE_ENTER(level,...)
#define SCOPE_CALL(level, __funcname,...)
#define SCOPE_EXIT_LOG_RTN(__log_level,...)
#define ast_trace(level,...)
ast_http_method
HTTP Request methods known by Asterisk.
enum ast_http_method ast_get_http_method_from_string(const char *method)
Return http method from string.
struct ast_variable * ast_http_parse_post_form(char *buf, int content_length, const char *content_type)
Get post variables from an application/x-www-form-urlencoded buffer.
#define ast_variable_list_append(head, new_var)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Asterisk JSON abstraction layer.
ast_json_nvp_ast_vars_code
@ AST_JSON_NVP_AST_VARS_CODE_NO_INPUT
Input was NULL or empty.
@ AST_JSON_NVP_AST_VARS_CODE_SUCCESS
Conversion successful.
struct ast_json * ast_json_null(void)
Get the JSON null value.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
void ast_json_free(void *p)
Asterisk's custom JSON allocator. Exposed for use by unit tests.
enum ast_json_nvp_ast_vars_code ast_json_nvp_array_to_ast_variables(struct ast_json *json_array, struct ast_variable **variables)
Convert a ast_json array of name/value pairs into an ast_variable list.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
struct ast_json * ast_json_load_buf(const char *buffer, size_t buflen, struct ast_json_error *error)
Parse buffer with known length into a JSON object or array.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
char * ast_json_dump_string_format(struct ast_json *root, enum ast_json_encoding_format format)
Encode a JSON value to a string.
int ast_json_is_null(const struct ast_json *value)
Check if value is JSON null.
const char * app_name(struct ast_app *app)
Stasis Application API. See Stasis Application API for detailed documentation.
int stasis_app_get_debug_by_name(const char *app_name)
Get debug status of an application.
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
struct ast_json * message
const char * response_text
JSON parsing error information.
Abstract JSON element (object, array, string, int, ...).
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
struct ast_variable * query_strings
enum ast_http_method method
int error(const char *format,...)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.