refit icon indicating copy to clipboard operation
refit copied to clipboard

Refit - change default HTTP protocol from 1.1 to 2.0

Open amalea opened this issue 3 years ago • 7 comments

Hello,

I have upgraded my .net project from 2.1 to 3.1 and also the Refit lib from 4.7.51 to the latest version 6. But, there is one thing related to the HttpClient that I could not set within RefitSettings.

.netCore 3.1 uses the default Http protocol version 1.1. image (3) When I create the client, I can set zuoraClient.DefaultRequestVersion = new Version(2, 0), but afterwards when _zuoraClient = RestService.For<IZuoraApi>(zuoraClient, ZuoraApi.RefitSettings); the Http version turns back to 1.1.

Could you please suggest which RefitSettings should be used to set the Http protocol?

Thank you and Best regards

amalea avatar Mar 10 '21 15:03 amalea

I don't know how you can do that with RestService.For syntaxe.

Here an example with dependency injection :

services.AddRefitClient<ZuoraApi>().ConfigureHttpClient(c => {
                c.DefaultRequestVersion = new Version(2, 0);
                c.BaseAddress = new Uri("base Url");
            });

Maybe a new property in RefitSettings should be add for this ?

Dashell avatar Mar 18 '21 18:03 Dashell

Hi @Dashell,

Thanks for your reply! I have tried to overwrite the defaultRequestVersion as you have proposed, but it seems that Refit is overwriting it again. I think a property in RefitSettings can help somehow.

amalea avatar Mar 23 '21 09:03 amalea

same question; var client = RestService.CreateHttpClient(endpoint, null); client.DefaultRequestVersion = new Version(2, 0); return RestService.For<T>(client); It doesn't work; I received HTTP/1.1 in server;

xckai avatar Sep 02 '21 03:09 xckai

A custom DelegatingHandler may help here, by changing the request version

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            request.Version = new Version(1, 0);
            return base.SendAsync(request, cancellationToken);
        }

getheme225 avatar Jan 29 '22 12:01 getheme225

We have also encountered an issue with not being able to set the default http version via the HttpClient and have resorted to setting it in a delegate handler. The API we are trying to call is configured with HTTP/2 only and not being able to set the http version on the client is causing the requests to outright fail with very confusing errors.

narthollis avatar Jun 22 '22 03:06 narthollis

builder.Services
    .AddRefitClient<IWebApi>()
    .ConfigureHttpClient(_ =>
    {
        _.BaseAddress = new Uri(EnvConfiguration.Keys().Api);
        _.DefaultRequestVersion = new Version(3, 0);
    });

I tried this but not worked

mehmet-erdogdu avatar Mar 16 '23 07:03 mehmet-erdogdu

I'm new to Refit, but needed HTTP/2.0 for one of my tasks. For those looking for a workaround, I was able to get code like this to work for my case. (based on info above and elsewhere) This defaults to HTTP/2.0, but you could specify a different version to the client's constructor if you need to. I haven't tried/needed to figure out how to make it work with builder.Services yet.

public class MyRefitHttpClient : HttpClient {
  public MyRefitHttpClient(Version? version = null) 
    : base(new MyHttpClientHandler(version)) {}
}

public class MyHttpClientHandler : HttpClientHandler {
  private readonly Version _version;
  public MyHttpClientHandler(Version? version = null) : base() {
    _version = version ?? HttpVersion.Version20;
  }
  async protected override Task<HttpResponseMessage> 
    SendAsync(HttpRequestMessage request, CancellationToken cToken) 
{	
    request.Version = _version;
    return await base.SendAsync(request, cToken).ConfigureAwait(false);
  }
}

// Invoke as follows (assuming the IMyApi Refit interface has already been defined)
var http2Client = new MyRefitHttpClient() { 
	BaseAddress = new Uri("https://some.restapi.server")
};
var MyRefitApi = RestService.For<IMyApi>(http2Client);

richk1 avatar Aug 04 '23 02:08 richk1