Yola
Yola

Reputation: 19051

Send HTTP_1_1_REQUIRED from ASP.NET Core controller

I need to request client to downgrade http protocol version from 2 to 1.1. Is it possible to send HTTP_1_1_REQUIRED from ASP.NET Core controller. For me it seems that this can be done only on some lower level than we can access in such a controller. But I was told that HttpReceiveClientCertificate does this in case it can't find the certificate.

Upvotes: 0

Views: 273

Answers (2)

vlad2135
vlad2135

Reputation: 1666

Yes, it's possible with the help of the IHttpResetFeature interface.

Keep in mind that it works only if Windows has HttpSetRequestProperty in httpapi.dll (Windows 10 and Windows Server 2016 don't have it).

If you need to support older OSes and you need HTTP_1_1_REQUIRED only to request a client certificate, AND if you are using HTTP.sys for hosting of your webapp, you can call the HttpReceiveClientCertificate API you mentioned - it will reset HTTP/2 connection with HTTP_1_1_REQUIRED reset code.

I did it via calling internal Request.GetClientCertificateAsync method via reflection. You can read a bit more about this approach in this answer.

Upvotes: 1

Yuning Duan
Yuning Duan

Reputation: 1692

You can create an HTTP client in the controller and use the _httpClientFactory.CreateClient() method to create an HTTP client instance. Then use yarp to let the reverse proxy use http_1_1. Here is an example:

Method:

public async Task<IActionResult> Privacy()
  {
      var client = _httpClientFactory.CreateClient();
      var response = await client.GetAsync($"https://localhost:7247/WeatherForecast/PP/v2?Key=a&Topic=d&Message=c");
      var content = await response.Content.ReadAsStringAsync();
           
      return Content(content, response.Content.Headers.ContentType?.ToString());
  }

Yarp configuration :

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ReverseProxy": {
    "Routes": {
      "route1": {
        "ClusterId": "cluster2",
        "Match": {
          "Path": "/WeatherForecast/PP/{**catch-all}"
        }
      }
    },
    "Clusters": {
      "cluster2": {
        "HttpClient": {
          "SslProtocols": [
            "Tls12"
          ]
        },
        "HttpRequest": {
          "Version": "1.1",
          "VersionPolicy": "RequestVersionExact"
        },
        "Destinations": {
          "cluster2/destination1": {
            "Address": "https://localhost:7258/"
          }
        }
      }
    }
  }
}

enter image description here

enter image description here

Upvotes: 0

Related Questions