Quellcode durchsuchen

Add experimental interface for initializing connection specific user data

Possible solution for #452
bel2125 vor 8 Jahren
Ursprung
Commit
8fbf727609
2 geänderte Dateien mit 39 neuen und 7 gelöschten Zeilen
  1. 28 4
      include/civetweb.h
  2. 11 3
      src/civetweb.c

+ 28 - 4
include/civetweb.h

@@ -219,11 +219,20 @@ struct mg_callbacks {
 #endif /* MG_LEGACY_INTERFACE */
 
 	/* Called when civetweb is closing a connection.  The per-context mutex is
-	   locked when this is invoked.  This is primarily useful for noting when
-	   a websocket is closing and removing it from any application-maintained
-	   list of clients.
+	   locked when this is invoked.
+
+	   Websockets:
+	   Before mg_set_websocket_handler has been added, it was primarily useful
+	   for noting when a websocket is closing, and used to remove it from any
+	   application-maintained list of clients.
 	   Using this callback for websocket connections is deprecated: Use
-	   mg_set_websocket_handler instead. */
+	   mg_set_websocket_handler instead.
+
+	   Connection specific data:
+	   If memory has been allocated for the connection specific user data
+	   (mg_request_info->conn_data, mg_get_user_connection_data),
+	   this is the last chance to free it.
+	*/
 	void (*connection_close)(const struct mg_connection *);
 
 #if defined(MG_USE_OPEN_FILE)
@@ -297,6 +306,21 @@ struct mg_callbacks {
 	   Parameters:
 	     ctx: context handle */
 	void (*exit_context)(const struct mg_context *ctx);
+
+	/* Called when initializing a new connection object.
+	 * Can be used to initialize the connection specific user data
+	 * (mg_request_info->conn_data, mg_get_user_connection_data).
+	 * When the callback is called, it is not yet known if a
+	 * valid HTTP(S) request will be made.
+	 * Parameters:
+	 *   conn: not yet fully initialized connection object
+	 *   conn_data: output parameter, set to initialize the
+	 *              connection specific user data
+	 * Return value:
+	 *   must be 0
+	 *   Otherwise, the result is undefined
+	 */
+	int (*init_connection)(const struct mg_connection *conn, void **conn_data);
 };
 
 

+ 11 - 3
src/civetweb.c

@@ -14260,6 +14260,9 @@ close_connection(struct mg_connection *conn)
 	}
 #endif
 
+	mg_lock_connection(conn);
+	conn->must_close = 1;
+
 	/* call the connection_close callback if assigned */
 	if ((conn->ctx->callbacks.connection_close != NULL)
 	    && (conn->ctx->context_type == 1)) {
@@ -14271,9 +14274,6 @@ close_connection(struct mg_connection *conn)
 	 * it must be done in the connection_close callback. */
 	mg_set_user_connection_data(conn, NULL);
 
-	mg_lock_connection(conn);
-
-	conn->must_close = 1;
 
 #ifndef NO_SSL
 	if (conn->ssl != NULL) {
@@ -15277,6 +15277,14 @@ init_connection(struct mg_connection *conn)
 	conn->data_len = 0;
 	conn->handled_requests = 0;
 	mg_set_user_connection_data(conn, NULL);
+
+	/* call the connection_close callback if assigned */
+	if ((conn->ctx->callbacks.init_connection != NULL)
+	    && (conn->ctx->context_type == 1)) {
+		void *conn_data = NULL;
+		conn->ctx->callbacks.init_connection(conn, &conn_data);
+		mg_set_user_connection_data(conn, conn_data);
+	}
 }