in lib/src/connection.dart [316:364]
void _handleFrameImpl(Frame? frame) {
// The first frame from the other side must be a [SettingsFrame], otherwise
// we terminate the connection.
if (_state.isInitialized) {
if (frame is! SettingsFrame) {
_terminate(ErrorCode.PROTOCOL_ERROR,
message: 'Expected to first receive a settings frame.');
return;
}
_state.state = ConnectionState.Operational;
_onInitialPeerSettingsReceived.complete();
}
// Try to defragment [frame] if it is a Headers/PushPromise frame.
frame = _defragmenter.tryDefragmentFrame(frame);
if (frame == null) return;
// Try to decode headers if it's a Headers/PushPromise frame.
// [This needs to be done even if the frames get ignored, since the entire
// connection shares one HPack compression context.]
if (frame is HeadersFrame) {
frame.decodedHeaders =
_hpackContext.decoder.decode(frame.headerBlockFragment);
} else if (frame is PushPromiseFrame) {
frame.decodedHeaders =
_hpackContext.decoder.decode(frame.headerBlockFragment);
}
// Handle the frame as either a connection or a stream frame.
if (frame.header.streamId == 0) {
if (frame is SettingsFrame) {
_settingsHandler.handleSettingsFrame(frame);
} else if (frame is PingFrame) {
_pingHandler.processPingFrame(frame);
} else if (frame is WindowUpdateFrame) {
_connectionWindowHandler.processWindowUpdate(frame);
} else if (frame is GoawayFrame) {
_streams.processGoawayFrame(frame);
_finishing(active: false);
} else if (frame is UnknownFrame) {
// We can safely ignore these.
} else {
throw ProtocolException(
'Cannot handle frame type ${frame.runtimeType} with stream-id 0.');
}
} else {
_streams.processStreamFrame(_state, frame);
}
}