Skip to content

Commit

Permalink
Webserver registry REST unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
CurlyMoo committed Oct 19, 2018
1 parent f0cfa04 commit f9266a0
Show file tree
Hide file tree
Showing 2 changed files with 303 additions and 53 deletions.
214 changes: 176 additions & 38 deletions libs/pilight/core/webserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#endif

#include "../config/settings.h"
#include "../config/registry.h"
#include "eventpool.h"
#include "sha256cache.h"
#include "pilight.h"
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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) {
Expand All @@ -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;b<a;b++) {
c = explode(array[b], "=", &array1);
if(c == 2) {
if(strcmp(array1[0], "protocol") == 0) {
struct JsonNode *jprotocol = json_mkarray();
json_append_element(jprotocol, json_mkstring(array1[1]));
json_append_member(jcode, "protocol", jprotocol);
has_protocol = 1;
} else if(strcmp(array1[0], "state") == 0) {
strcpy(state, array1[1]);
} else if(strcmp(array1[0], "device") == 0) {
dev = array1[1];
if(devices_select(ORIGIN_WEBSERVER, array1[1], NULL) != 0) {
char *z = "{\"message\":\"failed\",\"error\":\"device does not exist\"}";
send_data(req, "application/json", z, strlen(z));
goto clear;
}
} else if(strncmp(array1[0], "values", 6) == 0) {
char name[255], *ptr = name;
if(sscanf(array1[0], "values[%254[a-z]]", ptr) != 1) {
char *z = "{\"message\":\"failed\",\"error\":\"values should be passed like this \'values[dimlevel]=10\'\"}";
send_data(req, "application/json", z, strlen(z));
goto clear;
} else {
if(isNumeric(array1[1]) == 0) {
json_append_member(jvalues, name, json_mknumber(atof(array1[1]), nrDecimals(array1[1])));
if(type == 0 || type == 1) {
for(b=0;b<a;b++) {
c = explode(array[b], "=", &array1);
if(c == 2) {
if(strcmp(array1[0], "protocol") == 0) {
struct JsonNode *jprotocol = json_mkarray();
json_append_element(jprotocol, json_mkstring(array1[1]));
json_append_member(jcode, "protocol", jprotocol);
has_protocol = 1;
} else if(strcmp(array1[0], "state") == 0) {
strcpy(state, array1[1]);
} else if(strcmp(array1[0], "device") == 0) {
dev = array1[1];
if(devices_select(ORIGIN_WEBSERVER, array1[1], NULL) != 0) {
char *z = "{\"message\":\"failed\",\"error\":\"device does not exist\"}";
send_data(req, "application/json", z, strlen(z));
goto clear;
}
} else if(strncmp(array1[0], "values", 6) == 0) {
char name[255], *ptr = name;
if(sscanf(array1[0], "values[%254[a-z]]", ptr) != 1) {
char *z = "{\"message\":\"failed\",\"error\":\"values should be passed like this \'values[dimlevel]=10\'\"}";
send_data(req, "application/json", z, strlen(z));
goto clear;
} else {
json_append_member(jvalues, name, json_mkstring(array1[1]));
if(isNumeric(array1[1]) == 0) {
json_append_member(jvalues, name, json_mknumber(atof(array1[1]), nrDecimals(array1[1])));
} else {
json_append_member(jvalues, name, json_mkstring(array1[1]));
}
}
} else if(isNumeric(array1[1]) == 0) {
json_append_member(jcode, array1[0], json_mknumber(atof(array1[1]), nrDecimals(array1[1])));
} else {
json_append_member(jcode, array1[0], json_mkstring(array1[1]));
}
} else if(isNumeric(array1[1]) == 0) {
json_append_member(jcode, array1[0], json_mknumber(atof(array1[1]), nrDecimals(array1[1])));
} else {
json_append_member(jcode, array1[0], json_mkstring(array1[1]));
}
array_free(&array1, c);
}
}
if(type == 0) {
c = 0;

if(has_protocol == 0) {
char *z = "{\"message\":\"failed\",\"error\":\"no protocol was sent\"}";
send_data(req, "application/json", z, strlen(z));
Expand Down Expand Up @@ -643,12 +653,140 @@ static int parse_rest(uv_poll_t *req) {
}
}
}
} else if(type == 2) {
int getsetrm = 0; // g, s or r

for(b=0;b<a;b++) {
c = explode(array[b], "=", &array1);
if((strcmp(array1[0], "get") == 0) ||
(strcmp(array1[0], "set") == 0) ||
(strcmp(array1[0], "remove") == 0)) {
getsetrm = array1[0][0];
if((key = STRDUP(array1[1])) == NULL) {
OUT_OF_MEMORY
}
}
if(strcmp(array1[0], "value") == 0) {
if((value = STRDUP(array1[1])) == NULL) {
OUT_OF_MEMORY
}
}
array_free(&array1, c);
}
c = 0;

struct varcont_t out;
memset(&out, 0, sizeof(struct varcont_t));
if(key == NULL) {
char *z = "{\"message\":\"failed\"}";
send_data(req, "application/json", z, strlen(z));
FREE(decoded);
goto clear;
} else if(getsetrm == 'g') {
if(value != NULL) {
FREE(value);
}
if(config_registry_get(key, &out) == 0) {
if(out.type_ == LUA_TNUMBER) {
struct JsonNode *jsend = json_mkobject();
json_append_member(jsend, "message", json_mkstring("registry"));
json_append_member(jsend, "value", json_mknumber(out.number_, 6));
json_append_member(jsend, "key", json_mkstring(key));
char *output = json_stringify(jsend, NULL);
send_data(req, "application/json", output, strlen(output));
json_free(output);
json_delete(jsend);
FREE(decoded);
FREE(key);
goto clear;
} else if(out.type_ == LUA_TSTRING) {
struct JsonNode *jsend = json_mkobject();
json_append_member(jsend, "message", json_mkstring("registry"));
json_append_member(jsend, "value", json_mkstring(out.string_));
json_append_member(jsend, "key", json_mkstring(key));
char *output = json_stringify(jsend, NULL);
send_data(req, "application/json", output, strlen(output));
json_free(output);
json_delete(jsend);
FREE(out.string_);
FREE(decoded);
FREE(key);
goto clear;
} else {
char *z = "{\"message\":\"failed\"}";
send_data(req, "application/json", z, strlen(z));
FREE(decoded);
FREE(key);
goto clear;
}
} else {
FREE(key);
}
} else if(getsetrm == 's') {
if(value == NULL) {
char *z = "{\"message\":\"failed\"}";
send_data(req, "application/json", z, strlen(z));
FREE(decoded);
FREE(key);
goto clear;
} else {
if(isNumeric(value) == 0) {
if(config_registry_set_number(key, atof(value)) == 0) {
char *z = "{\"message\":\"success\"}";
send_data(req, "application/json", z, strlen(z));
FREE(decoded);
FREE(key);
FREE(value);
goto clear;
}
} else {
if(config_registry_set_string(key, value) == 0) {
char *z = "{\"message\":\"success\"}";
send_data(req, "application/json", z, strlen(z));
FREE(decoded);
FREE(key);
FREE(value);
goto clear;
}
}
}
char *z = "{\"message\":\"failed\"}";
send_data(req, "application/json", z, strlen(z));
FREE(decoded);
FREE(key);
FREE(value);
goto clear;
} else if(getsetrm == 'r') {
if(value != NULL) {
FREE(value);
}
if(config_registry_get(key, &out) == 0 &&
config_registry_set_null(key) == 0) {
char *z = "{\"message\":\"success\"}";
send_data(req, "application/json", z, strlen(z));
if(out.type_ == JSON_STRING) {
FREE(out.string_);
}
FREE(decoded);
FREE(key);
goto clear;
}
char *z = "{\"message\":\"failed\"}";
send_data(req, "application/json", z, strlen(z));
FREE(decoded);
FREE(key);
goto clear;
}
}
json_delete(jvalues);
json_delete(jobject);
}
FREE(decoded);
array_free(&array, a);
} else {
json_delete(jcode);
json_delete(jvalues);
json_delete(jobject);
}
char *z = "{\"message\":\"failed\"}";
send_data(req, "application/json", z, strlen(z));
Expand Down Expand Up @@ -750,7 +888,7 @@ static int request_handler(uv_poll_t *req) {

if(conn->is_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];
Expand Down Expand Up @@ -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"
Expand Down

0 comments on commit f9266a0

Please sign in to comment.