in neqo-http3/src/connection_client.rs [3368:3449]
fn goaway() {
let (mut client, mut server) = connect();
let request_stream_id_1 = make_request(&mut client, false, &[]);
assert_eq!(request_stream_id_1, 0);
let request_stream_id_2 = make_request(&mut client, false, &[]);
assert_eq!(request_stream_id_2, 4);
let request_stream_id_3 = make_request(&mut client, false, &[]);
assert_eq!(request_stream_id_3, 8);
let out = client.process_output(now());
drop(server.conn.process(out.dgram(), now()));
_ = server
.conn
.stream_send(server.control_stream_id.unwrap(), &[0x7, 0x1, 0x8])
.unwrap();
// find the new request/response stream and send frame v on it.
while let Some(e) = server.conn.next_event() {
if let ConnectionEvent::RecvStreamReadable { stream_id } = e {
let mut buf = [0_u8; 100];
_ = server.conn.stream_recv(stream_id, &mut buf).unwrap();
if (stream_id == request_stream_id_1) || (stream_id == request_stream_id_2) {
// send response - 200 Content-Length: 7
// with content: 'abcdefg'.
// The content will be send in 2 DATA frames.
_ = server.conn.stream_send(stream_id, HTTP_RESPONSE_1).unwrap();
server.conn.stream_close_send(stream_id).unwrap();
}
}
}
let out = server.conn.process_output(now());
client.process(out.dgram(), now());
let mut stream_reset = false;
while let Some(e) = client.next_event() {
match e {
Http3ClientEvent::HeaderReady { headers, fin, .. } => {
check_response_header_1(&headers);
assert!(!fin);
}
Http3ClientEvent::DataReadable { stream_id } => {
assert!(
(stream_id == request_stream_id_1) || (stream_id == request_stream_id_2)
);
let mut buf = [0_u8; 100];
assert_eq!(
(EXPECTED_RESPONSE_DATA_1.len(), true),
client.read_data(now(), stream_id, &mut buf).unwrap()
);
}
Http3ClientEvent::Reset {
stream_id,
error,
local,
} => {
assert_eq!(stream_id, request_stream_id_3);
assert_eq!(error, Error::HttpRequestRejected.code());
assert!(!local);
stream_reset = true;
}
_ => {}
}
}
assert!(stream_reset);
assert_eq!(client.state(), Http3State::GoingAway(StreamId::new(8)));
// Check that a new request cannot be made.
assert_eq!(
client.fetch(
now(),
"GET",
&("https", "something.com", "/"),
&[],
Priority::default()
),
Err(Error::AlreadyClosed)
);
client.close(now(), 0, "");
}