in neqo-http3/src/connection_server.rs [318:398]
fn handle_stream_readable(&mut self, conn: &mut Connection, stream_id: StreamId) -> Res<()> {
match self.base_handler.handle_stream_readable(conn, stream_id)? {
ReceiveOutput::NewStream(NewStreamType::Push(_)) => Err(Error::HttpStreamCreation),
ReceiveOutput::NewStream(NewStreamType::Http(first_frame_type)) => {
self.base_handler.add_streams(
stream_id,
Box::new(SendMessage::new(
MessageType::Response,
Http3StreamType::Http,
stream_id,
Rc::clone(&self.base_handler.qpack_encoder),
Box::new(self.events.clone()),
)),
Box::new(RecvMessage::new(
&RecvMessageInfo {
message_type: MessageType::Request,
stream_type: Http3StreamType::Http,
stream_id,
first_frame_type: Some(first_frame_type),
},
Rc::clone(&self.base_handler.qpack_decoder),
Box::new(self.events.clone()),
None,
PriorityHandler::new(false, Priority::default()),
)),
);
let res = self.base_handler.handle_stream_readable(conn, stream_id)?;
assert_eq!(ReceiveOutput::NoOutput, res);
Ok(())
}
ReceiveOutput::NewStream(NewStreamType::WebTransportStream(session_id)) => {
self.base_handler.webtransport_create_stream_remote(
StreamId::from(session_id),
stream_id,
Box::new(self.events.clone()),
Box::new(self.events.clone()),
)?;
let res = self.base_handler.handle_stream_readable(conn, stream_id)?;
assert_eq!(ReceiveOutput::NoOutput, res);
Ok(())
}
ReceiveOutput::ControlFrames(control_frames) => {
for f in control_frames {
match f {
HFrame::MaxPushId { .. } => {
// TODO implement push
Ok(())
}
HFrame::Goaway { .. } | HFrame::CancelPush { .. } => {
Err(Error::HttpFrameUnexpected)
}
HFrame::PriorityUpdatePush { element_id, priority } => {
// TODO: check if the element_id references a promised push stream or
// is greater than the maximum Push ID.
self.events.priority_update(StreamId::from(element_id), priority);
Ok(())
}
HFrame::PriorityUpdateRequest { element_id, priority } => {
// check that the element_id references a request stream
// within the client-sided bidirectional stream limit
let element_stream_id = StreamId::new(element_id);
if !element_stream_id.is_bidi()
|| !element_stream_id.is_client_initiated()
|| !conn.is_stream_id_allowed(element_stream_id)
{
return Err(Error::HttpId)
}
self.events.priority_update(element_stream_id, priority);
Ok(())
}
_ => unreachable!(
"we should only put MaxPushId, Goaway and PriorityUpdates into control_frames"
),
}?;
}
Ok(())
}
_ => Ok(()),
}
}