@@ -89,6 +89,9 @@ Http2ConnectionState::rcv_data_frame(const Http2Frame &frame)
8989
9090 Http2StreamDebug (this ->session , id, " Received DATA frame" );
9191
92+ // Update connection window size, before any stream specific handling
93+ this ->decrement_local_rwnd (payload_length);
94+
9295 if (this ->get_zombie_event ()) {
9396 Warning (" Data frame for zombied session %" PRId64, this ->session ->get_connection_id ());
9497 }
@@ -174,7 +177,8 @@ Http2ConnectionState::rcv_data_frame(const Http2Frame &frame)
174177 }
175178
176179 // Check whether Window Size is acceptable
177- if (!this ->_local_rwnd_is_shrinking && this ->get_local_rwnd () < payload_length) {
180+ // compare to 0 because we already decreased the connection rwnd with payload_length
181+ if (!this ->_local_rwnd_is_shrinking && this ->get_local_rwnd () < 0 ) {
178182 return Http2Error (Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_FLOW_CONTROL_ERROR,
179183 " recv data this->local_rwnd < payload_length" );
180184 }
@@ -183,8 +187,7 @@ Http2ConnectionState::rcv_data_frame(const Http2Frame &frame)
183187 " recv data stream->local_rwnd < payload_length" );
184188 }
185189
186- // Update Window size
187- this ->decrement_local_rwnd (payload_length);
190+ // Update stream window size
188191 stream->decrement_local_rwnd (payload_length);
189192
190193 if (is_debug_tag_set (" http2_con" )) {
@@ -316,9 +319,17 @@ Http2ConnectionState::rcv_headers_frame(const Http2Frame &frame)
316319 }
317320 }
318321
319- // Ignoring HEADERS frame on a closed stream. The HdrHeap has gone away and it will core.
322+ // HEADERS frame on a closed stream. The HdrHeap has gone away and it will core.
320323 if (stream->get_state () == Http2StreamState::HTTP2_STREAM_STATE_CLOSED) {
321- return Http2Error (Http2ErrorClass::HTTP2_ERROR_CLASS_NONE);
324+ Http2StreamDebug (session, stream_id, " Replaced closed stream" );
325+ free_stream_after_decoding = true ;
326+ stream = THREAD_ALLOC_INIT (http2StreamAllocator, this_ethread (), session->get_proxy_session (), stream_id,
327+ peer_settings.get (HTTP2_SETTINGS_INITIAL_WINDOW_SIZE), true , false );
328+ if (!stream) {
329+ // This happening is possibly catastrophic, the HPACK tables can be out of sync
330+ // Maybe this is a connection level error?
331+ return Http2Error (Http2ErrorClass::HTTP2_ERROR_CLASS_NONE);
332+ }
322333 }
323334
324335 Http2HeadersParameter params;
0 commit comments