diff --git a/mongoose.c b/mongoose.c
index da068a0125426fe727026408a342c78fae5f610e..d9940ab5980742129de96f82dda7536bec588182 100644
--- a/mongoose.c
+++ b/mongoose.c
@@ -491,6 +491,7 @@ struct mg_context {
   SSL_CTX *ssl_ctx;               // SSL context
   char *config[NUM_OPTIONS];      // Mongoose configuration parameters
   struct mg_callbacks callbacks;  // User-defined callback function
+  mg_callback_t user_callback;    // User-defined callback function
   void *user_data;                // User-defined data
 
   struct socket *listening_sockets;
@@ -540,6 +541,14 @@ const char **mg_get_valid_option_names(void) {
   return config_options;
 }
 
+static int call_user(enum mg_event ev, struct mg_connection *conn, void *p) {
+  if (conn != NULL && conn->ctx != NULL) {
+    conn->request_info.user_data = conn->ctx->user_data;
+  }
+  return conn == NULL || conn->ctx == NULL || conn->ctx->user_callback == NULL ?
+    0 : conn->ctx->user_callback(ev, conn, p);
+}
+
 static FILE *mg_fopen(const char *path, const char *mode) {
 #ifdef _WIN32
   wchar_t wbuf[PATH_MAX], wmode[20];
diff --git a/mongoose.h b/mongoose.h
index 1728963fe2c2a6509d64e18ffc39c4e933b4d709..a79e6090a1dbbd7994fa6d62f5b31c84edcad741 100644
--- a/mongoose.h
+++ b/mongoose.h
@@ -49,6 +49,17 @@ struct mg_request_info {
   } http_headers[64];         // Maximum 64 headers
 };
 
+enum mg_event {
+  MG_REQUEST_BEGIN,
+  MG_REQUEST_END,
+  MG_HTTP_ERROR,
+  MG_EVENT_LOG,
+  MG_THREAD_BEGIN,
+  MG_THREAD_END
+};
+typedef int (*mg_callback_t)(enum mg_event event,
+                             struct mg_connection *conn,
+                             void *data);
 
 struct mg_callbacks {
   int  (*begin_request)(struct mg_connection *);