Skip to content

Commit bae9de9

Browse files
committed
feat(http3): support classic HTTP CONNECT
1 parent a102f3f commit bae9de9

File tree

1 file changed

+30
-13
lines changed

1 file changed

+30
-13
lines changed

neqo-http3/src/connection.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,7 @@ impl Http3Connection {
770770
output
771771
}
772772

773+
// TODO: Rename?
773774
fn create_fetch_headers<'b, 't, T>(request: &RequestDescription<'b, 't, T>) -> Res<Vec<Header>>
774775
where
775776
T: AsRequestTarget<'t> + ?Sized + Debug,
@@ -780,12 +781,28 @@ impl Http3Connection {
780781
.map_err(|_| Error::InvalidRequestTarget)?;
781782

782783
// Transform pseudo-header fields
783-
let mut final_headers = vec![
784-
Header::new(":method", request.method),
785-
Header::new(":scheme", target.scheme()),
786-
Header::new(":authority", target.authority()),
787-
Header::new(":path", target.path()),
788-
];
784+
// TODO: Remove hack for classic CONNECT
785+
let is_classic_connect = request.connect_type.is_none()
786+
&& request
787+
.headers
788+
.iter()
789+
.any(|h| h.name() == ":method" && h.value() == "CONNECT");
790+
let mut final_headers = if is_classic_connect {
791+
// > The :scheme and :path pseudo-header fields are omitted
792+
//
793+
// <https://datatracker.ietf.org/doc/html/rfc9114#section-4.4>
794+
vec![
795+
Header::new(":method", request.method),
796+
Header::new(":authority", target.authority()),
797+
]
798+
} else {
799+
vec![
800+
Header::new(":method", request.method),
801+
Header::new(":scheme", target.scheme()),
802+
Header::new(":authority", target.authority()),
803+
Header::new(":path", target.path()),
804+
]
805+
};
789806
if let Some(conn_type) = request.connect_type {
790807
final_headers.push(Header::new(":protocol", conn_type.string()));
791808
}
@@ -847,6 +864,7 @@ impl Http3Connection {
847864
{
848865
let final_headers = Self::create_fetch_headers(request)?;
849866

867+
// TODO: Why is this here? WebTransport goes a different route, no?
850868
let stream_type = if request.connect_type.is_some() {
851869
Http3StreamType::ExtendedConnect
852870
} else {
@@ -1109,7 +1127,6 @@ impl Http3Connection {
11091127
where
11101128
T: AsRequestTarget<'x> + ?Sized + Debug,
11111129
{
1112-
11131130
let id = self.create_bidi_transport_stream(conn)?;
11141131

11151132
let extended_conn = Rc::new(RefCell::new(Session::new(
@@ -1632,11 +1649,7 @@ impl Http3Connection {
16321649
Ok(())
16331650
}
16341651

1635-
fn remove_extended_connect(
1636-
&mut self,
1637-
wt: &Rc<RefCell<Session>>,
1638-
conn: &mut Connection,
1639-
) {
1652+
fn remove_extended_connect(&mut self, wt: &Rc<RefCell<Session>>, conn: &mut Connection) {
16401653
let (recv, send) = wt.borrow_mut().take_sub_streams();
16411654

16421655
#[expect(
@@ -1690,7 +1703,11 @@ impl Http3Connection {
16901703
let stream = self.send_streams.remove(&stream_id);
16911704
if let Some(s) = &stream {
16921705
if s.stream_type() == Http3StreamType::ExtendedConnect {
1693-
if let Some(wt) = self.recv_streams.remove(&stream_id)?.extended_connect_session() {
1706+
if let Some(wt) = self
1707+
.recv_streams
1708+
.remove(&stream_id)?
1709+
.extended_connect_session()
1710+
{
16941711
self.remove_extended_connect(&wt, conn);
16951712
}
16961713
}

0 commit comments

Comments
 (0)