[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libmicrohttpd] Websockets?

From: Christian Grothoff
Subject: Re: [libmicrohttpd] Websockets?
Date: Mon, 23 Jan 2012 22:36:36 +0100
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv: Gecko/20111110 Lightning/1.0b1 Icedove/3.0.11

On 01/23/2012 07:12 PM, Simon Newton wrote:
I need to add server triggered notifications to my app so I'd love to
see this as well.

Ok, I guess I should propose an API then. Given that MHD is really supposed to "just" do HTTP and that (a) WebSocket standardization doesn't seem to be completely finished and that (b) there might be other upgrade mechanisms in the future, I propose a general-purpose upgrade-response (that can be used to implement "most" WebSocket drafts out there). Without further ado:

 * Function called after a protocol upgrade response was sent
 * successfully and the socket should now be controlled by some
 * protocol other than HTTP.  Note that from this point on, MHD will
 * consider this connection to be "complete", so it will no longer be
 * counted as an active connection for the
 * MHD_OPTION_CONNECTION_LIMIT.  After this function returns, the
 * MHD_RequestCompletedCallback will be called and all resources of
 * the connection (except for the socket itself) will be released.
 * @param cls closure
 * @param connection original HTTP connection handle,
 *                   giving the function a last chance
 *                   to inspect the original HTTP request
 * @param con_cls value as set by the last call to the
 *                MHD_AccessHandlerCallback; will afterwards
 *                be also given to the MHD_RequestCompletedCallback
 * @param upgrade_socket TCP socket that was upgraded from HTTP
 *                to some other protocol.  This function must
 *                take over the communication and is ultimately
 *                responsible for closing the socket.
typedef void (*MHD_UpgradeHandler)(void *cls,
                                   struct MHD_Connection *connection,
                                   void **con_cls,
                                   int upgrade_socket);

 * Create a response object that can be used for 101 UPGRADE
 * responses, for example to implement websockets.  After sending the
 * response, control over the socket is given to the callback (which
 * can then, for example, start some bi-directional communication).
 * If the response is queued for multiple connections, the callback
 * will be called with a socket for each connection.  The callback
 * will ONLY be called if the response header was successfully passed
 * to the OS; if there are communication errors before, the usual MHD
 * connection error handling code will be performed.
 * Setting the correct HTTP code (i.e. MHD_HTTP_SWITCHING_PROTOCOLS)
 * and setting correct HTTP headers for the upgrade must be done
 * manually (this way, it is possible to implement most existing
 * WebSocket version using this API; in fact, this API might be useful
 * for any protocol switch, not just web sockets).  Note that
 * draft-ietf-hybi-thewebsocketprotocol-00 cannot be implemented this
 * way as the header "HTTP/1.1 101 WebSocket Protocol Handshake"
 * cannot be generated; instead, MHD will always produce "HTTP/1.1 101
 * Switching Protocols" (if the response 101 is used).
 * As usual, the response object can be extended with header
 * information and then be used any number of times (as long as the
 * header information is not connection-specific).
 * @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);

The above should be reasonably easy to implement for plain HTTP; for HTTPS, eh, yeah, well, I guess we could alternatively return the GnuTLS handle for the HTTPS session instead of the raw socket (ugh). The above also leaves it to the user to actually implement the WebSocket protocol (parse request, do the hashing, generate response header, then later tokenize the stream, etc.). That's fine and could then be easily abstracted by a 'libmhdwebsocket' if needed (especially once the WebSocket standard is really final).

I'm open for other suggestions for how to solve this. Also, as documented this API would have some limitations with respect to connections no longer being tracked (and limited) by MHD at all. Is that good or bad? Feedback on the API and particular on these points would be very welcome.

Naturally, this API proposal does also in no way suggest a good way to test a potential implementation, so if some of you want to see this in 0.9.19, how about writing some nice tests against this API? That'd certainly increase my motivation to write an implementation ;-).

Happy hacking!


reply via email to

[Prev in Thread] Current Thread [Next in Thread]