diff --git a/native/yaha_native/src/binding.rs b/native/yaha_native/src/binding.rs index 0b23708..9bdc3ff 100644 --- a/native/yaha_native/src/binding.rs +++ b/native/yaha_native/src/binding.rs @@ -109,6 +109,16 @@ pub extern "C" fn yaha_client_config_add_root_certificates( valid } +#[no_mangle] +pub extern "C" fn yaha_client_config_add_override_server_name( + ctx: *mut YahaNativeContext, + override_server_name: *const StringBuffer, +) { + let ctx = YahaNativeContextInternal::from_raw_context(ctx); + let server_name = unsafe { (*override_server_name).to_str() }; + ctx.override_server_name.get_or_insert(server_name.to_string()); +} + #[no_mangle] pub extern "C" fn yaha_client_config_add_client_auth_certificates( ctx: *mut YahaNativeContext, diff --git a/native/yaha_native/src/context.rs b/native/yaha_native/src/context.rs index abdef9d..01e8a05 100644 --- a/native/yaha_native/src/context.rs +++ b/native/yaha_native/src/context.rs @@ -54,6 +54,7 @@ pub struct YahaNativeContextInternal<'a> { pub client_builder: Option, pub skip_certificate_verification: Option, pub root_certificates: Option, + pub override_server_name: Option, pub client_auth_certificates: Option>>, pub client_auth_key: Option>, pub client: Option, BoxBody>>, @@ -79,6 +80,7 @@ impl YahaNativeContextInternal<'_> { client_builder: Some(Client::builder(TokioExecutor::new())), skip_certificate_verification: None, root_certificates: None, + override_server_name: None, client_auth_certificates: None, client_auth_key: None, on_status_code_and_headers_receive, @@ -140,7 +142,15 @@ impl YahaNativeContextInternal<'_> { let builder = hyper_rustls::HttpsConnectorBuilder::new() .with_tls_config(tls_config) - .https_or_http() + .https_or_http(); + + let builder = if let Some(override_server_name) = &self.override_server_name { + builder.with_server_name(override_server_name.clone()) + } else { + builder + }; + + let builder = builder .enable_all_versions(); // Almost the same as `builder.build()`, but specify `set_nodelay(true)`. diff --git a/src/YetAnotherHttpHandler/NativeHttpHandlerCore.cs b/src/YetAnotherHttpHandler/NativeHttpHandlerCore.cs index 8c98cb8..0b044d3 100644 --- a/src/YetAnotherHttpHandler/NativeHttpHandlerCore.cs +++ b/src/YetAnotherHttpHandler/NativeHttpHandlerCore.cs @@ -86,6 +86,16 @@ private unsafe void Initialize(YahaNativeContext* ctx, NativeClientSettings sett if (YahaEventSource.Log.IsEnabled()) YahaEventSource.Log.Info($"yaha_client_config_add_root_certificates: ValidCertificatesCount={validCertificatesCount}"); } } + if (settings.OverrideServerName is { } overrideServerName) + { + if (YahaEventSource.Log.IsEnabled()) YahaEventSource.Log.Info($"Option '{nameof(settings.OverrideServerName)}' = {overrideServerName}"); + var overrideServerNameBytes = Encoding.UTF8.GetBytes(overrideServerName); + fixed (byte* buffer = overrideServerNameBytes) + { + var sb = new StringBuffer(buffer, overrideServerNameBytes.Length); + NativeMethods.yaha_client_config_add_override_server_name(ctx, &sb); + } + } if (settings.ClientAuthKey is { } clientAuthKey) { if (YahaEventSource.Log.IsEnabled()) YahaEventSource.Log.Info($"Option '{nameof(settings.ClientAuthKey)}' = {clientAuthKey}"); diff --git a/src/YetAnotherHttpHandler/NativeMethods.Uwp.g.cs b/src/YetAnotherHttpHandler/NativeMethods.Uwp.g.cs index ca46131..0eb13db 100644 --- a/src/YetAnotherHttpHandler/NativeMethods.Uwp.g.cs +++ b/src/YetAnotherHttpHandler/NativeMethods.Uwp.g.cs @@ -47,6 +47,9 @@ internal static unsafe partial class NativeMethods [DllImport(__DllName, EntryPoint = "yaha_client_config_add_root_certificates", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern nuint yaha_client_config_add_root_certificates(YahaNativeContext* ctx, StringBuffer* root_certs); + [DllImport(__DllName, EntryPoint = "yaha_client_config_add_override_server_name", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void yaha_client_config_add_override_server_name(YahaNativeContext* ctx, StringBuffer* override_server_name); + [DllImport(__DllName, EntryPoint = "yaha_client_config_add_client_auth_certificates", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern nuint yaha_client_config_add_client_auth_certificates(YahaNativeContext* ctx, StringBuffer* auth_certs); diff --git a/src/YetAnotherHttpHandler/NativeMethods.g.cs b/src/YetAnotherHttpHandler/NativeMethods.g.cs index 84968bf..2c921a7 100644 --- a/src/YetAnotherHttpHandler/NativeMethods.g.cs +++ b/src/YetAnotherHttpHandler/NativeMethods.g.cs @@ -52,6 +52,9 @@ internal static unsafe partial class NativeMethods [DllImport(__DllName, EntryPoint = "yaha_client_config_add_root_certificates", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern nuint yaha_client_config_add_root_certificates(YahaNativeContext* ctx, StringBuffer* root_certs); + [DllImport(__DllName, EntryPoint = "yaha_client_config_add_override_server_name", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + public static extern void yaha_client_config_add_override_server_name(YahaNativeContext* ctx, StringBuffer* override_server_name); + [DllImport(__DllName, EntryPoint = "yaha_client_config_add_client_auth_certificates", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] public static extern nuint yaha_client_config_add_client_auth_certificates(YahaNativeContext* ctx, StringBuffer* auth_certs); diff --git a/src/YetAnotherHttpHandler/YetAnotherHttpHandler.cs b/src/YetAnotherHttpHandler/YetAnotherHttpHandler.cs index 313b573..c0951a2 100644 --- a/src/YetAnotherHttpHandler/YetAnotherHttpHandler.cs +++ b/src/YetAnotherHttpHandler/YetAnotherHttpHandler.cs @@ -49,6 +49,11 @@ public class YetAnotherHttpHandler : HttpMessageHandler /// public string? RootCertificates { get => _settings.RootCertificates; set => _settings.RootCertificates = value; } + /// + /// Gets or sets a value that specifies subject alternative name (SAN) of the certificate. + /// + public string? OverrideServerName { get => _settings.OverrideServerName; set => _settings.OverrideServerName = value; } + /// /// Gets or sets a custom client auth certificates. /// @@ -192,6 +197,7 @@ internal class NativeClientSettings public bool? Http2Only { get; set; } public bool? SkipCertificateVerification { get; set; } public string? RootCertificates { get; set; } + public string? OverrideServerName { get; set; } public string? ClientAuthCertificates { get; set; } public string? ClientAuthKey { get; set; } public uint? Http2InitialStreamWindowSize { get; set; } @@ -214,6 +220,7 @@ public NativeClientSettings Clone() Http2Only = this.Http2Only, SkipCertificateVerification = this.SkipCertificateVerification, RootCertificates = this.RootCertificates, + OverrideServerName = this.OverrideServerName, ClientAuthCertificates = this.ClientAuthCertificates, ClientAuthKey = this.ClientAuthKey, Http2InitialStreamWindowSize = this.Http2InitialStreamWindowSize,