summaryrefslogtreecommitdiff
path: root/res/res_http_websocket.c
diff options
context:
space:
mode:
Diffstat (limited to 'res/res_http_websocket.c')
-rw-r--r--res/res_http_websocket.c55
1 files changed, 46 insertions, 9 deletions
diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c
index 129e92c19..b03745e6f 100644
--- a/res/res_http_websocket.c
+++ b/res/res_http_websocket.c
@@ -107,18 +107,24 @@ struct ast_websocket_server {
struct ao2_container *protocols; /*!< Container for registered protocols */
};
-static void websocket_server_dtor(void *obj)
+static void websocket_server_internal_dtor(void *obj)
{
struct ast_websocket_server *server = obj;
ao2_cleanup(server->protocols);
server->protocols = NULL;
}
-struct ast_websocket_server *ast_websocket_server_create(void)
+static void websocket_server_dtor(void *obj)
+{
+ websocket_server_internal_dtor(obj);
+ ast_module_unref(ast_module_info->self);
+}
+
+static struct ast_websocket_server *websocket_server_create_impl(void (*dtor)(void *))
{
RAII_VAR(struct ast_websocket_server *, server, NULL, ao2_cleanup);
- server = ao2_alloc(sizeof(*server), websocket_server_dtor);
+ server = ao2_alloc(sizeof(*server), dtor);
if (!server) {
return NULL;
}
@@ -132,6 +138,17 @@ struct ast_websocket_server *ast_websocket_server_create(void)
return server;
}
+static struct ast_websocket_server *websocket_server_internal_create(void)
+{
+ return websocket_server_create_impl(websocket_server_internal_dtor);
+}
+
+struct ast_websocket_server *AST_OPTIONAL_API_NAME(ast_websocket_server_create)(void)
+{
+ ast_module_ref(ast_module_info->self);
+ return websocket_server_create_impl(websocket_server_dtor);
+}
+
/*! \brief Destructor function for sessions */
static void session_destroy_fn(void *obj)
{
@@ -512,7 +529,7 @@ static struct websocket_protocol *one_protocol(
return ao2_callback(server->protocols, OBJ_NOLOCK, NULL, NULL);
}
-int ast_websocket_uri_cb(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_vars, struct ast_variable *headers)
+int AST_OPTIONAL_API_NAME(ast_websocket_uri_cb)(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_vars, struct ast_variable *headers)
{
struct ast_variable *v;
char *upgrade = NULL, *key = NULL, *key1 = NULL, *key2 = NULL, *protos = NULL, *requested_protocols = NULL, *protocol = NULL;
@@ -521,6 +538,8 @@ int ast_websocket_uri_cb(struct ast_tcptls_session_instance *ser, const struct a
struct ast_websocket *session;
struct ast_websocket_server *server;
+ SCOPED_MODULE_USE(ast_module_info->self);
+
/* Upgrade requests are only permitted on GET methods */
if (method != AST_HTTP_GET) {
ast_http_error(ser, 501, "Not Implemented", "Attempt to use unimplemented / unsupported method");
@@ -674,7 +693,7 @@ int ast_websocket_uri_cb(struct ast_tcptls_session_instance *ser, const struct a
}
static struct ast_http_uri websocketuri = {
- .callback = ast_websocket_uri_cb,
+ .callback = AST_OPTIONAL_API_NAME(ast_websocket_uri_cb),
.description = "Asterisk HTTP WebSocket",
.uri = "ws",
.has_subtree = 0,
@@ -719,7 +738,7 @@ end:
ast_websocket_unref(session);
}
-int AST_OPTIONAL_API_NAME(ast_websocket_add_protocol)(const char *name, ast_websocket_callback callback)
+static int websocket_add_protocol_internal(const char *name, ast_websocket_callback callback)
{
struct ast_websocket_server *ws_server = websocketuri.data;
if (!ws_server) {
@@ -728,7 +747,16 @@ int AST_OPTIONAL_API_NAME(ast_websocket_add_protocol)(const char *name, ast_webs
return ast_websocket_server_add_protocol(ws_server, name, callback);
}
-int AST_OPTIONAL_API_NAME(ast_websocket_remove_protocol)(const char *name, ast_websocket_callback callback)
+int AST_OPTIONAL_API_NAME(ast_websocket_add_protocol)(const char *name, ast_websocket_callback callback)
+{
+ int res = websocket_add_protocol_internal(name, callback);
+ if (res == 0) {
+ ast_module_ref(ast_module_info->self);
+ }
+ return res;
+}
+
+static int websocket_remove_protocol_internal(const char *name, ast_websocket_callback callback)
{
struct ast_websocket_server *ws_server = websocketuri.data;
if (!ws_server) {
@@ -737,14 +765,23 @@ int AST_OPTIONAL_API_NAME(ast_websocket_remove_protocol)(const char *name, ast_w
return ast_websocket_server_remove_protocol(ws_server, name, callback);
}
+int AST_OPTIONAL_API_NAME(ast_websocket_remove_protocol)(const char *name, ast_websocket_callback callback)
+{
+ int res = websocket_remove_protocol_internal(name, callback);
+ if (res == 0) {
+ ast_module_unref(ast_module_info->self);
+ }
+ return res;
+}
+
static int load_module(void)
{
- websocketuri.data = ast_websocket_server_create();
+ websocketuri.data = websocket_server_internal_create();
if (!websocketuri.data) {
return AST_MODULE_LOAD_FAILURE;
}
ast_http_uri_link(&websocketuri);
- ast_websocket_add_protocol("echo", websocket_echo_callback);
+ websocket_add_protocol_internal("echo", websocket_echo_callback);
return 0;
}