76 + 4 = 80

The websockets protocol reached its 80th version recently; after v76 was widely implemented they renamed it 00 and continued meddling with it. Many of the changes for 04 make a lot of sense, like moving keys and nonces into base64 encoded headers rather than raw 8-bit data. One particular expensive change is to require a SHA1 per payload frame and XOR munging of all payload data in the client -> server direction; the server -> client frames remain unmunged.

Standards politics

The reasoning behind that particular change makes no sense and is an entirely political decision AFAICT; after a "security problem" was identified, Firefox and Opera disabled websockets by default in their dev builds, putting the whole effort in danger of collapse. However on closer inspection, this "security problem" does not appear to identify any actual problem that exists in this world, and if it did exist it would be in the form of a broken intermediary / proxy that would remain broken and open to abuse no matter what websockets did to avoid enabling its theoretical exploitation (should it ever be discovered to exist). The end result is a pointless and expensive payload munging scheme that doesn't protect anything inserted into the standard, in order to encourage the browser vendors to re-enable support for it.

libwebsockets client support

I don't have a browser with 04 support yet, but it is implemented into libwebsockets and tested via libwebsockets' new client websocket support which is 04-only; the server support is 76/00 and -04 depending on what the individual client asks for on each connection. The client support means you can connect to an -04 server as if you were a browser. With support for 04 client transmission, the prepadding constant LWS_SEND_BUFFER_PRE_PADDING is increased to 14 reflecting the maximum needed to contain the new frame nonce along with the length coding, but you shouldn't have to worry about that if you are using "LWS_SEND_BUFFER_PRE_PADDING". Since the client support is so integrated into the server support, I changed the name of the common init API to "libwebsocket_create_context()" instead of ...create_server.

Breaking out the service loop

A libwebsocket user hit a problem with the forked service loop approach that the library was using because on his platform, IOS, fork() is not supported. To allow libwebsockets to work in single-threaded environments I exposed a new api libwebsockets_service() that just needs to be called periodically to perform the poll() on all the sockets and handle incoming websocket traffic then. There is a new configure option --enable-nofork which disables any references to fork() and similar in the sources and implies the user will call the service api periodically (as shown in the test server sources). Support for client sockets is integrated into the server stuff, it means that even if your application is simultaneously a websocket server and client to other servers, there is still just a single service call / poll action. Because of the integration, it means that a single protocol callback can handle both client and server callback reasons; I added a new reason LWS_CALLBACK_CLIENT_RECEIVE for client rx payloads so they are handled separately from the server rx payload callback reason LWS_CALLBACK_RECEIVE. You can see all these changes in the client and server test apps that are part of the sources and built along with the library. The test client connects to the test server with two websockets, one using the "dumb-increment" protocol where the server just keeps sending the client an incrementing number in ascii, and the other uses the "lws-mirror" protocol to draw circles in the canvas of any browser that is also connected to the same server. On both the server and client side this is done fork and threadlessly, and the same server is able to deal with say a -76 version browser and an -04 libwebsocket client connected and interoperate between them.