From 01bda1d59473e25b88095afea359e2c3530de1b5 Mon Sep 17 00:00:00 2001 From: Amos Wenger Date: Tue, 15 Mar 2022 15:08:46 +0100 Subject: [PATCH 1/2] Add a new constructor and an accessor to `Upgrade` Upgrading to HTTP/2.0 is common enough that I feel it should get its own constructor. Because the client can send values other than "websocket" as a request header, I feel like having a getter for the inner value is important. --- src/common/upgrade.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/common/upgrade.rs b/src/common/upgrade.rs index 8002b68b..1ed1b7cf 100644 --- a/src/common/upgrade.rs +++ b/src/common/upgrade.rs @@ -52,4 +52,23 @@ impl Upgrade { pub fn websocket() -> Upgrade { Upgrade(HeaderValue::from_static("websocket")) } + + /// Constructs an `Upgrade: HTTP/2.0` header. + pub fn http2() -> Upgrade { + // must be uppercase, see + // + Upgrade(HeaderValue::from_static("HTTP/2.0")) + } + + /// Constructs an `Upgrade` header with the given `HeaderValue` + pub fn new(value: HeaderValue) -> Upgrade { + Upgrade(value) + } + + /// Returns the header value, e.g. "websocket" or "HTTP/2.0", or a + /// comma-separated list of protocols, see RFC 7230: + /// + pub fn value(&self) -> &HeaderValue { + &self.0 + } } From 2b8d43afb18724bcf1de1d68c93fa93c3a6617ae Mon Sep 17 00:00:00 2001 From: Amos Wenger Date: Tue, 15 Mar 2022 21:41:23 +0100 Subject: [PATCH 2/2] Only provide h2c constructor, return an Option<&str> rather than a HeaderValue --- src/common/upgrade.rs | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/common/upgrade.rs b/src/common/upgrade.rs index 1ed1b7cf..06836619 100644 --- a/src/common/upgrade.rs +++ b/src/common/upgrade.rs @@ -53,11 +53,11 @@ impl Upgrade { Upgrade(HeaderValue::from_static("websocket")) } - /// Constructs an `Upgrade: HTTP/2.0` header. - pub fn http2() -> Upgrade { - // must be uppercase, see - // - Upgrade(HeaderValue::from_static("HTTP/2.0")) + /// Constructs an `Upgrade: h2c` header, for HTTP/2 over TCP. There's no + /// constructor for HTTP/2 over TLS, as using ALPN or prior knowledge is + /// better-suited to that usecase. + pub fn h2c() -> Upgrade { + Upgrade(HeaderValue::from_static("h2c")) } /// Constructs an `Upgrade` header with the given `HeaderValue` @@ -65,10 +65,27 @@ impl Upgrade { Upgrade(value) } - /// Returns the header value, e.g. "websocket" or "HTTP/2.0", or a - /// comma-separated list of protocols, see RFC 7230: + /// Returns the header value, e.g. "websocket" or "h2c", or a + /// comma-separated list, see RFC 7230: /// - pub fn value(&self) -> &HeaderValue { - &self.0 + /// + /// If the header value cannot be represented as a utf-8 string, + /// `None` is returned. + pub fn to_str(&self) -> Option<&str> { + self.0.to_str().ok() + } +} + +#[cfg(test)] +mod tests { + use super::super::test_decode; + use super::*; + + #[test] + fn websocket() { + let s = "websocket"; + let loc = test_decode::(&[s]).unwrap(); + + assert_eq!(loc.to_str(), Some(s)); } }