1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

ah: require parsing complete before detach

Introduce helpers to force to detachable state and to test the ah is
in a detachable state.

Require not only the ah rx buffer is all used, but that the
wsi has completed a full set of headers.
This commit is contained in:
Andy Green 2017-06-28 12:13:13 +08:00
parent 0b629d4037
commit 8f4f692945
7 changed files with 43 additions and 21 deletions

View file

@ -402,8 +402,8 @@ lws_client_connect_2(struct lws *wsi)
oom4:
/* we're closing, losing some rx is OK */
if (wsi->u.hdr.ah)
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
lws_header_table_force_to_detachable_state(wsi);
if (wsi->mode == LWSCM_HTTP_CLIENT ||
wsi->mode == LWSCM_HTTP_CLIENT_ACCEPTED ||
wsi->mode == LWSCM_WSCL_WAITING_CONNECT) {

View file

@ -583,7 +583,7 @@ lws_http_transaction_completed_client(struct lws *wsi)
* we can drop the ah, if any
*/
if (wsi->u.hdr.ah) {
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
lws_header_table_force_to_detachable_state(wsi);
lws_header_table_detach(wsi, 0);
}
@ -1258,7 +1258,7 @@ lws_generate_client_handshake(struct lws *wsi, char *pkt)
wsi->user_space, NULL, 0))
return NULL;
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
lws_header_table_force_to_detachable_state(wsi);
lws_union_transition(wsi, LWSCM_RAW);
lws_header_table_detach(wsi, 1);

View file

@ -243,9 +243,8 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason)
}
#endif
if (wsi->u.hdr.ah)
/* we're closing, losing some rx is OK */
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
/* we're closing, losing some rx is OK */
lws_header_table_force_to_detachable_state(wsi);
context = wsi->context;
pt = &context->pt[(int)wsi->tsi];
@ -2552,7 +2551,7 @@ lws_cgi(struct lws *wsi, const char * const *exec_array, int script_uri_path_len
* Actually having made the env, as a cgi we don't need the ah
* any more
*/
if (wsi->u.hdr.ah->rxpos == wsi->u.hdr.ah->rxlen)
if (lws_header_table_is_in_detachable_state(wsi))
lws_header_table_detach(wsi, 0);
/* we are ready with the redirection pipes... run the thing */

View file

@ -215,6 +215,24 @@ bail:
return 1;
}
void
lws_header_table_force_to_detachable_state(struct lws *wsi)
{
if (wsi->u.hdr.ah) {
wsi->u.hdr.ah->rxpos = -1;
wsi->u.hdr.ah->rxlen = -1;
wsi->hdr_parsing_completed = 1;
}
}
int
lws_header_table_is_in_detachable_state(struct lws *wsi)
{
struct allocated_headers *ah = wsi->u.hdr.ah;
return ah && ah->rxpos == ah->rxlen && wsi->hdr_parsing_completed;
}
int lws_header_table_detach(struct lws *wsi, int autoservice)
{
struct lws_context *context = wsi->context;
@ -224,6 +242,9 @@ int lws_header_table_detach(struct lws *wsi, int autoservice)
struct lws **pwsi;
time_t now;
if (!ah)
return 0;
lwsl_info("%s: wsi %p: ah %p (tsi=%d, count = %d)\n", __func__,
(void *)wsi, (void *)ah, wsi->tsi,
pt->ah_count_in_use);
@ -232,11 +253,9 @@ int lws_header_table_detach(struct lws *wsi, int autoservice)
lws_free_set_NULL(wsi->u.hdr.preamble_rx);
/* may not be detached while he still has unprocessed rx */
if (ah && ah->rxpos != ah->rxlen) {
lwsl_err("%s: %p: CANNOT DETACH rxpos:%d, rxlen:%d\n", __func__, wsi,
ah->rxpos, ah->rxlen);
assert(ah->rxpos == ah->rxlen);
if (!lws_header_table_is_in_detachable_state(wsi)) {
lwsl_err("%s: %p: CANNOT DETACH rxpos:%d, rxlen:%d, wsi->hdr_parsing_completed = %d\n", __func__, wsi,
ah->rxpos, ah->rxlen, wsi->hdr_parsing_completed);
return 0;
}

View file

@ -1904,6 +1904,11 @@ lws_header_table_reset(struct lws *wsi, int autoservice);
void
_lws_header_table_reset(struct allocated_headers *ah);
void
lws_header_table_force_to_detachable_state(struct lws *wsi);
int
lws_header_table_is_in_detachable_state(struct lws *wsi);
LWS_EXTERN char * LWS_WARN_UNUSED_RESULT
lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h);

View file

@ -1271,7 +1271,7 @@ deal_body:
bail_nuke_ah:
/* we're closing, losing some rx is OK */
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
lws_header_table_force_to_detachable_state(wsi);
// lwsl_notice("%s: drop1\n", __func__);
lws_header_table_detach(wsi, 1);
@ -1338,7 +1338,7 @@ raw_transition:
wsi->user_space, NULL, 0))
goto bail_nuke_ah;
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
lws_header_table_force_to_detachable_state(wsi);
lws_union_transition(wsi, LWSCM_RAW);
lws_header_table_detach(wsi, 1);
@ -1697,7 +1697,7 @@ upgrade_ws:
/* !!! drop ah unreservedly after ESTABLISHED */
if (!wsi->more_rx_waiting) {
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
lws_header_table_force_to_detachable_state(wsi);
//lwsl_notice("%p: dropping ah EST\n", wsi);
lws_header_table_detach(wsi, 1);
@ -1711,7 +1711,7 @@ upgrade_ws:
bail_nuke_ah:
/* drop the header info */
/* we're closing, losing some rx is OK */
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
lws_header_table_force_to_detachable_state(wsi);
//lwsl_notice("%s: drop2\n", __func__);
lws_header_table_detach(wsi, 1);
@ -1847,7 +1847,7 @@ lws_http_transaction_completed(struct lws *wsi)
wsi->more_rx_waiting);
if (!wsi->more_rx_waiting) {
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
lws_header_table_force_to_detachable_state(wsi);
lws_header_table_detach(wsi, 1);
#ifdef LWS_OPENSSL_SUPPORT
/*
@ -2260,7 +2260,7 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
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 &&
if (lws_header_table_is_in_detachable_state(wsi) &&
(wsi->mode != LWSCM_HTTP_SERVING &&
wsi->mode != LWSCM_HTTP_SERVING_ACCEPTED &&
wsi->mode != LWSCM_HTTP2_SERVING))

View file

@ -1257,8 +1257,7 @@ drain:
if (wsi->u.hdr.ah) {
lwsl_notice("%s: %p: detaching\n",
__func__, wsi);
/* show we used all the pending rx up */
wsi->u.hdr.ah->rxpos = wsi->u.hdr.ah->rxlen;
lws_header_table_force_to_detachable_state(wsi);
/* we can run the normal ah detach flow despite
* being in ws union mode, since all union members
* start with hdr */