From: Seonah Moon Date: Fri, 16 Apr 2021 08:08:43 +0000 (+0900) Subject: Add set/get_token plugin API X-Git-Tag: submit/tizen/20210426.035717~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0bf1bd615ba66a98343cef5543f3ea70cec7ccbb;p=platform%2Fcore%2Fapi%2Fvine.git Add set/get_token plugin API Change-Id: Ic0ffb001c9d20be9dba35ea11cc0597782d3883c --- diff --git a/plugins/libwebsockets/libwebsockets-plugin.cpp b/plugins/libwebsockets/libwebsockets-plugin.cpp index 99cacd7..1e6ad62 100755 --- a/plugins/libwebsockets/libwebsockets-plugin.cpp +++ b/plugins/libwebsockets/libwebsockets-plugin.cpp @@ -27,6 +27,7 @@ #include "vine-data-path-plugin.h" +#include "vine-constants.h" #include "vine-log.h" #include "vine-utils.h" #include "vine-queue.h" @@ -50,6 +51,10 @@ typedef struct { bool close_requested; int curr_conn; int max_conn; + + unsigned char *token; + int token_len; + VineQueue *recv_buffer; VineQueue *write_buffer; void *user; // vine_data_path_h @@ -97,6 +102,9 @@ static struct lws_protocols protocols[] = { { NULL, NULL, 0, 0 } /* terminator */ }; +#define VINE_SERVICE_NAME_HEADER "vine-service-name:" +#define VINE_SERVICE_NAME_HEADER_LEN 18 + static void websocket_process_event(int fd, int events); static void _connect_server(websocket_s *ws, int addr_family, const char *ip, int port, const char *iface_name, vine_dp_ssl ssl); @@ -353,18 +361,52 @@ static int _websocket_protocol_cb(struct lws *wsi, break; /* --- serving callbacks --- */ - case LWS_CALLBACK_ESTABLISHED: { - VINE_LOGI("Websocket connection is established."); - // When client is connected, ws(wsi->user_space) is automatically allocated by lws. + case LWS_CALLBACK_HTTP_CONFIRM_UPGRADE: { + //In LWS_CALLBACK_ESTABLISHED, ws(wsi->user_space) is automatically allocated by lws. // So lws has the ownership of a user data. - // Reset a user data to own the memory. + // Set a user data before lws allocates the memory to own the memory. + // If user_space is already exist, lws doesn't assign it. websocket_s *client_ws = (websocket_s *)calloc(1, sizeof(websocket_s)); if (!client_ws) - return 0; + return -1; + client_ws->wsi = wsi; lws_set_wsi_user(wsi, client_ws); - vhd->curr_conn++; + client_ws->token_len = lws_hdr_custom_length(wsi, VINE_SERVICE_NAME_HEADER, + strlen(VINE_SERVICE_NAME_HEADER)); + if (client_ws->token_len < 0) { + VINE_LOGI("Cannot find %s header.", VINE_SERVICE_NAME_HEADER); + return 0; + } + + char *service_name = (char *)calloc(client_ws->token_len + 1, + sizeof(char)); + if (!service_name) { + lws_set_wsi_user(wsi, NULL); + free(client_ws); + return -1; + } + + if (lws_hdr_custom_copy(wsi, service_name, sizeof(service_name), + VINE_SERVICE_NAME_HEADER, strlen(VINE_SERVICE_NAME_HEADER)) < 0) { + VINE_LOGE("Failed to get custom header."); + free(service_name); + lws_set_wsi_user(wsi, NULL); + free(client_ws); + return -1; + } + + client_ws->token = (unsigned char *)service_name; + VINE_LOGE("Peer service name[%s]", client_ws->token); + break; + } + + case LWS_CALLBACK_ESTABLISHED: { + VINE_LOGI("Websocket connection is established."); + + websocket_s *client_ws = (websocket_s *)lws_wsi_user(wsi); + vhd->curr_conn++; if (g_callbacks.accepted_cb) { char ip[INET6_ADDRSTRLEN]; int port; @@ -421,6 +463,21 @@ static int _websocket_protocol_cb(struct lws *wsi, g_callbacks.connected_cb(-1, ws->user); break; + case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: { + if (!ws || !ws->token) + return 0; + + VINE_LOGI("Add custom header."); + unsigned char **p = (unsigned char **) in, *end = (*p) + len; + unsigned char hdr[VINE_SERVICE_NAME_HEADER_LEN + 1] = {0, }; + memcpy(hdr, VINE_SERVICE_NAME_HEADER, VINE_SERVICE_NAME_HEADER_LEN); + if (lws_add_http_header_by_name(wsi, hdr, ws->token, ws->token_len, p, end) < 0) { + VINE_LOGE("Failed to add custom header."); + return -1; + } + break; + } + case LWS_CALLBACK_CLIENT_ESTABLISHED: VINE_LOGI("Connected with server."); if (ws && g_callbacks.connected_cb) @@ -822,6 +879,8 @@ static int websocket_create(vine_dp_plugin_h *handle, void *plugin_data, void *u ws->close_requested = false; ws->curr_conn = 0; ws->max_conn = 0; + ws->token = NULL; + ws->token_len = 0; ws->user = user; ws->recv_buffer = new VineQueue; ws->write_buffer = new VineQueue; @@ -840,6 +899,10 @@ static int websocket_destroy(vine_dp_plugin_h handle) ws->vh = NULL; ws->user = NULL; + free(ws->token); + ws->token = NULL; + ws->token_len = 0; + delete ws->recv_buffer; delete ws->write_buffer; @@ -856,6 +919,36 @@ static void websocket_register_callbacks(vine_dp_plugin_callbacks callbacks) g_callbacks = callbacks; } +static int websocket_set_token(vine_dp_plugin_h handle, const char *token) +{ + RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL"); + + websocket_s *ws = (websocket_s *)handle; + int len = strlen(token); + if (len < 0) + return -1; + + ws->token_len = len; + ws->token = (unsigned char *)calloc(len, sizeof(unsigned char)); + memcpy(ws->token, token, ws->token_len); + return VINE_DATA_PATH_ERROR_NONE; +} + +static int websocket_get_token(vine_dp_plugin_h handle, char **token) +{ + RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL"); + + websocket_s *ws = (websocket_s *)handle; + if (!ws->token || ws->token_len <= 0) { + *token = NULL; + return VINE_DATA_PATH_ERROR_INVALID_OPERATION; + } + + *token = (char *)calloc(ws->token_len, sizeof(char)); + memcpy(*token, ws->token, ws->token_len); + return VINE_DATA_PATH_ERROR_NONE; +} + void vine_data_path_plugin_init(vine_dp_plugin_fn *fn) { fn->init = websocket_init; @@ -870,4 +963,7 @@ void vine_data_path_plugin_init(vine_dp_plugin_fn *fn) fn->read = websocket_read; fn->write = websocket_write; fn->close = websocket_close; + + fn->set_token = websocket_set_token; + fn->get_token = websocket_get_token; } diff --git a/src/include/vine-data-path-plugin.h b/src/include/vine-data-path-plugin.h index dea2fb6..87d7496 100755 --- a/src/include/vine-data-path-plugin.h +++ b/src/include/vine-data-path-plugin.h @@ -100,6 +100,13 @@ typedef struct { int (*read)(vine_dp_plugin_h handle, unsigned char *buf, size_t len); int (*write)(vine_dp_plugin_h handle, unsigned char *buf, size_t len); int (*close)(vine_dp_plugin_h handle); + + // The token means an additional information which is used during connection establishing. + // The way to send it can be different based on a plugin. + // In case of libwebsockets, send it through a HTTP custom header. + // DPPubSub uses it to inform own service name to a peer. + int (*set_token)(vine_dp_plugin_h handle, const char *token); + int (*get_token)(vine_dp_plugin_h handle, char **token); } vine_dp_plugin_fn; extern "C" void vine_data_path_plugin_init(vine_dp_plugin_fn *fn); diff --git a/src/include/vine-data-path.h b/src/include/vine-data-path.h index b2b9f1c..e622aad 100755 --- a/src/include/vine-data-path.h +++ b/src/include/vine-data-path.h @@ -65,6 +65,7 @@ int vine_data_path_connect(vine_address_family_e addr_family, vine_event_queue_h event_fd); int vine_data_path_set_terminated_cb(vine_data_path_h datapath, vine_data_path_terminated_cb callback, void *user_data); +int vine_data_path_get_token(vine_data_path_h datapath, char **token); vine_security_h _vine_dp_get_security(vine_data_path_h datapath); diff --git a/src/vine-data-path.cpp b/src/vine-data-path.cpp index dff898a..25a62ae 100755 --- a/src/vine-data-path.cpp +++ b/src/vine-data-path.cpp @@ -722,6 +722,16 @@ int vine_data_path_set_terminated_cb(vine_data_path_h datapath, return VINE_ERROR_NONE; } +int vine_data_path_get_token(vine_data_path_h datapath, char **token) +{ + RET_VAL_IF(datapath == NULL, VINE_ERROR_INVALID_PARAMETER, "datapath is NULL"); + RET_VAL_IF(token == NULL, VINE_ERROR_INVALID_PARAMETER, "token is NULL"); + + vine_data_path_s *dp = (vine_data_path_s *)datapath; + int ret = g_dp_plugin_fn.get_token(dp->plugin_handle, token); + return __convert_data_path_error_to_vine_error((vine_data_path_error)ret); +} + vine_security_h _vine_dp_get_security(vine_data_path_h datapath) { RET_VAL_IF(datapath == NULL, NULL, "datapath is NULL");