Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add TCP connect timeout option #102

Merged
merged 1 commit into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions native/yaha_native/src/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,15 @@ pub extern "C" fn yaha_client_config_http2_keep_alive_while_idle(
.http2_keep_alive_while_idle(val);
}

#[no_mangle]
pub extern "C" fn yaha_client_config_connect_timeout(
ctx: *mut YahaNativeContext,
timeout_milliseconds: u64,
) {
let ctx = YahaNativeContextInternal::from_raw_context(ctx);
ctx.connect_timeout.get_or_insert(Duration::from_millis(timeout_milliseconds));
}

#[no_mangle]
pub extern "C" fn yaha_client_config_http2_max_concurrent_reset_streams(
ctx: *mut YahaNativeContext,
Expand Down
4 changes: 4 additions & 0 deletions native/yaha_native/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{
num::NonZeroIsize,
sync::{Arc, Mutex},
time::Duration,
};
use futures_channel::mpsc::Sender;
use http_body_util::combinators::BoxBody;
Expand Down Expand Up @@ -55,6 +56,7 @@ pub struct YahaNativeContextInternal<'a> {
pub skip_certificate_verification: Option<bool>,
pub root_certificates: Option<rustls::RootCertStore>,
pub override_server_name: Option<String>,
pub connect_timeout: Option<Duration>,
pub client_auth_certificates: Option<Vec<CertificateDer<'a>>>,
pub client_auth_key: Option<PrivateKeyDer<'a>>,
pub client: Option<Client<HttpsConnector<HttpConnector>, BoxBody<Bytes, hyper::Error>>>,
Expand All @@ -81,6 +83,7 @@ impl YahaNativeContextInternal<'_> {
skip_certificate_verification: None,
root_certificates: None,
override_server_name: None,
connect_timeout: None,
client_auth_certificates: None,
client_auth_key: None,
on_status_code_and_headers_receive,
Expand Down Expand Up @@ -157,6 +160,7 @@ impl YahaNativeContextInternal<'_> {
let mut http_conn = HttpConnector::new();
http_conn.set_nodelay(true);
http_conn.enforce_http(false);
http_conn.set_connect_timeout(self.connect_timeout);
builder.wrap_connector(http_conn)
}

Expand Down
5 changes: 5 additions & 0 deletions src/YetAnotherHttpHandler/NativeHttpHandlerCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ private unsafe void Initialize(YahaNativeContext* ctx, NativeClientSettings sett
if (YahaEventSource.Log.IsEnabled()) YahaEventSource.Log.Info($"Option '{nameof(settings.Http2MaxFrameSize)}' = {http2MaxFrameSize}");
NativeMethods.yaha_client_config_http2_max_frame_size(ctx, http2MaxFrameSize);
}
if (settings.ConnectTimeout is { } connectTimeout)
{
if (YahaEventSource.Log.IsEnabled()) YahaEventSource.Log.Info($"Option '{nameof(settings.ConnectTimeout)}' = {connectTimeout}");
NativeMethods.yaha_client_config_connect_timeout(ctx, (ulong)connectTimeout.TotalMilliseconds);
}
if (settings.Http2KeepAliveInterval is { } http2KeepAliveInterval)
{
if (YahaEventSource.Log.IsEnabled()) YahaEventSource.Log.Info($"Option '{nameof(settings.Http2KeepAliveInterval)}' = {http2KeepAliveInterval}");
Expand Down
3 changes: 3 additions & 0 deletions src/YetAnotherHttpHandler/NativeMethods.Uwp.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ internal static unsafe partial class NativeMethods
[DllImport(__DllName, EntryPoint = "yaha_client_config_http2_keep_alive_while_idle", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void yaha_client_config_http2_keep_alive_while_idle(YahaNativeContext* ctx, [MarshalAs(UnmanagedType.U1)] bool val);

[DllImport(__DllName, EntryPoint = "yaha_client_config_connect_timeout", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void yaha_client_config_connect_timeout(YahaNativeContext* ctx, ulong timeout_milliseconds);

[DllImport(__DllName, EntryPoint = "yaha_client_config_http2_max_concurrent_reset_streams", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void yaha_client_config_http2_max_concurrent_reset_streams(YahaNativeContext* ctx, nuint max);

Expand Down
3 changes: 3 additions & 0 deletions src/YetAnotherHttpHandler/NativeMethods.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ internal static unsafe partial class NativeMethods
[DllImport(__DllName, EntryPoint = "yaha_client_config_http2_keep_alive_while_idle", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void yaha_client_config_http2_keep_alive_while_idle(YahaNativeContext* ctx, [MarshalAs(UnmanagedType.U1)] bool val);

[DllImport(__DllName, EntryPoint = "yaha_client_config_connect_timeout", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void yaha_client_config_connect_timeout(YahaNativeContext* ctx, ulong timeout_milliseconds);

[DllImport(__DllName, EntryPoint = "yaha_client_config_http2_max_concurrent_reset_streams", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void yaha_client_config_http2_max_concurrent_reset_streams(YahaNativeContext* ctx, nuint max);

Expand Down
12 changes: 12 additions & 0 deletions src/YetAnotherHttpHandler/YetAnotherHttpHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,16 @@ public class YetAnotherHttpHandler : HttpMessageHandler
/// <see href="https://docs.rs/hyper-util/latest/hyper_util/client/legacy/struct.Builder.html#method.http2_max_frame_size">hyper: http2_max_frame_size</see>
/// </remarks>
public uint? Http2MaxFrameSize { get => _settings.Http2MaxFrameSize; set => _settings.Http2MaxFrameSize = value; }

/// <summary>
/// Gets or sets timeout for TCP connection establishment
/// Pass <value>null</value> to never timeout.
/// Default is never timeout.
/// </summary>
/// <remarks>
/// <see href="https://docs.rs/hyper-util/latest/hyper_util/client/legacy/connect/struct.HttpConnector.html#method.set_connect_timeout">hyper: set_connect_timeout</see>
/// </remarks>
public TimeSpan? ConnectTimeout { get => _settings.ConnectTimeout; set => _settings.ConnectTimeout = value; }

/// <summary>
/// Gets or sets an interval for HTTP2 Ping frames should be sent to keep a connection alive.
Expand Down Expand Up @@ -204,6 +214,7 @@ internal class NativeClientSettings
public uint? Http2InitialConnectionWindowSize { get; set; }
public bool? Http2AdaptiveWindow { get; set; }
public uint? Http2MaxFrameSize { get; set; }
public TimeSpan? ConnectTimeout { get; set; }
public TimeSpan? Http2KeepAliveInterval { get; set; }
public TimeSpan? Http2KeepAliveTimeout { get; set; }
public bool? Http2KeepAliveWhileIdle { get; set; }
Expand All @@ -227,6 +238,7 @@ public NativeClientSettings Clone()
Http2InitialConnectionWindowSize = this.Http2InitialConnectionWindowSize,
Http2AdaptiveWindow = this.Http2AdaptiveWindow,
Http2MaxFrameSize = this.Http2MaxFrameSize,
ConnectTimeout = this.ConnectTimeout,
Http2KeepAliveInterval = this.Http2KeepAliveInterval,
Http2KeepAliveTimeout = this.Http2KeepAliveTimeout,
Http2KeepAliveWhileIdle = this.Http2KeepAliveWhileIdle,
Expand Down
Loading