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

Exposing HTTP2 "additional debug data" in received GOAWAY frames #308

Open
rnowak opened this issue Dec 5, 2022 · 4 comments
Open

Exposing HTTP2 "additional debug data" in received GOAWAY frames #308

rnowak opened this issue Dec 5, 2022 · 4 comments

Comments

@rnowak
Copy link

rnowak commented Dec 5, 2022

Being able to act on the "additional debug data" that can be part of the GOAWAY frames is necessary for correct usage of certain services.

One such service is Apple Push Notification service (APNs). When connecting to APNs, if the client certificate is bad or for the wrong environment (prod vs sandbox), the service will send a GOAWAY frame with some JSON stating the error reason, and then close the socket immediately after. In both of these cases, it is meaningless to attempt connecting again as the situation is unlikely to resolve itself and needs intervention.

In the APNs documentation, it is stated "The JSON data might also be included in a GOAWAY frame when a connection is terminated."

When this happens, gun sends a gun_down message with reason=normal:

{gun_down,<0.1386.0>,http2,normal,[]}

In the conversation in #cowboy on the Erlang Slack on the 5th of December, Loïc wrote:

Perhaps the down function could be modified to change the Reason and add GOAWAY data when that happens.
But I wonder what happens when it's tunnel that goes down right now instead

I know some people do APNS through tunnels

---

In theory it results in a gun_error for the stream but I'm not totally sure that it's handled properly

In that case the data can be passed around through the Reason field of both gun_error and gun_down.
I do not think this is a breaking change so it can wait after 2.0 is out.

---

I'm thinking of exposing it only when the gun_down has normal as a reason, there are no streams at that time 
(otherwise the streams already receive it) and there was no streams opened to begin with. And only changing if 
there was debug data. Basically handling the case where a connection was accepted and terminated apparently 
normally but with a sneaky error. Specifically to support this APNS scenario. So I do not think an option is necessary
@rnowak
Copy link
Author

rnowak commented Jan 9, 2023

The third value in the goaway tuple, the error code, would also be great to have access to. This is already translated in cow_http2 by parse_error_code/1. I've so far seen 0 / no_error and 11 / enhance_your_calm emitted in the wild.

@essen
Copy link
Member

essen commented Jan 9, 2023

If the error code is not no_error (equivalent to "normal") it probably should be reflected yes.

@manas-chaudhari
Copy link

+1 for this requirement.
I am also willing to take a stab at implementing if I can get some guidance on the approach.

@essen
Copy link
Member

essen commented Feb 1, 2024

The close reason just has to be propagated from gun_http2 to gun. Currently gun_http2 returns the close command, we would need a new command {close, Reason, Extra} that can then be given to the gun_down message. Note that if the Reason is no_error, we should handle it by using normal like currently and not propagate the extra data.

There is additional difficulty because:

  • the connection isn't closed as soon as we receive the GOAWAY frame, so we need to keep the reason/extra data in our state until then
  • the server may send multiple GOAWAY frames during the shutdown; we should keep only the most recent reason/extra data

The last item has the caveat that servers may not send the extra data multiple times, but we'll cross that bridge when we get to it. For now we should just leave a comment in the code indicating that because we keep the last GOAWAY information only, that data may be lost if the server changes what it sends in subsequent GOAWAY frames.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants