Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HTTP/2] Throw meaningful exception if we get GOAWAY while reading response body #104707

Merged
merged 7 commits into from
Jul 12, 2024

Conversation

liveans
Copy link
Member

@liveans liveans commented Jul 11, 2024

Fixes #97128

Not sure if this is the correct way to fix this.

@liveans
Copy link
Member Author

liveans commented Jul 11, 2024

/azp run runtime-libraries-coreclr outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Member

@MihaZupan MihaZupan left a comment

Choose a reason for hiding this comment

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

Glad to see this was a simple enough change to get into 9.0.
Thanks

@MihaZupan MihaZupan added this to the 9.0.0 milestone Jul 11, 2024
@ManickaP
Copy link
Member

ManickaP commented Jul 11, 2024

Is the original issue an issue at all?
We call OnReset for all streams with id > than indicated in GO_AWAY.

Based on JNK logs:

ProcessIncomingFramesAsync,Frame 15: StreamId=0; Type=GoAway; Flags=None; PayloadLength=22.
ReadGoAwayFrame,lastStreamId=1, errorCode=EnhanceYourCalm

He complains that server didn't let the client finish stream Id 1, while sending GO_AWAY with id 1. What does the RFC says? I'd expect server is supposed to let us finish those requests.

@liveans
Copy link
Member Author

liveans commented Jul 11, 2024

What does the RFC says? I'd expect server is supposed to let us finish those requests.

RFC9113 - HTTP/2 says:

Activity on streams numbered lower than or equal to the last stream identifier might still complete successfully. The sender of a GOAWAY frame might gracefully shut down a connection by sending a GOAWAY frame, maintaining the connection in an "open" state until all in-progress streams complete.

If I'm interpreting this correctly, this can go either way.

@antonfirsov
Copy link
Member

Not sure if this is the correct way to fix this.

I think @JamesNK should be able to test private binaries to confirm.

@liveans
Copy link
Member Author

liveans commented Jul 11, 2024

Not sure if this is the correct way to fix this.

I think @JamesNK should be able to test private binaries to confirm.

That would be nice, but the test is written as he described in the reproduction steps. So, I think this kind of confirms that it's behaving as expected.

@JamesNK
Copy link
Member

JamesNK commented Jul 11, 2024

He complains that server didn't let the client finish stream Id 1, while sending GO_AWAY with id 1. What does the RFC says? I'd expect server is supposed to let us finish those requests.

What do you mean by "let us finish those requests"? Are you expecting reading from the response stream so say there is no more data without throwing an error?

Because of the GO_AWAY the server is never going to send a final stream frame with END_STREAM on it. The stream ended ungracefully. I expect an error when trying to read more of the stream body. What I want improved is the exception's message to say why the response ended.

@JamesNK
Copy link
Member

JamesNK commented Jul 12, 2024

Something that occurred to me, can responseStream.ReadAsync throw HttpProtocolException in other scenarios? If reading from the stream only throws IOException and friends, should the error by wrapped in HttpIOException?

@liveans
Copy link
Member Author

liveans commented Jul 12, 2024

Something that occurred to me, can responseStream.ReadAsync throw HttpProtocolException in other scenarios? If reading from the stream only throws IOException and friends, should the error by wrapped in HttpIOException?

That's a great question, so you're saying that this can be breaking change. I'll leave the answer to the HTTP experts.

@JamesNK
Copy link
Member

JamesNK commented Jul 12, 2024

ReadAsync throws a protocol error in some situations so it's not a new error. That is what I was worried about.

Is it breaking change? Maybe. I don't know the semantics of when to throw an IOException vs HttpProtocolException.

@ManickaP
Copy link
Member

HttpProtocolException derives from HttpIOException which derives from IOException.

@liveans liveans deleted the fix_97128 branch July 12, 2024 08:54
@github-actions github-actions bot locked and limited conversation to collaborators Aug 12, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

HTTP/2 request doesn't report the correct reason why request ends on connection GOAWAY
5 participants