Skip to content

HTTP version selection #987

@scalablecory

Description

@scalablecory

This API will update HttpClient behavior to enable more useful version selection from users. This will make possible prenegotiated HTTP/2 cleartext, H2C upgrade, prenegotiated HTTP/3, and leave the door open for Alt-Svc to migrate connections in the future.

If accepted, would supersede #988 and allow us to get rid of the current AppContext switch for prenegotiated H2C.

Proposed API

class HttpClient
{
    //Version DefaultVersion { get; set; } // Exists today - will be interpreted as Min or Max based on new API below.
    public HttpVersionPolicy DefaultVersionPolicy { get; set; } = HttpVersionPolicy.RequestVersionOrLower;
}

class HttpRequestMessage
{
    //Version Version { get; set; } // Exists today - will be interpreted as Min or Max based on new API below.
    public HttpVersionPolicy VersionPolicy { get; set; } = HttpVersionPolicy.RequestVersionOrLower;
}

public enum HttpVersionPolicy
{
    RequestVersionOrLower,
    RequestVersionOrHigher,
    RequestVersionExact
}

Behavior

The default would have identical behavior to what we have today.

  • RequestVersionOrLower: start as high as possible (HTTP/1.1, or ALPN if available) up to HttpRequestMessage.Version.
  • RequestVersionOrHigher: start as high as possible (at least HttpRequestMessage.Version, or ALPN if available), and upgrade (via H2C upgrade or Alt-Svc) if possible. Enables prenegotiated H2C.
  • RequestVersionExact: use explicitly the version the user asked for, and if server requires an upgrade/downgrade for a specific request, return an appropriate error. Enables prenegotiated H2C.

Example: User doesn't know, but use whatever server has available.

var msg = new HttpRequestMessage { VersionPolicy = HttpVersionPolicy.RequestVersionOrHigher };
// ...

Example: Prenegotiated HTTP/3

var msg = new HttpRequestMessage { Version = HttpVersion.Version30, VersionPolicy = VersionPolicy = HttpVersionPolicy.RequestVersionOrHigher };
// ...

Example: H2C upgrade

var msg = new HttpRequestMessage { VersionPolicy = HttpVersionPolicy.RequestVersionOrHigher };

Example: Prenegotiated H2C

var msg = new HttpRequestMessage
{
    Version = HttpVersion.Version20,
    VersionPolicy = HttpVersionPolicy.RequestVersionOrHigher
    RequestUri = new Uri("http://unsecure-url.com")
};

Example: app depends on Connection: close

var msg = new HttpRequestMessage { }; // default policy just fine.
msg.Headers.ConnectionClose = true;

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions