fn connect_peers(hconn_c: &mut Http3Client, hconn_s: &='color:red'>mut Http3Server) -> Option<Datagram> {
assert_eq!(hconn_c.state(), Http3State::Initializing); let out = hconn_c.process_output(now()); // Initial let out = hconn_s.process(out.dgram(), now()); // Initial + Handshake let out = hconn_c.process(out.dgram(), now()); // ACK
mem::drop(hconn_s.process(out.dgram(), now())); // consume ACK let authentication_needed = |e| matches!(e, Http3ClientEvent::AuthenticationNeeded);
assert!(hconn_c.events().any(authentication_needed));
hconn_c.authenticated(AuthenticationStatus::Ok, now()); let out = hconn_c.process_output(now()); // Handshake
assert_eq!(hconn_c.state(), Http3State::Connected); let out = hconn_s.process(out.dgram(), now()); // Handshake let out = hconn_c.process(out.dgram(), now()); let out = hconn_s.process(out.dgram(), now()); // assert!(hconn_s.settings_received); let out = hconn_c.process(out.dgram(), now()); // assert!(hconn_c.settings_received);
out.dgram()
}
fn connect_peers_with_network_propagation_delay(
hconn_c: &mut Http3Client,
hconn_s: &mut Http3Server,
net_delay: u64,
) -> (Option<Datagram>, Instant) { let net_delay = Duration::from_millis(net_delay);
assert_eq!(hconn_c.state(), Http3State::Initializing); letmut now = now(); let out = hconn_c.process_output(now); // Initial
now += net_delay; let out = hconn_s.process(out.dgram(), now); // Initial + Handshake
now += net_delay; let out = hconn_c.process(out.dgram(), now); // ACK
now += net_delay; let out = hconn_s.process(out.dgram(), now); // consume ACK
assert!(out.dgram().is_none()); let authentication_needed = |e| matches!(e, Http3ClientEvent::AuthenticationNeeded);
assert!(hconn_c.events().any(authentication_needed));
now += net_delay;
hconn_c.authenticated(AuthenticationStatus::Ok, now); let out = hconn_c.process_output(now); // Handshake
assert_eq!(hconn_c.state(), Http3State::Connected);
now += net_delay; let out = hconn_s.process(out.dgram(), now); // HANDSHAKE_DONE
now += net_delay; let out = hconn_c.process(out.dgram(), now); // Consume HANDSHAKE_DONE, send control streams.
now += net_delay; let out = hconn_s.process(out.dgram(), now); // consume and send control streams.
now += net_delay; let out = hconn_c.process(out.dgram(), now); // consume control streams.
(out.dgram(), now)
}
set_response(&request); let out = hconn_s.process(None::<Datagram>, now());
mem::drop(hconn_c.process(out.dgram(), now()));
process_client_events(&mut hconn_c);
}
/// Test [`neqo_http3::SendMessage::send_data`] to set /// [`neqo_transport::SendStream::set_writable_event_low_watermark`]. #[allow(clippy::cast_possible_truncation)] #[test] fn data_writable_events_low_watermark() -> Result<(), Box<dyn std::error::Error>> { const STREAM_LIMIT: u64 = 5000; const DATA_FRAME_HEADER_SIZE: usize = 3;
// Create a client and a server. letmut hconn_c = http3_client_with_params(Http3Parameters::default().connection_parameters(
ConnectionParameters::default().max_stream_data(StreamType::BiDi, false, STREAM_LIMIT),
)); letmut hconn_s = default_http3_server();
mem::drop(connect_peers(&mut hconn_c, &>mut hconn_s));
// Client sends GET to server. let stream_id = hconn_c.fetch(
now(), "GET",
&("https", "something.com", "/"),
&[],
Priority::default(),
)?;
hconn_c.stream_close_send(stream_id)?;
exchange_packets(&mut hconn_c, &mut hconn_s, None);
// Server receives GET and responds with headers. let request = receive_request(&hconn_s).unwrap();
request.send_headers(&[Header::new(":status", "200")])?;
// Sending these headers clears the server's send stream buffer and thus // emits a DataWritable event.
exchange_packets(&mut hconn_c, &mut hconn_s, None); let data_writable = |e| {
matches!(
e,
Http3ServerEvent::DataWritable {
stream
} if stream.stream_id() == stream_id
)
};
assert!(hconn_s.events().any(data_writable));
// Have server fill entire send buffer minus 1 byte. let all_but_one = request.available()? - DATA_FRAME_HEADER_SIZE - 1; let buf = vec![1; all_but_one]; let sent = request.send_data(&buf)?;
assert_eq!(sent, all_but_one);
assert_eq!(request.available()?, 1);
// Sending the buffered data clears the send stream buffer and thus emits a // DataWritable event.
exchange_packets(&mut hconn_c, &mut hconn_s, None);
assert!(hconn_s.events().any(data_writable));
// Sending more fails, given that each data frame needs to be preceeded by a // header, i.e. needs more than 1 byte of send space to send 1 byte payload.
assert_eq!(request.available()?, 1);
assert_eq!(request.send_data(&buf)?, 0);
// Have the client read all the pending data. letmut recv_buf = vec![0_u8; all_but_one]; let (recvd, _) = hconn_c.read_data(now(), stream_id, &mut recv_buf)?;
assert_eq!(sent, recvd);
exchange_packets(&mut hconn_c, &mut hconn_s, None);
// Expect the server's available send space to be back to the stream limit.
assert_eq!(request.available()?, STREAM_LIMIT as usize);
// Expect the server to emit a DataWritable event, even though it always had // at least 1 byte available to send, i.e. it never exhausted the entire // available send space.
assert!(hconn_s.events().any(data_writable));
// Send a lot of data let buf = &[1; DATA_AMOUNT]; letmut sent = request.send_data(buf).unwrap();
assert!(sent < DATA_AMOUNT);
// Exchange packets and read the data on the client side.
exchange_packets(&mut hconn_c, &mut hconn_s, None); let stream_id = request.stream_id(); letmut recv_buf = [0_u8; DATA_AMOUNT]; let (mut recvd, _) = hconn_c.read_data(now(), stream_id, &mut recv_buf).unwrap();
assert_eq!(sent, recvd);
exchange_packets(&mut hconn_c, &mut hconn_s, None);
let data_writable = |e| {
matches!(
e,
Http3ServerEvent::DataWritable {
stream
} if stream.stream_id() == stream_id
)
}; // Make sure we have a DataWritable event.
assert!(hconn_s.events().any(data_writable)); // Data can be sent again. let s = request.send_data(&buf[sent..]).unwrap();
assert!(s > 0);
sent += s;
// Exchange packets and read the data on the client side.
exchange_packets(&mut hconn_c, &mut hconn_s, None); let (r, _) = hconn_c
.read_data(now(), stream_id, &mut recv_buf[recvd..])
.unwrap();
recvd += r;
exchange_packets(&mut hconn_c, &mut hconn_s, None);
assert_eq!(sent, recvd);
// One more DataWritable event.
assert!(hconn_s.events().any(data_writable)); // Send more data. let s = request.send_data(&buf[sent..]).unwrap();
assert!(s > 0);
sent += s;
assert_eq!(sent, DATA_AMOUNT);
#[test] /// When a client has an outstanding fetch, it will send keepalives. /// Test that it will successfully run until the connection times out. fn fetch_noresponse_will_idletimeout() { letmut hconn_c = default_http3_client(); letmut hconn_s = default_http3_server();
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.