/// Supply a response for a request. /// /// # Errors /// /// `InvalidStreamId` if the stream does not exist, /// `AlreadyClosed` if the stream has already been closed. /// `TransportStreamDoesNotExist` if the transport stream does not exist (this may happen if /// `process_output` has not been called when needed, and HTTP3 layer has not picked up the /// info that the stream has been closed.) `InvalidInput` if an empty buffer has been /// supplied. pub(crate) fn send_data(
&mutself,
stream_id: StreamId,
data: &[u8],
conn: &mut Connection,
) -> Res<usize> { let n = self
.base_handler
.send_streams
.get_mut(&stream_id)
.ok_or(Error::InvalidStreamId)?
.send_data(conn, data)?; if n > 0 { self.base_handler.stream_has_pending_data(stream_id);
} self.needs_processing = true;
Ok(n)
}
/// This is called when application is done sending a request. /// /// # Errors /// /// An error will be returned if stream does not exist. pubfn stream_close_send(&mutself, stream_id: StreamId, conn: &an style='color:red'>mut Connection) -> Res<()> {
qdebug!([self], "Close sending side stream={}.", stream_id); self.base_handler.stream_close_send(conn, stream_id)?; self.needs_processing = true;
Ok(())
}
/// An application may reset a stream(request). /// Both sides, sending and receiving side, will be closed. /// /// # Errors /// /// An error will be return if a stream does not exist. pubfn cancel_fetch(
&mutself,
stream_id: StreamId,
error: AppError,
conn: &mut Connection,
) -> Res<()> {
qinfo!([self], "cancel_fetch {} error={}.", stream_id, error); self.needs_processing = true; self.base_handler.cancel_fetch(stream_id, error, conn)
}
/// Close `WebTransport` cleanly /// /// # Errors /// /// `InvalidStreamId` if the stream does not exist, /// `TransportStreamDoesNotExist` if the transport stream does not exist (this may happen if /// `process_output` has not been called when needed, and HTTP3 layer has not picked up the /// info that the stream has been closed.) `InvalidInput` if an empty buffer has been /// supplied. pubfn webtransport_close_session(
&mutself,
conn: &mut Connection,
session_id: StreamId,
error: u32,
message: &str,
) -> Res<()> { self.needs_processing = true; self.base_handler
.webtransport_close_session(conn, session_id, error, message)
}
let res = self.check_connection_events(conn, now); if !self.check_result(conn, now, &res) && self.base_handler.state().active() { let res = self.base_handler.process_sending(conn); self.check_result(conn, now, &res);
}
}
/// Take the next available event. pub(crate) fn next_event(&self) -> Option<Http3ServerConnEvent> { self.events.next_event()
}
/// Whether this connection has events to process or data to send. pub(crate) fn should_be_processed(&mutself) -> bool { ifself.needs_processing { self.needs_processing = false; returntrue;
} self.base_handler.has_data_to_send() || self.events.has_events()
}
// This function takes the provided result and check for an error. // An error results in closing the connection. fn check_result<ERR>(&mutself, conn: &mutConnection, now: Instant, res: &Res<ERR>) -> bool { match &res {
Err(e) => { self.close(conn, now, e); true
}
_ => false,
}
}
fn handle_stream_readable(&mutself, conn: &mut Connection, stream_id: StreamId) -> Res<()> { matchself.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, self.base_handler.qpack_encoder.clone(), 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(()),
}
}
/// Response data are read directly into a buffer supplied as a parameter of this function to /// avoid copying data. /// /// # Errors /// /// It returns an error if a stream does not exist or an error happen while reading a stream, /// e.g. early close, protocol error, etc. pubfn read_data(
&mutself,
conn: &mut Connection,
now: Instant,
stream_id: StreamId,
buf: &mut [u8],
) -> Res<(usize, bool)> {
qdebug!([self], "read_data from stream {}.", stream_id); let res = self.base_handler.read_data(conn, stream_id, buf); iflet Err(e) = &res { if e.connection_error() { self.close(conn, now, e);
}
}
res
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.28 Sekunden
(vorverarbeitet am 2026-06-19)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.