|
@@ -2468,6 +2468,7 @@ static const char month_names[][4] = {"Jan",
|
|
|
"Dec"};
|
|
|
#endif /* !NO_CACHING */
|
|
|
|
|
|
+
|
|
|
/* Unified socket address. For IPv6 support, add IPv6 address structure in
|
|
|
* the union u. */
|
|
|
union usa {
|
|
@@ -2478,6 +2479,7 @@ union usa {
|
|
|
#endif
|
|
|
};
|
|
|
|
|
|
+
|
|
|
#if defined(USE_IPV6)
|
|
|
#define USA_IN_PORT_UNSAFE(s) \
|
|
|
(((s)->sa.sa_family == AF_INET6) ? (s)->sin6.sin6_port : (s)->sin.sin_port)
|
|
@@ -4164,7 +4166,6 @@ mg_construct_local_link(const struct mg_connection *conn,
|
|
|
if ((buflen < 1) || (buf == 0) || (conn == 0)) {
|
|
|
return -1;
|
|
|
} else {
|
|
|
-
|
|
|
int truncated = 0;
|
|
|
const struct mg_request_info *ri = &conn->request_info;
|
|
|
|
|
@@ -15301,6 +15302,7 @@ set_ports_option(struct mg_context *phys_ctx)
|
|
|
}
|
|
|
}
|
|
|
#endif
|
|
|
+
|
|
|
else {
|
|
|
mg_cry_ctx_internal(
|
|
|
phys_ctx,
|
|
@@ -19240,10 +19242,20 @@ master_thread_run(struct mg_context *ctx)
|
|
|
tls.user_ptr = NULL;
|
|
|
}
|
|
|
|
|
|
+ /* Lua background script "start" event */
|
|
|
+#if defined(USE_LUA)
|
|
|
+ if (ctx->lua_background_state) {
|
|
|
+ lua_State *lstate = (lua_State *)ctx->lua_background_state;
|
|
|
+ /* call "start()" in Lua */
|
|
|
+ lua_getglobal(lstate, "start");
|
|
|
+ (void)lua_pcall(lstate, /* args */ 0, /* results */ 0, 0);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
/* Server starts *now* */
|
|
|
ctx->start_time = time(NULL);
|
|
|
|
|
|
- /* Start the server */
|
|
|
+ /* Server accept loop */
|
|
|
pfd = ctx->listening_socket_fds;
|
|
|
while (STOP_FLAG_IS_ZERO(&ctx->stop_flag)) {
|
|
|
for (i = 0; i < ctx->num_listening_sockets; i++) {
|
|
@@ -19295,12 +19307,9 @@ master_thread_run(struct mg_context *ctx)
|
|
|
/* Free Lua state of lua background task */
|
|
|
if (ctx->lua_background_state) {
|
|
|
lua_State *lstate = (lua_State *)ctx->lua_background_state;
|
|
|
- lua_getglobal(lstate, LUABACKGROUNDPARAMS);
|
|
|
- if (lua_istable(lstate, -1)) {
|
|
|
- reg_boolean(lstate, "shutdown", 1);
|
|
|
- lua_pop(lstate, 1);
|
|
|
- mg_sleep(2);
|
|
|
- }
|
|
|
+ /* call "stop()" in Lua */
|
|
|
+ lua_getglobal(lstate, "stop");
|
|
|
+ (void)lua_pcall(lstate, /* args */ 0, /* results */ 0, 0);
|
|
|
lua_close(lstate);
|
|
|
ctx->lua_background_state = 0;
|
|
|
}
|
|
@@ -19831,10 +19840,14 @@ static
|
|
|
struct vec opt_vec;
|
|
|
struct vec eq_vec;
|
|
|
const char *sparams;
|
|
|
- lua_State *state = mg_prepare_lua_context_script(
|
|
|
+
|
|
|
+ /* Create a Lua state, load all standard libraries and the mg table */
|
|
|
+ lua_State *state = mg_lua_context_script_prepare(
|
|
|
ctx->dd.config[LUA_BACKGROUND_SCRIPT], ctx, ebuf, sizeof(ebuf));
|
|
|
if (!state) {
|
|
|
- mg_cry_ctx_internal(ctx, "lua_background_script error: %s", ebuf);
|
|
|
+ mg_cry_ctx_internal(ctx,
|
|
|
+ "lua_background_script load error: %s",
|
|
|
+ ebuf);
|
|
|
if ((error != NULL) && (error->text_buffer_size > 0)) {
|
|
|
mg_snprintf(NULL,
|
|
|
NULL, /* No truncation check for error buffers */
|
|
@@ -19848,20 +19861,51 @@ static
|
|
|
pthread_setspecific(sTlsKey, NULL);
|
|
|
return NULL;
|
|
|
}
|
|
|
- ctx->lua_background_state = (void *)state;
|
|
|
-
|
|
|
- lua_newtable(state);
|
|
|
- reg_boolean(state, "shutdown", 0);
|
|
|
|
|
|
+ /* Add a table with parameters into mg.params */
|
|
|
sparams = ctx->dd.config[LUA_BACKGROUND_SCRIPT_PARAMS];
|
|
|
+ if (sparams && sparams[0]) {
|
|
|
+ lua_getglobal(state, "mg");
|
|
|
+ lua_pushstring(state, "params");
|
|
|
+ lua_newtable(state);
|
|
|
+
|
|
|
+ while ((sparams = next_option(sparams, &opt_vec, &eq_vec))
|
|
|
+ != NULL) {
|
|
|
+ reg_llstring(
|
|
|
+ state, opt_vec.ptr, opt_vec.len, eq_vec.ptr, eq_vec.len);
|
|
|
+ if (mg_strncasecmp(sparams, opt_vec.ptr, opt_vec.len) == 0)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ lua_rawset(state, -3);
|
|
|
+ lua_pop(state, 1);
|
|
|
+ }
|
|
|
|
|
|
- while ((sparams = next_option(sparams, &opt_vec, &eq_vec)) != NULL) {
|
|
|
- reg_llstring(
|
|
|
- state, opt_vec.ptr, opt_vec.len, eq_vec.ptr, eq_vec.len);
|
|
|
- if (mg_strncasecmp(sparams, opt_vec.ptr, opt_vec.len) == 0)
|
|
|
- break;
|
|
|
+ /* Call script */
|
|
|
+ state = mg_lua_context_script_run(state,
|
|
|
+ ctx->dd.config[LUA_BACKGROUND_SCRIPT],
|
|
|
+ ctx,
|
|
|
+ ebuf,
|
|
|
+ sizeof(ebuf));
|
|
|
+ if (!state) {
|
|
|
+ mg_cry_ctx_internal(ctx,
|
|
|
+ "lua_background_script start error: %s",
|
|
|
+ ebuf);
|
|
|
+ if ((error != NULL) && (error->text_buffer_size > 0)) {
|
|
|
+ mg_snprintf(NULL,
|
|
|
+ NULL, /* No truncation check for error buffers */
|
|
|
+ error->text,
|
|
|
+ error->text_buffer_size,
|
|
|
+ "Error in script %s: %s",
|
|
|
+ config_options[DOCUMENT_ROOT].name,
|
|
|
+ ebuf);
|
|
|
+ }
|
|
|
+ free_context(ctx);
|
|
|
+ pthread_setspecific(sTlsKey, NULL);
|
|
|
+ return NULL;
|
|
|
}
|
|
|
- lua_setglobal(state, LUABACKGROUNDPARAMS);
|
|
|
+
|
|
|
+ /* state remains valid */
|
|
|
+ ctx->lua_background_state = (void *)state;
|
|
|
|
|
|
} else {
|
|
|
ctx->lua_background_state = 0;
|