Aspnetcore: Kestrel and IIS set different Request.Protocol values for HTTP/2

Created on 19 Sep 2019  路  17Comments  路  Source: dotnet/aspnetcore

Kestrel sets HTTP/2 while IIS sets HTTP/2.0.

Is this expected behavior?

Done area-servers bug servers-iis

Most helpful comment

In @gfoidl we trust.

All 17 comments

Bug. The official value is HTTP/2. Is this messing with your gPRC logic?

@Tratcher is there anything we can do if IIS sets it?

I misunderstood the original issue. I see now.

Is this messing with your gPRC logic?

Kind of. I have a test for protocol, and IIS (specifically IIS express) is failing that test even though it is HTTP/2. It doesn't actually break anyone at the moment because IIS express can't support gRPC, but it gives people an odd error message.

https://github.com/grpc/grpc-dotnet/issues/526#issuecomment-532899495

Current:

 if (httpContext.Request.Protocol != "HTTP/2") 
 { 
     // Set error response on HttpResponse
     return Task.CompletedTask; 
 } 

I can change it to:

 if (httpContext.Request.Protocol != "HTTP/2" && httpContext.Request.Protocol != "HTTP/2.0") 
 { 
     // Set error response on HttpResponse
     return Task.CompletedTask; 
 } 

IIS will still fail but it will fail for a less odd reason.

So all we need to do is add a clause to the IISHttpContext.FeatureCollection code @Tratcher linked above to have it explicitly return HTTP/2. Sounds good. Good first issue for a new contributor!

@anure I'm going to do this.

In @gfoidl we trust.

That turnaround was awesome :). Nice work and thanks @gfoidl!

I've just finished a gRPC service in .NET Core 3.0 and I'd like to host it with IIS inprocess, but I got this 426 error. It was correctualy qualified as a bug, but will only be included in 5.0-preview? Shall I drop my intention to use IIS so?

@tiago-quintanilha I don't think your question is related to this issue thread. Can you open a new issue please?

IIS doesn't support gRPC. It needs improvements to support HTTP/2 trailers and bi-directional streaming.

@anurse, I posted here because the error was exactly the same, since gRPC always uses http/2, and I noticed that '3.1-candidate' tag was exchanged for '5.0.0-preview1'.

@JamesNK, thanks for your feedback. I've searched for this very information but I could't find. Guess it is all too new. I'll have to use windows service then.

I'd like to host it with IIS inprocess, but I got this 426 error.

The initial post was just about being more consistent with how we report HttpRequest.Protocol, with nothing about a client error so I'm still a little confused what is related between your issue and the initial report. As @JamesNK said, IIS doesn't have sufficient HTTP/2 features to support gRPC (we are working on it though), so that's probably the root of the issue you were seeing.

Anyway, I think we got to the bottom of your issue @tiago-quintanilha, but feel free to file a new issue if you need to! Even if your issue is related to this one, once this issue is closed it's better to just file a new one rather than posting on a closed issue (since we don't triage these anymore).

Re-opening because I think this should be unit tested to prevent regression. gRPC tests this string to verify the request is HTTP/2. It is important it is correct.

For testing, I think the most useful verification would be a couple of integration/functional tests that check Kestrel and IIS product the same Request.Protocol values in HTTP/2.

I can do this. It's fairly non-trivial to verify Http/2+IIS.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Kevenvz picture Kevenvz  路  3Comments

ermithun picture ermithun  路  3Comments

UweKeim picture UweKeim  路  3Comments

BrennanConroy picture BrennanConroy  路  3Comments

FourLeafClover picture FourLeafClover  路  3Comments