use bytes::Buf; use std::io; use std::task::{Context, Poll}; use tokio::io::AsyncWrite;
/// Manages our sending of GOAWAY frames. #[derive(Debug)] pub(super) struct GoAway { /// Whether the connection should close now, or wait until idle.
close_now: bool, /// Records if we've sent any GOAWAY before.
going_away: Option<GoingAway>, /// Whether the user started the GOAWAY by calling `abrupt_shutdown`.
is_user_initiated: bool, /// A GOAWAY frame that must be buffered in the Codec immediately.
pending: Option<frame::GoAway>,
}
/// Keeps a memory of any GOAWAY frames we've sent before. /// /// This looks very similar to a `frame::GoAway`, but is a separate type. Why? /// Mostly for documentation purposes. This type is to record status. If it /// were a `frame::GoAway`, it might appear like we eventually wanted to /// serialize it. We **only** want to be able to look up these fields at a /// later time. #[derive(Debug)] pub(crate) struct GoingAway { /// Stores the highest stream ID of a GOAWAY that has been sent. /// /// It's illegal to send a subsequent GOAWAY with a higher ID.
last_processed_id: StreamId,
/// Records the error code of any GOAWAY frame sent.
reason: Reason,
}
/// Returns the going away info, if any. pubfn going_away(&self) -> Option<&GoingAway> { self.going_away.as_ref()
}
/// Returns if the connection should close now, or wait until idle. pubfn should_close_now(&self) -> bool { self.pending.is_none() && self.close_now
}
/// Returns if the connection should be closed when idle. pubfn should_close_on_idle(&self) -> bool {
!self.close_now
&& self
.going_away
.as_ref()
.map(|g| g.last_processed_id != StreamId::MAX)
.unwrap_or(false)
}
/// Try to write a pending GOAWAY frame to the buffer. /// /// If a frame is written, the `Reason` of the GOAWAY is returned. pubfn send_pending_go_away<T, B>(
&mutself,
cx: &mut Context,
dst: &mut Codec<T, B>,
) -> Poll<Option<io::Result<Reason>>> where
T: AsyncWrite + Unpin,
B: Buf,
{ iflet Some(frame) = self.pending.take() { if !dst.poll_ready(cx)?.is_ready() { self.pending = Some(frame); return Poll::Pending;
}
let reason = frame.reason();
dst.buffer(frame.into()).expect("invalid GOAWAY frame");
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.