|
@@ -704,17 +704,54 @@ enum {
|
|
|
LUA_ENV_TYPE_LUA_WEBSOCKET = 2,
|
|
|
};
|
|
|
|
|
|
-static void prepare_lua_environment(struct mg_context * ctx, struct mg_connection *conn, struct lua_websock_data *conn_list, lua_State *L, const char *script_name, int lua_env_type)
|
|
|
+static void prepare_lua_request_info(struct mg_connection *conn, lua_State *L)
|
|
|
{
|
|
|
- const char * preload_file = ((conn != NULL) ? conn->ctx->config[LUA_PRELOAD_FILE] : NULL);
|
|
|
char src_addr[IP_ADDR_STR_LEN] = "";
|
|
|
int i;
|
|
|
|
|
|
- extern void luaL_openlibs(lua_State *);
|
|
|
+ sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);
|
|
|
+
|
|
|
+ /* Export mg.request_info */
|
|
|
+ lua_pushstring(L, "request_info");
|
|
|
+ lua_newtable(L);
|
|
|
+ reg_string(L, "request_method", conn->request_info.request_method);
|
|
|
+ reg_string(L, "uri", conn->request_info.uri);
|
|
|
+ reg_string(L, "http_version", conn->request_info.http_version);
|
|
|
+ reg_string(L, "query_string", conn->request_info.query_string);
|
|
|
+ reg_int(L, "remote_ip", conn->request_info.remote_ip); /* remote_ip is deprecated, use remote_addr instead */
|
|
|
+ reg_string(L, "remote_addr", src_addr);
|
|
|
+ /* TODO: ip version */
|
|
|
+ reg_int(L, "remote_port", conn->request_info.remote_port);
|
|
|
+ reg_int(L, "num_headers", conn->request_info.num_headers);
|
|
|
+ reg_int(L, "server_port", ntohs(conn->client.lsa.sin.sin_port));
|
|
|
+
|
|
|
+ if (conn->request_info.remote_user != NULL) {
|
|
|
+ reg_string(L, "remote_user", conn->request_info.remote_user);
|
|
|
+ reg_string(L, "auth_type", "Digest");
|
|
|
+ }
|
|
|
|
|
|
- if (conn != NULL) {
|
|
|
- sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);
|
|
|
+ reg_boolean(L, "https", conn->ssl != NULL);
|
|
|
+
|
|
|
+ if (conn->status_code > 0) {
|
|
|
+ /* Lua error handler should show the status code */
|
|
|
+ reg_int(L, "status", conn->status_code);
|
|
|
+ }
|
|
|
+
|
|
|
+ lua_pushstring(L, "http_headers");
|
|
|
+ lua_newtable(L);
|
|
|
+ for (i = 0; i < conn->request_info.num_headers; i++) {
|
|
|
+ reg_string(L, conn->request_info.http_headers[i].name, conn->request_info.http_headers[i].value);
|
|
|
}
|
|
|
+ lua_rawset(L, -3);
|
|
|
+
|
|
|
+ lua_rawset(L, -3);
|
|
|
+}
|
|
|
+
|
|
|
+static void prepare_lua_environment(struct mg_context * ctx, struct mg_connection *conn, struct lua_websock_data *conn_list, lua_State *L, const char *script_name, int lua_env_type)
|
|
|
+{
|
|
|
+ const char * preload_file = ((conn != NULL) ? conn->ctx->config[LUA_PRELOAD_FILE] : NULL);
|
|
|
+
|
|
|
+ extern void luaL_openlibs(lua_State *);
|
|
|
|
|
|
luaL_openlibs(L);
|
|
|
#ifdef USE_LUA_SQLITE3
|
|
@@ -806,40 +843,7 @@ static void prepare_lua_environment(struct mg_context * ctx, struct mg_connectio
|
|
|
|
|
|
/* Export connection specific info */
|
|
|
if (conn!=NULL) {
|
|
|
- /* Export mg.request_info */
|
|
|
- lua_pushstring(L, "request_info");
|
|
|
- lua_newtable(L);
|
|
|
- reg_string(L, "request_method", conn->request_info.request_method);
|
|
|
- reg_string(L, "uri", conn->request_info.uri);
|
|
|
- reg_string(L, "http_version", conn->request_info.http_version);
|
|
|
- reg_string(L, "query_string", conn->request_info.query_string);
|
|
|
- reg_int(L, "remote_ip", conn->request_info.remote_ip); /* remote_ip is deprecated, use remote_addr instead */
|
|
|
- reg_string(L, "remote_addr", src_addr);
|
|
|
- /* TODO: ip version */
|
|
|
- reg_int(L, "remote_port", conn->request_info.remote_port);
|
|
|
- reg_int(L, "num_headers", conn->request_info.num_headers);
|
|
|
- reg_int(L, "server_port", ntohs(conn->client.lsa.sin.sin_port));
|
|
|
-
|
|
|
- if (conn->request_info.remote_user != NULL) {
|
|
|
- reg_string(L, "remote_user", conn->request_info.remote_user);
|
|
|
- reg_string(L, "auth_type", "Digest");
|
|
|
- }
|
|
|
-
|
|
|
- reg_boolean(L, "https", conn->ssl != NULL);
|
|
|
-
|
|
|
- if (conn->status_code > 0) {
|
|
|
- /* Lua error handler should show the status code */
|
|
|
- reg_int(L, "status", conn->status_code);
|
|
|
- }
|
|
|
-
|
|
|
- lua_pushstring(L, "http_headers");
|
|
|
- lua_newtable(L);
|
|
|
- for (i = 0; i < conn->request_info.num_headers; i++) {
|
|
|
- reg_string(L, conn->request_info.http_headers[i].name, conn->request_info.http_headers[i].value);
|
|
|
- }
|
|
|
- lua_rawset(L, -3);
|
|
|
-
|
|
|
- lua_rawset(L, -3);
|
|
|
+ prepare_lua_request_info(conn, L);
|
|
|
}
|
|
|
|
|
|
lua_setglobal(L, "mg");
|
|
@@ -1040,13 +1044,11 @@ static void * lua_websocket_new(const char * script, struct mg_connection *conn)
|
|
|
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);
|
|
|
if (err != 0) {
|
|
|
- mg_cry(conn, "Lua websocket: Error %i loading %s: %s", err, script,
|
|
|
- lua_tostring((*shared_websock_list)->ws.state, -1));
|
|
|
+ websock_cry(conn, err, (*shared_websock_list)->ws.state, script, "load");
|
|
|
}
|
|
|
err = lua_pcall((*shared_websock_list)->ws.state, 0, 0, 0);
|
|
|
if (err != 0) {
|
|
|
- mg_cry(conn, "Lua websocket: Error %i initializing %s: %s", err, script,
|
|
|
- lua_tostring((*shared_websock_list)->ws.state, -1));
|
|
|
+ websock_cry(conn, err, (*shared_websock_list)->ws.state, script, "init");
|
|
|
}
|
|
|
} else {
|
|
|
/* inc ref count */
|
|
@@ -1059,8 +1061,7 @@ static void * lua_websocket_new(const char * script, struct mg_connection *conn)
|
|
|
lua_getglobal((*shared_websock_list)->ws.state, "open");
|
|
|
err = lua_pcall((*shared_websock_list)->ws.state, 0, 1, 0);
|
|
|
if (err != 0) {
|
|
|
- mg_cry(conn, "Lua websocket: Error %i calling open handler of %s: %s", err, script,
|
|
|
- lua_tostring((*shared_websock_list)->ws.state, -1));
|
|
|
+ websock_cry(conn, err, (*shared_websock_list)->ws.state, script, "open handler");
|
|
|
} else {
|
|
|
if (lua_isboolean((*shared_websock_list)->ws.state, -1)) {
|
|
|
ok = lua_toboolean((*shared_websock_list)->ws.state, -1);
|
|
@@ -1090,7 +1091,7 @@ static int lua_websocket_data(struct mg_connection * conn, void *ws_arg, int bit
|
|
|
lua_pushlstring(ws->state, data, data_len);
|
|
|
err = lua_pcall(ws->state, 2, 1, 0);
|
|
|
if (err != 0) {
|
|
|
- mg_cry(conn, "Lua websocket: Error %i calling data handler of %s", err, ws->script);
|
|
|
+ websock_cry(conn, err, ws->state, ws->script, "open handler");
|
|
|
} else {
|
|
|
if (lua_isboolean(ws->state, -1)) {
|
|
|
ok = lua_toboolean(ws->state, -1);
|
|
@@ -1104,7 +1105,28 @@ static int lua_websocket_data(struct mg_connection * conn, void *ws_arg, int bit
|
|
|
|
|
|
static int lua_websocket_ready(struct mg_connection * conn, void * ws_arg)
|
|
|
{
|
|
|
- return lua_websocket_data(conn, ws_arg, -1, NULL, 0);
|
|
|
+ struct lua_websock_data *ws = (struct lua_websock_data *)(ws_arg);
|
|
|
+ int err, ok = 0;
|
|
|
+
|
|
|
+ assert(ws != NULL);
|
|
|
+ assert(ws->state != NULL);
|
|
|
+
|
|
|
+ (void)pthread_mutex_lock(&ws->ws_mutex);
|
|
|
+ lua_getglobal(ws->state, "ready");
|
|
|
+ lua_newtable(ws->state);
|
|
|
+ prepare_lua_request_info(conn, ws->state);
|
|
|
+ err = lua_pcall(ws->state, 1, 1, 0);
|
|
|
+ if (err != 0) {
|
|
|
+ websock_cry(conn, err, ws->state, ws->script, "ready handler");
|
|
|
+ } else {
|
|
|
+ if (lua_isboolean(ws->state, -1)) {
|
|
|
+ ok = lua_toboolean(ws->state, -1);
|
|
|
+ }
|
|
|
+ lua_pop(ws->state, 1);
|
|
|
+ }
|
|
|
+ (void)pthread_mutex_unlock(&ws->ws_mutex);
|
|
|
+
|
|
|
+ return ok;
|
|
|
}
|
|
|
|
|
|
static void lua_websocket_close(struct mg_connection * conn, void * ws_arg)
|
|
@@ -1121,7 +1143,7 @@ static void lua_websocket_close(struct mg_connection * conn, void * ws_arg)
|
|
|
lua_getglobal(ws->state, "close");
|
|
|
err = lua_pcall(ws->state, 0, 0, 0);
|
|
|
if (err != 0) {
|
|
|
- mg_cry(conn, "Lua websocket: Error %i calling close handler of %s", err, ws->script);
|
|
|
+ websock_cry(conn, err, ws->state, ws->script, "close handler");
|
|
|
}
|
|
|
for (i=0;i<ws->references;i++) {
|
|
|
if (ws->conn[i]==conn) {
|