diff --git a/lib/http2/http2.c b/lib/http2/http2.c index 009df817..de0f33d5 100644 --- a/lib/http2/http2.c +++ b/lib/http2/http2.c @@ -134,7 +134,7 @@ void lws_h2_init(struct lws *wsi) wsi->h2.h2n->set = wsi->vhost->set; } -static void +void lws_h2_state(struct lws *wsi, enum lws_h2_states s) { if (!wsi) @@ -1022,6 +1022,8 @@ lws_h2_parse_frame_header(struct lws *wsi) if (h2n->sid) { h2n->swsi = lws_h2_wsi_from_id(wsi, h2n->sid); lwsl_info("HEADERS: nwsi %p: sid %d mapped to wsi %p\n", wsi, h2n->sid, h2n->swsi); + if (!h2n->swsi) + break; } goto update_end_headers; } @@ -1260,6 +1262,9 @@ lws_h2_parse_end_of_frame(struct lws *wsi) case LWS_H2_FRAME_TYPE_CONTINUATION: case LWS_H2_FRAME_TYPE_HEADERS: + if (!h2n->swsi) + break; + /* service the http request itself */ if (h2n->last_action_dyntable_resize) { diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index fb0fd818..3061acbc 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -1559,6 +1559,9 @@ enum lws_h2_states { */ }; +void +lws_h2_state(struct lws *wsi, enum lws_h2_states s); + #define LWS_H2_STREAM_ID_MASTER 0 #define LWS_H2_SETTINGS_LEN 6 #define LWS_H2_FLAG_SETTINGS_ACK 1 diff --git a/lib/service.c b/lib/service.c index 11201846..4fe9b9e7 100644 --- a/lib/service.c +++ b/lib/service.c @@ -621,11 +621,13 @@ user_service_go_again: goto next_child; } - if (lws_calllback_as_writeable(w) || w->h2.send_END_STREAM) { + if (lws_calllback_as_writeable(w)) { lwsl_info("Closing POLLOUT child (end stream %d)\n", w->h2.send_END_STREAM); lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS, "h2 pollout handle"); wa = &wsi->h2.child_list; - } + } else + if (w->h2.send_END_STREAM) + lws_h2_state(w, LWS_H2_STATE_HALF_CLOSED_LOCAL); next_child: wsi2 = wa;