diff --git a/lib/core-net/private-lib-core-net.h b/lib/core-net/private-lib-core-net.h index b841dc1d1..7e335adc5 100644 --- a/lib/core-net/private-lib-core-net.h +++ b/lib/core-net/private-lib-core-net.h @@ -692,6 +692,7 @@ struct lws { unsigned int h2_stream_immortal:1; unsigned int h2_stream_carries_ws:1; /* immortal set as well */ unsigned int h2_stream_carries_sse:1; /* immortal set as well */ + unsigned int h2_acked_settings:1; unsigned int seen_nonpseudoheader:1; unsigned int listener:1; unsigned int user_space_externally_allocated:1; diff --git a/lib/roles/h2/http2.c b/lib/roles/h2/http2.c index b45a00b47..b8d4f96aa 100644 --- a/lib/roles/h2/http2.c +++ b/lib/roles/h2/http2.c @@ -1032,11 +1032,19 @@ lws_h2_parse_frame_header(struct lws *wsi) if (h2n->type == LWS_H2_FRAME_TYPE_COUNT) return 0; - if (wsi->upgraded_to_http2) { + if (wsi->upgraded_to_http2 && +#if defined(LWS_WITH_CLIENT) + (!(wsi->flags & LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM) || +#else + ( +#endif + !wsi->h2_acked_settings)) { + pps = lws_h2_new_pps(LWS_H2_PPS_ACK_SETTINGS); if (!pps) return 1; lws_pps_schedule(wsi, pps); + wsi->h2_acked_settings = 1; } break; } @@ -1353,11 +1361,18 @@ lws_h2_parse_end_of_frame(struct lws *wsi) lws_callback_on_writable(h2n->swsi); - pps = lws_h2_new_pps(LWS_H2_PPS_ACK_SETTINGS); - if (!pps) - return 1; - lws_pps_schedule(wsi, pps); - lwsl_info("%s: scheduled settings ack PPS\n", __func__); + if (!wsi->h2_acked_settings +#if defined(LWS_WITH_CLIENT) + || !(wsi->flags & LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM) +#endif + ) { + pps = lws_h2_new_pps(LWS_H2_PPS_ACK_SETTINGS); + if (!pps) + return 1; + lws_pps_schedule(wsi, pps); + lwsl_info("%s: scheduled settings ack PPS\n", __func__); + wsi->h2_acked_settings = 1; + } /* also attach any queued guys */