diff --git a/libs/pilight/core/webserver.c b/libs/pilight/core/webserver.c index 0e065121f..0d659f918 100644 --- a/libs/pilight/core/webserver.c +++ b/libs/pilight/core/webserver.c @@ -52,6 +52,7 @@ #endif #include "../config/settings.h" +#include "../config/registry.h" #include "eventpool.h" #include "sha256cache.h" #include "pilight.h" @@ -207,9 +208,11 @@ int webserver_gc(void) { if(poll_http_req != NULL) { poll_close_cb(poll_http_req); + poll_http_req = NULL; } if(poll_https_req != NULL) { poll_close_cb(poll_https_req); + poll_https_req = NULL; } if(authentication_username != NULL) { @@ -528,6 +531,7 @@ static int parse_rest(uv_poll_t *req) { struct connection_t *conn = custom_poll_data->data; char **array = NULL, **array1 = NULL; + char *key = NULL, *value = NULL; struct JsonNode *jobject = json_mkobject(); struct JsonNode *jcode = json_mkobject(); struct JsonNode *jvalues = json_mkobject(); @@ -564,8 +568,8 @@ static int parse_rest(uv_poll_t *req) { a = explode((char *)decoded, "&", &array), b = 0, c = 0; memset(state, 0, 16); - if(a > 1) { - int type = 0; //0 = SEND, 1 = CONTROL + if(a >= 1) { + int type = 0; //0 = SEND, 1 = CONTROL, 2 = REGISTRY json_append_member(jobject, "code", jcode); if(strcmp(conn->uri, "/send") == 0) { @@ -574,46 +578,52 @@ static int parse_rest(uv_poll_t *req) { } else if(strcmp(conn->uri, "/control") == 0) { type = 1; json_append_member(jobject, "action", json_mkstring("control")); + } else if(strcmp(conn->uri, "/registry") == 0) { + type = 2; + json_append_member(jobject, "action", json_mkstring("registry")); } - for(b=0;bis_websocket == 0) { if(conn->uri != NULL && strlen(conn->uri) > 0) { - if(strcmp(conn->uri, "/send") == 0 || strcmp(conn->uri, "/control") == 0) { + if(strcmp(conn->uri, "/send") == 0 || strcmp(conn->uri, "/control") == 0 || strcmp(conn->uri, "/registry") == 0) { return parse_rest(req); } else if(strcmp(conn->uri, "/config") == 0) { char media[15]; @@ -1287,12 +1425,12 @@ static void send_websocket_handshake(uv_poll_t *req, const char *key) { memset(&sha, '\0', 20); - snprintf(buf, sizeof(buf), "%s%s", key, magic); + snprintf(buf, sizeof(buf), "%s%s", key, magic); mbedtls_sha1_init(&ctx); mbedtls_sha1_starts(&ctx); mbedtls_sha1_update(&ctx, (unsigned char *)buf, strlen(buf)); mbedtls_sha1_finish(&ctx, sha); - b64_sha = base64encode(p, 20); + b64_sha = base64encode(p, 20); int i = sprintf(buf, "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" "Connection: Upgrade\r\n" diff --git a/tests/webserver_rest.c b/tests/webserver_rest.c index 33f1d72dd..52c2aa8b6 100644 --- a/tests/webserver_rest.c +++ b/tests/webserver_rest.c @@ -24,10 +24,12 @@ #include "../libs/pilight/core/log.h" #include "../libs/pilight/core/socket.h" #include "../libs/pilight/lua_c/lua.h" +#include "../libs/pilight/config/config.h" #include "alltests.h" #define CORE 0 +#define REGISTRY 1 static int run = CORE; static CuTest *gtc = NULL; @@ -35,6 +37,47 @@ static uv_timer_t *timer_req = NULL; static int check = 0; static uv_async_t *async_close_req = NULL; +static int testnr = 0; + +static struct tests_t { + char *desc; + char *url; + int code; + int size; + char *type; + char *data; +} tests[] = { + { "get existing key", "http://127.0.0.1:10080/registry?get=foo", 200, 48, "application/json", + "{\"message\":\"registry\",\"value\":\"bar\",\"key\":\"foo\"}" + }, + { "get nonexisting key", "http://127.0.0.1:10080/registry?get=bar", 200, 20, "application/json", + "{\"message\":\"failed\"}" + }, + { "set key", "http://127.0.0.1:10080/registry?set=bar&value=foo", 200, 21, "application/json", + "{\"message\":\"success\"}" + }, + { "set key", "http://127.0.0.1:10080/registry?remove=foo", 200, 21, "application/json", + "{\"message\":\"success\"}" + }, + { "set key", "http://127.0.0.1:10080/registry?remove=tmp", 200, 20, "application/json", + "{\"message\":\"failed\"}" + }, + { "set key", "http://127.0.0.1:10080/registry?set=bar&value=foo", 200, 21, "application/json", + "{\"message\":\"success\"}" + }, + { "set key", "http://127.0.0.1:10080/registry?remove=bar&bar=1", 200, 21, "application/json", + "{\"message\":\"success\"}" + }, + { "set key", "http://127.0.0.1:10080/registry?foo", 200, 20, "application/json", + "{\"message\":\"failed\"}" + }, + { "set key", "http://127.0.0.1:10080/registry", 200, 20, "application/json", + "{\"message\":\"failed\"}" + }, + { "set key", "http://127.0.0.1:10080/registry?set=bar&value=foo", 200, 21, "application/json", + "{\"message\":\"success\"}" + }, +}; static void close_cb(uv_handle_t *handle) { FREE(handle); @@ -76,6 +119,23 @@ static void *socket_connected(int reason, void *param) { return NULL; } +static void callback(int code, char *data, int size, char *type, void *userdata) { + CuAssertIntEquals(gtc, code, tests[testnr].code); + CuAssertIntEquals(gtc, size, tests[testnr].size); + CuAssertStrEquals(gtc, data, tests[testnr].data); + if(tests[testnr].type != NULL) { + CuAssertStrEquals(gtc, type, tests[testnr].type); + } + + testnr++; + + if(testnr < sizeof(tests)/sizeof(tests[0])) { + http_get_content(tests[testnr].url, callback, NULL); + } else { + check = 1; + uv_async_send(async_close_req); + } +} static void test_webserver(CuTest *tc) { memtrack(); @@ -88,27 +148,31 @@ static void test_webserver(CuTest *tc) { } uv_async_init(uv_default_loop(), async_close_req, async_close_cb); - timer_req = MALLOC(sizeof(uv_timer_t)); - CuAssertPtrNotNull(tc, timer_req); - uv_timer_init(uv_default_loop(), timer_req); - uv_timer_start(timer_req, (void (*)(uv_timer_t *))stop, 1000, 0); + if(run == CORE) { + timer_req = MALLOC(sizeof(uv_timer_t)); + CuAssertPtrNotNull(tc, timer_req); + uv_timer_init(uv_default_loop(), timer_req); + uv_timer_start(timer_req, (void (*)(uv_timer_t *))stop, 1000, 0); + } plua_init(); test_set_plua_path(tc, __FILE__, "webserver_rest.c"); - storage_init(); - CuAssertIntEquals(tc, 0, storage_read("webserver.json", CONFIG_SETTINGS)); + config_init(); + CuAssertIntEquals(tc, 0, config_read("webserver.json", CONFIG_SETTINGS | CONFIG_REGISTRY)); ssl_init(); - if(run == CORE) { - eventpool_init(EVENTPOOL_NO_THREADS); - } + eventpool_init(EVENTPOOL_NO_THREADS); webserver_start(); - eventpool_callback(REASON_SOCKET_CONNECTED, socket_connected); - socket_connect("127.0.0.1", 10080, on_read); + if(run == CORE) { + eventpool_callback(REASON_SOCKET_CONNECTED, socket_connected); + socket_connect("127.0.0.1", 10080, on_read); + } else if(run == REGISTRY) { + http_get_content(tests[testnr].url, callback, NULL); + } uv_run(uv_default_loop(), UV_RUN_DEFAULT); uv_walk(uv_default_loop(), walk_cb, NULL); @@ -117,17 +181,48 @@ static void test_webserver(CuTest *tc) { while(uv_loop_close(uv_default_loop()) == UV_EBUSY) { uv_run(uv_default_loop(), UV_RUN_DEFAULT); } +} + +static void test_webserver_core_api(CuTest *tc) { + printf("[ %-48s ]\n", __FUNCTION__); + fflush(stdout); + + if(gtc != NULL && gtc->failed == 1) { + return; + } + + char config[1024] = "{\"devices\":{},\"gui\":{},\"rules\":{},"\ + "\"settings\":{\"pem-file\":\"%s../res/pilight.pem\",\"webserver-root\":\"%s../libs/webgui/\","\ + "\"webserver-enable\":1,\"webserver-http-port\":10080,\"webserver-https-port\":10443},"\ + "\"hardware\":{},\"registry\":{}}"; + + char *file = strdup(__FILE__); + if(file == NULL) { + OUT_OF_MEMORY + } + str_replace("webserver_rest.c", "", &file); + + FILE *f = fopen("webserver.json", "w"); + fprintf(f, config, file, file); + fclose(f); + strdup(file); + + gtc = tc; + check = 0; + + run = CORE; + test_webserver(tc); ssl_gc(); - storage_gc(); plua_gc(); eventpool_gc(); + storage_gc(); CuAssertIntEquals(tc, 1, check); CuAssertIntEquals(tc, 0, xfree()); } -static void test_webserver_core_api(CuTest *tc) { +static void test_webserver_rest_registry(CuTest *tc) { printf("[ %-48s ]\n", __FUNCTION__); fflush(stdout); @@ -138,7 +233,7 @@ static void test_webserver_core_api(CuTest *tc) { char config[1024] = "{\"devices\":{},\"gui\":{},\"rules\":{},"\ "\"settings\":{\"pem-file\":\"%s../res/pilight.pem\",\"webserver-root\":\"%s../libs/webgui/\","\ "\"webserver-enable\":1,\"webserver-http-port\":10080,\"webserver-https-port\":10443},"\ - "\"hardware\":{},\"registry\":{}}"; + "\"hardware\":{},\"registry\":{\"foo\":\"bar\"}}"; char *file = strdup(__FILE__); if(file == NULL) { @@ -153,15 +248,32 @@ static void test_webserver_core_api(CuTest *tc) { gtc = tc; check = 0; + testnr = 0; - run = CORE; + run = REGISTRY; test_webserver(tc); + + char *registry = config_callback_write("registry"); + if(registry != NULL) { + CuAssertStrEquals(tc, registry, "{\n\t\"bar\": \"foo\"\n}"); + FREE(registry); + } + + ssl_gc(); + plua_gc(); + eventpool_gc(); + storage_gc(); + config_gc(); + + CuAssertIntEquals(tc, 1, check); + CuAssertIntEquals(tc, 0, xfree()); } CuSuite *suite_webserver_rest(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_webserver_core_api); + SUITE_ADD_TEST(suite, test_webserver_rest_registry); return suite; }