lws_header_table_reset: make caller responsibility to clear down ah rx buffer

There are two kinds of reaason to call lws_header_table_reset(), one is we are reallocating
a destroyed ah to another wsi, and the other is we are moving to the next pipelined header set
still on the same wsi, and we need a "weaker" reset that only clears down the state related
to the header parsing, not everything about the ah context including the ah rx buffer.

This patch moves the ah rxbuffer rxpos and rxlen resetting out of lws_header_table_reset() and to
be the responsibility of the caller.  Callers who are moving the ah to another wsi are
patched to deal with resetting rxpos and rxlen and lws_http_transaction_completed() who only
resets the ah when moving to the next pipelined headers, no longer wrongly clears the ah rxbuf.

https://github.com/warmcat/libwebsockets/issues/638
This commit is contained in:
Andy Green 2016-09-29 10:38:26 +08:00
parent 3d48ce8f09
commit ab9c2f329c
2 changed files with 14 additions and 4 deletions

View file

@ -60,6 +60,8 @@ lextable_decode(int pos, char c)
}
}
// doesn't scrub the ah rxbuffer by default, parent must do if needed
void
lws_header_table_reset(struct lws *wsi, int autoservice)
{
@ -77,10 +79,6 @@ lws_header_table_reset(struct lws *wsi, int autoservice)
ah->nfrag = 0;
ah->pos = 0;
/* and reset the rx state */
ah->rxpos = 0;
ah->rxlen = 0;
/* since we will restart the ah, our new headers are not completed */
wsi->hdr_parsing_completed = 0;
@ -182,6 +180,11 @@ lws_header_table_attach(struct lws *wsi, int autoservice)
lws_pt_unlock(pt);
reset:
/* and reset the rx state */
wsi->u.hdr.ah->rxpos = 0;
wsi->u.hdr.ah->rxlen = 0;
lws_header_table_reset(wsi, autoservice);
time(&wsi->u.hdr.ah->assigned);
@ -284,6 +287,9 @@ int lws_header_table_detach(struct lws *wsi, int autoservice)
wsi->u.hdr.ah = ah;
ah->wsi = wsi; /* new owner */
/* and reset the rx state */
ah->rxpos = 0;
ah->rxlen = 0;
lws_header_table_reset(wsi, autoservice);
time(&wsi->u.hdr.ah->assigned);

View file

@ -1579,11 +1579,15 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
if ( wsi->u.hdr.ah->rxlen)
wsi->u.hdr.ah->rxpos += n;
lwsl_debug("%s: wsi %p: ah read rxpos %d, rxlen %d\n", __func__, wsi, wsi->u.hdr.ah->rxpos, wsi->u.hdr.ah->rxlen);
if (wsi->u.hdr.ah->rxpos == wsi->u.hdr.ah->rxlen &&
(wsi->mode != LWSCM_HTTP_SERVING &&
wsi->mode != LWSCM_HTTP_SERVING_ACCEPTED &&
wsi->mode != LWSCM_HTTP2_SERVING))
lws_header_table_detach(wsi, 1);
else
wsi->more_rx_waiting = 1;
}
break;
}