diff --git a/bindings/rust/s2n-tls/src/connection.rs b/bindings/rust/s2n-tls/src/connection.rs index 6a287a502e0..56bab8f9c88 100644 --- a/bindings/rust/s2n-tls/src/connection.rs +++ b/bindings/rust/s2n-tls/src/connection.rs @@ -947,6 +947,14 @@ impl Connection { }) } + pub fn application_protocol(&self) -> Option<&[u8]> { + let protocol = unsafe { s2n_get_application_protocol(self.connection.as_ptr()) }; + if protocol.is_null() { + return None; + } + Some(unsafe { CStr::from_ptr(protocol).to_bytes() }) + } + /// Provides access to the TLS-Exporter functionality. /// /// See https://datatracker.ietf.org/doc/html/rfc5705 and https://www.rfc-editor.org/rfc/rfc8446. diff --git a/bindings/rust/s2n-tls/src/testing/s2n_tls.rs b/bindings/rust/s2n-tls/src/testing/s2n_tls.rs index 7cab316f35f..82f23b8a6c2 100644 --- a/bindings/rust/s2n-tls/src/testing/s2n_tls.rs +++ b/bindings/rust/s2n-tls/src/testing/s2n_tls.rs @@ -998,4 +998,31 @@ mod tests { Ok(()) } + + #[test] + fn no_application_protocol() -> Result<(), Error> { + let config = config_builder(&security::DEFAULT)?.build()?; + let mut pair = tls_pair(config); + assert!(poll_tls_pair_result(&mut pair).is_ok()); + assert!(pair.server.0.connection.application_protocol().is_none()); + Ok(()) + } + + #[test] + fn application_protocol() -> Result<(), Error> { + let config = config_builder(&security::DEFAULT)?.build()?; + let mut pair = tls_pair(config); + pair.server + .0 + .connection + .set_application_protocol_preference(["http/1.1", "h2"])?; + pair.client + .0 + .connection + .append_application_protocol_preference(b"h2")?; + assert!(poll_tls_pair_result(&mut pair).is_ok()); + let protocol = pair.server.0.connection.application_protocol().unwrap(); + assert_eq!(protocol, b"h2"); + Ok(()) + } }