diff --git a/ylong_http_client/src/async_impl/ssl_stream/c_ssl_stream.rs b/ylong_http_client/src/async_impl/ssl_stream/c_ssl_stream.rs index 8ee6dca6318a8ea1c2947b394cc611598175eb79..75aa3ce0928f2d70a19589ec39dad5a4f87ba45c 100644 --- a/ylong_http_client/src/async_impl/ssl_stream/c_ssl_stream.rs +++ b/ylong_http_client/src/async_impl/ssl_stream/c_ssl_stream.rs @@ -46,6 +46,10 @@ impl AsyncSslStream { // SAFETY: unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().0.get_mut().stream) } } + + pub(crate) fn negotiated_alpn_protocol(&self) -> Option<&[u8]> { + self.0.ssl().negotiated_alpn_protocol() + } } impl AsyncSslStream diff --git a/ylong_http_client/src/util/c_openssl/ffi/ssl.rs b/ylong_http_client/src/util/c_openssl/ffi/ssl.rs index 3af302050d38a020f7e56abcdb9919b743933caf..c02eafe28824e1cfee52eb865eaef5a5cb83f4db 100644 --- a/ylong_http_client/src/util/c_openssl/ffi/ssl.rs +++ b/ylong_http_client/src/util/c_openssl/ffi/ssl.rs @@ -79,11 +79,18 @@ extern "C" { /// Client sets the list of protocols available to be negotiated. pub(crate) fn SSL_CTX_set_alpn_protos( - s: *mut SSL_CTX, + ctx: *mut SSL_CTX, data: *const c_uchar, len: c_uint, ) -> c_int; + /// returns the selected protocol. It is not NUL-terminated. + pub(crate) fn SSL_get0_alpn_selected( + ssl: *const SSL, + data: *mut *const c_uchar, + len: *mut c_uint, + ); + /// Sets/replaces the certificate verification storage of ctx to/with store. /// If another X509_STORE object is currently set in ctx, it will be /// X509_STORE_free()ed. diff --git a/ylong_http_client/src/util/c_openssl/ssl/ssl_base.rs b/ylong_http_client/src/util/c_openssl/ssl/ssl_base.rs index 1f65d12706a979c03214e4ee1b95a7470b4777c2..ad2f58b9647226ba2ffd934aeaae6569430d648d 100644 --- a/ylong_http_client/src/util/c_openssl/ssl/ssl_base.rs +++ b/ylong_http_client/src/util/c_openssl/ssl/ssl_base.rs @@ -12,9 +12,11 @@ // limitations under the License. use core::{cmp, ffi, fmt, str}; -use std::ffi::CString; +use std::ffi::{c_uchar, CString}; #[cfg(feature = "sync")] use std::io::{Read, Write}; +use std::ptr::null; +use std::slice::from_raw_parts; use libc::{c_char, c_int, c_long, c_void}; @@ -35,7 +37,7 @@ use crate::c_openssl::x509::{ }; use crate::util::c_openssl::check_ptr; use crate::util::c_openssl::error::ErrorStack; -use crate::util::c_openssl::ffi::ssl::{SSL_free, SSL_new, SSL}; +use crate::util::c_openssl::ffi::ssl::{SSL_free, SSL_new, SSL, SSL_get0_alpn_selected}; use crate::util::c_openssl::foreign::Foreign; foreign_type!( @@ -140,6 +142,19 @@ impl SslRef { Err(_) => param.set_host(host_name), } } + + pub(crate) fn negotiated_alpn_protocol(&self) -> Option<&[u8]> { + let mut data = null() as *const c_uchar; + let mut len = 0_u32; + unsafe { + SSL_get0_alpn_selected(self.as_ptr(), &mut data, &mut len); + if data.is_null() { + None + } else { + Some(from_raw_parts(data, len as usize)) + } + } + } } impl fmt::Debug for SslRef {