in neqo-http3/src/connection_client.rs [1173:1228]
fn handle_goaway(&mut self, goaway_stream_id: StreamId) -> Res<()> {
qinfo!("[{self}] handle_goaway {goaway_stream_id}");
if goaway_stream_id.is_uni() || goaway_stream_id.is_server_initiated() {
return Err(Error::HttpId);
}
match self.base_handler.state {
Http3State::Connected => {
self.base_handler.state = Http3State::GoingAway(goaway_stream_id);
}
Http3State::GoingAway(ref mut stream_id) => {
if goaway_stream_id > *stream_id {
return Err(Error::HttpGoaway);
}
*stream_id = goaway_stream_id;
}
Http3State::Closing(..) | Http3State::Closed(..) => {}
_ => unreachable!("Should not receive Goaway frame in this state"),
}
// Issue reset events for streams >= goaway stream id
let send_ids: Vec<StreamId> = self
.base_handler
.send_streams
.iter()
.filter_map(id_gte(goaway_stream_id))
.collect();
for id in send_ids {
// We do not care about streams that are going to be closed.
drop(self.base_handler.handle_stream_stop_sending(
id,
Error::HttpRequestRejected.code(),
&mut self.conn,
));
}
let recv_ids: Vec<StreamId> = self
.base_handler
.recv_streams
.iter()
.filter_map(id_gte(goaway_stream_id))
.collect();
for id in recv_ids {
// We do not care about streams that are going to be closed.
drop(self.base_handler.handle_stream_reset(
id,
Error::HttpRequestRejected.code(),
&mut self.conn,
));
}
self.events.goaway_received();
Ok(())
}