|
@@ -858,7 +858,7 @@ lsp_random(lua_State *L)
|
|
|
* https://en.wikipedia.org/wiki/Double-precision_floating-point_format
|
|
|
* Thus, mask with 2^53-1 to get an integer with the maximum
|
|
|
* precission available. */
|
|
|
- r &= ((1<<53)-1);
|
|
|
+ r &= ((((uint64_t)1)<<53)-1);
|
|
|
lua_pushnumber(L, (double)r);
|
|
|
return 1;
|
|
|
}
|
|
@@ -868,6 +868,59 @@ lsp_random(lua_State *L)
|
|
|
}
|
|
|
|
|
|
|
|
|
+union {
|
|
|
+ void *p;
|
|
|
+ void (*f)(unsigned char uuid[16]);
|
|
|
+} pf_uuid_generate;
|
|
|
+
|
|
|
+
|
|
|
+/* mg.uuid */
|
|
|
+static int
|
|
|
+lsp_uuid(lua_State *L)
|
|
|
+{
|
|
|
+ union {
|
|
|
+ unsigned char uuid_array[16];
|
|
|
+ struct uuid_struct_type {
|
|
|
+ uint32_t data1;
|
|
|
+ uint16_t data2;
|
|
|
+ uint16_t data3;
|
|
|
+ uint8_t data4[8];
|
|
|
+ } uuid_struct;
|
|
|
+ } uuid;
|
|
|
+
|
|
|
+ char uuid_str[40];
|
|
|
+ int num_args = lua_gettop(L);
|
|
|
+
|
|
|
+ memset(&uuid, 0, sizeof(uuid));
|
|
|
+ memset(uuid_str, 0, sizeof(uuid_str));
|
|
|
+
|
|
|
+ if (num_args == 0) {
|
|
|
+
|
|
|
+ pf_uuid_generate.f(uuid.uuid_array);
|
|
|
+
|
|
|
+ sprintf(uuid_str, "{%08lX-%04X-%04X-%02X%02X-"
|
|
|
+ "%02X%02X%02X%02X%02X%02X}",
|
|
|
+ (unsigned long)uuid.uuid_struct.data1,
|
|
|
+ (unsigned)uuid.uuid_struct.data2,
|
|
|
+ (unsigned)uuid.uuid_struct.data3,
|
|
|
+ (unsigned)uuid.uuid_struct.data4[0],
|
|
|
+ (unsigned)uuid.uuid_struct.data4[1],
|
|
|
+ (unsigned)uuid.uuid_struct.data4[2],
|
|
|
+ (unsigned)uuid.uuid_struct.data4[3],
|
|
|
+ (unsigned)uuid.uuid_struct.data4[4],
|
|
|
+ (unsigned)uuid.uuid_struct.data4[5],
|
|
|
+ (unsigned)uuid.uuid_struct.data4[6],
|
|
|
+ (unsigned)uuid.uuid_struct.data4[7]);
|
|
|
+
|
|
|
+ lua_pushstring(L, uuid_str);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Syntax error */
|
|
|
+ return luaL_error(L, "invalid random() call");
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
#ifdef USE_WEBSOCKET
|
|
|
struct lua_websock_data {
|
|
|
lua_State *state;
|
|
@@ -878,6 +931,7 @@ struct lua_websock_data {
|
|
|
};
|
|
|
#endif
|
|
|
|
|
|
+
|
|
|
/* mg.write for websockets */
|
|
|
static int
|
|
|
lwebsock_write(lua_State *L)
|
|
@@ -977,6 +1031,7 @@ lwebsock_write(lua_State *L)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
struct laction_arg {
|
|
|
lua_State *state;
|
|
|
const char *script;
|
|
@@ -984,6 +1039,7 @@ struct laction_arg {
|
|
|
char txt[1];
|
|
|
};
|
|
|
|
|
|
+
|
|
|
static int
|
|
|
lua_action(struct laction_arg *arg)
|
|
|
{
|
|
@@ -1027,6 +1083,7 @@ lua_action(struct laction_arg *arg)
|
|
|
return ok;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static int
|
|
|
lua_action_free(struct laction_arg *arg)
|
|
|
{
|
|
@@ -1036,6 +1093,7 @@ lua_action_free(struct laction_arg *arg)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static int
|
|
|
lwebsocket_set_timer(lua_State *L, int is_periodic)
|
|
|
{
|
|
@@ -1103,6 +1161,7 @@ lwebsocket_set_timer(lua_State *L, int is_periodic)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/* mg.set_timeout for websockets */
|
|
|
static int
|
|
|
lwebsocket_set_timeout(lua_State *L)
|
|
@@ -1110,6 +1169,7 @@ lwebsocket_set_timeout(lua_State *L)
|
|
|
return lwebsocket_set_timer(L, 0);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/* mg.set_interval for websockets */
|
|
|
static int
|
|
|
lwebsocket_set_interval(lua_State *L)
|
|
@@ -1123,6 +1183,7 @@ enum {
|
|
|
LUA_ENV_TYPE_LUA_WEBSOCKET = 2,
|
|
|
};
|
|
|
|
|
|
+
|
|
|
static void
|
|
|
prepare_lua_request_info(struct mg_connection *conn, lua_State *L)
|
|
|
{
|
|
@@ -1186,6 +1247,7 @@ prepare_lua_request_info(struct mg_connection *conn, lua_State *L)
|
|
|
lua_rawset(L, -3);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
void
|
|
|
civetweb_open_lua_libs(lua_State *L)
|
|
|
{
|
|
@@ -1224,6 +1286,7 @@ civetweb_open_lua_libs(lua_State *L)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static void
|
|
|
prepare_lua_environment(struct mg_context *ctx,
|
|
|
struct mg_connection *conn,
|
|
@@ -1308,6 +1371,9 @@ prepare_lua_environment(struct mg_context *ctx,
|
|
|
reg_function(L, "base64_decode", lsp_base64_decode);
|
|
|
reg_function(L, "get_response_code_text", lsp_get_response_code_text);
|
|
|
reg_function(L, "random", lsp_random);
|
|
|
+ if (pf_uuid_generate.f) {
|
|
|
+ reg_function(L, "uuid", lsp_uuid);
|
|
|
+ }
|
|
|
|
|
|
reg_string(L, "version", CIVETWEB_VERSION);
|
|
|
|
|
@@ -1350,6 +1416,7 @@ prepare_lua_environment(struct mg_context *ctx,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static int
|
|
|
lua_error_handler(lua_State *L)
|
|
|
{
|
|
@@ -1373,6 +1440,7 @@ lua_error_handler(lua_State *L)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static void *
|
|
|
lua_allocator(void *ud, void *ptr, size_t osize, size_t nsize)
|
|
|
{
|
|
@@ -1387,6 +1455,7 @@ lua_allocator(void *ud, void *ptr, size_t osize, size_t nsize)
|
|
|
return mg_realloc(ptr, nsize);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static void
|
|
|
mg_exec_lua_script(struct mg_connection *conn,
|
|
|
const char *path,
|
|
@@ -1433,6 +1502,7 @@ mg_exec_lua_script(struct mg_connection *conn,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static int
|
|
|
handle_lsp_request(struct mg_connection *conn,
|
|
|
const char *path,
|
|
@@ -1547,12 +1617,14 @@ cleanup_handle_lsp_request:
|
|
|
return error;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
#ifdef USE_WEBSOCKET
|
|
|
struct mg_shared_lua_websocket_list {
|
|
|
struct lua_websock_data ws;
|
|
|
struct mg_shared_lua_websocket_list *next;
|
|
|
};
|
|
|
|
|
|
+
|
|
|
static void *
|
|
|
lua_websocket_new(const char *script, struct mg_connection *conn)
|
|
|
{
|
|
@@ -1637,6 +1709,7 @@ lua_websocket_new(const char *script, struct mg_connection *conn)
|
|
|
return ok ? (void *)ws : NULL;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static int
|
|
|
lua_websocket_data(struct mg_connection *conn,
|
|
|
int bits,
|
|
@@ -1681,6 +1754,7 @@ lua_websocket_data(struct mg_connection *conn,
|
|
|
return ok;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static int
|
|
|
lua_websocket_ready(struct mg_connection *conn, void *ws_arg)
|
|
|
{
|
|
@@ -1712,6 +1786,7 @@ lua_websocket_ready(struct mg_connection *conn, void *ws_arg)
|
|
|
return ok;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static void
|
|
|
lua_websocket_close(struct mg_connection *conn, void *ws_arg)
|
|
|
{
|
|
@@ -1750,3 +1825,16 @@ lua_websocket_close(struct mg_connection *conn, void *ws_arg)
|
|
|
(void)pthread_mutex_unlock(&(ws->ws_mutex));
|
|
|
}
|
|
|
#endif
|
|
|
+
|
|
|
+
|
|
|
+static void
|
|
|
+lua_init_optional_libraries(void)
|
|
|
+{
|
|
|
+#if !defined(_WIN32)
|
|
|
+ void *dll_handle = dlopen("libuuid.so", RTLD_LAZY);
|
|
|
+ pf_uuid_generate.p = dlsym(dll_handle, "uuid_generate");
|
|
|
+#else
|
|
|
+ pf_uuid_generate.p = 0;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|