From 4ca75894c16ea3be1e4c19a7469f1595c18b2f63 Mon Sep 17 00:00:00 2001 From: Omar Rizwan Date: Sun, 11 Nov 2018 05:32:44 -0800 Subject: WebSocket communication seems to work. --- fs/cJSON | 1 + fs/hello.c | 182 +++++++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 129 insertions(+), 54 deletions(-) create mode 160000 fs/cJSON (limited to 'fs') diff --git a/fs/cJSON b/fs/cJSON new file mode 160000 index 0000000..2c914c0 --- /dev/null +++ b/fs/cJSON @@ -0,0 +1 @@ +Subproject commit 2c914c073d71701b596fa58a84529712a0bd1eeb diff --git a/fs/hello.c b/fs/hello.c index d136cf8..2d5db9c 100644 --- a/fs/hello.c +++ b/fs/hello.c @@ -10,6 +10,8 @@ #define WBY_USE_ASSERT #include "mmx/web.h" +#include "cJSON/cJSON.h" +#include "cJSON/cJSON.c" #define MAX_WSCONN 8 struct server_state { @@ -19,6 +21,15 @@ struct server_state { int conn_count; }; +struct wby_server server; +struct wby_con *con; + +typedef struct response_readdir_t { + char **names; + size_t num_names; +} response_readdir_t; + +response_readdir_t *response; static const char *file_path = "/hello.txt"; static const char file_content[] = "Hello World!\n"; @@ -61,6 +72,32 @@ hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler, if (strcmp(path, "/") != 0) /* We only recognize the root directory. */ return -ENOENT; + // send [READDIR, path] to the websocket handler + { + char *msg; + { + cJSON *req = cJSON_CreateObject(); + cJSON_AddStringToObject(req, "op", "readdir"); + cJSON_AddStringToObject(req, "path", path); + + msg = cJSON_Print(req); + printf("%s\n", msg); + + cJSON_Delete(req); + } + + wby_frame_begin(con, WBY_WSOP_TEXT_FRAME); + wby_write(con, msg, strlen(msg)); + wby_frame_end(con); + + free(msg); + } + + response = NULL; + do { + wby_update(&server); + } while (response == NULL); + filler(buf, ".", NULL, 0); /* Current directory (.) */ filler(buf, "..", NULL, 0); /* Parent directory (..) */ filler(buf, file_path + 1, NULL, 0); /* The only file we have. */ @@ -96,83 +133,120 @@ static struct fuse_operations hello_filesystem_operations = { static int dispatch(struct wby_con *connection, void *userdata) { + return 1; +} + +static int +websocket_connect(struct wby_con *connection, void *userdata) +{ + /* Allow websocket upgrades on /wstest */ struct server_state *state = (struct server_state*)userdata; - if (!strcmp("/foo", connection->request.uri)) { - wby_response_begin(connection, 200, 14, NULL, 0); - wby_write(connection, "Hello, world!\n", 14); - wby_response_end(connection); - return 0; - } else if (!strcmp("/bar", connection->request.uri)) { - wby_response_begin(connection, 200, -1, NULL, 0); - wby_write(connection, "Hello, world!\n", 14); - wby_write(connection, "Hello, world?\n", 14); - wby_response_end(connection); + /* connection bound userdata */ + connection->user_data = NULL; + if (0 == strcmp(connection->request.uri, "/") && state->conn_count < MAX_WSCONN) return 0; - } else if (!strcmp("/quit", connection->request.uri)) { - wby_response_begin(connection, 200, -1, NULL, 0); - wby_write(connection, "Goodbye, cruel world\n", 22); - wby_response_end(connection); - state->quit = 1; - return 0; - } else return 1; + else return 1; +} + +static void +websocket_connected(struct wby_con *connection, void *userdata) +{ + struct server_state *state = (struct server_state*)userdata; + printf("WebSocket connected\n"); + con = connection; +} + +static int +websocket_frame(struct wby_con *connection, const struct wby_frame *frame, void *userdata) +{ + int i = 0; + printf("WebSocket frame incoming\n"); + printf(" Frame OpCode: %d\n", frame->opcode); + printf(" Final frame?: %s\n", (frame->flags & WBY_WSF_FIN) ? "yes" : "no"); + printf(" Masked? : %s\n", (frame->flags & WBY_WSF_MASKED) ? "yes" : "no"); + printf(" Data Length : %d\n", (int) frame->payload_length); + while (i < frame->payload_length) { + unsigned char buffer[16]; + int remain = frame->payload_length - i; + size_t read_size = remain > (int) sizeof buffer ? sizeof buffer : (size_t) remain; + size_t k; + + printf("%08x ", (int) i); + if (0 != wby_read(connection, buffer, read_size)) + break; + for (k = 0; k < read_size; ++k) + printf("%02x ", buffer[k]); + for (k = read_size; k < 16; ++k) + printf(" "); + printf(" | "); + for (k = 0; k < read_size; ++k) + printf("%c", isprint(buffer[k]) ? buffer[k] : '?'); + printf("\n"); + i += (int)read_size; + } + return 0; +} + +static void +websocket_closed(struct wby_con *connection, void *userdata) +{ + int i; + struct server_state *state = (struct server_state*)userdata; + printf("WebSocket closed\n"); + for (i = 0; i < state->conn_count; i++) { + if (state->conn[i] == connection) { + int remain = state->conn_count - i; + memmove(state->conn + i, state->conn + i + 1, (size_t)remain * sizeof(struct wby_con*)); + --state->conn_count; + break; + } + } +} + +static void +test_log(const char* text) +{ + printf("[debug] %s\n", text); } int main(int argc, char **argv) { - void *memory = NULL; + void *memory = NULL; wby_size needed_memory = 0; struct server_state state; - struct wby_server server; struct wby_config config; memset(&config, 0, sizeof config); config.userdata = &state; config.address = "127.0.0.1"; config.port = 8888; - config.connection_max = 4; + config.connection_max = 1; config.request_buffer_size = 2048; config.io_buffer_size = 8192; - /* config.log = test_log; */ + config.log = test_log; config.dispatch = dispatch; - /* config.ws_connect = websocket_connect; */ - /* config.ws_connected = websocket_connected; */ - /* config.ws_frame = websocket_frame; */ - /* config.ws_closed = websocket_closed; */ - -#if defined(_WIN32) - {WORD wsa_version = MAKEWORD(2,2); - WSADATA wsa_data; - if (WSAStartup(wsa_version, &wsa_data)) { - fprintf(stderr, "WSAStartup failed\n"); - return 1; - }} -#endif - + config.ws_connect = websocket_connect; + config.ws_connected = websocket_connected; + config.ws_frame = websocket_frame; + config.ws_closed = websocket_closed; + wby_init(&server, &config, &needed_memory); memory = calloc(needed_memory, 1); wby_start(&server, memory); memset(&state, 0, sizeof state); - while (!state.quit) { - int i = 0; + + printf("Awaiting WebSocket connection from Chrome extension.\n"); + while (con == NULL) { wby_update(&server); - /* Push some test data over websockets */ - if (!(state.frame_counter & 0x7f)) { - for (i = 0; i < state.conn_count; ++i) { - wby_frame_begin(state.conn[i], WBY_WSOP_TEXT_FRAME); - wby_write(state.conn[i], "Hello world over websockets!\n", 29); - wby_frame_end(state.conn[i]); - } - } - /* sleep_for(30); */ - ++state.frame_counter; } - wby_stop(&server); - free(memory); -#if defined(_WIN32) - WSACleanup(); -#endif - return 0; - // return fuse_main(argc, argv, &hello_filesystem_operations, NULL); + return fuse_main(argc, argv, &hello_filesystem_operations, NULL); +/* wby_stop(&server); */ +/* free(memory); */ +/* #if defined(_WIN32) */ +/* WSACleanup(); */ +/* #endif */ +/* return 0; */ + // } -- cgit v1.2.3