[Libwebsockets] HTTP keep-alive

Carl carl at appception.com
Tue Aug 19 01:20:06 CEST 2014

On 8/15/2014 7:24 PM, Andy Green wrote:
> On 16 August 2014 02:05:48 GMT+08:00, Carl Stehle <droid at appception.com> wrote:
>> When an HTTP request header contains 'Connection: keep-alive',
>> a persistent HTTP connection is established. The initial HTTP
>> request is processed fine, but in subsequent requests (on the
>> same connection), the URI header (as read with lws_hdr_copy())
>> is corrupted. This occurs on a Windows platform (not yet tested
>> elsewhere).
>> It results from an artifact of sharing in the union, described
>> below:
>> union u {
>> 		struct _lws_http_mode_related http;
>> 		struct _lws_header_related hdr;
>> 		struct _lws_websocket_related ws;
>> 	} u;
>> While processing the headers, u.hdr is valid. Once the headers
>> are processed, a 'transition' from u.hdr to u.http is made (in
>> lws_handshake_server()) so that u.hdr becomes invalid (except for
>> the retained ah structure). At this point, u.hdr should not be
>> used for the remainder of the HTTP request processing, which is
>> fine.
> Right.
>> When the next HTTP request arrives (on the same connection, since
>> keep-alive is used), u.hdr.ah is re-allocated and partially
>> re-initialized (by lws_allocate_header_table(), however, the
>> u.hdr.ues field is not re-initialized, so any previous (overlapping)
>> value from u.http remains. In the failure case, it appears to be
>> URIES_SEEN_PERCENT rather than the expected URIES_IDLE
>> (perhaps 'request_version = HTTP_VERSION_1_1' in
>> lws_handshake_server()).
>> This confuses the parser, causing it to insert a '%' before the
>> URI value.
> I see.
>> No failure occurs in the first request on the connection since
>> the u.hdr.ues is zeroed when initially allocated and URIES_IDLE
>> is 0.
> Yes.
>> As a workaround, I added:
>> wsi->u.hdr.ues = URIES_IDLE;
>> to lws_allocate_header_table(), but perhaps the full u.hdr structure
>> should be re-initialized.
>> This has only been tested on Windows, so it could be a remnant
>> of union handling there (Visual Studio 10, Windows 7, 64-bit
>> platform but compiled in 32-bit mode with the native 'cl' compiler)
>> or tickled by the particular test/datastream used.
> I think what you did hits the mark at least for that header re-init bug.
> But putting it in lws_allocate_header_table() would make it a bit of an unexpected side-effect of calling that, since it's unrelated to allocating the header table itself.
> So I moved it instead to the caller of that which actually does the http keeplive looping.
> http://git.libwebsockets.org/cgi-bin/cgit/libwebsockets/commit/?id=66d466a1a4ef405ec4baeda4e1e6ab3fd334f1fb
> I think it does the same but maybe you can confirm.

The keep-alive fix works fine, thank you.

By the way, there is a compilation error in libwebsockets.c when -DLWS_WITH_SSL=NO
(wsi->use_ssl is not defined).

Originally planned to use libwebsockets for, well, WebSockets only.
But it is really convenient to have integrated HTTP and WebSockets for our
(message broker) application as it allows us to link in a library
and share data arbitrarily between HTTP and WebSocket connections.
Nice work!


More information about the Libwebsockets mailing list