소스 검색

Merge branch 'master' of https://github.com/civetweb/civetweb

bel2125 6 년 전
부모
커밋
4978377a2c
5개의 변경된 파일150개의 추가작업 그리고 134개의 파일을 삭제
  1. 0 4
      VisualStudio/civetweb_lua/civetweb_lua.vcxproj
  2. 0 6
      VisualStudio/civetweb_lua/civetweb_lua.vcxproj.filters
  3. 144 118
      src/civetweb.c
  4. 4 4
      src/mod_duktape.inl
  5. 2 2
      src/mod_lua.inl

+ 0 - 4
VisualStudio/civetweb_lua/civetweb_lua.vcxproj

@@ -175,9 +175,6 @@
     </Link>
     </Link>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
   <ItemGroup>
   <ItemGroup>
-    <Text Include="ReadMe.txt" />
-  </ItemGroup>
-  <ItemGroup>
     <ClInclude Include="..\..\include\civetweb.h" />
     <ClInclude Include="..\..\include\civetweb.h" />
     <ClInclude Include="..\..\src\third_party\civetweb_lua.h" />
     <ClInclude Include="..\..\src\third_party\civetweb_lua.h" />
     <ClInclude Include="..\..\src\third_party\lua-5.2.4\src\lauxlib.h" />
     <ClInclude Include="..\..\src\third_party\lua-5.2.4\src\lauxlib.h" />
@@ -208,7 +205,6 @@
     <None Include="..\..\src\mod_duktape.inl" />
     <None Include="..\..\src\mod_duktape.inl" />
     <None Include="..\..\src\mod_lua.inl" />
     <None Include="..\..\src\mod_lua.inl" />
     <None Include="..\..\src\timer.inl" />
     <None Include="..\..\src\timer.inl" />
-    <None Include="..\..\src\file_ops.inl" />
   </ItemGroup>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   <ImportGroup Label="ExtensionTargets">

+ 0 - 6
VisualStudio/civetweb_lua/civetweb_lua.vcxproj.filters

@@ -18,9 +18,6 @@
     </Filter>
     </Filter>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
-    <Text Include="ReadMe.txt" />
-  </ItemGroup>
-  <ItemGroup>
     <ClInclude Include="..\..\include\civetweb.h">
     <ClInclude Include="..\..\include\civetweb.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
@@ -65,9 +62,6 @@
     <None Include="..\..\src\timer.inl">
     <None Include="..\..\src\timer.inl">
       <Filter>inl files</Filter>
       <Filter>inl files</Filter>
     </None>
     </None>
-    <None Include="..\..\src\file_ops.inl">
-      <Filter>inl files</Filter>
-    </None>
     <None Include="..\..\src\mod_duktape.inl">
     <None Include="..\..\src\mod_duktape.inl">
       <Filter>inl files</Filter>
       <Filter>inl files</Filter>
     </None>
     </None>

+ 144 - 118
src/civetweb.c

@@ -2201,18 +2201,18 @@ static struct ssl_func crypto_sw[] = {{"CRYPTO_num_locks", NULL},
 
 
 
 
 #if !defined(NO_CACHING)
 #if !defined(NO_CACHING)
-static const char *month_names[] = {"Jan",
-                                    "Feb",
-                                    "Mar",
-                                    "Apr",
-                                    "May",
-                                    "Jun",
-                                    "Jul",
-                                    "Aug",
-                                    "Sep",
-                                    "Oct",
-                                    "Nov",
-                                    "Dec"};
+static const char month_names[][4] = {"Jan",
+                                      "Feb",
+                                      "Mar",
+                                      "Apr",
+                                      "May",
+                                      "Jun",
+                                      "Jul",
+                                      "Aug",
+                                      "Sep",
+                                      "Oct",
+                                      "Nov",
+                                      "Dec"};
 #endif /* !NO_CACHING */
 #endif /* !NO_CACHING */
 
 
 /* Unified socket address. For IPv6 support, add IPv6 address structure in
 /* Unified socket address. For IPv6 support, add IPv6 address structure in
@@ -2759,8 +2759,6 @@ struct mg_connection {
 #if defined(USE_LUA) && defined(USE_WEBSOCKET)
 #if defined(USE_LUA) && defined(USE_WEBSOCKET)
 	void *lua_websocket_state; /* Lua_State for a websocket connection */
 	void *lua_websocket_state; /* Lua_State for a websocket connection */
 #endif
 #endif
-
-	int thread_index; /* Thread index within ctx */
 };
 };
 
 
 
 
