diff options
Diffstat (limited to 'include/asterisk')
-rw-r--r-- | include/asterisk/http.h | 5 | ||||
-rw-r--r-- | include/asterisk/json.h | 34 | ||||
-rw-r--r-- | include/asterisk/stasis_app.h | 44 | ||||
-rw-r--r-- | include/asterisk/stasis_http.h | 171 | ||||
-rw-r--r-- | include/asterisk/strings.h | 42 |
5 files changed, 282 insertions, 14 deletions
diff --git a/include/asterisk/http.h b/include/asterisk/http.h index 3400240a1..db424d3d3 100644 --- a/include/asterisk/http.h +++ b/include/asterisk/http.h @@ -58,7 +58,10 @@ enum ast_http_method { AST_HTTP_GET = 0, AST_HTTP_POST, AST_HTTP_HEAD, - AST_HTTP_PUT, /*!< Not supported in Asterisk */ + AST_HTTP_PUT, + AST_HTTP_DELETE, + AST_HTTP_OPTIONS, + AST_HTTP_MAX_METHOD, /*!< Last entry in ast_http_method enum */ }; struct ast_http_uri; diff --git a/include/asterisk/json.h b/include/asterisk/json.h index 62e21293b..d06416f58 100644 --- a/include/asterisk/json.h +++ b/include/asterisk/json.h @@ -586,16 +586,33 @@ int ast_json_object_iter_set(struct ast_json *object, struct ast_json_iter *iter /*!@{*/ /*! + * \brief Encoding format type. + * \since 12.0.0 + */ +enum ast_json_encoding_format +{ + /*! Compact format, low human readability */ + AST_JSON_COMPACT, + /*! Formatted for human readability */ + AST_JSON_PRETTY, +}; + +#define ast_json_dump_string(root) ast_json_dump_string_format(root, AST_JSON_COMPACT) + +/*! * \brief Encode a JSON value to a string. * \since 12.0.0 * * Returned string must be freed by calling ast_free(). * - * \param JSON value. + * \param root JSON value. + * \param format encoding format type. * \return String encoding of \a root. * \return \c NULL on error. */ -char *ast_json_dump_string(struct ast_json *root); +char *ast_json_dump_string_format(struct ast_json *root, enum ast_json_encoding_format format); + +#define ast_json_dump_str(root, dst) ast_json_dump_str_format(root, dst, AST_JSON_COMPACT) /*! * \brief Encode a JSON value to an \ref ast_str. @@ -605,10 +622,13 @@ char *ast_json_dump_string(struct ast_json *root); * * \param root JSON value. * \param dst \ref ast_str to store JSON encoding. + * \param format encoding format type. * \return 0 on success. * \return -1 on error. The contents of \a dst are undefined. */ -int ast_json_dump_str(struct ast_json *root, struct ast_str **dst); +int ast_json_dump_str_format(struct ast_json *root, struct ast_str **dst, enum ast_json_encoding_format format); + +#define ast_json_dump_file(root, output) ast_json_dump_file_format(root, output, AST_JSON_COMPACT) /*! * \brief Encode a JSON value to a \c FILE. @@ -616,10 +636,13 @@ int ast_json_dump_str(struct ast_json *root, struct ast_str **dst); * * \param root JSON value. * \param output File to write JSON encoding to. + * \param format encoding format type. * \return 0 on success. * \return -1 on error. The contents of \a output are undefined. */ -int ast_json_dump_file(struct ast_json *root, FILE *output); +int ast_json_dump_file_format(struct ast_json *root, FILE *output, enum ast_json_encoding_format format); + +#define ast_json_dump_new_file(root, path) ast_json_dump_new_file_format(root, path, AST_JSON_COMPACT) /*! * \brief Encode a JSON value to a file at the given location. @@ -627,10 +650,11 @@ int ast_json_dump_file(struct ast_json *root, FILE *output); * * \param root JSON value. * \param path Path to file to write JSON encoding to. + * \param format encoding format type. * \return 0 on success. * \return -1 on error. The contents of \a output are undefined. */ -int ast_json_dump_new_file(struct ast_json *root, const char *path); +int ast_json_dump_new_file_format(struct ast_json *root, const char *path, enum ast_json_encoding_format format); #define AST_JSON_ERROR_TEXT_LENGTH 160 #define AST_JSON_ERROR_SOURCE_LENGTH 80 diff --git a/include/asterisk/stasis_app.h b/include/asterisk/stasis_app.h index caec19bbc..a789e4012 100644 --- a/include/asterisk/stasis_app.h +++ b/include/asterisk/stasis_app.h @@ -66,7 +66,7 @@ struct ast_channel_snapshot; * \param argv Arguments for the application. */ int stasis_app_exec(struct ast_channel *chan, const char *app_name, int argc, - char *argv[]); + char *argv[]); /*! @} */ @@ -126,22 +126,50 @@ int stasis_app_send(const char *app_name, struct ast_json *message); struct stasis_app_control; /*! - * \brief Returns the handler for the given channel + * \brief Returns the handler for the given channel. * \param chan Channel to handle. - * \return NULL channel not in Stasis application - * \return Pointer to stasis handler. + * \return NULL channel not in Stasis application. + * \return Pointer to \c res_stasis handler. */ struct stasis_app_control *stasis_app_control_find_by_channel( const struct ast_channel *chan); /*! - * \brief Exit \c app_stasis and continue execution in the dialplan. + * \brief Returns the handler for the channel with the given id. + * \param channel_id Uniqueid of the channel. + * \return NULL channel not in Stasis application, or channel does not exist. + * \return Pointer to \c res_stasis handler. + */ +struct stasis_app_control *stasis_app_control_find_by_channel_id( + const char *channel_id); + +/*! + * \brief Exit \c res_stasis and continue execution in the dialplan. * - * If the channel is no longer in \c app_stasis, this function does nothing. + * If the channel is no longer in \c res_stasis, this function does nothing. * - * \param handler Handler for \c app_stasis + * \param control Control for \c res_stasis + */ +void stasis_app_control_continue(struct stasis_app_control *control); + +/*! + * \brief Answer the channel associated with this control. + * \param control Control for \c res_stasis. + * \return 0 for success. + * \return -1 for error. + */ +int stasis_app_control_answer(struct stasis_app_control *control); + +/*! @} */ + +/*! @{ */ + +/*! + * \brief Build a JSON object from a \ref ast_channel_snapshot. + * \return JSON object representing channel snapshot. + * \return \c NULL on error */ -void stasis_app_control_continue(struct stasis_app_control *handler); +struct ast_json *ast_channel_snapshot_to_json(const struct ast_channel_snapshot *snapshot); /*! @} */ diff --git a/include/asterisk/stasis_http.h b/include/asterisk/stasis_http.h new file mode 100644 index 000000000..cc0ceeee4 --- /dev/null +++ b/include/asterisk/stasis_http.h @@ -0,0 +1,171 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2012 - 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. + */ + +#ifndef _ASTERISK_STASIS_HTTP_H +#define _ASTERISK_STASIS_HTTP_H + +/*! \file + * + * \brief Stasis RESTful API hooks. + * + * This header file is used mostly as glue code between generated declarations + * and res_stasis_http.c. + * + * \author David M. Lee, II <dlee@digium.com> + */ + +#include "asterisk/http.h" +#include "asterisk/json.h" +#include "asterisk/http_websocket.h" + +struct stasis_http_response; + +/*! + * \brief Callback type for RESTful method handlers. + * \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 stasis_http_response *response); + +/*! + * \brief Handler for a single RESTful path segment. + */ +struct stasis_rest_handlers { + /*! Path segement to handle */ + const char *path_segment; + /*! If true (non-zero), path_segment is a wildcard, and will match all values. + * + * Value of the segement will be passed into the \a path_vars parameter of the callback. + */ + int is_wildcard; + /*! Callbacks for all handled HTTP methods. */ + stasis_rest_callback callbacks[AST_HTTP_MAX_METHOD]; + /*! Number of children in the children array */ + size_t num_children; + /*! Handlers for sub-paths */ + struct stasis_rest_handlers *children[]; +}; + +/*! + * Response type for RESTful requests + */ +struct stasis_http_response { + /*! Response message */ + struct ast_json *message; + /*! \r\n seperated response headers */ + struct ast_str *headers; + /*! HTTP response code. + * See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html */ + int response_code; + /*! Corresponding text for the response code */ + const char *response_text; // Shouldn't http.c handle this? +}; + +/*! + * Add a resource for REST handling. + * \param handler Handler to add. + * \return 0 on success. + * \return non-zero on failure. + */ +int stasis_http_add_handler(struct stasis_rest_handlers *handler); + +/*! + * Remove a resource for REST handling. + * \param handler Handler to add. + * \return 0 on success. + * \return non-zero on failure. + */ +int stasis_http_remove_handler(struct stasis_rest_handlers *handler); + +/*! + * \internal + * \brief Stasis RESTful invocation handler. + * + * Only call from res_stasis_http and test_stasis_http. Only public to allow + * for unit testing. + * + * \param uri HTTP URI, relative to the API path. + * \param method HTTP method. + * \param get_params HTTP \c GET parameters. + * \param headers HTTP headers. + * \param[out] response RESTful HTTP response. + */ +void stasis_http_invoke(const char *uri, enum ast_http_method method, struct ast_variable *get_params, + struct ast_variable *headers, struct stasis_http_response *response); + +/*! + * \internal + * \brief Service function for API declarations. + * + * Only call from res_stasis_http and test_stasis_http. Only public to allow + * for unit testing. + * + * \param uri Requested URI, relative to the docs path. + * \param headers HTTP headers. + * \param[out] response RESTful HTTP response. + */ +void stasis_http_get_docs(const char *uri, struct ast_variable *headers, struct stasis_http_response *response); + +/*! + * \internal + * \brief Stasis WebSocket connection handler + * \param session WebSocket session. + * \param parameters HTTP \c GET parameters. + * \param headers HTTP headers. + */ +void stasis_websocket_callback(struct ast_websocket *session, struct ast_variable *parameters, struct ast_variable *headers); + +/*! + * \brief Fill in an error \a stasis_http_response. + * \param response Response to fill in. + * \param response_code HTTP response code. + * \param response_text Text corresponding to the HTTP response code. + * \param message_fmt Error message format string. + */ +void stasis_http_response_error(struct stasis_http_response *response, + int response_code, + const char *response_text, + const char *message_fmt, ...) +__attribute__((format(printf, 4, 5))); + +/*! + * \brief Fill in an \c OK (200) \a stasis_http_response. + * \param response Response to fill in. + * \param message JSON response. This reference is stolen, so just \ref + * ast_json_incref if you need to keep a reference to it. + */ +void stasis_http_response_ok(struct stasis_http_response *response, + struct ast_json *message); + +/*! + * \brief Fill in a <tt>No Content</tt> (204) \a stasis_http_response. + */ +void stasis_http_response_no_content(struct stasis_http_response *response); + +/*! + * \brief Fill in \a response with a 500 message for allocation failures. + * \param response Response to fill in. + */ +void stasis_http_response_alloc_failed(struct stasis_http_response *response); + +#endif /* _ASTERISK_STASIS_HTTP_H */ diff --git a/include/asterisk/strings.h b/include/asterisk/strings.h index d16e9f7bd..967eb82a0 100644 --- a/include/asterisk/strings.h +++ b/include/asterisk/strings.h @@ -82,6 +82,48 @@ static force_inline int attribute_pure ast_strlen_zero(const char *s) */ #define S_COR(a, b, c) ({typeof(&((b)[0])) __x = (b); (a) && !ast_strlen_zero(__x) ? (__x) : (c);}) +/* + \brief Checks whether a string begins with another. + \since 12.0.0 + \param str String to check. + \param prefix Prefix to look for. + \param 1 if \a str begins with \a prefix, 0 otherwise. + */ +static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix) +{ + ast_assert(str != NULL); + ast_assert(prefix != NULL); + while (*str == *prefix && *prefix != '\0') { + ++str; + ++prefix; + } + return *prefix == '\0'; +} + +/* + \brief Checks whether a string ends with another. + \since 12.0.0 + \param str String to check. + \param suffix Suffix to look for. + \param 1 if \a str ends with \a suffix, 0 otherwise. + */ +static int force_inline attribute_pure ast_ends_with(const char *str, const char *suffix) +{ + size_t str_len; + size_t suffix_len; + + ast_assert(str != NULL); + ast_assert(suffix != NULL); + str_len = strlen(str); + suffix_len = strlen(suffix); + + if (suffix_len > str_len) { + return 0; + } + + return strcmp(str + str_len - suffix_len, suffix) == 0; +} + /*! * \brief return Yes or No depending on the argument. * |