ah move more_rx_waiting to wsi scope
Originally this was alright in wsi->u.hdr, because ah implied header processing. But since we allowed ah to be held across http keep-alive transactions if we saw we had more header data, it means we were trying to read this union member out of scope after it had transitioned. Moving the more_rx_waiting member to be a 1-bit bifield in the wsi solves it and lets us check the state any time later at http transaction completion. https://github.com/warmcat/libwebsockets/issues/441 Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
parent
03384721e7
commit
83af28a747
4 changed files with 16 additions and 5 deletions
|
@ -30,6 +30,12 @@ trips around the event loop (and cgi...).
|
|||
6) MAJOR connections on ah waiting list that closed did not get removed from
|
||||
the waiting list...
|
||||
|
||||
7) MAJOR since we added the ability to hold an ah across http keepalive
|
||||
transactions where more headers had already arrived, we broke the ability
|
||||
to tell if more headers had arrived. Result was if the browser didn't
|
||||
close the keepalive, we retained ah for the lifetime of the keepalive,
|
||||
using up the pool.
|
||||
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
|
|
@ -229,7 +229,7 @@ int lws_header_table_detach(struct lws *wsi)
|
|||
"wsi->more_rx_waiting %d\n", __func__, wsi,
|
||||
(int)(now - wsi->u.hdr.ah->assigned),
|
||||
ah->rxpos, ah->rxlen, wsi->mode, wsi->state,
|
||||
wsi->u.hdr.more_rx_waiting);
|
||||
wsi->more_rx_waiting);
|
||||
}
|
||||
|
||||
/* if we think we're detaching one, there should be one in use */
|
||||
|
|
|
@ -964,7 +964,6 @@ struct _lws_header_related {
|
|||
char post_literal_equal;
|
||||
unsigned char parser_state; /* enum lws_token_indexes */
|
||||
char redirects;
|
||||
char more_rx_waiting;
|
||||
};
|
||||
|
||||
struct _lws_websocket_related {
|
||||
|
@ -1091,6 +1090,7 @@ struct lws {
|
|||
unsigned int user_space_externally_allocated:1;
|
||||
unsigned int socket_is_permanently_unusable:1;
|
||||
unsigned int rxflow_change_to:2;
|
||||
unsigned int more_rx_waiting:1; /* has to live here since ah may stick to end */
|
||||
#ifndef LWS_NO_EXTENSIONS
|
||||
unsigned int extension_data_pending:1;
|
||||
#endif
|
||||
|
|
11
lib/server.c
11
lib/server.c
|
@ -352,7 +352,7 @@ lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len)
|
|||
assert(wsi->u.hdr.ah);
|
||||
|
||||
while (len--) {
|
||||
wsi->u.hdr.more_rx_waiting = !!len;
|
||||
wsi->more_rx_waiting = !!len;
|
||||
|
||||
assert(wsi->mode == LWSCM_HTTP_SERVING);
|
||||
|
||||
|
@ -364,7 +364,9 @@ lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len)
|
|||
if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE)
|
||||
continue;
|
||||
|
||||
lwsl_parser("lws_parse sees parsing complete\n");
|
||||
lwsl_parser("%s: lws_parse sees parsing complete\n", __func__);
|
||||
lwsl_debug("%s: wsi->more_rx_waiting=%d\n", __func__,
|
||||
wsi->more_rx_waiting);
|
||||
|
||||
wsi->mode = LWSCM_PRE_WS_SERVING_ACCEPT;
|
||||
lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
|
||||
|
@ -746,7 +748,10 @@ lws_http_transaction_completed(struct lws *wsi)
|
|||
* reset the existing header table and keep it.
|
||||
*/
|
||||
if (wsi->u.hdr.ah) {
|
||||
if (!wsi->u.hdr.more_rx_waiting) {
|
||||
lwsl_info("%s: wsi->more_rx_waiting=%d\n", __func__,
|
||||
wsi->more_rx_waiting);
|
||||
|
||||
if (!wsi->more_rx_waiting) {
|
||||
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
|
||||
lws_header_table_detach(wsi);
|
||||
} else
|
||||
|
|
Loading…
Add table
Reference in a new issue