diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-08-27 18:08:00 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-08-27 18:08:00 +0000 |
commit | e0a43cb194fd22ceaed6905d964f2fcd829b933d (patch) | |
tree | e4ec639adcbc441535cdd6e92a5ac3e5ea0be5b9 | |
parent | 63eb4c75a31654c0b74e2985a0b7861ddaa8d5b3 (diff) |
sketching support for upgrade handling
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/include/microhttpd.h | 7 | ||||
-rw-r--r-- | src/microhttpd/connection.c | 33 | ||||
-rw-r--r-- | src/microhttpd/internal.h | 10 | ||||
-rw-r--r-- | src/microhttpd/response.c | 31 | ||||
-rw-r--r-- | src/microhttpd/response.h | 18 |
6 files changed, 75 insertions, 28 deletions
@@ -1,3 +1,7 @@ +Sat Aug 27 20:07:53 CEST 2016 + Adding completely *untested* logic for HTTP "Upgrade" + handling. -CG + Sat Aug 27 18:20:38 CEST 2016 Releasing libmicrohttpd 0.9.51. -CG diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h index ff292280..0a7e4711 100644 --- a/src/include/microhttpd.h +++ b/src/include/microhttpd.h @@ -126,7 +126,7 @@ typedef intptr_t ssize_t; * Current version of the library. * 0x01093001 = 1.9.30-1. */ -#define MHD_VERSION 0x00095100 +#define MHD_VERSION 0x00095101 /** * MHD-internal return code for "YES". @@ -2221,7 +2221,6 @@ MHD_create_response_from_fd_at_offset64 (uint64_t size, uint64_t offset); -#if 0 /** * Enumeration for actions MHD should perform on the underlying socket * of the upgrade. This API is not finalized, and in particular @@ -2334,7 +2333,7 @@ typedef void struct MHD_Connection *connection, const char *extra_in, size_t extra_in_size, - MHD_SOCKET sock, + MHD_socket sock, struct MHD_UpgradeResponseHandle *urh); @@ -2370,7 +2369,7 @@ typedef void _MHD_EXTERN 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 diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c index ff7f663f..b1b34cef 100644 --- a/src/microhttpd/connection.c +++ b/src/microhttpd/connection.c @@ -736,7 +736,8 @@ keepalive_possible (struct MHD_Connection *connection) if (NULL == end) return MHD_YES; if ( (MHD_str_equal_caseless_ (end, "close")) || - (MHD_str_equal_caseless_ (end, "upgrade")) ) + ( (MHD_str_equal_caseless_ (end, "upgrade")) && + (NULL == connection->response->upgrade_handler) ) ) return MHD_NO; return MHD_YES; } @@ -2222,6 +2223,9 @@ MHD_connection_handle_read (struct MHD_Connection *connection) break; case MHD_CONNECTION_CLOSED: return MHD_YES; + case MHD_CONNECTION_UPGRADE: + EXTRA_CHECK (0); + break; default: /* shrink read buffer to how much is actually used */ MHD_pool_reallocate (connection->pool, @@ -2305,7 +2309,8 @@ MHD_connection_handle_write (struct MHD_Connection *connection) do_write (connection); if (connection->state != MHD_CONNECTION_HEADERS_SENDING) break; - check_write_done (connection, MHD_CONNECTION_HEADERS_SENT); + check_write_done (connection, + MHD_CONNECTION_HEADERS_SENT); break; case MHD_CONNECTION_HEADERS_SENT: EXTRA_CHECK (0); @@ -2395,6 +2400,9 @@ MHD_connection_handle_write (struct MHD_Connection *connection) case MHD_TLS_CONNECTION_INIT: EXTRA_CHECK (0); break; + case MHD_CONNECTION_UPGRADE: + EXTRA_CHECK (0); + break; default: EXTRA_CHECK (0); CONNECTION_CLOSE_ERROR (connection, @@ -2586,9 +2594,9 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) } if ( (NULL != connection->response) && ( (MHD_str_equal_caseless_ (connection->method, - MHD_HTTP_METHOD_POST)) || + MHD_HTTP_METHOD_POST)) || (MHD_str_equal_caseless_ (connection->method, - MHD_HTTP_METHOD_PUT))) ) + MHD_HTTP_METHOD_PUT))) ) { /* we refused (no upload allowed!) */ connection->remaining_upload_size = 0; @@ -2722,6 +2730,21 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) } else socket_start_normal_buffering (connection); + if (NULL != connection->response->upgrade_handler) + { + /* This connection is "upgraded". Pass socket to application. */ + if (MHD_YES != + MHD_response_execute_upgrade_ (connection->response, + connection)) + { + /* upgrade failed, fail hard */ + CONNECTION_CLOSE_ERROR (connection, + NULL); + continue; + } + connection->state = MHD_CONNECTION_UPGRADE; + continue; + } if (connection->have_chunked_upload) connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY; @@ -2882,6 +2905,8 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) case MHD_CONNECTION_CLOSED: cleanup_connection (connection); return MHD_NO; + case MHD_CONNECTION_UPGRADE: + return MHD_YES; /* keep open */ default: EXTRA_CHECK (0); break; diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h index d6f1177c..a810d319 100644 --- a/src/microhttpd/internal.h +++ b/src/microhttpd/internal.h @@ -274,7 +274,6 @@ struct MHD_Response */ MHD_ContentReaderFreeCallback crfc; -#if 0 /** * Application function to call once we are done sending the headers * of the response; NULL unless this is a response created with @@ -286,7 +285,6 @@ struct MHD_Response * Closure for @e uh. */ void *upgrade_handler_cls; -#endif /** * Mutex to synchronize access to @e data, @e size and @@ -476,7 +474,13 @@ enum MHD_CONNECTION_STATE * Handshake messages will be processed in this state & while * in the #MHD_TLS_HELLO_REQUEST state */ - MHD_TLS_CONNECTION_INIT = MHD_CONNECTION_IN_CLEANUP + 1 + MHD_TLS_CONNECTION_INIT = MHD_CONNECTION_IN_CLEANUP + 1, + + /** + * Connection was "upgraded" and socket is now under the + * control of the application. + */ + MHD_CONNECTION_UPGRADE = MHD_TLS_CONNECTION_INIT + 1 }; diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c index f0ebf5c6..66a1650d 100644 --- a/src/microhttpd/response.c +++ b/src/microhttpd/response.c @@ -1,6 +1,6 @@ /* This file is part of libmicrohttpd - Copyright (C) 2007, 2009, 2010 Daniel Pittman and Christian Grothoff + Copyright (C) 2007, 2009, 2010, 2016 Daniel Pittman and Christian Grothoff This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -29,6 +29,9 @@ #include "internal.h" #include "response.h" #include "mhd_limits.h" +#include "mhd_sockets.h" +#include "mhd_itc.h" +#include "connection.h" #if defined(_WIN32) && defined(MHD_W32_MUTEX_) #ifndef WIN32_LEAN_AND_MEAN @@ -577,7 +580,6 @@ MHD_create_response_from_buffer (size_t size, } -#if 0 /** * Handle given to the application to manage special * actions relating to MHD responses that "upgrade" @@ -596,13 +598,13 @@ struct MHD_UpgradeResponseHandle /** * The socket we gave to the application (r/w). */ - MHD_SOCKET app_sock; + MHD_socket app_socket; /** * If @a app_sock was a socketpair, our end of it, otherwise * #MHD_INVALID_SOCKET; (r/w). */ - MHD_SOCKET mhd_sock; + MHD_socket mhd_socket; }; @@ -629,12 +631,12 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh, case MHD_UPGRADE_ACTION_CLOSE: /* Application is done with this connection, tear it down! */ if ( (MHD_INVALID_SOCKET != urh->app_socket) && - (0 != MHD_socket_close (urh->app_socket)) ) + (0 != MHD_socket_close_ (urh->app_socket)) ) MHD_PANIC ("close failed\n"); if ( (MHD_INVALID_SOCKET != urh->mhd_socket) && - (0 != MHD_socket_close (urh->mhd_socket)) ) + (0 != MHD_socket_close_ (urh->mhd_socket)) ) MHD_PANIC ("close failed\n"); - MHD_connection_resume (urh->connection); + MHD_resume_connection (urh->connection); MHD_connection_close_ (urh->connection, MHD_REQUEST_TERMINATED_COMPLETED_OK); free (urh); @@ -659,9 +661,6 @@ MHD_upgrade_action (struct MHD_UpgradeResponseHandle *urh, * @return #MHD_YES on success, #MHD_NO on failure (will cause * connection to be closed) */ -// FIXME: This function will need to be called at the right place(s) -// in the connection processing (just after we are done sending the header) -// (for responses that have the 'upgrade_header' callback set). int MHD_response_execute_upgrade_ (struct MHD_Response *response, struct MHD_Connection *connection) @@ -674,7 +673,7 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response, if (NULL == urh) return MHD_NO; #if HTTPS_SUPPORT - if (0 != (connection->daemon->flags & MHD_USE_SSL) ) + if (0 != (connection->daemon->options & MHD_USE_SSL) ) { /* FIXME: this is non-portable for now; W32 port pending... */ if (0 != socketpair (AF_UNIX, @@ -694,12 +693,12 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response, connection, connection->read_buffer, rbo, - urh->app_sock, + urh->app_socket, urh); /* As far as MHD is concerned, this connection is suspended; it will be resumed once we are done in the #MHD_upgrade_action() function */ - MHD_connection_suspend (connection); + MHD_suspend_connection (connection); /* FIXME: also need to start some processing logic in _all_ MHD event loops for the sv traffic! (NOT IMPLEMENTED!!!) */ return MHD_YES; @@ -718,7 +717,7 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response, /* As far as MHD is concerned, this connection is suspended; it will be resumed once we are done in the #MHD_upgrade_action() function */ - MHD_connection_suspend (connection); + MHD_suspend_connection (connection); return MHD_YES; } @@ -758,7 +757,7 @@ MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, { struct MHD_Response *response; - if (NULL == upgrade_header) + if (NULL == upgrade_handler) return NULL; /* invalid request */ response = malloc (sizeof (struct MHD_Response)); if (NULL == response) @@ -769,14 +768,12 @@ MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, free (response); return NULL; } - urh->response = response; response->upgrade_handler = upgrade_handler; response->upgrade_handler_cls = upgrade_handler_cls; response->total_size = MHD_SIZE_UNKNOWN; response->reference_count = 1; return response; } -#endif /** diff --git a/src/microhttpd/response.h b/src/microhttpd/response.h index a13683d1..ce7e131c 100644 --- a/src/microhttpd/response.h +++ b/src/microhttpd/response.h @@ -36,4 +36,22 @@ void MHD_increment_response_rc (struct MHD_Response *response); +/** + * We are done sending the header of a given response + * to the client. Now it is time to perform the upgrade + * and hand over the connection to the application. + * + * @param response the response that was created for an upgrade + * @param connection the specific connection we are upgrading + * @return #MHD_YES on success, #MHD_NO on failure (will cause + * connection to be closed) + */ +// FIXME: This function will need to be called at the right place(s) +// in the connection processing (just after we are done sending the header) +// (for responses that have the 'upgrade_header' callback set). +int +MHD_response_execute_upgrade_ (struct MHD_Response *response, + struct MHD_Connection *connection); + + #endif |