diff --git a/bindings/python/mongoose.py b/bindings/python/mongoose.py
index d67ea454fd92f4d05e3e6d655b197c10bfda588a..aaad9d1a5053780c109ce28f1e520c061740a631 100644
--- a/bindings/python/mongoose.py
+++ b/bindings/python/mongoose.py
@@ -72,6 +72,8 @@ class mg_request_info(ctypes.Structure):
     ('is_ssl', ctypes.c_int),
     ('num_headers', ctypes.c_int),
     ('http_headers', mg_header * 64),
+    ('user_data', ctypes.c_void_p),
+    ('ev_data', ctypes.c_void_p),
   ]
 
 
@@ -86,10 +88,6 @@ class Connection(object):
     self.m = mongoose
     self.conn = ctypes.c_void_p(connection)
     self.info = self.m.dll.mg_get_request_info(self.conn).contents
-    self.user_data = self.m.dll.mg_get_user_data(self.conn)
-    self.log_message = self.m.dll.mg_get_log_message(self.conn)
-    self.reply_status_code = self.m.dll.mg_get_reply_status_code(self.conn)
-    self.ssl_context = self.m.dll.mg_get_ssl_context(self.conn)
 
   def get_header(self, name):
     val = self.m.dll.mg_get_header(self.conn, name)
diff --git a/main.c b/main.c
index 27d2045d5d954b6c9434a9061ff940292992e8cb..b8c2285efc1991c29565fb63ee395da4d7828c09 100644
--- a/main.c
+++ b/main.c
@@ -221,7 +221,7 @@ static void init_server_name(void) {
 
 static void *mongoose_callback(enum mg_event ev, struct mg_connection *conn) {
   if (ev == MG_EVENT_LOG) {
-    printf("%s\n", mg_get_log_message(conn));
+    printf("%s\n", (const char *) mg_get_request_info(conn)->ev_data);
   }
 
   // Returning NULL marks request as not handled, signalling mongoose to
diff --git a/mongoose.c b/mongoose.c
index a7fea61b96bec234f8df3964a40459e2e246a743..22ea85b2a3cec063b23ffdeeeb38453d3b15c95c 100644
--- a/mongoose.c
+++ b/mongoose.c
@@ -632,8 +632,7 @@ const char *mg_version(void) {
   return MONGOOSE_VERSION;
 }
 
-const struct mg_request_info *
-mg_get_request_info(const struct mg_connection *conn) {
+struct mg_request_info *mg_get_request_info(struct mg_connection *conn) {
   return &conn->request_info;
 }
 
@@ -4000,11 +3999,12 @@ static void handle_request(struct mg_connection *conn) {
   struct mgstat st;
 
   if ((conn->request_info.query_string = strchr(ri->uri, '?')) != NULL) {
-    *conn->request_info.query_string++ = '\0';
+    * ((char *) conn->request_info.query_string++) = '\0';
   }
   uri_len = (int) strlen(ri->uri);
-  url_decode(ri->uri, (size_t)uri_len, ri->uri, (size_t)(uri_len + 1), 0);
-  remove_double_dots_and_double_slashes(ri->uri);
+  url_decode(ri->uri, (size_t)uri_len, (char *) ri->uri,
+             (size_t) (uri_len + 1), 0);
+  remove_double_dots_and_double_slashes((char *) ri->uri);
   stat_result = convert_uri_to_file_name(conn, path, sizeof(path), &st);
   conn->throttle = set_throttle(conn->ctx->config[THROTTLE],
                                 get_remote_ip(conn), ri->uri);
diff --git a/mongoose.h b/mongoose.h
index f72cfc0daa16b0396ca2de1b31bdbb500572ac5d..b54130a231bddb68719cf0e290ba532ff99df725 100644
--- a/mongoose.h
+++ b/mongoose.h
@@ -34,35 +34,74 @@ struct mg_connection;  // Handle for the individual connection
 
 // This structure contains information about the HTTP request.
 struct mg_request_info {
-  char *request_method;  // "GET", "POST", etc
-  char *uri;             // URL-decoded URI
-  char *http_version;    // E.g. "1.0", "1.1"
-  char *query_string;    // URL part after '?' (not including '?') or NULL
-  char *remote_user;     // Authenticated user, or NULL if no auth used
-  long remote_ip;        // Client's IP address
-  int remote_port;       // Client's port
-  int is_ssl;            // 1 if SSL-ed, 0 if not
-  int num_headers;       // Number of headers
+  const char *request_method; // "GET", "POST", etc
+  const char *uri;            // URL-decoded URI
+  const char *http_version;   // E.g. "1.0", "1.1"
+  const char *query_string;   // URL part after '?', not including '?', or NULL
+  const char *remote_user;    // Authenticated user, or NULL if no auth used
+  long remote_ip;             // Client's IP address
+  int remote_port;            // Client's port
+  int is_ssl;                 // 1 if SSL-ed, 0 if not
+  int num_headers;            // Number of headers
   struct mg_header {
-    char *name;          // HTTP header name
-    char *value;         // HTTP header value
-  } http_headers[64];    // Maximum 64 headers
+    const char *name;         // HTTP header name
+    const char *value;        // HTTP header value
+  } http_headers[64];         // Maximum 64 headers
+  void *user_data;            // User data pointer passed to the mg_start()
+  void *ev_data;              // Event-specific data pointer
 };
 
 
-// Various events on which user-defined function is called by Mongoose.
+// Various events on which user-defined callback function is called by Mongoose.
 enum mg_event {
-  MG_NEW_REQUEST,       // New HTTP request has arrived from the client
-  MG_REQUEST_COMPLETE,  // Mongoose has finished handling the request
-  MG_HTTP_ERROR,        // HTTP error must be returned to the client
-  MG_EVENT_LOG,         // Mongoose logs an event, request_info.log_message
-  MG_INIT_SSL,          // SSL initialization, sent before certificate setup
-  MG_WEBSOCKET_CONNECT, // Sent on HTTP connect, before websocket handshake.
-                        // If user callback returns NULL, then mongoose proceeds
-                        // with handshake, otherwise it closes the connection.
-  MG_WEBSOCKET_READY,   // Handshake has been successfully completed.
-  MG_WEBSOCKET_MESSAGE, // Incoming message from the client
-  MG_WEBSOCKET_CLOSE,   // Client has closed the connection
+  // New HTTP request has arrived from the client.
+  // If callback returns non-NULL, Mongoose stops handling current request.
+  // ev_data contains NULL.
+  MG_NEW_REQUEST,
+
+  // Mongoose has finished handling the request.
+  // Callback return value is ignored.
+  // ev_data contains NULL.
+  MG_REQUEST_COMPLETE,
+
+  // HTTP error must be returned to the client.
+  // If callback returns non-NULL, Mongoose stops handling error.
+  // ev_data contains HTTP error code:
+  //  int http_reply_status_code = (int) request_info->ev_data;
+  MG_HTTP_ERROR,
+
+  // Mongoose logs a message.
+  // If callback returns non-NULL, Mongoose stops handling that event.
+  // ev_data contains a message to be logged:
+  //   const char *log_message = request_info->ev_data;
+  MG_EVENT_LOG,
+
+  // SSL initialization, sent before certificate setup.
+  // If callback returns non-NULL, Mongoose does not set up certificates.
+  // ev_data contains server's OpenSSL context:
+  //   SSL_CTX *ssl_context = request_info->ev_data;
+  MG_INIT_SSL,
+
+  // Sent on HTTP connect, before websocket handshake.
+  // If user callback returns NULL, then mongoose proceeds
+  // with handshake, otherwise it closes the connection.
+  // ev_data contains NULL.
+  MG_WEBSOCKET_CONNECT,
+
+  // Handshake has been successfully completed.
+  // Callback's return value is ignored.
+  // ev_data contains NULL.
+  MG_WEBSOCKET_READY,
+
+  // Incoming message from the client, data could be read with mg_read().
+  // If user callback returns non-NULL, mongoose closes the websocket.
+  // ev_data contains NULL.
+  MG_WEBSOCKET_MESSAGE,
+
+  // Client has closed the connection.
+  // Callback's return value is ignored.
+  // ev_data contains NULL.
+  MG_WEBSOCKET_CLOSE,
 };
 
 
@@ -155,12 +194,7 @@ int mg_modify_passwords_file(const char *passwords_file_name,
 
 
 // Return information associated with the request.
-// These functions always succeed.
-const struct mg_request_info *mg_get_request_info(const struct mg_connection *);
-void *mg_get_user_data(struct mg_connection *);
-const char *mg_get_log_message(const struct mg_connection *);
-int mg_get_reply_status_code(const struct mg_connection *);
-void *mg_get_ssl_context(const struct mg_connection *);
+struct mg_request_info *mg_get_request_info(struct mg_connection *);
 
 
 // Send data to the client.