diff --git a/share/trick/sim_objects/CivetServer.sm b/share/trick/sim_objects/CivetServer.sm index 76b65e65..543a10a5 100644 --- a/share/trick/sim_objects/CivetServer.sm +++ b/share/trick/sim_objects/CivetServer.sm @@ -24,4 +24,3 @@ class MyCivetServerSimObject : public Trick::SimObject { }; MyCivetServerSimObject web; - diff --git a/trick_source/web/CivetServer/include/http_GET_handlers.hh b/trick_source/web/CivetServer/include/http_GET_handlers.hh index 42e4febf..a9aca2f9 100644 --- a/trick_source/web/CivetServer/include/http_GET_handlers.hh +++ b/trick_source/web/CivetServer/include/http_GET_handlers.hh @@ -8,7 +8,31 @@ LIBRARY DEPENDENCIES: #include "civet/CivetServer.h" -void handle_HTTP_GET_vs_connections(struct mg_connection *nc, struct http_message *hm); -void handle_HTTP_GET_alloc_info(struct mg_connection *nc, struct http_message *hm); +int handle_HTTP_GET_vs_connections(struct mg_connection *nc, void* cbdata); +int handle_HTTP_GET_alloc_info(struct mg_connection *nc, void* ignore); + +int echo_connect_handler(const struct mg_connection *conn, + void *cbdata); + +void echo_ready_handler(struct mg_connection *conn, void *cbdata); + +int echo_data_handler(struct mg_connection *conn, int bits, + char *data, size_t data_len, void *cbdata); + +void echo_close_handler(const struct mg_connection *conn, + void *cbdata); + +int ws_connect_handler(const struct mg_connection *conn, + void *ignore); + +//VariableServer +void ws_ready_handler(struct mg_connection *conn, void *my_server); + +int ws_data_handler(struct mg_connection *conn, int bits, + char *data, size_t data_len, void *my_server); + +void ws_close_handler(const struct mg_connection *conn, + void *my_server); + #endif diff --git a/trick_source/web/CivetServer/obj/CivetServer.o b/trick_source/web/CivetServer/obj/CivetServer.o index 885248cb..0740ef56 100644 Binary files a/trick_source/web/CivetServer/obj/CivetServer.o and b/trick_source/web/CivetServer/obj/CivetServer.o differ diff --git a/trick_source/web/CivetServer/obj/http_GET_handlers.o b/trick_source/web/CivetServer/obj/http_GET_handlers.o index bce08f29..4b658649 100644 Binary files a/trick_source/web/CivetServer/obj/http_GET_handlers.o and b/trick_source/web/CivetServer/obj/http_GET_handlers.o differ diff --git a/trick_source/web/CivetServer/src/CivetServer.cpp b/trick_source/web/CivetServer/src/CivetServer.cpp index b59a3001..edffadc5 100644 --- a/trick_source/web/CivetServer/src/CivetServer.cpp +++ b/trick_source/web/CivetServer/src/CivetServer.cpp @@ -21,7 +21,7 @@ PURPOSE: (Represent the state and initial conditions for my server) #include "civet/CivetServer.h" #include "civet/civetweb.h" -// #include "handlers.cpp" +#include "../include/http_GET_handlers.hh" void MyCivetServer::deleteWebSocketSession(struct mg_connection * nc) { @@ -53,10 +53,10 @@ void* start_civet(void* obj) std::cout << "ERROR: Could not create server." << std::endl; } - // mg_set_request_handler(server->ctx, "/api/http/vs_connections", handle_HTTP_GET_vs_connections, NULL); - // mg_set_request_handler(server->ctx, "/api/http/alloc_info", handle_HTTP_GET_alloc_info, NULL); + mg_set_request_handler(server->ctx, "/api/http/vs_connections", handle_HTTP_GET_vs_connections, NULL); + mg_set_request_handler(server->ctx, "/api/http/alloc_info", handle_HTTP_GET_alloc_info, NULL); - // mg_set_websocket_handler(server->ctx, "/api/ws/VariableServer", ws_connect_handler, ws_ready_handler, ws_data_handler, ws_close_handler, obj); + mg_set_websocket_handler(server->ctx, "/api/ws/VariableServer", ws_connect_handler, ws_ready_handler, ws_data_handler, ws_close_handler, obj); } diff --git a/trick_source/web/CivetServer/src/http_GET_handlers.cpp b/trick_source/web/CivetServer/src/http_GET_handlers.cpp index 61f45015..3019714d 100644 --- a/trick_source/web/CivetServer/src/http_GET_handlers.cpp +++ b/trick_source/web/CivetServer/src/http_GET_handlers.cpp @@ -4,62 +4,148 @@ LIBRARY DEPENDENCIES: ( (../src/http_GET_handlers.o)) **************************************************************************/ -// #include -// #include "../include/http_GET_handlers.hh" +#include "../include/http_GET_handlers.hh" +#include "trick/CivetServer.hh" -// #include "trick/VariableServer.hh" -// extern Trick::VariableServer * the_vs ; +#include "civet/CivetServer.h" +#include "civet/civetweb.h" +#include -// #include "trick/MemoryManager.hh" -// extern Trick::MemoryManager* trick_MM; +#include "trick/VariableServer.hh" +extern Trick::VariableServer * the_vs ; -// // In the Trick HTTP Server, a HTTP GET request whose URI starts with the API_PREFIX -// // is processed by a http-handler-function of the following form: -// // -// // void HTTP_METHOD_HANDLER( struct mg_connection *, struct http_message *); -// // -// // The purpose of these functions are generally to produce dynamically generated -// // HTTP responses, like JSON. These handler-functions are installed into the HTTP_Server -// // with the member-function .install_API_GET_handler. For example: -// // -// // http.server.install_API_GET_handler("vs_connections", &handle_HTTP_GET_vs_connections); -// // -// // installs the function handle_HTTP_GET_vs_connections() with the key "vs_connections". -// // So if, for example the host and port of the webserver is "localhost:8888", and the API_PREFIX is "/api/v1/", -// // then loading the URL "localhost:8888/api/v1/vs_connections" in your browser will cause -// // handle_HTTP_GET_vs_connections() to run and return its response, which in this case is a JSON object -// // describing the variable server connections. +#include "trick/MemoryManager.hh" +extern Trick::MemoryManager* trick_MM; +void http_send(struct mg_connection *conn, const char* msg, int len, int chunk_size) { + int size = len; + int count = 0; + if (chunk_size > size) { + chunk_size = len; + } + while (size > 0) { + std::string buff = std::string(msg).substr(count * chunk_size, chunk_size); + std::cout << "Sending chunk: " << buff << std::endl; + mg_send_chunk(conn, buff.c_str(), buff.length()); + count++; + size = size - chunk_size; + } + std::string buff = std::string(msg).substr(count * chunk_size, chunk_size); + mg_send_chunk(conn, buff.c_str(), buff.length()); +} -// // Send a JSON object to the given mongoose HTTP connection that describes the -// // Variable Server Connections. -// void handle_HTTP_GET_vs_connections(struct mg_connection *nc, struct http_message *hm) { -// mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"); -// std::stringstream ss; -// ss << *the_vs << std::endl; -// std::string someJSON = ss.str(); -// mg_send_http_ok(nc, "%s", someJSON.c_str()); -// mg_send_http_chunk(nc, "", 0); -// } +///// HTTP -// static int getIntegerQueryValue(struct http_message *hm, const char* key, int defaultVal) { -// char value_text[100]; -// if ( mg_get_http_var(&(hm->query_string), key, value_text, sizeof(value_text)) > 0) { -// return atoi(value_text); -// } else { -// return defaultVal; -// } -// } +int handle_HTTP_GET_vs_connections(struct mg_connection* conn, void *cbdata) { + mg_printf(conn, + "HTTP/1.1 200 OK\r\nConnection: " + "close\r\nTransfer-Encoding: chunked\r\n"); + mg_printf(conn, "Content-Type: text/plain\r\n\r\n"); + + std::stringstream ss; + ss << *the_vs << std::endl; + std::string someJSON = ss.str(); -// // Send a JSON object to the given mongoose HTTP connection that contains information -// // about a range of memory allocations in the Trick Memory Manager. -// void handle_HTTP_GET_alloc_info(struct mg_connection *nc, struct http_message *hm) { -// int start = getIntegerQueryValue(hm, "start", 0); -// int count = getIntegerQueryValue(hm, "count", 10); -// mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"); -// std::stringstream ss; -// trick_MM->write_JSON_alloc_list(ss, start, count); -// std::string someJSON = ss.str(); -// mg_send_http_ok(nc, "%s", someJSON.c_str()); -// mg_send_http_chunk(nc, "", 0); -// } + http_send(conn, someJSON.c_str(), someJSON.length(), 100); + return 200; +} + +int handle_HTTP_GET_alloc_info(struct mg_connection *conn, void* ignore) { + mg_printf(conn, + "HTTP/1.1 200 OK\r\nConnection: " + "close\r\nTransfer-Encoding: chunked\r\n"); + mg_printf(conn, "Content-Type: text/plain\r\n\r\n"); + + const struct mg_request_info* ri = mg_get_request_info(conn); + int max_size = 100; + char start_str[max_size], count_str[max_size]; + mg_get_var2(ri->request_uri, strlen(ri->request_uri), "start", start_str, max_size, 0); + mg_get_var2(ri->request_uri, strlen(ri->request_uri), "count", count_str, max_size, 0); + mg_send_http_ok(conn, "text/plain", -1); + std::stringstream ss; + int start = strtol(start_str, NULL, 0); + int count = strtol(count_str, NULL, 0); + trick_MM->write_JSON_alloc_list(ss, start, count); + std::string someJSON = ss.str(); + + http_send(conn, someJSON.c_str(), someJSON.length(), 100); + + return 200; +} + +///// websockets + +int echo_connect_handler(const struct mg_connection *conn, + void *cbdata) +{ + int ret_val = 0; + return ret_val; +} + +void echo_ready_handler(struct mg_connection *conn, void *cbdata) +{ +} + +int echo_data_handler(struct mg_connection *conn, int bits, + char *data, size_t data_len, void *cbdata) +{ + std::cout << "from client:" << data << std::endl; + mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_TEXT, data, strlen(data)); + return 1; +} + +void echo_close_handler(const struct mg_connection *conn, + void *cbdata) +{ +} + +int ws_connect_handler(const struct mg_connection *conn, + void *ignore) +{ + int ret_val = 0; + return ret_val; +} + +//VariableServer +void ws_ready_handler(struct mg_connection *conn, void *my_server) +{ + MyCivetServer* server = (MyCivetServer*) my_server; + WebSocketSession* session = server->makeWebSocketSession(conn, "VariableServer"); //TODO: Make this dynamic + server->addWebSocketSession(conn, session); +} + +int ws_data_handler(struct mg_connection *conn, int bits, + char *data, size_t data_len, void *my_server) +{ + int rvalue = 1; + std::cout << "Handling message:" << data << ":" << std::endl; + + MyCivetServer* server = (MyCivetServer*) my_server; + if (data_len > 0) { + // pthread_mutex_lock(&server->WebSocketSessionMapLock); //TODO: Do we need this lock? + std::map::iterator iter; + iter = server->webSocketSessionMap.find(conn); + if (iter != server->webSocketSessionMap.end()) { + WebSocketSession* session = iter->second; + session->handleMessage(data); + } + // pthread_mutex_unlock(&server->WebSocketSessionMapLock); + + } + return rvalue; +} + +void ws_close_handler(const struct mg_connection *conn, + void *my_server) +{ + MyCivetServer* server = (MyCivetServer*) my_server; + server->deleteWebSocketSession(const_cast(conn)); +} + +//Hooks + +int begin_request(struct mg_connection* conn) { + std::cout << "Processing request" << std::endl; + // std::cin.get(); + return 0; +} \ No newline at end of file