Index: src/daemon/connection.c =================================================================== --- src/daemon/connection.c (revision 23229) +++ src/daemon/connection.c (working copy) @@ -2046,6 +2046,7 @@ unsigned int timeout; const char *end; int rend; + int upgraded = MHD_NO; char *line; while (1) @@ -2320,6 +2321,16 @@ MHD_get_response_header (connection->response, MHD_HTTP_HEADER_CONNECTION); rend = ( (end != NULL) && (0 == strcasecmp (end, "close")) ); + + if (connection->response->upgrade != NULL) + { + upgraded = + connection->response->upgrade (connection->response->upgrade_cls, + connection, + &connection->client_context, + connection->socket_fd); + } + MHD_destroy_response (connection->response); connection->response = NULL; if (connection->daemon->notify_completed != NULL) @@ -2350,6 +2361,17 @@ connection->read_closed = MHD_YES; connection->read_buffer_offset = 0; } + if (upgraded == MHD_YES) + { + connection->state = MHD_CONNECTION_CLOSED; + connection->socket_fd = -1; + MHD_pool_destroy (connection->pool); + connection->pool = NULL; + connection->read_buffer = NULL; + connection->read_buffer_size = 0; + connection->read_buffer_offset = 0; + continue; + } if (((MHD_YES == connection->read_closed) && (0 == connection->read_buffer_offset)) || (connection->version == NULL) || Index: src/daemon/daemon.c =================================================================== --- src/daemon/daemon.c (revision 23229) +++ src/daemon/daemon.c (working copy) @@ -882,7 +882,7 @@ #if HAVE_MESSAGES #if DEBUG_CONNECT - MHD_DLOG (daemon, "Accepted connection on socket %d\n", s); + MHD_DLOG (daemon, "Accepted connection on socket %d\n", client_socket); #endif #endif if ( (0 == daemon->max_connections) || Index: src/daemon/internal.h =================================================================== --- src/daemon/internal.h (revision 23229) +++ src/daemon/internal.h (working copy) @@ -278,6 +278,16 @@ */ int fd; + /** + * Function to call when a connection: upgrade + * header is present. May be NULL. + */ + MHD_UpgradeHandler upgrade; + + /** + * Closure argument to notify_completed. + */ + void *upgrade_cls; }; Index: src/daemon/response.c =================================================================== --- src/daemon/response.c (revision 23229) +++ src/daemon/response.c (working copy) @@ -408,7 +408,28 @@ mode == MHD_RESPMEM_MUST_COPY); } +/** + * Create a response object. The response object can be extended with + * header information and then be used any number of times. + * + * @param upgrade_handler function to call with the 'upgraded' socket + * @param upgrade_handler_cls closure for 'upgrade_handler' + * @return NULL on error (i.e. invalid arguments, out of memory) + */ +struct MHD_Response * +MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, + void *upgrade_handler_cls) +{ + struct MHD_Response *response; + response = MHD_create_response_from_data (0, NULL, 0, 1); + + response->upgrade = upgrade_handler; + response->upgrade_cls = upgrade_handler_cls; + + return response; +} + /** * Destroy a response object and associated resources. Note that * libmicrohttpd may keep some of the resources around if the response Index: src/include/microhttpd.h =================================================================== --- src/include/microhttpd.h (revision 23229) +++ src/include/microhttpd.h (working copy) @@ -1420,13 +1420,15 @@ * to some other protocol. This function must * take over the communication and is ultimately * responsible for closing the socket. + * @return MHD_NO on error, the handler want to stop the upgrade process, + * the connection is still handle by MHD. + * MHD_YES on success, the socket will should not be handled by MHD any more. */ -typedef void (*MHD_UpgradeHandler)(void *cls, +typedef int (*MHD_UpgradeHandler) (void *cls, struct MHD_Connection *connection, void **con_cls, int upgrade_socket); -#if 0 /** * Create a response object that can be used for 101 UPGRADE * responses, for example to implement websockets. After sending the @@ -1459,7 +1461,6 @@ struct MHD_Response * MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, void *upgrade_handler_cls); -#endif /** * Destroy a response object and associated resources. Note that Index: src/testcurl/Makefile.am =================================================================== --- src/testcurl/Makefile.am (revision 23229) +++ src/testcurl/Makefile.am (working copy) @@ -62,7 +62,8 @@ endif noinst_PROGRAMS = \ - daemon_options_test + daemon_options_test \ + daemontest_upgrade if ENABLE_DAUTH check_PROGRAMS += \ @@ -153,6 +154,12 @@ $(top_builddir)/src/daemon/libmicrohttpd.la \ @LIBCURL@ +daemontest_upgrade_SOURCES = \ + daemontest_upgrade.c +daemontest_upgrade_LDADD = \ + $(top_builddir)/src/daemon/libmicrohttpd.la \ + @LIBCURL@ + daemontest_process_headers_SOURCES = \ daemontest_process_headers.c daemontest_process_headers_LDADD = \