Skip to content

API Proposal: WinHttpHandler.TcpKeepAlive #44025

@antonfirsov

Description

@antonfirsov

Background and Motivation

Starting from version 20H1 (May 2020 Update) WinHTTP exposes an option (WINHTTP_OPTION_TCP_KEEPALIVE) to control TCP keepalive parameters in a way similar to the corresponding IOCTL option in Winsock:
https://docs.microsoft.com/en-us/windows/win32/winsock/sio-keepalive-vals#remarks

We have a customer request to expose this option in a managed API over WinHttpHandler (goal: meet scalability needs). This would also close a feature gap for users migrating from Framework & HttpWebRequest, where it was possible to control this parameter through ServicePoint.SetTcpKeepAlive.

Proposed API

// Using a class, so we can set default values for properties
// The verbose name is here to avoid potential future conflicts 
// with a TcpKeepAlive type we may define in System.Net.Sockets
public class WinHttpTcpKeepAlive
{
    // Must be greater than TimeSpan.Zero
    // Hard coded default value: 2 hours (based on Windows default)
    public TimeSpan KeepAliveTime { get; set; }

    // Must be greater than TimeSpan.Zero
    // Hard coded default value: 1 sec (based on Windows default)
    public TimeSpan KeepAliveInterval { get; set; }
}

public class WinHttpHandler
{
#if NET5
    [SupportedOSPlatform("windows10.0.2004")]
#endif
    // If the option is not supported by the OS, WinHttpException will be thrown during FIRST REQUEST (just like with other options).
    // We may consider throwing `PlatformNotSupprtedException` below version 2004, although that would be unprecedental in WinHttpHandler
    public WinHttpTcpKeepAlive? TcpKeepAlive { get; set; }
}

Usage Examples

static HttpClient CreateHttpClient()
{
    var winHttpHandler = new WinHttpHandler()
    {
        TcpKeepAlive = new WinHttpTcpKeepAlive() 
        { 
            KeepAliveTime = TimeSpan.FromMinutes(2), 
            KeepAliveInterval = TimeSpan.FromSeconds(2)
        }
    }
    return new HttpClient(winHttpHandler);
}

Alternative Designs

  • Instead of exposing a property, expose a method with 3 arguments, like ServicePoint.SetTcpKeepAlive.

  • We may consider exposing two separate properties to match the design of the HTTP/2 timeout properties on SocketsHttpHandler (see configurable HTTP/2 PING timeouts in HttpClient #31198 (comment)), but with Winsock tcp_keepalive we are expected to set both values with the single call, so this would require us to add unnecessary arbitrary logic to the managed implementation on a place where users expect a thin wrapper over a native API.

Risks

Couldn't identify any.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions