commit 97c5ed3c963f0b43775a008d9120779b31dda96d
parent 10f519f933411749defbc118956c28dc910addef
Author: Kershaw Chang <kershaw@mozilla.com>
Date: Sun, 4 Jan 2026 20:16:21 +0000
Bug 2000787 - Using stable connection ID from StreamHandler::conn, r=mxinden,necko-reviewers,valentin
Differential Revision: https://phabricator.services.mozilla.com/D277758
Diffstat:
2 files changed, 41 insertions(+), 35 deletions(-)
diff --git a/netwerk/test/http3server/src/main.rs b/netwerk/test/http3server/src/main.rs
@@ -7,7 +7,7 @@
use base64::prelude::*;
use neqo_bin::server::{HttpServer, Runner};
use neqo_common::Bytes;
-use neqo_common::{event::Provider, qdebug, qinfo, qtrace, qerror, Datagram, Header};
+use neqo_common::{event::Provider, qdebug, qerror, qinfo, qtrace, Datagram, Header};
use neqo_crypto::{generate_ech_keys, init_db, AllowZeroRtt, AntiReplay};
use neqo_http3::{
ConnectUdpRequest, ConnectUdpServerEvent, Error, Http3OrWebTransportStream, Http3Parameters,
@@ -70,7 +70,6 @@ struct Http3TestServer {
posts: HashMap<Http3OrWebTransportStream, usize>,
responses: HashMap<Http3OrWebTransportStream, Vec<u8>>,
connections_to_close: HashMap<Instant, Vec<ConnectionRef>>,
- current_connection_hash: u64,
sessions_to_close: HashMap<Instant, Vec<WebTransportRequest>>,
sessions_to_create_stream: Vec<(WebTransportRequest, StreamType, Option<Vec<u8>>)>,
webtransport_bidi_stream: HashSet<Http3OrWebTransportStream>,
@@ -91,7 +90,6 @@ impl Http3TestServer {
posts: HashMap::new(),
responses: HashMap::new(),
connections_to_close: HashMap::new(),
- current_connection_hash: 0,
sessions_to_close: HashMap::new(),
sessions_to_create_stream: Vec::new(),
webtransport_bidi_stream: HashSet::new(),
@@ -231,6 +229,12 @@ impl HttpServer for Http3TestServer {
} => {
qtrace!("Headers (request={} fin={}): {:?}", stream, fin, headers);
+ let connection_hash = {
+ let mut hasher = DefaultHasher::new();
+ stream.conn.hash(&mut hasher);
+ hasher.finish()
+ };
+
// Some responses do not have content-type. This is on purpose to exercise
// UnknownDecoder code.
let default_ret = b"Hello World".to_vec();
@@ -238,17 +242,17 @@ impl HttpServer for Http3TestServer {
Header::new(":status", "200"),
Header::new("cache-control", "no-cache"),
Header::new("content-length", default_ret.len().to_string()),
- Header::new(
- "x-http3-conn-hash",
- self.current_connection_hash.to_string(),
- ),
+ Header::new("x-http3-conn-hash", connection_hash.to_string()),
];
let path_hdr = headers.iter().find(|&h| h.name() == ":path");
match path_hdr {
Some(ph) if !ph.value().is_empty() => {
let path = ph.value();
- qtrace!("Serve request {:?}", ph.value_utf8().unwrap_or("<invalid utf8>"));
+ qtrace!(
+ "Serve request {:?}",
+ ph.value_utf8().unwrap_or("<invalid utf8>")
+ );
if path == b"/Response421" {
let response_body = b"0123456789".to_vec();
stream
@@ -373,18 +377,17 @@ impl HttpServer for Http3TestServer {
Header::new(":status", "200"),
Header::new("cache-control", "no-cache"),
Header::new("content-type", "text/plain"),
- Header::new("priority-mirror", priority.value_utf8().unwrap()),
+ Header::new(
+ "priority-mirror",
+ priority.value_utf8().unwrap(),
+ ),
Header::new(
"content-length",
priority.value().len().to_string(),
),
])
.unwrap();
- self.new_response(
- stream,
- priority.value().to_vec(),
- now,
- );
+ self.new_response(stream, priority.value().to_vec(), now);
} else {
stream
.send_headers(&[
@@ -460,7 +463,9 @@ impl HttpServer for Http3TestServer {
self.new_response(stream, vec![b'a'; 100], now);
}
} else {
- match ph.value_utf8().ok().and_then(|s| s.trim_matches(|p| p == '/').parse::<usize>().ok()) {
+ match ph.value_utf8().ok().and_then(|s| {
+ s.trim_matches(|p| p == '/').parse::<usize>().ok()
+ }) {
Some(v) => {
stream
.send_headers(&[
@@ -524,13 +529,7 @@ impl HttpServer for Http3TestServer {
Http3ServerEvent::DataWritable { stream } => {
self.handle_stream_writable(stream, now)
}
- Http3ServerEvent::StateChange { conn, state } => {
- if matches!(state, neqo_http3::Http3State::Connected) {
- let mut h = DefaultHasher::new();
- conn.hash(&mut h);
- self.current_connection_hash = h.finish();
- }
- }
+ Http3ServerEvent::StateChange { .. } => {}
Http3ServerEvent::PriorityUpdate { .. } => {}
Http3ServerEvent::StreamReset { stream, error } => {
qtrace!("Http3ServerEvent::StreamReset {:?} {:?}", stream, error);
@@ -555,7 +554,10 @@ impl HttpServer for Http3TestServer {
match path_hdr {
Some(ph) if !ph.value().is_empty() => {
let path = ph.value();
- qtrace!("Serve request {:?}", ph.value_utf8().unwrap_or("<invalid utf8>"));
+ qtrace!(
+ "Serve request {:?}",
+ ph.value_utf8().unwrap_or("<invalid utf8>")
+ );
if path == b"/success" {
session.response(&SessionAcceptAction::Accept, now).unwrap();
} else if path == b"/redirect" {
@@ -997,7 +999,9 @@ impl HttpServer for Http3ReverseProxyServer {
let content_length =
headers.iter().find(|&h| h.name() == "content-length");
if let Some(length_str) = content_length {
- if let Ok(len) = length_str.value_utf8().unwrap_or("0").parse::<u32>() {
+ if let Ok(len) =
+ length_str.value_utf8().unwrap_or("0").parse::<u32>()
+ {
if len > 0 {
self.requests.insert(stream, (headers, Vec::new()));
} else {
@@ -1275,7 +1279,11 @@ impl HttpServer for Http3ConnectProxyServer {
reason,
headers: _,
}) => {
- qdebug!("ConnectUdp session closed: {:?} reason: {:?}", session, reason);
+ qdebug!(
+ "ConnectUdp session closed: {:?} reason: {:?}",
+ session,
+ reason
+ );
self.udp_sockets.remove(&session.stream_id());
}
Http3ServerEvent::StateChange { .. } | Http3ServerEvent::PriorityUpdate { .. } => {}
@@ -1407,7 +1415,11 @@ impl HttpServer for Http3ConnectProxyServer {
progressed = true;
}
Poll::Ready(Err(e)) => {
- qerror!("Error sending UDP datagram: {} {:?}, closing socket", e, socket.socket);
+ qerror!(
+ "Error sending UDP datagram: {} {:?}, closing socket",
+ e,
+ socket.socket
+ );
failed_udp_sockets.push(*stream_id);
break;
}
@@ -1420,7 +1432,9 @@ impl HttpServer for Http3ConnectProxyServer {
if let Some(socket) = self.udp_sockets.remove(&stream_id) {
qdebug!("Removed failed UDP socket for stream {}", stream_id);
// Close the session with an error code
- let _ = socket.session.close_session(0x0100, "UDP socket error", Instant::now());
+ let _ = socket
+ .session
+ .close_session(0x0100, "UDP socket error", Instant::now());
}
}
diff --git a/netwerk/test/unit/test_http3_coalescing.js b/netwerk/test/unit/test_http3_coalescing.js
@@ -68,14 +68,6 @@ function channelOpenPromise(chan, flags) {
}
async function H3CoalescingTest(host1, host2) {
- // Disable PMTUD (Path MTU Discovery) to avoid race condition between DNS
- // resolution (to validate whether we can coalesce) and new connection
- // attempt. Long term one might not want to start the new connection attempt
- // in the first place.
- //
- // See Bug 1909910 for more details.
- Services.prefs.setBoolPref("network.http.http3.pmtud", false);
-
Services.prefs.setCharPref(
"network.http.http3.alt-svc-mapping-for-testing",
`${host1};h3=:${h3Port}`