diff --git a/ft/node_test.robot b/ft/node_test.robot index 660072ff..8a65b412 100644 --- a/ft/node_test.robot +++ b/ft/node_test.robot @@ -59,6 +59,19 @@ Get APP node, it should be success. Check Response Status ${res} 200 Node Should Exist ${res}[nodes] mqtt-node +Update node name to empty string, it should fail. + ${res} = Update Node modbus-node ${EMPTY} + + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_NODE_NAME_EMPTY} + +Update node name to excessive long string, it should fail. + ${name} = Evaluate 'a'*200 + ${res} = Update Node modbus-node ${name} + + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_NODE_NAME_TOO_LONG} + Update driver node name, it should fail if the node does not exist ${res} = Update Node modbus-node-nonexistent mqtt-node diff --git a/ft/template.robot b/ft/template.robot index a30c3387..327f4c96 100644 --- a/ft/template.robot +++ b/ft/template.robot @@ -126,12 +126,26 @@ Create a template with singleton plugin, it should fail. [Teardown] Del Template ${g_template} +Create a template with north plugin, it should fail. + ${res} = Add Template ${g_template} MQTT ${g_empty} + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_PLUGIN_NOT_SUPPORT_TEMPLATE} + + [Teardown] Del Template ${g_template} + + Get nonexistent template, it should fail. ${res} = Get Template ${g_template} Check Response Status ${res} 404 Check Error Code ${res} ${NEU_ERR_TEMPLATE_NOT_FOUND} +Get a template using too long name query parameter, it should fail. + ${res} = Get Template ${g_long_str} + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_PARAM_IS_WRONG} + + Get an existent template having no groups, it should success. ${res} = Add Template ${g_template} ${g_plugin} ${g_empty} Check Response Status ${res} 200 @@ -186,6 +200,12 @@ Delete a nonexistent template, it should fail. Check Error Code ${res} ${NEU_ERR_TEMPLATE_NOT_FOUND} +Delete a template using too long name query parameter, it should fail. + ${res} = Del Template ${g_long_str} + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_PARAM_IS_WRONG} + + Delete an existent template, it should success. ${res} = Add Template ${g_template} ${g_plugin} ${g_empty} Check Response Status ${res} 200 @@ -311,6 +331,18 @@ Add group with invalid interval to existing template, it should fail. [Teardown] Del Template ${g_template} +Add group using too long template name in request, it should fail. + ${res} = Add Template ${g_template} ${g_plugin} ${g_empty} + Check Response Status ${res} 200 + Check Error Code ${res} ${NEU_ERR_SUCCESS} + + ${res} = Add Template Group ${g_long_str} ${g_group1}[name] ${2000} + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_TEMPLATE_NAME_TOO_LONG} + + [Teardown] Del Template ${g_template} + + Add group with too long name to existing template, it should fail. ${res} = Add Template ${g_template} ${g_plugin} ${g_empty} Check Response Status ${res} 200 @@ -346,6 +378,18 @@ Get groups from nonexistent template, it should fail. Check Error Code ${res} ${NEU_ERR_TEMPLATE_NOT_FOUND} +Get groups using too long name query parameter, it should fail. + ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} + Check Response Status ${res} 200 + Check Error Code ${res} ${NEU_ERR_SUCCESS} + + ${res} = Get Template Groups ${g_long_str} + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_PARAM_IS_WRONG} + + [Teardown] Del Template ${g_template} + + Get groups when there are no groups, it should return empty result. ${res} = Add Template ${g_template} ${g_plugin} ${g_empty} Check Response Status ${res} 200 @@ -379,6 +423,30 @@ Update group interval when template does not exist, it should fail. [Teardown] Del Template ${g_template} +Update group using too long template name in request, it should fail. + ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} + Check Response Status ${res} 200 + Check Error Code ${res} ${NEU_ERR_SUCCESS} + + ${res} = Put Template Group ${g_long_str} ${g_group1}[name] ${2000} + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_TEMPLATE_NAME_TOO_LONG} + + [Teardown] Del Template ${g_template} + + +Update group using too long group name in request, it should fail. + ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} + Check Response Status ${res} 200 + Check Error Code ${res} ${NEU_ERR_SUCCESS} + + ${res} = Put Template Group ${g_template} ${g_long_str} ${2000} + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_GROUP_NAME_TOO_LONG} + + [Teardown] Del Template ${g_template} + + Update group interval when group does not exist, it should fail. ${res} = Add Template ${g_template} ${g_plugin} ${g_empty} Check Response Status ${res} 200 @@ -438,6 +506,30 @@ Delete nonexistent group from existent template, it should fail. [Teardown] Del Template ${g_template} +Delete group using too long template name in request, it should fail. + ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} + Check Response Status ${res} 200 + Check Error Code ${res} ${NEU_ERR_SUCCESS} + + ${res} = Del Template Group ${g_long_str} ${g_group1}[name] + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_TEMPLATE_NAME_TOO_LONG} + + [Teardown] Del Template ${g_template} + + +Delete group using too long group name in request, it should fail. + ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} + Check Response Status ${res} 200 + Check Error Code ${res} ${NEU_ERR_SUCCESS} + + ${res} = Del Template Group ${g_template} ${g_long_str} + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_GROUP_NAME_TOO_LONG} + + [Teardown] Del Template ${g_template} + + Delete group from existent template, it should success. ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} Check Response Status ${res} 200 @@ -526,6 +618,26 @@ Add tag with conflicting name to existing template group, it should fail. [Teardown] Del Template ${g_template} +Add tag using too long template name in request, it should fail. + Add Template And One Group ${g_template} ${g_plugin} ${g_group1}[name] ${g_group1}[interval] + + ${res} = Add Template Tags ${g_long_str} ${g_group1}[name] ${g_tag1} + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_TEMPLATE_NAME_TOO_LONG} + + [Teardown] Del Template ${g_template} + + +Add tag using too long group name in request, it should fail. + Add Template And One Group ${g_template} ${g_plugin} ${g_group1}[name] ${g_group1}[interval] + + ${res} = Add Template Tags ${g_template} ${g_long_str} ${g_tag1} + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_GROUP_NAME_TOO_LONG} + + [Teardown] Del Template ${g_template} + + Add tag with too long name to existing template group, it should fail. Add Template And One Group ${g_template} ${g_plugin} ${g_group1}[name] ${g_group1}[interval] @@ -601,6 +713,30 @@ Get tags from nonexistent template group, it should fail. [Teardown] Del Template ${g_template} +Get tags using too long template name query parameter, it should fail. + ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} + Check Response Status ${res} 200 + Check Error Code ${res} ${NEU_ERR_SUCCESS} + + ${res} = Get Template Tags ${g_long_str} ${g_group1}[name] + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_PARAM_IS_WRONG} + + [Teardown] Del Template ${g_template} + + +Get tags using too long group name query parameter, it should fail. + ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} + Check Response Status ${res} 200 + Check Error Code ${res} ${NEU_ERR_SUCCESS} + + ${res} = Get Template Tags ${g_template} ${g_long_str} + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_PARAM_IS_WRONG} + + [Teardown] Del Template ${g_template} + + Get tags when there are none from existent template group, it should return empty result. Add Template And One Group ${g_template} ${g_plugin} ${g_group1}[name] ${g_group1}[interval] @@ -623,6 +759,18 @@ Get tags from existent template group, it should return the tags. [Teardown] Del Template ${g_template} +Get tags using too long tag name query parameter, it should fail. + ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} + Check Response Status ${res} 200 + Check Error Code ${res} ${NEU_ERR_SUCCESS} + + ${res} = Grep Template Tags ${g_template} ${g_group1}[name] ${g_long_str} + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_PARAM_IS_WRONG} + + [Teardown] Del Template ${g_template} + + Get tags by name pattern when there is no match, it should return empty result. Add Template And One Group ${g_template} ${g_plugin} ${g_group1}[name] ${g_group1}[interval] @@ -688,6 +836,30 @@ Update tag when template tag does not exist, it should fail. [Teardown] Del Template ${g_template} +Update tag using too long template name in request, it should fail. + ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} + Check Response Status ${res} 200 + Check Error Code ${res} ${NEU_ERR_SUCCESS} + + ${res} = Put Template Tags ${g_long_str} ${g_group1}[name] ${g_tag1} + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_TEMPLATE_NAME_TOO_LONG} + + [Teardown] Del Template ${g_template} + + +Update tag using too long group name in request, it should fail. + ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} + Check Response Status ${res} 200 + Check Error Code ${res} ${NEU_ERR_SUCCESS} + + ${res} = Put Template Tags ${g_template} ${g_long_str} ${g_tag1} + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_GROUP_NAME_TOO_LONG} + + [Teardown] Del Template ${g_template} + + Update tag name to invalid value, it should fail. ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} Check Response Status ${res} 200 @@ -786,6 +958,42 @@ Delete tag when template tag does not exist, it trivially success. [Teardown] Del Template ${g_template} +Delete tag using too long template name in request, it should should fail. + ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} + Check Response Status ${res} 200 + Check Error Code ${res} ${NEU_ERR_SUCCESS} + + ${res} = Del Template Tags ${g_long_str} ${g_group1}[name] ${g_tag1}[name] + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_TEMPLATE_NAME_TOO_LONG} + + [Teardown] Del Template ${g_template} + + +Delete tag using too long group name in request, it should should fail. + ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} + Check Response Status ${res} 200 + Check Error Code ${res} ${NEU_ERR_SUCCESS} + + ${res} = Del Template Tags ${g_template} ${g_long_str} ${g_tag1}[name] + Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_GROUP_NAME_TOO_LONG} + + [Teardown] Del Template ${g_template} + + +Delete tag using too long tag name in request, it should should fail. + ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} + Check Response Status ${res} 200 + Check Error Code ${res} ${NEU_ERR_SUCCESS} + + ${res} = Del Template Tags ${g_template} ${g_group1}[name] ${g_tag1}[name] ${g_long_str} + #Check Response Status ${res} 400 + Check Error Code ${res} ${NEU_ERR_TAG_NAME_TOO_LONG} + + [Teardown] Del Template ${g_template} + + Delete one tag, it should keep other tags untouched. ${res} = Add Template ${g_template} ${g_plugin} ${g_groups} Check Response Status ${res} 200 diff --git a/include/neuron/errcodes.h b/include/neuron/errcodes.h index c4b27423..8f500eea 100644 --- a/include/neuron/errcodes.h +++ b/include/neuron/errcodes.h @@ -45,6 +45,7 @@ typedef enum { NEU_ERR_INVALID_PASSWORD_LEN = 1012, NEU_ERR_DUPLICATE_PASSWORD = 1013, NEU_ERR_COMMAND_EXECUTION_FAILED = 1014, + NEU_ERR_INVALID_IP_ADDRESS = 1015, NEU_ERR_NODE_EXIST = 2002, NEU_ERR_NODE_NOT_EXIST = 2003, @@ -59,6 +60,7 @@ typedef enum { NEU_ERR_NODE_NOT_ALLOW_SUBSCRIBE = 2012, NEU_ERR_NODE_NOT_ALLOW_UPDATE = 2013, NEU_ERR_NODE_NOT_ALLOW_MAP = 2014, + NEU_ERR_NODE_NAME_EMPTY = 2015, NEU_ERR_GROUP_ALREADY_SUBSCRIBED = 2101, NEU_ERR_GROUP_NOT_SUBSCRIBE = 2102, diff --git a/persistence/0030_2.4.0_ekuiper_node.sql.ex b/persistence/0030_2.4.0_ekuiper_node.sql.ex deleted file mode 100644 index 23fedf46..00000000 --- a/persistence/0030_2.4.0_ekuiper_node.sql.ex +++ /dev/null @@ -1,27 +0,0 @@ -/** - * NEURON IIoT System for Industry 4.0 - * Copyright (C) 2020-2023 EMQ Technologies Co., Ltd All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - **/ -BEGIN TRANSACTION; - --- default data-stream-processing node for neuronex -INSERT -OR REPLACE INTO nodes (name, type, state, plugin_name) -VALUES - ('data-stream-processing', 2, 1, 'eKuiper'); - -COMMIT; diff --git a/persistence/0031_2.4.2_ekuiper_node.sql.ex b/persistence/0031_2.4.2_ekuiper_node.sql.ex deleted file mode 100644 index d5cab9ac..00000000 --- a/persistence/0031_2.4.2_ekuiper_node.sql.ex +++ /dev/null @@ -1,45 +0,0 @@ -/** - * NEURON IIoT System for Industry 4.0 - * Copyright (C) 2020-2023 EMQ Technologies Co., Ltd All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - **/ -BEGIN TRANSACTION; - --- Update default data-stream-processing node setting when --- the data-stream-processing node exists and is at init state. --- The init state implies the user has not provide any setting yet. -INSERT INTO - settings (node_name, setting) -SELECT - name, - '{"params":{"host":"0.0.0.0","port":7081}}' -FROM - nodes -WHERE - name = 'data-stream-processing' - and state = 1; - --- Update default data-stream-processing node to running state when --- the data-stream-processing node exists and is at init state. -UPDATE - nodes -SET - state = 3 -where - name = 'data-stream-processing' - and state = 1; - -COMMIT; diff --git a/plugins/ekuiper/plugin_ekuiper.c b/plugins/ekuiper/plugin_ekuiper.c index 9325651c..c4edaeb1 100644 --- a/plugins/ekuiper/plugin_ekuiper.c +++ b/plugins/ekuiper/plugin_ekuiper.c @@ -17,6 +17,10 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ +#include +#include +#include + #include "errcodes.h" #include "neuron.h" #include "utils/asprintf.h" @@ -127,7 +131,8 @@ static int ekuiper_plugin_start(neu_plugin_t *plugin) if ((rv = nng_listen(plugin->sock, url, NULL, 0)) != 0) { plog_error(plugin, "nng_listen: %s", nng_strerror(rv)); nng_close(plugin->sock); - return NEU_ERR_EINTERNAL; + rv = (NNG_EADDRINVAL == rv) ? NEU_ERR_INVALID_IP_ADDRESS + : NEU_ERR_EINTERNAL; } nng_recv_aio(plugin->sock, plugin->recv_aio); @@ -163,6 +168,12 @@ static int parse_config(neu_plugin_t *plugin, const char *setting, goto error; } + struct in_addr addr; + if (0 == inet_aton(host.v.val_str, &addr)) { + plog_error(plugin, "inet_aton fail: %s", host.v.val_str); + goto error; + } + // port, required if (0 == port.v.val_int || port.v.val_int > 65535) { plog_error(plugin, "setting invalid port: %" PRIi64, port.v.val_int); @@ -182,6 +193,24 @@ error: return -1; } +static inline int check_url_listenable(neu_plugin_t *plugin, const char *url) +{ + int rv = nng_pair0_open(&plugin->sock); + if (0 != rv) { + plog_error(plugin, "nng_pair0_open: %s", nng_strerror(rv)); + return NEU_ERR_EINTERNAL; + } + + if (0 != (rv = nng_listen(plugin->sock, url, NULL, 0))) { + plog_error(plugin, "nng_listen: %s", nng_strerror(rv)); + rv = (NNG_EADDRINVAL == rv) ? NEU_ERR_INVALID_IP_ADDRESS + : NEU_ERR_EINTERNAL; + } + + nng_close(plugin->sock); + return rv; +} + static int ekuiper_plugin_config(neu_plugin_t *plugin, const char *setting) { int rv = 0; @@ -201,6 +230,10 @@ static int ekuiper_plugin_config(neu_plugin_t *plugin, const char *setting) goto error; } + if (0 != (rv = check_url_listenable(plugin, url))) { + goto error; + } + plog_notice(plugin, "config success"); free(plugin->host); diff --git a/plugins/restful/adapter_handle.c b/plugins/restful/adapter_handle.c index e7cdeb0b..be5cf5d3 100644 --- a/plugins/restful/adapter_handle.c +++ b/plugins/restful/adapter_handle.c @@ -62,26 +62,47 @@ void handle_add_adapter(nng_aio *aio) }) } -void handle_update_adapter(nng_aio *aio) +static inline int send_node_update_req(nng_aio * aio, + neu_json_update_node_req_t *req) { neu_plugin_t *plugin = neu_rest_get_plugin(); + int len = strlen(req->name); + if (NEU_NODE_NAME_LEN <= len) { + return NEU_ERR_NODE_NAME_TOO_LONG; + } + + len = strlen(req->new_name); + if (NEU_NODE_NAME_LEN <= len) { + return NEU_ERR_NODE_NAME_TOO_LONG; + } else if (0 == len) { + return NEU_ERR_NODE_NAME_EMPTY; + } + + neu_req_update_node_t cmd = { 0 }; + strcpy(cmd.node, req->name); + strcpy(cmd.new_name, req->new_name); + + neu_reqresp_head_t header = { + .ctx = aio, + .type = NEU_REQ_UPDATE_NODE, + }; + + if (0 != neu_plugin_op(plugin, header, &cmd)) { + return NEU_ERR_IS_BUSY; + } + + return 0; +} + +void handle_update_adapter(nng_aio *aio) +{ NEU_PROCESS_HTTP_REQUEST_VALIDATE_JWT( aio, neu_json_update_node_req_t, neu_json_decode_update_node_req, { - int ret = 0; - neu_reqresp_head_t header = { 0 }; - neu_req_update_node_t cmd = { 0 }; - - header.ctx = aio; - header.type = NEU_REQ_UPDATE_NODE; - strcpy(cmd.node, req->name); - strcpy(cmd.new_name, req->new_name); - - ret = neu_plugin_op(plugin, header, &cmd); - if (ret != 0) { - NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, { - neu_http_response(aio, NEU_ERR_IS_BUSY, result_error); - }); + int ret = send_node_update_req(aio, req); + if (0 != ret) { + NEU_JSON_RESPONSE_ERROR( + ret, { neu_http_response(aio, ret, result_error); }); } }) } diff --git a/plugins/restful/handle.c b/plugins/restful/handle.c index c086e03a..29b1e137 100644 --- a/plugins/restful/handle.c +++ b/plugins/restful/handle.c @@ -152,12 +152,6 @@ static struct neu_http_handler rest_handlers[] = { .url = "/", .value.path = "/web", }, - { - .method = NEU_HTTP_METHOD_UNDEFINE, - .type = NEU_HTTP_HANDLER_PROXY, - .url = "/api/v2/ekuiper", - .value.dst_url = "http://127.0.0.1:9081", - }, { .method = NEU_HTTP_METHOD_POST, .type = NEU_HTTP_HANDLER_FUNCTION, diff --git a/plugins/restful/template_handle.c b/plugins/restful/template_handle.c index 332f8891..4be9abed 100644 --- a/plugins/restful/template_handle.c +++ b/plugins/restful/template_handle.c @@ -170,15 +170,22 @@ void handle_del_template(nng_aio *aio) NEU_VALIDATE_JWT(aio); + neu_req_del_template_t cmd = { 0 }; + + int ret = neu_http_get_param_str(aio, "name", cmd.name, sizeof(cmd.name)); + // optional parameter + if (-2 != ret && (ret <= 0 || sizeof(cmd.name) <= (size_t) ret)) { + NEU_JSON_RESPONSE_ERROR(NEU_ERR_PARAM_IS_WRONG, { + neu_http_response(aio, NEU_ERR_PARAM_IS_WRONG, result_error); + }); + return; + } + neu_reqresp_head_t header = { .ctx = aio, .type = NEU_REQ_DEL_TEMPLATE, }; - neu_req_del_template_t cmd = { 0 }; - - neu_http_get_param_str(aio, "name", cmd.name, sizeof(cmd.name)); - if (0 != neu_plugin_op(plugin, header, &cmd)) { NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, { neu_http_response(aio, NEU_ERR_IS_BUSY, result_error); @@ -197,10 +204,19 @@ void handle_get_template(nng_aio *aio) }; neu_req_get_template_t cmd = { 0 }; - if (neu_http_get_param_str(aio, "name", cmd.name, sizeof(cmd.name)) <= 0) { + int ret = neu_http_get_param_str(aio, "name", cmd.name, sizeof(cmd.name)); + if (0 < ret && (size_t) ret < sizeof(cmd.name)) { + // valid name parameter provided + header.type = NEU_REQ_GET_TEMPLATE; + } else if (-2 == ret) { + // no name parameter header.type = NEU_REQ_GET_TEMPLATES; } else { - header.type = NEU_REQ_GET_TEMPLATE; + // invalid name parameter + NEU_JSON_RESPONSE_ERROR(NEU_ERR_PARAM_IS_WRONG, { + neu_http_response(aio, NEU_ERR_PARAM_IS_WRONG, result_error); + }); + return; } if (0 != neu_plugin_op(plugin, header, &cmd)) { @@ -327,16 +343,24 @@ send_template_mod_group_req(nng_aio *aio, neu_reqresp_type_e type, { neu_plugin_t *plugin = neu_rest_get_plugin(); - neu_reqresp_head_t header = { - .ctx = aio, - .type = type, - }; + if (strlen(req->tmpl) >= NEU_TEMPLATE_NAME_LEN) { + return NEU_ERR_TEMPLATE_NAME_TOO_LONG; + } else if (strlen(req->group) >= NEU_GROUP_NAME_LEN) { + return NEU_ERR_GROUP_NAME_TOO_LONG; + } else if (req->interval < NEU_GROUP_INTERVAL_LIMIT) { + return NEU_ERR_GROUP_PARAMETER_INVALID; + } neu_req_add_template_group_t cmd = { 0 }; strcpy(cmd.tmpl, req->tmpl); strcpy(cmd.group, req->group); cmd.interval = req->interval; + neu_reqresp_head_t header = { + .ctx = aio, + .type = type, + }; + if (0 != neu_plugin_op(plugin, header, &cmd)) { return NEU_ERR_IS_BUSY; } @@ -350,22 +374,10 @@ static inline void process_mod_template_group(nng_aio * aio, NEU_PROCESS_HTTP_REQUEST_VALIDATE_JWT( aio, neu_json_template_mod_group_req_t, neu_json_decode_template_mod_group_req, { - if (strlen(req->group) >= NEU_GROUP_NAME_LEN) { - NEU_JSON_RESPONSE_ERROR(NEU_ERR_GROUP_NAME_TOO_LONG, { - neu_http_response(aio, NEU_ERR_GROUP_NAME_TOO_LONG, - result_error); - }); - } else if (req->interval < NEU_GROUP_INTERVAL_LIMIT) { - NEU_JSON_RESPONSE_ERROR(NEU_ERR_GROUP_PARAMETER_INVALID, { - neu_http_response(aio, NEU_ERR_GROUP_PARAMETER_INVALID, - result_error); - }); - } else { - int ret = send_template_mod_group_req(aio, type, req); - if (ret != 0) { - NEU_JSON_RESPONSE_ERROR( - ret, { neu_http_response(aio, ret, result_error); }); - } + int ret = send_template_mod_group_req(aio, type, req); + if (ret != 0) { + NEU_JSON_RESPONSE_ERROR( + ret, { neu_http_response(aio, ret, result_error); }); } }) } @@ -380,23 +392,43 @@ void handle_update_template_group(nng_aio *aio) process_mod_template_group(aio, NEU_REQ_UPDATE_TEMPLATE_GROUP); } -void handle_del_template_group(nng_aio *aio) +static inline int +send_template_del_group_req(nng_aio * aio, + neu_json_template_del_group_req_t *req) { neu_plugin_t *plugin = neu_rest_get_plugin(); + if (strlen(req->tmpl) >= NEU_TEMPLATE_NAME_LEN) { + return NEU_ERR_TEMPLATE_NAME_TOO_LONG; + } + + if (strlen(req->group) >= NEU_GROUP_NAME_LEN) { + return NEU_ERR_GROUP_NAME_TOO_LONG; + } + + neu_req_add_template_tag_t cmd = { 0 }; + strcpy(cmd.tmpl, req->tmpl); + strcpy(cmd.group, req->group); + + neu_reqresp_head_t header = { + .ctx = aio, + .type = NEU_REQ_DEL_TEMPLATE_GROUP, + }; + + if (0 != neu_plugin_op(plugin, header, &cmd)) { + return NEU_ERR_IS_BUSY; + } + + return 0; +} + +void handle_del_template_group(nng_aio *aio) +{ NEU_PROCESS_HTTP_REQUEST_VALIDATE_JWT( aio, neu_json_template_del_group_req_t, neu_json_decode_template_del_group_req, { - neu_reqresp_head_t header = { 0 }; - header.ctx = aio; - header.type = NEU_REQ_DEL_TEMPLATE_GROUP; - - neu_req_add_template_group_t cmd = { 0 }; - strcpy(cmd.tmpl, req->tmpl); - strcpy(cmd.group, req->group); - - if (0 != neu_plugin_op(plugin, header, &cmd)) { - int ret = NEU_ERR_IS_BUSY; + int ret = send_template_del_group_req(aio, req); + if (0 != ret) { NEU_JSON_RESPONSE_ERROR( ret, { neu_http_response(aio, ret, result_error); }); } @@ -406,15 +438,16 @@ void handle_del_template_group(nng_aio *aio) static int send_template_mod_tags_req(nng_aio *aio, neu_reqresp_type_e type, neu_json_template_mod_tags_req_t *req) { + int ret = 0; neu_plugin_t *plugin = neu_rest_get_plugin(); - int ret = 0; - int i = 0; + if (strlen(req->tmpl) >= NEU_TEMPLATE_NAME_LEN) { + return NEU_ERR_TEMPLATE_NAME_TOO_LONG; + } - neu_reqresp_head_t header = { - .ctx = aio, - .type = type, - }; + if (strlen(req->group) >= NEU_GROUP_NAME_LEN) { + return NEU_ERR_GROUP_NAME_TOO_LONG; + } neu_req_add_template_tag_t cmd = { 0 }; strcpy(cmd.tmpl, req->tmpl); @@ -425,7 +458,7 @@ static int send_template_mod_tags_req(nng_aio *aio, neu_reqresp_type_e type, return NEU_ERR_EINTERNAL; } - for (i = 0; i < req->n_tag; i++) { + for (int i = 0; i < req->n_tag; i++) { cmd.n_tag += 1; if (0 != (ret = set_tag_by_json(&cmd.tags[i], &req->tags[i]))) { neu_req_add_template_tag_fini(&cmd); @@ -433,6 +466,11 @@ static int send_template_mod_tags_req(nng_aio *aio, neu_reqresp_type_e type, } } + neu_reqresp_head_t header = { + .ctx = aio, + .type = type, + }; + if (0 != neu_plugin_op(plugin, header, &cmd)) { neu_req_add_template_tag_fini(&cmd); return NEU_ERR_IS_BUSY; @@ -447,26 +485,38 @@ static int send_template_del_tags_req(nng_aio * aio, int ret = 0; neu_plugin_t *plugin = neu_rest_get_plugin(); - neu_reqresp_head_t header = { - .ctx = aio, - .type = NEU_REQ_DEL_TEMPLATE_TAG, - }; + if (strlen(req->tmpl) >= NEU_TEMPLATE_NAME_LEN) { + return NEU_ERR_TEMPLATE_NAME_TOO_LONG; + } + + if (strlen(req->group) >= NEU_GROUP_NAME_LEN) { + return NEU_ERR_GROUP_NAME_TOO_LONG; + } neu_req_del_template_tag_t cmd = { 0 }; strcpy(cmd.tmpl, req->tmpl); strcpy(cmd.group, req->group); - cmd.n_tag = req->n_tags; - cmd.tags = calloc(req->n_tags, sizeof(char *)); + cmd.tags = calloc(req->n_tags, sizeof(char *)); if (NULL == cmd.tags) { return NEU_ERR_EINTERNAL; } for (int i = 0; i < req->n_tags; i++) { + if (strlen(req->tags[i]) >= NEU_TAG_NAME_LEN) { + neu_req_del_template_tag_fini(&cmd); + return NEU_ERR_TAG_NAME_TOO_LONG; + } cmd.tags[i] = req->tags[i]; req->tags[i] = NULL; // ownership moved + cmd.n_tag += 1; } + neu_reqresp_head_t header = { + .ctx = aio, + .type = NEU_REQ_DEL_TEMPLATE_TAG, + }; + if (ret != neu_plugin_op(plugin, header, &cmd)) { neu_req_del_template_tag_fini(&cmd); ret = NEU_ERR_IS_BUSY; @@ -530,44 +580,74 @@ void handle_get_template_tags(nng_aio *aio) neu_req_get_template_tag_t cmd = { 0 }; - if (neu_http_get_param_str(aio, "template", cmd.tmpl, sizeof(cmd.tmpl)) <= - 0 || - neu_http_get_param_str(aio, "group", cmd.group, sizeof(cmd.group)) <= - 0) { - NEU_JSON_RESPONSE_ERROR(NEU_ERR_PARAM_IS_WRONG, { - neu_http_response(aio, NEU_ERR_PARAM_IS_WRONG, result_error); - }) - return; + ret = neu_http_get_param_str(aio, "template", cmd.tmpl, sizeof(cmd.tmpl)); + // required parameter + if (ret <= 0 || sizeof(cmd.tmpl) <= (size_t) ret) { + ret = NEU_ERR_PARAM_IS_WRONG; + goto end; } - // optional - neu_http_get_param_str(aio, "name", cmd.name, sizeof(cmd.name)); + ret = neu_http_get_param_str(aio, "group", cmd.group, sizeof(cmd.group)); + // required parameter + if (ret <= 0 || sizeof(cmd.tmpl) <= (size_t) ret) { + ret = NEU_ERR_PARAM_IS_WRONG; + goto end; + } + + ret = neu_http_get_param_str(aio, "name", cmd.name, sizeof(cmd.name)); + // optional parameter + if (-2 != ret && (ret <= 0 || sizeof(cmd.name) <= (size_t) ret)) { + ret = NEU_ERR_PARAM_IS_WRONG; + goto end; + } ret = neu_plugin_op(plugin, header, &cmd); - if (ret != 0) { - NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, { - neu_http_response(aio, NEU_ERR_IS_BUSY, result_error); - }); + if (0 != ret) { + ret = NEU_ERR_IS_BUSY; } + +end: + if (0 != ret) { + NEU_JSON_RESPONSE_ERROR(ret, + { neu_http_response(aio, ret, result_error); }); + } +} + +static inline int send_template_inst_req(nng_aio * aio, + neu_json_template_inst_req_t *req) +{ + neu_plugin_t *plugin = neu_rest_get_plugin(); + + if (strlen(req->name) >= NEU_TEMPLATE_NAME_LEN) { + return NEU_ERR_TEMPLATE_NAME_TOO_LONG; + } + + if (strlen(req->node) >= NEU_NODE_NAME_LEN) { + return NEU_ERR_PLUGIN_NAME_TOO_LONG; + } + + neu_req_inst_template_t cmd = { 0 }; + strncpy(cmd.tmpl, req->name, sizeof(cmd.tmpl)); + strncpy(cmd.node, req->node, sizeof(cmd.node)); + + neu_reqresp_head_t header = { + .ctx = aio, + .type = NEU_REQ_INST_TEMPLATE, + }; + + if (0 != neu_plugin_op(plugin, header, &cmd)) { + return NEU_ERR_IS_BUSY; + } + + return 0; } void handle_instantiate_template(nng_aio *aio) { NEU_PROCESS_HTTP_REQUEST_VALIDATE_JWT( aio, neu_json_template_inst_req_t, neu_json_decode_template_inst_req, { - neu_plugin_t *plugin = neu_rest_get_plugin(); - - neu_reqresp_head_t header = { 0 }; - header.ctx = aio; - header.type = NEU_REQ_INST_TEMPLATE; - - neu_req_inst_template_t cmd = { 0 }; - strncpy(cmd.tmpl, req->name, sizeof(cmd.tmpl)); - strncpy(cmd.node, req->node, sizeof(cmd.node)); - - int ret = neu_plugin_op(plugin, header, &cmd); + int ret = send_template_inst_req(aio, req); if (0 != ret) { - ret = NEU_ERR_IS_BUSY; NEU_JSON_RESPONSE_ERROR( ret, { neu_http_response(aio, ret, result_error); }); } @@ -587,7 +667,8 @@ void handle_get_template_group(nng_aio *aio) neu_req_get_template_group_t cmd = { 0 }; int ret = neu_http_get_param_str(aio, "name", cmd.tmpl, sizeof(cmd.tmpl)); - if (ret <= 0 || (size_t) ret >= sizeof(cmd.tmpl)) { + // required parameter + if (ret <= 0 || sizeof(cmd.tmpl) <= (size_t) ret) { NEU_JSON_RESPONSE_ERROR(NEU_ERR_PARAM_IS_WRONG, { neu_http_response(aio, NEU_ERR_PARAM_IS_WRONG, result_error); }); diff --git a/src/core/manager_internal.c b/src/core/manager_internal.c index e4710dcc..de9f4c3b 100644 --- a/src/core/manager_internal.c +++ b/src/core/manager_internal.c @@ -167,6 +167,11 @@ int neu_manager_add_template(neu_manager_t *manager, const char *name, return NEU_ERR_EINTERNAL; } + if (NEU_NA_TYPE_DRIVER != plug_inst->module->type) { + free_plugin_instance(plug_inst); + return NEU_ERR_PLUGIN_NOT_SUPPORT_TEMPLATE; + } + neu_template_t *tmpl = neu_template_new(name, plugin); if (NULL == tmpl) { free_plugin_instance(plug_inst); @@ -521,7 +526,7 @@ int neu_manager_instantiate_template(neu_manager_t * manager, neu_adapter_driver_t *driver = (neu_adapter_driver_t *) adapter; if (adapter->module->type != NEU_NA_TYPE_DRIVER) { - ret = NEU_ERR_GROUP_NOT_ALLOW; + ret = NEU_ERR_PLUGIN_NOT_SUPPORT_TEMPLATE; goto end; } diff --git a/src/utils/http.c b/src/utils/http.c index 1d1ed877..e76f7c44 100644 --- a/src/utils/http.c +++ b/src/utils/http.c @@ -77,7 +77,7 @@ ssize_t neu_url_decode(const char *s, size_t len, char *buf, size_t size) } buf[j++] = c; } - buf[(j < size) ? j : --j] = '\0'; + buf[(j < size) ? j : j - 1] = '\0'; return j; } @@ -321,6 +321,7 @@ int neu_http_response(nng_aio *aio, neu_err_code_e code, char *content) break; case NEU_ERR_BODY_IS_WRONG: case NEU_ERR_PARAM_IS_WRONG: + case NEU_ERR_INVALID_IP_ADDRESS: case NEU_ERR_NODE_SETTING_INVALID: case NEU_ERR_NODE_NOT_ALLOW_UPDATE: case NEU_ERR_NODE_NOT_ALLOW_SUBSCRIBE: @@ -332,6 +333,7 @@ int neu_http_response(nng_aio *aio, neu_err_code_e code, char *content) case NEU_ERR_LIBRARY_FAILED_TO_OPEN: case NEU_ERR_LIBRARY_MODULE_INVALID: case NEU_ERR_NODE_NAME_TOO_LONG: + case NEU_ERR_NODE_NAME_EMPTY: case NEU_ERR_GROUP_NAME_TOO_LONG: case NEU_ERR_INVALID_PASSWORD_LEN: case NEU_ERR_DUPLICATE_PASSWORD: diff --git a/tests/http_test.cc b/tests/http_test.cc index 098dbd59..a6a28e7a 100644 --- a/tests/http_test.cc +++ b/tests/http_test.cc @@ -113,6 +113,11 @@ TEST(HTTPTest, http_get_param_str) EXPECT_EQ(ret, 3); EXPECT_EQ(0, strcmp("组", buf)); + nng_http_req_set_uri(req, "/?group=%E7%BB%84"); + ret = neu_http_get_param_str(aio, "group", buf, 3); + EXPECT_EQ(ret, 3); + EXPECT_EQ(0, strncmp("组", buf, 2)); + nng_aio_free(aio); nng_http_req_free(req); nng_url_free(url);