Skip to content

Commit 70eade5

Browse files
authored
Add too_many_resets debug_data to the GOAWAY we send (#678)
Closes hyperium/hyper#3211
1 parent b0e5470 commit 70eade5

File tree

8 files changed

+33
-72
lines changed

8 files changed

+33
-72
lines changed

src/frame/go_away.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,11 @@ impl GoAway {
2020
}
2121
}
2222

23-
#[doc(hidden)]
24-
#[cfg(feature = "unstable")]
25-
pub fn with_debug_data(self, debug_data: impl Into<Bytes>) -> Self {
23+
pub fn with_debug_data(last_stream_id: StreamId, reason: Reason, debug_data: Bytes) -> Self {
2624
Self {
27-
debug_data: debug_data.into(),
28-
..self
25+
last_stream_id,
26+
error_code: reason,
27+
debug_data,
2928
}
3029
}
3130

src/proto/connection.rs

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -398,16 +398,10 @@ where
398398
self.go_away.go_away_now(frame);
399399
}
400400

401-
#[doc(hidden)]
402-
#[cfg(feature = "unstable")]
403-
fn go_away_now_debug_data(&mut self) {
401+
fn go_away_now_data(&mut self, e: Reason, data: Bytes) {
404402
let last_processed_id = self.streams.last_processed_id();
405-
406-
let frame = frame::GoAway::new(last_processed_id, Reason::NO_ERROR)
407-
.with_debug_data("something went wrong");
408-
409-
self.streams.send_go_away(last_processed_id);
410-
self.go_away.go_away(frame);
403+
let frame = frame::GoAway::with_debug_data(last_processed_id, e, data);
404+
self.go_away.go_away_now(frame);
411405
}
412406

413407
fn go_away_from_user(&mut self, e: Reason) {
@@ -430,7 +424,7 @@ where
430424
// error. This is handled by setting a GOAWAY frame followed by
431425
// terminating the connection.
432426
Err(Error::GoAway(debug_data, reason, initiator)) => {
433-
let e = Error::GoAway(debug_data, reason, initiator);
427+
let e = Error::GoAway(debug_data.clone(), reason, initiator);
434428
tracing::debug!(error = ?e, "Connection::poll; connection error");
435429

436430
// We may have already sent a GOAWAY for this error,
@@ -447,7 +441,7 @@ where
447441

448442
// Reset all active streams
449443
self.streams.handle_error(e);
450-
self.go_away_now(reason);
444+
self.go_away_now_data(reason, debug_data);
451445
Ok(())
452446
}
453447
// Attempting to read a frame resulted in a stream level error.
@@ -588,17 +582,6 @@ where
588582
// for a pong before proceeding.
589583
self.inner.ping_pong.ping_shutdown();
590584
}
591-
592-
#[doc(hidden)]
593-
#[cfg(feature = "unstable")]
594-
pub fn go_away_debug_data(&mut self) {
595-
if self.inner.go_away.is_going_away() {
596-
return;
597-
}
598-
599-
self.inner.as_dyn().go_away_now_debug_data();
600-
self.inner.ping_pong.ping_shutdown();
601-
}
602585
}
603586

604587
impl<T, P, B> Drop for Connection<T, P, B>

src/proto/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ impl Error {
4040
Self::GoAway(Bytes::new(), reason, Initiator::Library)
4141
}
4242

43+
pub(crate) fn library_go_away_data(reason: Reason, debug_data: impl Into<Bytes>) -> Self {
44+
Self::GoAway(debug_data.into(), reason, Initiator::Library)
45+
}
46+
4347
pub(crate) fn remote_reset(stream_id: StreamId, reason: Reason) -> Self {
4448
Self::Reset(stream_id, reason, Initiator::Remote)
4549
}

src/proto/streams/recv.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,10 @@ impl Recv {
763763
"recv_reset; remotely-reset pending-accept streams reached limit ({:?})",
764764
counts.max_remote_reset_streams(),
765765
);
766-
return Err(Error::library_go_away(Reason::ENHANCE_YOUR_CALM));
766+
return Err(Error::library_go_away_data(
767+
Reason::ENHANCE_YOUR_CALM,
768+
"too_many_resets",
769+
));
767770
}
768771
}
769772

src/server.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -544,12 +544,6 @@ where
544544
self.connection.go_away_gracefully();
545545
}
546546

547-
#[doc(hidden)]
548-
#[cfg(feature = "unstable")]
549-
pub fn debug_data_shutdown(&mut self) {
550-
self.connection.go_away_debug_data();
551-
}
552-
553547
/// Takes a `PingPong` instance from the connection.
554548
///
555549
/// # Note

tests/h2-support/src/frames.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,11 +309,19 @@ impl Mock<frame::GoAway> {
309309
where
310310
I: Into<Bytes>,
311311
{
312-
Mock(self.0.with_debug_data(debug_data.into()))
312+
Mock(frame::GoAway::with_debug_data(
313+
self.0.last_stream_id(),
314+
self.0.reason(),
315+
debug_data.into(),
316+
))
313317
}
314318

315319
pub fn reason(self, reason: frame::Reason) -> Self {
316-
Mock(frame::GoAway::new(self.0.last_stream_id(), reason))
320+
Mock(frame::GoAway::with_debug_data(
321+
self.0.last_stream_id(),
322+
reason,
323+
self.0.debug_data().clone(),
324+
))
317325
}
318326
}
319327

tests/h2-tests/tests/server.rs

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -705,41 +705,6 @@ async fn graceful_shutdown() {
705705
join(client, srv).await;
706706
}
707707

708-
#[tokio::test]
709-
async fn go_away_sends_debug_data() {
710-
h2_support::trace_init!();
711-
712-
let (io, mut client) = mock::new();
713-
714-
let client = async move {
715-
let settings = client.assert_server_handshake().await;
716-
assert_default_settings!(settings);
717-
client
718-
.send_frame(frames::headers(1).request("POST", "https://example.com/"))
719-
.await;
720-
client
721-
.recv_frame(frames::go_away(1).no_error().data("something went wrong"))
722-
.await;
723-
};
724-
725-
let src = async move {
726-
let mut srv = server::handshake(io).await.expect("handshake");
727-
let (_req, _tx) = srv.next().await.unwrap().expect("server receives request");
728-
729-
srv.debug_data_shutdown();
730-
731-
let srv_fut = async move {
732-
poll_fn(move |cx| srv.poll_closed(cx))
733-
.await
734-
.expect("server");
735-
};
736-
737-
srv_fut.await
738-
};
739-
740-
join(client, src).await;
741-
}
742-
743708
#[tokio::test]
744709
async fn goaway_even_if_client_sent_goaway() {
745710
h2_support::trace_init!();

tests/h2-tests/tests/stream_states.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,14 @@ async fn reset_streams_dont_grow_memory_continuously() {
211211
.await;
212212
client.send_frame(frames::reset(n).protocol_error()).await;
213213
}
214+
214215
tokio::time::timeout(
215216
std::time::Duration::from_secs(1),
216-
client.recv_frame(frames::go_away((MAX * 2 + 1) as u32).calm()),
217+
client.recv_frame(
218+
frames::go_away((MAX * 2 + 1) as u32)
219+
.data("too_many_resets")
220+
.calm(),
221+
),
217222
)
218223
.await
219224
.expect("client goaway");

0 commit comments

Comments
 (0)