Ver Fonte

Add a "after connection was closed" callback

The existing callback `connection_close` is called before the
connection is closed (i. e., while the connection is still
open). This commit adds a new callback, `connection_closed`,
which is called after the SSL shutdown is complete and the
socket has been closed.
Wolfram Rösler há 4 anos atrás
pai
commit
aaf0ff0393
3 ficheiros alterados com 17 adições e 2 exclusões
  1. 3 1
      docs/api/mg_callbacks.md
  2. 7 1
      include/civetweb.h
  3. 7 0
      src/civetweb.c

+ 3 - 1
docs/api/mg_callbacks.md

@@ -9,7 +9,9 @@
 |**`begin_request`**|**`int (*begin_request)( struct mg_connection *conn );`**|
 | |The `begin_request()` callback function is called when CivetWeb has received a new HTTP request. If the callback function does not process the request, it should return 0. In that case CivetWeb will handle the request with the default callback routine. If the callback function returns a value between 1 and 999, CivetWeb does nothing and the callback function should do all the processing, including sending the proper HTTP headers etc. Starting at CivetWeb version 1.7, the function `begin_request()` is called before any authorization is done. If an authorization check is required, `request_handler()` should be used instead. The return value of the callback function is not only used to signal CivetWeb to not further process the request. The returned value is also stored as HTTP status code in the access log. |
 |**`connection_close`**|**`void (*connection_close)( const struct mg_connection *conn );`**|
-| |The callback function `connection_close()` is called when CivetWeb is closing a connection. The per-context mutex is locked when the callback function is invoked. The function is primarily useful for noting when a websocket is closing and removing it from any application-maintained list of clients. *Using this callback for websocket connections is deprecated. Use* `mg_set_websocket_handler()` *instead.*|
+| |The callback function `connection_close()` is called before CivetWeb closes a connection. The per-context mutex is locked when the callback function is invoked. The function is primarily useful for noting when a websocket is closing and removing it from any application-maintained list of clients. *Using this callback for websocket connections is deprecated. Use* `mg_set_websocket_handler()` *instead.*|
+|**`connection_closed`**|**`void (*connection_closed)( const struct mg_connection *conn );`**|
+| |The callback function `connection_closed()` is called after CivetWeb has closed a connection (after SSL shutdown and after closing the socket). The per-context mutex is locked when the callback function is invoked.|
 |**`end_request`**|**`void (*end_request)(const struct mg_connection *conn, int reply_status_code);`**|
 | |The callback function `end_request()` is called by CivetWeb when a request has been completely processed. It sends the reply status code which was sent to the client to the application.|
 |**`exit_context`**|**`void (*exit_context)( const struct mg_context *ctx );`**|

+ 7 - 1
include/civetweb.h

@@ -326,13 +326,19 @@ struct mg_callbacks {
 	   application-maintained list of clients.
 	   Using this callback for websocket connections is deprecated: Use
 	   mg_set_websocket_handler instead.
+	*/
+	void (*connection_close)(const struct mg_connection *);
+
+       /* Called after civetweb has closed a connection.  The per-context mutex is
+          locked when this is invoked.
 
 	   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 *);
+	void (*connection_closed)(const struct mg_connection *);
+
 
 	/* init_lua is called when civetweb is about to serve Lua server page.
 	   exit_lua is called when the Lua processing is complete.

+ 7 - 0
src/civetweb.c

@@ -17029,6 +17029,13 @@ close_connection(struct mg_connection *conn)
 		conn->client.sock = INVALID_SOCKET;
 	}
 
+	/* call the connection_closed callback if assigned */
+	if (conn->phys_ctx->callbacks.connection_closed != NULL) {
+		if (conn->phys_ctx->context_type == CONTEXT_SERVER) {
+			conn->phys_ctx->callbacks.connection_closed(conn);
+		}
+	}
+
 	mg_unlock_connection(conn);
 
 #if defined(USE_SERVER_STATS)