Skip to content

HTTP2: Allow frame of type RstStreamFrame when in state HalfClosedLocalWaitingForPeerStream - #614

Open
jtjeferreira wants to merge 4 commits into
apache:mainfrom
jtjeferreira:http2-rst_stream
Open

HTTP2: Allow frame of type RstStreamFrame when in state HalfClosedLocalWaitingForPeerStream#614
jtjeferreira wants to merge 4 commits into
apache:mainfrom
jtjeferreira:http2-rst_stream

Conversation

@jtjeferreira

Copy link
Copy Markdown
Contributor

As described in apache/pekko-connectors#830, I got an "Received unexpected frame of type RstStreamFrame for stream 1 in state HalfClosedLocalWaitingForPeerStream" which I think is a bug in the http2 client side support.

In this PR I took the approach of returning an HttpResponse with status 429, and with an failed source with PeerClosedStreamException as entity. I though of several alternatives but I could not implement them:

  • transparently retry the request when the error code is REFUSED_STREAM, since the spec clearly says the request can be retried.
  • return/throw PeerClosedStreamException, without having to "wrap" it in a HttpResponse

@raboof

Copy link
Copy Markdown
Member

Thanks for looking into this!

transparently retry the request when the error code is REFUSED_STREAM, since the spec clearly says the request can be retried.

That would indeed be nice but could get pretty complex, seems reasonable to postpone that.

return/throw PeerClosedStreamException, without having to "wrap" it in a HttpResponse

Hmm, not having to create a 'fake' HttpResponse would indeed be nice, I wonder if we can avoid that somehow

@jrudolph

Copy link
Copy Markdown
Contributor

return/throw PeerClosedStreamException, without having to "wrap" it in a HttpResponse

Hmm, not having to create a 'fake' HttpResponse would indeed be nice, I wonder if we can avoid that somehow

Indeed! In the API it's not even easy to support failed requests because the HTTP/2 API is ultimately flow based, so we would have to change the flow type to support failed requests that somehow support the request association.

Maybe it's indeed better to create a well-document fake response that works with the existing API types (i.e. HttpResponse).

In some way, the server misses the opportunity to offer a better response code by rejecting a request with a RST frame instead of returning a (potentially canned) response giving more information about the reason.

@jtjeferreira

Copy link
Copy Markdown
ContributorAuthor

Indeed! In the API it's not even easy to support failed requests because the HTTP/2 API is ultimately flow based, so we would have to change the flow type to support failed requests that somehow support the request association.

I guess that would mean changing the HTTP/2 flow API to be similar to the HTTP/1 flow api: Flow[(HttpRequest, T), (Try[HttpResponse], T), HostConnectionPool], that uses Try[HttpResponse] ? But again thats a bigger change for another PR...

Meanwhile feel free to review the PR

@jtjeferreira
jtjeferreira marked this pull request as ready for review October 2, 2024 14:52
Comment on lines +448 to +452
case rst: RstStreamFrame =>
val headers = ParsedHeadersFrame(rst.streamId, endStream = false, Seq((":status", "429")), None)
dispatchSubstream(headers, Right(Source.failed(new PeerClosedStreamException(rst.streamId, rst.errorCode))),
correlationAttributes)
Closed

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

should I handle rst: RstStreamFrame is other states? should I change other places that handle RstStreamFrame to return the fake response?

@pjfanningpjfanning added this to the 1.1.1 milestone Oct 10, 2024
@pjfanningpjfanning modified the milestones: 1.1.1, 1.2.0Nov 27, 2024
@pjfanningpjfanning modified the milestones: 1.2.0, 1.3.0May 7, 2025
@pjfanningpjfanning modified the milestones: 1.3.0, 2.0.0Oct 5, 2025
@pjfanningpjfanning modified the milestones: 2.0.0-M1, 2.0.0-M2Dec 10, 2025
@pjfanningpjfanning removed this from the 2.0.0-M2 milestone Jul 27, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@jtjeferreira@raboof@jrudolph@pjfanning