diff --git a/lib/handshake.c b/lib/handshake.c index e1bafb60..22453814 100644 --- a/lib/handshake.c +++ b/lib/handshake.c @@ -298,12 +298,19 @@ postbody_completion: read_ok: /* Nothing more to do for now */ - lwsl_info("%s: %p: read_ok, used %ld (len %d, state %d)\n", __func__, wsi, (long)(buf - oldbuf), (int)len, wsi->state); + lwsl_info("%s: %p: read_ok, used %ld (len %d, state %d)\n", __func__, + wsi, (long)(buf - oldbuf), (int)len, wsi->state); return lws_ptr_diff(buf, oldbuf); bail: - lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS); + /* + * h2 / h2-ws calls us recursively in lws_read()->lws_h2_parser()-> + * lws_read() pattern. Make sure that only the outer lws_read() does + * the wsi close. + */ + if (!wsi->outer_will_close) + lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS); return -1; } diff --git a/lib/http2/http2.c b/lib/http2/http2.c index e875f501..87cc1c17 100644 --- a/lib/http2/http2.c +++ b/lib/http2/http2.c @@ -1485,9 +1485,11 @@ lws_h2_parser(struct lws *wsi, unsigned char *in, lws_filepos_t inlen, break; } + h2n->swsi->outer_will_close = 1; n = lws_read(h2n->swsi, in - 1, inlen + 1); + h2n->swsi->outer_will_close = 0; if (n < 0) - break; + goto fail; inlen -= n - 1; in += n - 1; diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index 26eb90a7..aa6a100e 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -1931,6 +1931,7 @@ struct lws { unsigned int could_have_pending:1; /* detect back-to-back writes */ unsigned int timer_active:1; + unsigned int outer_will_close:1; #ifdef LWS_WITH_ACCESS_LOG unsigned int access_log_pending:1;