diff --git a/src/mod_lua.inl b/src/mod_lua.inl index 8f16c65b..58aa8a58 100644 --- a/src/mod_lua.inl +++ b/src/mod_lua.inl @@ -1013,6 +1013,7 @@ static void websock_cry(struct mg_connection *conn, int err, lua_State * L, cons static void * lua_websocket_new(const char * script, struct mg_connection *conn) { struct mg_shared_lua_websocket_list **shared_websock_list = &(conn->ctx->shared_lua_websockets); + struct lua_websock_data *ws; int err, ok = 0; assert(conn->lua_websocket_state == NULL); @@ -1035,46 +1036,54 @@ static void * lua_websocket_new(const char * script, struct mg_connection *conn) return NULL; } /* init ws list element */ - (*shared_websock_list)->ws.script = mg_strdup(script); /* TODO: handle OOM */ - pthread_mutex_init(&((*shared_websock_list)->ws.ws_mutex), NULL); - (*shared_websock_list)->ws.state = lua_newstate(lua_allocator, NULL); - (*shared_websock_list)->ws.conn[0] = conn; - (*shared_websock_list)->ws.references = 1; - (void)pthread_mutex_lock(&((*shared_websock_list)->ws.ws_mutex)); - prepare_lua_environment(conn->ctx, NULL, &((*shared_websock_list)->ws), (*shared_websock_list)->ws.state, script, LUA_ENV_TYPE_LUA_WEBSOCKET); - err = luaL_loadfile((*shared_websock_list)->ws.state, script); + ws = &(*shared_websock_list)->ws; + ws->script = mg_strdup(script); /* TODO: handle OOM */ + pthread_mutex_init(&(ws->ws_mutex), NULL); + ws->state = lua_newstate(lua_allocator, NULL); + ws->conn[0] = conn; + ws->references = 1; + (void)pthread_mutex_lock(&(ws->ws_mutex)); + prepare_lua_environment(conn->ctx, NULL, ws, ws->state, script, LUA_ENV_TYPE_LUA_WEBSOCKET); + err = luaL_loadfile(ws->state, script); if (err != 0) { - websock_cry(conn, err, (*shared_websock_list)->ws.state, script, "load"); + websock_cry(conn, err, ws->state, script, "load"); } - err = lua_pcall((*shared_websock_list)->ws.state, 0, 0, 0); + err = lua_pcall(ws->state, 0, 0, 0); if (err != 0) { - websock_cry(conn, err, (*shared_websock_list)->ws.state, script, "init"); + websock_cry(conn, err, ws->state, script, "init"); } } else { /* inc ref count */ - (void)pthread_mutex_lock(&((*shared_websock_list)->ws.ws_mutex)); - (*shared_websock_list)->ws.conn[((*shared_websock_list)->ws.references)++] = conn; + ws = &(*shared_websock_list)->ws; + (void)pthread_mutex_lock(&(ws->ws_mutex)); + (*shared_websock_list)->ws.conn[(ws->references)++] = conn; } (void)pthread_mutex_unlock(&conn->ctx->nonce_mutex); /* call add */ - lua_getglobal((*shared_websock_list)->ws.state, "open"); - err = lua_pcall((*shared_websock_list)->ws.state, 0, 1, 0); + lua_getglobal(ws->state, "open"); + lua_newtable(ws->state); + prepare_lua_request_info(conn, ws->state); + lua_pushstring(ws->state, "client"); + lua_pushlightuserdata(ws->state, (void *)conn); + lua_rawset(ws->state, -3); + + err = lua_pcall(ws->state, 1, 1, 0); if (err != 0) { - websock_cry(conn, err, (*shared_websock_list)->ws.state, script, "open handler"); + websock_cry(conn, err, ws->state, script, "open handler"); } else { - if (lua_isboolean((*shared_websock_list)->ws.state, -1)) { - ok = lua_toboolean((*shared_websock_list)->ws.state, -1); + if (lua_isboolean(ws->state, -1)) { + ok = lua_toboolean(ws->state, -1); } - lua_pop((*shared_websock_list)->ws.state, 1); + lua_pop(ws->state, 1); } if (!ok) { /* TODO */ } - (void)pthread_mutex_unlock(&((*shared_websock_list)->ws.ws_mutex)); + (void)pthread_mutex_unlock(&(ws->ws_mutex)); - return (void*)&((*shared_websock_list)->ws); + return (void*)ws; } static int lua_websocket_data(struct mg_connection * conn, void *ws_arg, int bits, char *data, size_t data_len) @@ -1125,7 +1134,6 @@ static int lua_websocket_ready(struct mg_connection * conn, void * ws_arg) lua_getglobal(ws->state, "ready"); lua_newtable(ws->state); - prepare_lua_request_info(conn, ws->state); lua_pushstring(ws->state, "client"); lua_pushlightuserdata(ws->state, (void *)conn); lua_rawset(ws->state, -3); diff --git a/test/websocket.lua b/test/websocket.lua index 70096cba..5cb48bd0 100644 --- a/test/websocket.lua +++ b/test/websocket.lua @@ -41,16 +41,25 @@ function ser(val) return t end +-- table of all active connection +allConnections = {} + +-- function to get a client identification string +function who(tab) + local ri = allConnections[tab.client] + return ri.remote_addr .. ":" .. ri.remote_port +end -- Callback to reject a connection -function open() - trace("open") +function open(tab) + allConnections[tab.client] = tab.request_info + trace("open[" .. who(tab) .. "]: " .. ser(tab)) return true end -- Callback for "Websocket ready" function ready(tab) - trace("ready: " .. ser(tab)) + trace("ready[" .. who(tab) .. "]: " .. ser(tab)) mg.write("text", "Websocket ready") senddata() return true @@ -58,15 +67,16 @@ end -- Callback for "Websocket received data" function data(tab) - trace("data: " .. ser(tab)) + trace("data[" .. who(tab) .. "]: " .. ser(tab)) senddata() return true end -- Callback for "Websocket is closing" function close(tab) - trace("close: " .. ser(tab)) + trace("close[" .. who(tab) .. "]: " .. ser(tab)) mg.write("text", "end") + allConnections[tab.client] = nil end function senddata()