[asterisk-commits] dlee: branch dlee/stasis-http r382976 - in /team/dlee/stasis-http: include/as...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Mar 12 17:14:11 CDT 2013
Author: dlee
Date: Tue Mar 12 17:14:08 2013
New Revision: 382976
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=382976
Log:
Clean up; extracted common code
Modified:
team/dlee/stasis-http/include/asterisk/stasis_http.h
team/dlee/stasis-http/res/res_stasis_http.c
team/dlee/stasis-http/res/stasis_http/resource_channels.c
Modified: team/dlee/stasis-http/include/asterisk/stasis_http.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/include/asterisk/stasis_http.h?view=diff&rev=382976&r1=382975&r2=382976
==============================================================================
--- team/dlee/stasis-http/include/asterisk/stasis_http.h (original)
+++ team/dlee/stasis-http/include/asterisk/stasis_http.h Tue Mar 12 17:14:08 2013
@@ -136,4 +136,37 @@
*/
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 */
Modified: team/dlee/stasis-http/res/res_stasis_http.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/res/res_stasis_http.c?view=diff&rev=382976&r1=382975&r2=382976
==============================================================================
--- team/dlee/stasis-http/res/res_stasis_http.c (original)
+++ team/dlee/stasis-http/res/res_stasis_http.c Tue Mar 12 17:14:08 2013
@@ -83,39 +83,48 @@
#include <sys/stat.h>
#include <unistd.h>
-/*! Handler for root RESTful resource */
+/*! Handler for root RESTful resource. */
static struct stasis_rest_handlers *root_handler;
-/*!
- * \internal
- * \brief Fill in an error \a stasis_http_response.
- * \param response Response to fill in.
- * \param message Error message.
- * \param response_code HTTP response code.
- * \param response_text Text corresponding to the HTTP response code.
- */
-static void response_error(struct stasis_http_response *response,
- const char *message,
- int response_code,
- const char *response_text)
-{
- response->message = ast_json_pack("{s: s}", "message", message);
+/*! Pre-defined message for allocation failures. */
+static struct ast_json *alloc_failed_message;
+
+void stasis_http_response_error(struct stasis_http_response *response,
+ int response_code,
+ const char *response_text,
+ const char *message_fmt, ...)
+{
+ RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+ va_list ap;
+
+ va_start(ap, message_fmt);
+ message = ast_json_vstringf(message_fmt, ap);
+ response->message = ast_json_pack("{s: o}",
+ "message", ast_json_ref(message));
response->response_code = response_code;
response->response_text = response_text;
}
-/*!
- * \internal
- * \brief Fill in an OK \a stasis_http_response.
- * \param response Response to fill in. This reference is stolen, so just
- * \ref ast_json_incref if you need to keep a reference to it.
- * \param message JSON response.
- */
-static void response_ok(struct stasis_http_response *response, struct ast_json *message)
+void stasis_http_response_ok(struct stasis_http_response *response,
+ struct ast_json *message)
{
response->message = message;
response->response_code = 200;
response->response_text = "OK";
+}
+
+void stasis_http_response_no_content(struct stasis_http_response *response)
+{
+ response->message = NULL;
+ response->response_code = 204;
+ response->response_text = "No Content";
+}
+
+void stasis_http_response_alloc_failed(struct stasis_http_response *response)
+{
+ response->message = ast_json_ref(alloc_failed_message);
+ response->response_code = 500;
+ response->response_text = "Internal Server Error";
}
static void add_allow_header(struct stasis_rest_handlers *handler,
@@ -160,8 +169,7 @@
allow = ast_str_create(20);
if (!allow) {
- response_error(response, "Allocation failed", 500,
- "Internal Server Error");
+ stasis_http_response_alloc_failed(response);
return;
}
@@ -227,7 +235,9 @@
if (found_handler == NULL) {
/* resource not found */
ast_debug(3, " Handler not found\n");
- response_error(response, "Resource not found", 404, "Not Found");
+ stasis_http_response_error(
+ response, 404, "Not Found",
+ "Resource not found");
return;
} else {
ast_debug(3, " Got it!\n");
@@ -243,14 +253,18 @@
if (method < 0 || method >= AST_HTTP_MAX_METHOD) {
add_allow_header(handler, response);
- response_error(response, "Invalid method", 405, "Method Not Allowed");
+ stasis_http_response_error(
+ response, 405, "Method Not Allowed",
+ "Invalid method");
return;
}
callback = handler->callbacks[method];
if (callback == NULL) {
add_allow_header(handler, response);
- response_error(response, "Unsupported method", 405, "Method Not Allowed");
+ stasis_http_response_error(
+ response, 405, "Method Not Allowed",
+ "Invalid method");
return;
}
@@ -258,12 +272,16 @@
if (response->message == NULL && response->response_code == 0) {
/* Really should not happen */
ast_assert(0);
- response_error(response, "Method not implemented", 418, "I'm a teapot");
- }
-}
-
-void stasis_http_get_docs(const char *uri, struct ast_variable *headers, struct stasis_http_response *response) {
- RAII_VAR(struct ast_str *, absolute_path_builder, ast_str_create(80), ast_free);
+ stasis_http_response_error(
+ response, 418, "I'm a teapot",
+ "Method not implemented");
+ }
+}
+
+void stasis_http_get_docs(const char *uri, struct ast_variable *headers,
+ struct stasis_http_response *response)
+{
+ RAII_VAR(struct ast_str *, absolute_path_builder, NULL, ast_free);
RAII_VAR(char *, absolute_api_dirname, NULL, free);
RAII_VAR(char *, absolute_filename, NULL, free);
struct ast_json *obj = NULL;
@@ -273,9 +291,9 @@
ast_debug(3, "%s(%s)\n", __func__, uri);
+ absolute_path_builder = ast_str_create(80);
if (absolute_path_builder == NULL) {
- ast_log(LOG_ERROR, "Allocation failed\n");
- response_error(response, "Allocation failed", 500, "Internal Server Error");
+ stasis_http_response_alloc_failed(response);
return;
}
@@ -285,7 +303,9 @@
absolute_api_dirname = realpath(ast_str_buffer(absolute_path_builder), NULL);
if (absolute_api_dirname == NULL) {
ast_log(LOG_ERROR, "Error determining real directory for rest-api\n");
- response_error(response, "Cannot find rest-api directory", 500, "Internal Server Error");
+ stasis_http_response_error(
+ response, 500, "Internal Server Error",
+ "Cannot find rest-api directory");
return;
}
@@ -297,14 +317,22 @@
case ENAMETOOLONG:
case ENOENT:
case ENOTDIR:
- response_error(response, "Resource not found", 404, "Not Found");
+ stasis_http_response_error(
+ response, 404, "Not Found",
+ "Resource not found");
break;
case EACCES:
- response_error(response, "Permission denied", 403, "Forbidden");
+ stasis_http_response_error(
+ response, 403, "Forbidden",
+ "Permission denied");
break;
default:
- ast_log(LOG_ERROR, "Error determining real path for uri '%s': %s\n", uri, strerror(errno));
- response_error(response, "Cannot find file", 500, "Internal Server Error");
+ ast_log(LOG_ERROR,
+ "Error determining real path for uri '%s': %s\n",
+ uri, strerror(errno));
+ stasis_http_response_error(
+ response, 500, "Internal Server Error",
+ "Cannot find file");
break;
}
return;
@@ -312,27 +340,37 @@
if (!ast_begins_with(absolute_filename, absolute_api_dirname)) {
/* HACKERZ! */
- ast_log(LOG_ERROR, "Invalid attempt to access '%s' (not in %s)\n", absolute_filename, absolute_api_dirname);
- response_error(response, "Resource not found", 404, "Not Found");
+ ast_log(LOG_ERROR,
+ "Invalid attempt to access '%s' (not in %s)\n",
+ absolute_filename, absolute_api_dirname);
+ stasis_http_response_error(
+ response, 404, "Not Found",
+ "Resource not found");
return;
}
if (stat(absolute_filename, &file_stat) == 0) {
if (!(file_stat.st_mode & S_IFREG)) {
/* Not a file */
- response_error(response, "Invalid access", 403, "Forbidden");
+ stasis_http_response_error(
+ response, 403, "Forbidden",
+ "Invalid access");
return;
}
} else {
/* Does not exist */
- response_error(response, "Resource not found", 404, "Not Found");
+ stasis_http_response_error(
+ response, 404, "Not Found",
+ "Resource not found");
return;
}
/* Load resource object from file */
obj = ast_json_load_new_file(absolute_filename, &error);
if (obj == NULL) {
- response_error(response, "Yikes! Cannot parse resource", 500, "Internal Server Error");
+ stasis_http_response_error(
+ response, 500, "Internal Server Error",
+ "Yikes! Cannot parse resource");
return;
}
@@ -344,14 +382,28 @@
}
}
if (host != NULL) {
- ast_json_object_set(obj, "basePath", ast_json_stringf("http://%s/stasis", host->value));
+ ast_json_object_set(
+ obj, "basePath",
+ ast_json_stringf("http://%s/stasis", host->value));
} else {
/* Without the host, we don't have the basePath */
ast_json_object_del(obj, "basePath");
}
}
- response_ok(response, obj);
+ stasis_http_response_ok(response, obj);
+}
+
+static void remove_trailing_slash(const char *uri,
+ struct stasis_http_response *response)
+{
+ char *slashless = ast_strdupa(uri);
+ slashless[strlen(slashless) - 1] = '\0';
+
+ ast_str_append(&response->headers, 0,
+ "Location: /stasis/%s\r\n", slashless);
+ stasis_http_response_error(response, 302, "Found",
+ "Redirecting to %s", slashless);
}
/*!
@@ -381,22 +433,13 @@
int ret = 0;
if (!response_headers || !response_body) {
- ast_log(LOG_ERROR, "Allocation failure!\n");
return -1;
}
response.headers = ast_str_create(40);
if (ast_ends_with(uri, "/")) {
- char *slashless = ast_strdupa(uri);
- slashless[strlen(slashless) - 1] = '\0';
-
- ast_str_append(&response_headers, 0,
- "Location: /stasis/%s\r\n", slashless);
-
- response.message = ast_json_pack("{s: o}", "message", ast_json_stringf("Redirecting to %s", slashless));
- response.response_code = 302;
- response.response_text = "Found";
+ remove_trailing_slash(uri, &response);
} else if (ast_begins_with(uri, "api/")) {
/* Other RESTful resources */
stasis_http_invoke(uri, method, get_params, headers, &response);
@@ -472,6 +515,9 @@
{
int r = 0;
+ alloc_failed_message = ast_json_pack("{s: s}",
+ "message", "Allocation failed");
+
stasis_set_root_handler(stasis_default_root_handler());
r |= ast_http_uri_link(&http_uri);
return r;
@@ -481,6 +527,8 @@
{
int r = 0;
+ ast_json_unref(alloc_failed_message);
+ alloc_failed_message = NULL;
ast_http_uri_unlink(&http_uri);
return r;
}
Modified: team/dlee/stasis-http/res/stasis_http/resource_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/res/stasis_http/resource_channels.c?view=diff&rev=382976&r1=382975&r2=382976
==============================================================================
--- team/dlee/stasis-http/res/stasis_http/resource_channels.c (original)
+++ team/dlee/stasis-http/res/stasis_http/resource_channels.c Tue Mar 12 17:14:08 2013
@@ -34,41 +34,6 @@
#include "asterisk/app_stasis.h"
#include "asterisk/channel.h"
#include "resource_channels.h"
-
-static void fill_error(struct stasis_http_response *response, int response_code,
- const char *response_text, const char *message)
-{
- response->message = ast_json_pack("{s: s}", "message", message);
- if (response->message) {
- response->response_code = response_code;
- response->response_text = response_text;
- } else {
- /* Error sending the error; great. */
- response->response_code = 500;
- response->response_text = "Internal Server Error";
- response->message =
- ast_json_pack("{s: s}", "message", "Allocation failed");
- }
-}
-
-static void fill_ok(struct stasis_http_response *response,
- struct ast_json *message)
-{
- if (!message) {
- fill_error(response, 500, "Internal Server Error",
- "Allocation failed");
- }
-
- response->response_code = 200;
- response->response_text = "OK";
- response->message = message;
-}
-
-static void fill_no_content(struct stasis_http_response *response)
-{
- response->response_code = 204;
- response->response_text = "No Content";
-}
/*!
* \brief Finds the control object for a channel, filling the response with an
@@ -92,12 +57,12 @@
RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup);
chan = ast_channel_get_by_name(channel_id);
if (chan == NULL) {
- fill_error(response, 404, "Not Found",
+ stasis_http_response_error(response, 404, "Not Found",
"Channel not found");
return NULL;
}
- fill_error(response, 409, "Conflict",
+ stasis_http_response_error(response, 409, "Conflict",
"Channel not in Stasis application");
return NULL;
}
@@ -111,7 +76,10 @@
ast_log(LOG_ERROR, "TODO: stasis_http_dial\n");
}
-void stasis_http_continue_in_dialplan(struct ast_variable *headers, struct ast_continue_in_dialplan_args *args, struct stasis_http_response *response)
+void stasis_http_continue_in_dialplan(
+ struct ast_variable *headers,
+ struct ast_continue_in_dialplan_args *args,
+ struct stasis_http_response *response)
{
RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
@@ -123,7 +91,7 @@
}
stasis_app_control_continue(control);
- fill_no_content(response);
+ stasis_http_response_no_content(response);
}
void stasis_http_reject_channel(struct ast_variable *headers, struct ast_reject_channel_args *args, struct stasis_http_response *response)
@@ -143,12 +111,13 @@
}
if (stasis_app_control_answer(control) != 0) {
- fill_error(response, 500, "Internal Server Error",
- "Failed to answer channel");
- return;
- }
-
- fill_no_content(response);
+ stasis_http_response_error(
+ response, 500, "Internal Server Error",
+ "Failed to answer channel");
+ return;
+ }
+
+ stasis_http_response_no_content(response);
}
void stasis_http_mute_channel(struct ast_variable *headers, struct ast_mute_channel_args *args, struct stasis_http_response *response)
@@ -163,7 +132,9 @@
{
ast_log(LOG_ERROR, "TODO: stasis_http_record_channel\n");
}
-void stasis_http_get_channel(struct ast_variable *headers, struct ast_get_channel_args *args, struct stasis_http_response *response)
+void stasis_http_get_channel(struct ast_variable *headers,
+ struct ast_get_channel_args *args,
+ struct stasis_http_response *response)
{
RAII_VAR(struct stasis_caching_topic *, caching_topic, NULL, ao2_cleanup);
RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
@@ -171,21 +142,27 @@
caching_topic = ast_channel_topic_all_cached();
if (!caching_topic) {
- fill_error(response, 500, "Internal Server Error", "Message bus not initialized");
+ stasis_http_response_error(
+ response, 500, "Internal Server Error",
+ "Message bus not initialized");
return;
}
ao2_ref(caching_topic, +1);
- msg = stasis_cache_get(caching_topic, ast_channel_snapshot(), args->channel_id);
+ msg = stasis_cache_get(caching_topic, ast_channel_snapshot(),
+ args->channel_id);
if (!msg) {
- fill_error(response, 404, "Not Found", "Channel not found");
+ stasis_http_response_error(
+ response, 404, "Not Found",
+ "Channel not found");
return;
}
snapshot = stasis_message_data(msg);
ast_assert(snapshot != NULL);
- fill_ok(response, ast_channel_snapshot_to_json(snapshot));
+ stasis_http_response_ok(response,
+ ast_channel_snapshot_to_json(snapshot));
}
void stasis_http_delete_channel(struct ast_variable *headers,
@@ -196,40 +173,45 @@
chan = ast_channel_get_by_name(args->channel_id);
if (chan == NULL) {
- fill_error(response, 404, "Not Found",
- "Channel not found");
+ stasis_http_response_error(
+ response, 404, "Not Found",
+ "Channel not found");
return;
}
ast_softhangup(chan, AST_SOFTHANGUP_EXPLICIT);
- fill_no_content(response);
-}
-
-void stasis_http_get_channels(struct ast_variable *headers, struct ast_get_channels_args *args, struct stasis_http_response *response)
+ stasis_http_response_no_content(response);
+}
+
+void stasis_http_get_channels(struct ast_variable *headers,
+ struct ast_get_channels_args *args,
+ struct stasis_http_response *response)
{
RAII_VAR(struct stasis_caching_topic *, caching_topic, NULL, ao2_cleanup);
RAII_VAR(struct ao2_container *, snapshots, NULL, ao2_cleanup);
- RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
+ RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
struct ao2_iterator i;
void *obj;
caching_topic = ast_channel_topic_all_cached();
if (!caching_topic) {
- fill_error(response, 500, "Internal Server Error", "Message bus not initialized");
+ stasis_http_response_error(
+ response, 500, "Internal Server Error",
+ "Message bus not initialized");
return;
}
ao2_ref(caching_topic, +1);
snapshots = stasis_cache_dump(caching_topic, ast_channel_snapshot());
if (!snapshots) {
- fill_error(response, 500, "Internal Server Error", "Allocation failed");
- return;
- }
-
- message = ast_json_array_create();
- if (!message) {
- fill_error(response, 500, "Internal Server Error", "Allocation failed");
+ stasis_http_response_alloc_failed(response);
+ return;
+ }
+
+ json = ast_json_array_create();
+ if (!json) {
+ stasis_http_response_alloc_failed(response);
return;
}
@@ -237,17 +219,21 @@
while ((obj = ao2_iterator_next(&i))) {
RAII_VAR(struct stasis_message *, msg, obj, ao2_cleanup);
struct ast_channel_snapshot *snapshot = stasis_message_data(msg);
- if (ast_json_array_append(message, ast_channel_snapshot_to_json(snapshot))) {
- fill_error(response, 500, "Internal Server Error", "Allocation failed");
+ int r = ast_json_array_append(
+ json, ast_channel_snapshot_to_json(snapshot));
+ if (r != 0) {
+ stasis_http_response_alloc_failed(response);
return;
}
}
ao2_iterator_destroy(&i);
- fill_ok(response, ast_json_ref(message));
-}
-
-void stasis_http_originate(struct ast_variable *headers, struct ast_originate_args *args, struct stasis_http_response *response)
+ stasis_http_response_ok(response, ast_json_ref(json));
+}
+
+void stasis_http_originate(struct ast_variable *headers,
+ struct ast_originate_args *args,
+ struct stasis_http_response *response)
{
if (args->endpoint) {
ast_log(LOG_DEBUG, "Dialing specific endpoint %s\n", args->endpoint);
More information about the asterisk-commits
mailing list