Skip to content

Commit

Permalink
Initial support for RFC 9298 "Proxying UDP in HTTP" (#203)
Browse files Browse the repository at this point in the history
* Add support for RFC 9298 in :protocol extension

* bugfix: Properly encode :protocol header

Previously, the `:protocol` header wouldn't be set when the `Protocol`
extension was active for a `Request`.

This was most likely because the Webtransport PR (the PR that introduced
the `Protocol` extension) did not include a client implementation and
thus did not test this.

---------
  • Loading branch information
dongcarl committed Jul 11, 2023
1 parent 58c8e5c commit 5a87580
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
13 changes: 13 additions & 0 deletions h3/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,23 @@ pub struct Protocol(ProtocolInner);
impl Protocol {
/// WebTransport protocol
pub const WEB_TRANSPORT: Protocol = Protocol(ProtocolInner::WebTransport);
/// RFC 9298 protocol
pub const CONNECT_UDP: Protocol = Protocol(ProtocolInner::ConnectUdp);

/// Return a &str representation of the `:protocol` pseudo-header value
#[inline]
pub fn as_str(&self) -> &str {
match self.0 {
ProtocolInner::WebTransport => "webtransport",
ProtocolInner::ConnectUdp => "connect-udp",
}
}
}

#[derive(Copy, PartialEq, Debug, Clone)]
enum ProtocolInner {
WebTransport,
ConnectUdp,
}

/// Error when parsing the protocol
Expand All @@ -36,6 +48,7 @@ impl FromStr for Protocol {
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"webtransport" => Ok(Self(ProtocolInner::WebTransport)),
"connect-udp" => Ok(Self(ProtocolInner::ConnectUdp)),
_ => Err(InvalidProtocol),
}
}
Expand Down
4 changes: 4 additions & 0 deletions h3/src/proto/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ impl Iterator for HeaderIter {
if let Some(status) = pseudo.status.take() {
return Some((":status", status.as_str()).into());
}

if let Some(protocol) = pseudo.protocol.take() {
return Some((":protocol", protocol.as_str().as_bytes()).into());
}
}

self.pseudo = None;
Expand Down

0 comments on commit 5a87580

Please sign in to comment.