Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Add TrailingHeaders support for HTTP/2 #36128

Merged
wfurt merged 8 commits intodotnet:masterfrom
wfurt:trailing2_35337
Apr 1, 2019
Merged

Add TrailingHeaders support for HTTP/2 #36128
wfurt merged 8 commits intodotnet:masterfrom
wfurt:trailing2_35337

Conversation

@wfurt
Copy link
Member

@wfurt wfurt commented Mar 18, 2019

follow-up on #35337, fixes #34912

This adds processing for HeaderFrame after DataFrame. To track if some data was received, I split ExpectingData into two states.

The Http2GetAsync_TrailerHeaders_TrailingPseudoHeadersThrow() test give me some grief.
rfc7540 8.1.2.1. suggest that pseudo-headers in trailer should be treated as invalid response.
That means that one could get stream and we could Throw later on when reading stream is finished and we process trailing headers. This was easier for HTTP/1 where invalid headers should be ignored.

BTW besides tests, I also did some testing with nginx server sending trailers over HTTP/2.

@wfurt
Copy link
Member Author

wfurt commented Mar 18, 2019

/azp run corefx-outerloop-osx

@wfurt
Copy link
Member Author

wfurt commented Mar 18, 2019

/azp run corefx-outerloop-linux

@wfurt
Copy link
Member Author

wfurt commented Mar 18, 2019

/azp run corefx-outerloop-windows

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

2 similar comments
@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@wfurt wfurt requested a review from a team March 18, 2019 20:45
@davidsh davidsh added this to the 3.0 milestone Mar 18, 2019
@JamesNK
Copy link
Member

JamesNK commented Mar 29, 2019

Is there much work remaining on this PR? It would be great to get it in so that I can begin testing HttpClient with some realistic gRPC workloads.

@wfurt
Copy link
Member Author

wfurt commented Mar 29, 2019

I'll update the state machine as @rmkerr suggested. Hopefully I can do that later today.
Any feedback from realistic workload would be appreciated @JamesNK

else
{
await SendResponseHeadersAsync(streamId, false, statusCode, headers);
await SendResponseHeadersAsync(streamId, false, statusCode, false, headers);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: for both the existing and new Boolean args, can you please use named arguments? Otherwise, it's hard to know what they mean.

// See the LICENSE file in the project root for more information.

using System.Diagnostics;
using System;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be necessary. Is there a reason you needed to add it?

public void OnResponseHeadersStart()
{
lock (SyncObject)
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What other states can this be in other than ExpectingData? Can we assert that it's only in one of those states?

{
private static byte[] DataBytes = Encoding.ASCII.GetBytes("data");
private static IList<HttpHeaderData> TrailingHeaders = new HttpHeaderData[] {
new HttpHeaderData("MyCoolTrailerHeader", "amazingtrailer"), new HttpHeaderData("Hello", "World") };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm amused that my terrible choice in random name/values is being propagated into new tests :)

public abstract class HttpClientHandlerTest_TrailingHeaders_Test : HttpClientHandlerTestBase
{
private static byte[] DataBytes = Encoding.ASCII.GetBytes("data");
private static IList<HttpHeaderData> TrailingHeaders = new HttpHeaderData[] {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: s_dataBytes, s_trailingHeaders

// Server doesn't send trailing header frame.
HttpResponseMessage response = await sendTask;
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.NotNull(response.TrailingHeaders);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The title of the test says it's expecting an empty collection; this should validate that.

Assert.Equal(HttpStatusCode.OK, response.StatusCode);

// Pending read on the response content.
Console.WriteLine(response.TrailingHeaders);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove these Console.WriteLines.

await server.SendResponseHeadersAsync(streamId, endStream : true, isTrailingHeader:true, headers: TrailingHeaders);

// Read data until EOF is reached
while (stream.Read(data, 0, data.Length) != 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be good to add another Assert.Empty check into the body of this loop, since we want to validate that the collection isn't populated until we stream.Read returns 0.

Copy link
Member

@stephentoub stephentoub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

@wfurt wfurt merged commit 57cb805 into dotnet:master Apr 1, 2019
@JamesNK
Copy link
Member

JamesNK commented Apr 2, 2019

I'd like to test with this ASAP.

When will it be published in an SDK I can download from https://github.com/dotnet/core-sdk#installers-and-binaries?

@karelz
Copy link
Member

karelz commented Apr 2, 2019

@JamesNK as soon as maestro kicks off the right builds ... not sure how long it takes.
@wtgodbe do you know?

@JamesNK
Copy link
Member

JamesNK commented Apr 2, 2019

If the build always runs every night then it's not a problem to wait until tomorrow. I just want to double check that it won't be days until I can use this 😄

@karelz
Copy link
Member

karelz commented Apr 2, 2019

I would expect <12h, but these things never stop surprising :)

@wtgodbe
Copy link
Member

wtgodbe commented Apr 2, 2019

The builds run about 6-8 times per day (we batch commits), so we should have an SDK published by now

picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
* add trailing header tests for HTTP/2

* initial implementation

* more fixes and tests

* style cleanup

* feedback from review

* feedback from review


Commit migrated from dotnet/corefx@57cb805
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement trailing headers support on SocketsHttpHandler

8 participants