Преглед изворни кода

Add UUID for Lua (in Linux). See also #140.

bel2125 пре 9 година
родитељ
комит
01998fbcfe
3 измењених фајлова са 106 додато и 1 уклоњено
  1. 4 0
      src/civetweb.c
  2. 89 1
      src/mod_lua.inl
  3. 13 0
      test/page4.lua

+ 4 - 0
src/civetweb.c

@@ -12719,6 +12719,10 @@ mg_start(const struct mg_callbacks *callbacks,
 #endif
 	pthread_setspecific(sTlsKey, &tls);
 
+#if defined(USE_LUA)
+	lua_init_optional_libraries();
+#endif
+
 	ok = 0 == pthread_mutex_init(&ctx->thread_mutex, &pthread_mutex_attr);
 	ok &= 0 == pthread_cond_init(&ctx->thread_cond, NULL);
 	ok &= 0 == pthread_cond_init(&ctx->sq_empty, NULL);

+ 89 - 1
src/mod_lua.inl

@@ -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
+}
+

+ 13 - 0
test/page4.lua

@@ -162,6 +162,19 @@ dec_mg_string = mg.base64_decode(mg_string)
 dec_ref_string = mg.base64_decode(ref_string)
 mg.write("  decoded mg-base64:        " .. htmlEscape(dec_mg_string) .. "\r\n")
 mg.write("  decoded reference base64: " .. htmlEscape(dec_ref_string) .. "\r\n")
+mg.write("\r\n")
+
+-- random
+mg.write("Random numbers:\r\n")
+for i=1,10 do mg.write(string.format("%18u\r\n", mg.random())) end
+mg.write("\r\n")
+
+-- uuid
+if mg.uuid then
+mg.write("UUIDs:\r\n")
+for i=1,10 do mg.write(string.format("%40s\r\n", mg.uuid())) end
+mg.write("\r\n")
+end
 
 -- end of page
 mg.write("</pre>\r\n</body>\r\n</html>\r\n")