[Libwebsockets] HTTP keep-alive

Andy Green andy at warmcat.com
Sat Aug 16 04:24:10 CEST 2014



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.

Thanks a lot for the fix!

-Andy

>Regards, Carl
>
>
>
>_______________________________________________
>Libwebsockets mailing list
>Libwebsockets at ml.libwebsockets.org
>http://ml.libwebsockets.org/mailman/listinfo/libwebsockets




More information about the Libwebsockets mailing list