Closed zuiderkwast closed 3 years ago
I have tested this locally against a modified version of the Graceful Shutdown branch of Cowboy.
You need to ignore (at least some) frames after all the checks, not before. For example if you ignore HEADERS where you currently do, it will not update the HPACK state, and as a result if trailers come in for a legitimate stream the state will not be valid.
Of course. :facepalm: I assumed HPACK and flow control was done in some earlier stage (e.g. while parsing), but of course it's in the machine. I've updated now. Ignored DATA frames are counted towards the connection flow-control window. Frames that affect the HPACK state are processed and then the result is discarded afterwards.
Bump.
I updated this a week ago. Do you have time to take a look soon?
After Gun 2.0.0-rc.1.
In general I don't think we need to modify the
*_frame
functions. The PR should act on the returned value fromframe/2
only. I think we should just wrap the result and, depending on the frame, transform the returned tuple into a plain{ok, State}
. Errors should be returned regardless.
So, I'll apply maybe_discard_result/1
on the result regardless of frame type.
Then maybe_discard_result/1
needs to allow the result {ok, {goaway, LastStreamID, ...}, State}
regardless of LastStreamID, which is the only tuple which doesn't follow the pattern that, because the StreamID is a LastStreamID (such as 0x7fffff) and not an actual stream ID.
So I think you're right that data_frame/2
, rst_stream_frame/2
and window_update_frame/2
(the one with a stream ID) don't need any changes as long as the result is discarded afterwards. (The #http2_machine{}
state contains the discarded streams so we won't have 'unknown stream' errors and such.)
Not sure about
send
.
Send can be triggered by window_update_frame/2
, but I don't think there can ever be any buffered data to send for streams which are ignored in this way, so I think we don't need to add any logic for send results.
OK that looks better I'll do a double check this coming week. Thanks!
Please update https://github.com/ninenines/cowboy/pull/1471 as well so I can test that it all works as intended.
Merged, thanks!
New function
set_last_streamid/1
sets the last accepted stream ID to the last known remote stream ID. Frames with a remote stream ID greater than this are thereafter ignored byframe/2
, which returns{ok, Http2Machine}
for such frames.