@@ -5406,9 +5404,10 @@ poll(struct mg_pollfd *pfd, unsigned int n, int milliseconds)
 
 
 	for (i = 0; i < n; i++) {
 	for (i = 0; i < n; i++) {
 		if (pfd[i].events & POLLIN) {
 		if (pfd[i].events & POLLIN) {
-			FD_SET((SOCKET)pfd[i].fd, &rset);
-		} else if (pfd[i].events & POLLOUT) {
-			FD_SET((SOCKET)pfd[i].fd, &wset);
+			FD_SET(pfd[i].fd, &rset);
+		}
+		if (pfd[i].events & POLLOUT) {
+			FD_SET(pfd[i].fd, &wset);
 		}
 		}
 		pfd[i].revents = 0;
 		pfd[i].revents = 0;
 
 
@@ -5488,9 +5487,9 @@ mg_start_thread_with_id(unsigned(__stdcall *f)(void *),
 	HANDLE threadhandle;
 	HANDLE threadhandle;
 	int result = -1;
 	int result = -1;
 
 
-	uip = _beginthreadex(NULL, 0, (unsigned(__stdcall *)(void *))f, p, 0, NULL);
+	uip = _beginthreadex(NULL, 0, f, p, 0, NULL);
 	threadhandle = (HANDLE)uip;
 	threadhandle = (HANDLE)uip;
-	if ((uip != (uintptr_t)(-1L)) && (threadidptr != NULL)) {
+	if ((uip != 0) && (threadidptr != NULL)) {
 		*threadidptr = threadhandle;
 		*threadidptr = threadhandle;
 		result = 0;
 		result = 0;
 	}
 	}
@@ -9000,8 +8999,8 @@ mg_url_encode(const char *src, char *dst, size_t dst_len)
 static int
 static int
 print_dir_entry(struct de *de)
 print_dir_entry(struct de *de)
 {
 {
-	size_t hrefsize;
-	char *href;
+	size_t namesize, escsize, i;
+	char *href, *esc, *p;
 	char size[64], mod[64];
 	char size[64], mod[64];
 #if defined(REENTRANT_TIME)
 #if defined(REENTRANT_TIME)
 	struct tm _tm;
 	struct tm _tm;
@@ -9010,11 +9009,30 @@ print_dir_entry(struct de *de)
 	struct tm *tm;
 	struct tm *tm;
 #endif
 #endif
 
 
-	hrefsize = PATH_MAX * 3; /* worst case */
-	href = (char *)mg_malloc(hrefsize);
+	/* Estimate worst case size for encoding and escaping */
+	namesize = strlen(de->file_name) + 1;
+	escsize = de->file_name[strcspn(de->file_name, "&<>")] ? namesize * 5 : 0;
+	href = (char *)mg_malloc(namesize * 3 + escsize);
 	if (href == NULL) {
 	if (href == NULL) {
 		return -1;
 		return -1;
 	}
 	}
+	mg_url_encode(de->file_name, href, namesize * 3);
+	esc = NULL;
+	if (escsize > 0) {
+		/* HTML escaping needed */
+		esc = href + namesize * 3;
+		for (i = 0, p = esc; de->file_name[i]; i++, p += strlen(p)) {
+			mg_strlcpy(p, de->file_name + i, 2);
+			if (*p == '&') {
+				strcpy(p, "&amp;");
+			} else if (*p == '<') {
+				strcpy(p, "&lt;");
+			} else if (*p == '>') {
+				strcpy(p, "&gt;");
+			}
+		}
+	}
+
 	if (de->file.is_directory) {
 	if (de->file.is_directory) {
 		mg_snprintf(de->conn,
 		mg_snprintf(de->conn,
 		            NULL, /* Buffer is big enough */
 		            NULL, /* Buffer is big enough */
@@ -9070,13 +9088,12 @@ print_dir_entry(struct de *de)
 		mg_strlcpy(mod, "01-Jan-1970 00:00", sizeof(mod));
 		mg_strlcpy(mod, "01-Jan-1970 00:00", sizeof(mod));
 		mod[sizeof(mod) - 1] = '\0';
 		mod[sizeof(mod) - 1] = '\0';
 	}
 	}
-	mg_url_encode(de->file_name, href, hrefsize);
 	mg_printf(de->conn,
 	mg_printf(de->conn,
 	          "<tr><td><a href=\"%s%s\">%s%s</a></td>"
 	          "<tr><td><a href=\"%s%s\">%s%s</a></td>"
 	          "<td>&nbsp;%s</td><td>&nbsp;&nbsp;%s</td></tr>\n",
 	          "<td>&nbsp;%s</td><td>&nbsp;&nbsp;%s</td></tr>\n",
 	          href,
 	          href,
 	          de->file.is_directory ? "/" : "",
 	          de->file.is_directory ? "/" : "",
-	          de->file_name,
+	          esc ? esc : de->file_name,
 	          de->file.is_directory ? "/" : "",
 	          de->file.is_directory ? "/" : "",
 	          mod,
 	          mod,
 	          size);
 	          size);
@@ -9097,8 +9114,8 @@ compare_dir_entries(const void *p1, const void *p2)
 		const char *query_string = a->conn->request_info.query_string;
 		const char *query_string = a->conn->request_info.query_string;
 		int cmp_result = 0;
 		int cmp_result = 0;
 
 
-		if (query_string == NULL) {
-			query_string = "na";
+		if ((query_string == NULL) || (query_string[0] == '\0')) {
+			query_string = "n";
 		}
 		}
 
 
 		if (a->file.is_directory && !b->file.is_directory) {
 		if (a->file.is_directory && !b->file.is_directory) {
@@ -9313,7 +9330,8 @@ handle_directory_request(struct mg_connection *conn, const char *dir)
 	unsigned int i;
 	unsigned int i;
 	int sort_direction;
 	int sort_direction;
 	struct dir_scan_data data = {NULL, 0, 128};
 	struct dir_scan_data data = {NULL, 0, 128};
-	char date[64];
+	char date[64], *esc, *p;
+	const char *title;
 	time_t curtime = time(NULL);
 	time_t curtime = time(NULL);
 
 
 	if (!scan_directory(conn, dir, &data, dir_scan_callback)) {
 	if (!scan_directory(conn, dir, &data, dir_scan_callback)) {
@@ -9331,7 +9349,29 @@ handle_directory_request(struct mg_connection *conn, const char *dir)
 		return;
 		return;
 	}
 	}
 
 
+	esc = NULL;
+	title = conn->request_info.local_uri;
+	if (title[strcspn(title, "&<>")]) {
+		/* HTML escaping needed */
+		esc = (char *)mg_malloc(strlen(title) * 5 + 1);
+		if (esc) {
+			for (i = 0, p = esc; title[i]; i++, p += strlen(p)) {
+				mg_strlcpy(p, title + i, 2);
+				if (*p == '&') {
+					strcpy(p, "&amp;");
+				} else if (*p == '<') {
+					strcpy(p, "&lt;");
+				} else if (*p == '>') {
+					strcpy(p, "&gt;");
+				}
+			}
+		} else {
+			title = "";
+		}
+	}
+
 	sort_direction = ((conn->request_info.query_string != NULL)
 	sort_direction = ((conn->request_info.query_string != NULL)
+	                  && (conn->request_info.query_string[0] != '\0')
 	                  && (conn->request_info.query_string[1] == 'd'))
 	                  && (conn->request_info.query_string[1] == 'd'))
 	                     ? 'a'
 	                     ? 'a'
 	                     : 'd';
 	                     : 'd';
@@ -9353,11 +9393,12 @@ handle_directory_request(struct mg_connection *conn, const char *dir)
 	          "<th><a href=\"?d%c\">Modified</a></th>"
 	          "<th><a href=\"?d%c\">Modified</a></th>"
 	          "<th><a href=\"?s%c\">Size</a></th></tr>"
 	          "<th><a href=\"?s%c\">Size</a></th></tr>"
 	          "<tr><td colspan=\"3\"><hr></td></tr>",
 	          "<tr><td colspan=\"3\"><hr></td></tr>",
-	          conn->request_info.local_uri,
-	          conn->request_info.local_uri,
+	          esc ? esc : title,
+	          esc ? esc : title,
 	          sort_direction,
 	          sort_direction,
 	          sort_direction,
 	          sort_direction,
 	          sort_direction);
 	          sort_direction);
+	mg_free(esc);
 
 
 	/* Print first entry - link to a parent directory */
 	/* Print first entry - link to a parent directory */
 	mg_printf(conn,
 	mg_printf(conn,
@@ -9381,7 +9422,7 @@ handle_directory_request(struct mg_connection *conn, const char *dir)
 		mg_free(data.entries);
 		mg_free(data.entries);
 	}
 	}
 
 
-	mg_printf(conn, "%s", "</table></body></html>");
+	mg_printf(conn, "%s", "</table></pre></body></html>");
 	conn->status_code = 200;
 	conn->status_code = 200;
 }
 }
 
 
@@ -11902,16 +11943,40 @@ send_options(struct mg_connection *conn)
 
 
 
 
 /* Writes PROPFIND properties for a collection element */
 /* Writes PROPFIND properties for a collection element */
-static void
+static int
 print_props(struct mg_connection *conn,
 print_props(struct mg_connection *conn,
             const char *uri,
             const char *uri,
+            const char *name,
             struct mg_file_stat *filep)
             struct mg_file_stat *filep)
 {
 {
-	char mtime[64];
+	size_t href_size, i, j;
+	int len;
+	char *href, mtime[64];
 
 
-	if ((conn == NULL) || (uri == NULL) || (filep == NULL)) {
-		return;
+	if ((conn == NULL) || (uri == NULL) || (name == NULL) || (filep == NULL)) {
+		return 0;
+	}
+	/* Estimate worst case size for encoding */
+	href_size = (strlen(uri) + strlen(name)) * 3 + 1;
+	href = (char *)mg_malloc(href_size);
+	if (href == NULL) {
+		return 0;
 	}
 	}
+	len = mg_url_encode(uri, href, href_size);
+	if (len >= 0) {
+		/* Append an extra string */
+		mg_url_encode(name, href + len, href_size - (size_t)len);
+	}
+	/* Directory separator should be preserved. */
+	for (i = j = 0; href[i]; j++) {
+		if (!strncmp(href + i, "%2f", 3)) {
+			href[j] = '/';
+			i += 3;
+		} else {
+			href[j] = href[i++];
+		}
+	}
+	href[j] = '\0';
 
 
 	gmt_time_string(mtime, sizeof(mtime), &filep->last_modified);
 	gmt_time_string(mtime, sizeof(mtime), &filep->last_modified);
 	mg_printf(conn,
 	mg_printf(conn,
@@ -11926,45 +11991,23 @@ print_props(struct mg_connection *conn,
 	          "<d:status>HTTP/1.1 200 OK</d:status>"
 	          "<d:status>HTTP/1.1 200 OK</d:status>"
 	          "</d:propstat>"
 	          "</d:propstat>"
 	          "</d:response>\n",
 	          "</d:response>\n",
-	          uri,
+	          href,
 	          filep->is_directory ? "<d:collection/>" : "",
 	          filep->is_directory ? "<d:collection/>" : "",
 	          filep->size,
 	          filep->size,
 	          mtime);
 	          mtime);
+	mg_free(href);
+	return 1;
 }
 }
 
 
 
 
 static int
 static int
 print_dav_dir_entry(struct de *de, void *data)
 print_dav_dir_entry(struct de *de, void *data)
 {
 {
-	char href[PATH_MAX];
-	int truncated;
-
 	struct mg_connection *conn = (struct mg_connection *)data;
 	struct mg_connection *conn = (struct mg_connection *)data;
-	if (!de || !conn) {
+	if (!de || !conn || !print_props(conn, conn->request_info.local_uri,
+	                                 de->file_name, &de->file)) {
 		return -1;
 		return -1;
 	}
 	}
-	mg_snprintf(conn,
-	            &truncated,
-	            href,
-	            sizeof(href),
-	            "%s%s",
-	            conn->request_info.local_uri,
-	            de->file_name);
-
-	if (!truncated) {
-		size_t href_encoded_size;
-		char *href_encoded;
-
-		href_encoded_size = PATH_MAX * 3; /* worst case */
-		href_encoded = (char *)mg_malloc(href_encoded_size);
-		if (href_encoded == NULL) {
-			return -1;
-		}
-		mg_url_encode(href, href_encoded, href_encoded_size);
-		print_props(conn, href_encoded, &de->file);
-		mg_free(href_encoded);
-	}
-
 	return 0;
 	return 0;
 }
 }
 
 
@@ -12002,7 +12045,7 @@ handle_propfind(struct mg_connection *conn,
 	          "<d:multistatus xmlns:d='DAV:'>\n");
 	          "<d:multistatus xmlns:d='DAV:'>\n");
 
 
 	/* Print properties for the requested resource itself */
 	/* Print properties for the requested resource itself */
-	print_props(conn, conn->request_info.local_uri, filep);
+	print_props(conn, conn->request_info.local_uri, "", filep);
 
 
 	/* If it is a directory, print directory entries too if Depth is not 0
 	/* If it is a directory, print directory entries too if Depth is not 0
 	 */
 	 */
@@ -15095,7 +15138,7 @@ sslize(struct mg_connection *conn,
 	/* SSL functions may fail and require to be called again:
 	/* SSL functions may fail and require to be called again:
 	 * see https://www.openssl.org/docs/manmaster/ssl/SSL_get_error.html
 	 * see https://www.openssl.org/docs/manmaster/ssl/SSL_get_error.html
 	 * Here "func" could be SSL_connect or SSL_accept. */
 	 * Here "func" could be SSL_connect or SSL_accept. */
-	for (i = 16; i <= timeout; i *= 2) {
+	for (i = 0; i <= timeout; i += 50) {
 		ret = func(conn->ssl);
 		ret = func(conn->ssl);
 		if (ret != 1) {
 		if (ret != 1) {
 			err = SSL_get_error(conn->ssl, ret);
 			err = SSL_get_error(conn->ssl, ret);
@@ -15103,14 +15146,24 @@ sslize(struct mg_connection *conn,
 			    || (err == SSL_ERROR_WANT_ACCEPT)
 			    || (err == SSL_ERROR_WANT_ACCEPT)
 			    || (err == SSL_ERROR_WANT_READ) || (err == SSL_ERROR_WANT_WRITE)
 			    || (err == SSL_ERROR_WANT_READ) || (err == SSL_ERROR_WANT_WRITE)
 			    || (err == SSL_ERROR_WANT_X509_LOOKUP)) {
 			    || (err == SSL_ERROR_WANT_X509_LOOKUP)) {
-				/* Need to retry the function call "later".
-				 * See https://linux.die.net/man/3/ssl_get_error
-				 * This is typical for non-blocking sockets. */
 				if (*stop_server) {
 				if (*stop_server) {
 					/* Don't wait if the server is going to be stopped. */
 					/* Don't wait if the server is going to be stopped. */
 					break;
 					break;
 				}
 				}
-				mg_sleep(i);
+				if (err == SSL_ERROR_WANT_X509_LOOKUP) {
+					/* Simply retry the function call. */
+					mg_sleep(50);
+				} else {
+					/* Need to retry the function call "later".
+					 * See https://linux.die.net/man/3/ssl_get_error
+					 * This is typical for non-blocking sockets. */
+					struct mg_pollfd pfd;
+					pfd.fd = conn->client.sock;
+					pfd.events = ((err == SSL_ERROR_WANT_CONNECT)
+					              || (err == SSL_ERROR_WANT_WRITE)) ? POLLOUT
+					                                                : POLLIN;
+					mg_poll(&pfd, 1, 50, stop_server);
+				}
 
 
 			} else if (err == SSL_ERROR_SYSCALL) {
 			} else if (err == SSL_ERROR_SYSCALL) {
 				/* This is an IO error. Look at errno. */
 				/* This is an IO error. Look at errno. */
@@ -17763,17 +17816,11 @@ produce_socket(struct mg_context *ctx, const struct socket *sp)
 #endif /* ALTERNATIVE_QUEUE */
 #endif /* ALTERNATIVE_QUEUE */
 
 
 
 
-struct worker_thread_args {
-	struct mg_context *ctx;
-	int index;
-};
-
-
-static void *
-worker_thread_run(struct worker_thread_args *thread_args)
+static void
+worker_thread_run(struct mg_connection *conn)
 {
 {
-	struct mg_context *ctx = thread_args->ctx;
-	struct mg_connection *conn;
+	struct mg_context *ctx = conn->phys_ctx;
+	int thread_index;
 	struct mg_workerTLS tls;
 	struct mg_workerTLS tls;
 #if defined(MG_LEGACY_INTERFACE)
 #if defined(MG_LEGACY_INTERFACE)
 	uint32_t addr;
 	uint32_t addr;
@@ -17796,15 +17843,15 @@ worker_thread_run(struct worker_thread_args *thread_args)
 	}
 	}
 
 
 	/* Connection structure has been pre-allocated */
 	/* Connection structure has been pre-allocated */
-	if (((int)thread_args->index < 0)
-	    || ((unsigned)thread_args->index
+	thread_index = (int)(conn - ctx->worker_connections);
+	if ((thread_index < 0)
+	    || ((unsigned)thread_index
 	        >= (unsigned)ctx->cfg_worker_threads)) {
 	        >= (unsigned)ctx->cfg_worker_threads)) {
 		mg_cry_internal(fc(ctx),
 		mg_cry_internal(fc(ctx),
 		                "Internal error: Invalid worker index %i",
 		                "Internal error: Invalid worker index %i",
-		                (int)thread_args->index);
-		return NULL;
+		                thread_index);
+		return;
 	}
 	}
-	conn = ctx->worker_connections + thread_args->index;
 
 
 	/* Request buffers are not pre-allocated. They are private to the
 	/* Request buffers are not pre-allocated. They are private to the
 	 * request and do not contain any state information that might be
 	 * request and do not contain any state information that might be
@@ -17813,16 +17860,14 @@ worker_thread_run(struct worker_thread_args *thread_args)
 	if (conn->buf == NULL) {
 	if (conn->buf == NULL) {
 		mg_cry_internal(fc(ctx),
 		mg_cry_internal(fc(ctx),
 		                "Out of memory: Cannot allocate buffer for worker %i",
 		                "Out of memory: Cannot allocate buffer for worker %i",
-		                (int)thread_args->index);
-		return NULL;
+		                thread_index);
+		return;
 	}
 	}
 	conn->buf_size = (int)ctx->max_request_size;
 	conn->buf_size = (int)ctx->max_request_size;
 
 
-	conn->phys_ctx = ctx;
 	conn->dom_ctx = &(ctx->dd); /* Use default domain and default host */
 	conn->dom_ctx = &(ctx->dd); /* Use default domain and default host */
 	conn->host = NULL;          /* until we have more information. */
 	conn->host = NULL;          /* until we have more information. */
 
 
-	conn->thread_index = thread_args->index;
 	conn->request_info.user_data = ctx->user_data;
 	conn->request_info.user_data = ctx->user_data;
 	/* Allocate a mutex for this connection to allow communication both
 	/* Allocate a mutex for this connection to allow communication both
 	 * within the request handler and from elsewhere in the application
 	 * within the request handler and from elsewhere in the application
@@ -17830,7 +17875,7 @@ worker_thread_run(struct worker_thread_args *thread_args)
 	if (0 != pthread_mutex_init(&conn->mutex, &pthread_mutex_attr)) {
 	if (0 != pthread_mutex_init(&conn->mutex, &pthread_mutex_attr)) {
 		mg_free(conn->buf);
 		mg_free(conn->buf);
 		mg_cry_internal(fc(ctx), "%s", "Cannot create mutex");
 		mg_cry_internal(fc(ctx), "%s", "Cannot create mutex");
-		return NULL;
+		return;
 	}
 	}
 
 
 #if defined(USE_SERVER_STATS)
 #if defined(USE_SERVER_STATS)
@@ -17840,7 +17885,7 @@ worker_thread_run(struct worker_thread_args *thread_args)
 	/* Call consume_socket() even when ctx->stop_flag > 0, to let it
 	/* Call consume_socket() even when ctx->stop_flag > 0, to let it
 	 * signal sq_empty condvar to wake up the master waiting in
 	 * signal sq_empty condvar to wake up the master waiting in
 	 * produce_socket() */
 	 * produce_socket() */
-	while (consume_socket(ctx, &conn->client, conn->thread_index)) {
+	while (consume_socket(ctx, &conn->client, thread_index)) {
 
 
 		conn->conn_birth_time = time(NULL);
 		conn->conn_birth_time = time(NULL);
 
 
@@ -17931,7 +17976,6 @@ worker_thread_run(struct worker_thread_args *thread_args)
 #endif
 #endif
 
 
 	DEBUG_TRACE("%s", "exiting");
 	DEBUG_TRACE("%s", "exiting");
-	return NULL;
 }
 }
 
 
 
 
@@ -17939,18 +17983,13 @@ worker_thread_run(struct worker_thread_args *thread_args)
 #if defined(_WIN32)
 #if defined(_WIN32)
 static unsigned __stdcall worker_thread(void *thread_func_param)
 static unsigned __stdcall worker_thread(void *thread_func_param)
 {
 {
-	struct worker_thread_args *pwta =
-	    (struct worker_thread_args *)thread_func_param;
-	worker_thread_run(pwta);
-	mg_free(thread_func_param);
+	worker_thread_run((struct mg_connection *)thread_func_param);
 	return 0;
 	return 0;
 }
 }
 #else
 #else
 static void *
 static void *
 worker_thread(void *thread_func_param)
 worker_thread(void *thread_func_param)
 {
 {
-	struct worker_thread_args *pwta =
-	    (struct worker_thread_args *)thread_func_param;
 	struct sigaction sa;
 	struct sigaction sa;
 
 
 	/* Ignore SIGPIPE */
 	/* Ignore SIGPIPE */
@@ -17958,8 +17997,7 @@ worker_thread(void *thread_func_param)
 	sa.sa_handler = SIG_IGN;
 	sa.sa_handler = SIG_IGN;
 	sigaction(SIGPIPE, &sa, NULL);
 	sigaction(SIGPIPE, &sa, NULL);
 
 
-	worker_thread_run(pwta);
-	mg_free(thread_func_param);
+	worker_thread_run((struct mg_connection *)thread_func_param);
 	return NULL;
 	return NULL;
 }
 }
 #endif /* _WIN32 */
 #endif /* _WIN32 */
@@ -18051,9 +18089,8 @@ accept_new_connection(const struct socket *listener, struct mg_context *ctx)
 
 
 
 
 static void
 static void
-master_thread_run(void *thread_func_param)
+master_thread_run(struct mg_context *ctx)
 {
 {
-	struct mg_context *ctx = (struct mg_context *)thread_func_param;
 	struct mg_workerTLS tls;
 	struct mg_workerTLS tls;
 	struct mg_pollfd *pfd;
 	struct mg_pollfd *pfd;
 	unsigned int i;
 	unsigned int i;
@@ -18175,7 +18212,7 @@ master_thread_run(void *thread_func_param)
 #if defined(_WIN32)
 #if defined(_WIN32)
 static unsigned __stdcall master_thread(void *thread_func_param)
 static unsigned __stdcall master_thread(void *thread_func_param)
 {
 {
-	master_thread_run(thread_func_param);
+	master_thread_run((struct mg_context *)thread_func_param);
 	return 0;
 	return 0;
 }
 }
 #else
 #else
@@ -18189,7 +18226,7 @@ master_thread(void *thread_func_param)
 	sa.sa_handler = SIG_IGN;
 	sa.sa_handler = SIG_IGN;
 	sigaction(SIGPIPE, &sa, NULL);
 	sigaction(SIGPIPE, &sa, NULL);
 
 
-	master_thread_run(thread_func_param);
+	master_thread_run((struct mg_context *)thread_func_param);
 	return NULL;
 	return NULL;
 }
 }
 #endif /* _WIN32 */
 #endif /* _WIN32 */
@@ -18683,24 +18720,13 @@ mg_start(const struct mg_callbacks *callbacks,
 
 
 	/* Start worker threads */
 	/* Start worker threads */
 	for (i = 0; i < ctx->cfg_worker_threads; i++) {
 	for (i = 0; i < ctx->cfg_worker_threads; i++) {
-		struct worker_thread_args *wta = (struct worker_thread_args *)
-		    mg_malloc_ctx(sizeof(struct worker_thread_args), ctx);
-		if (wta) {
-			wta->ctx = ctx;
-			wta->index = (int)i;
-		}
-
-		if ((wta == NULL)
-		    || (mg_start_thread_with_id(worker_thread,
-		                                wta,
-		                                &ctx->worker_threadids[i])
-		        != 0)) {
+		/* worker_thread sets up the other fields */
+		ctx->worker_connections[i].phys_ctx = ctx;
+		if (mg_start_thread_with_id(worker_thread,
+		                            &ctx->worker_connections[i],
+		                            &ctx->worker_threadids[i]) != 0) {
 
 
 			/* thread was not created */
 			/* thread was not created */
-			if (wta != NULL) {
-				mg_free(wta);
-			}
-
 			if (i > 0) {
 			if (i > 0) {
 				mg_cry_internal(fc(ctx),
 				mg_cry_internal(fc(ctx),
 				                "Cannot start worker thread %i: error %ld",
 				                "Cannot start worker thread %i: error %ld",

+ 4 - 4
src/mod_duktape.inl

@@ -13,10 +13,10 @@
 
 
 /* Note: This is only experimental support, so the API may still change. */
 /* Note: This is only experimental support, so the API may still change. */
 
 
-static const char *civetweb_conn_id = "\xFF"
-                                      "civetweb_conn";
-static const char *civetweb_ctx_id = "\xFF"
-                                     "civetweb_ctx";
+static const char *const civetweb_conn_id = "\xFF"
+                                            "civetweb_conn";
+static const char *const civetweb_ctx_id = "\xFF"
+                                           "civetweb_ctx";
 
 
 
 
 static void *
 static void *

+ 2 - 2
src/mod_lua.inl

@@ -48,11 +48,11 @@ munmap(void *addr, int64_t length)
 #include <sys/mman.h>
 #include <sys/mman.h>
 #endif
 #endif
 
 
-static const char *LUASOCKET = "luasocket";
+static const char *const LUASOCKET = "luasocket";
 static const char lua_regkey_ctx = 1;
 static const char lua_regkey_ctx = 1;
 static const char lua_regkey_connlist = 2;
 static const char lua_regkey_connlist = 2;
 static const char lua_regkey_lsp_include_history = 3;
 static const char lua_regkey_lsp_include_history = 3;
-static const char *LUABACKGROUNDPARAMS = "mg";
+static const char *const LUABACKGROUNDPARAMS = "mg";
 
 
 /* Limit nesting depth of mg.include.
 /* Limit nesting depth of mg.include.
  * This takes a lot of stack (~10 kB per recursion),
  * This takes a lot of stack (~10 kB per recursion),