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

ReverseProxy does not properly handle received GOAWAY on gRPC (or HTTP/2) connections #6540

Open
djablonski-moia opened this issue Sep 18, 2024 · 0 comments
Labels

Comments

@djablonski-moia
Copy link

djablonski-moia commented Sep 18, 2024

Branch/Environment/Version

  • Branch/Version: Release 5.4.0 (but also master afaik)
  • Environment: On-prem (Open Source)

Describe the bug
When proxying an HTTP/2 request Tyk gateway does not properly handle receiving a GOAWAY frame from the upstream server, but instead just returns an INTERNAL-error, server closed the stream without sending trailers, which does not properly indicate the client to retry.

Reproduction steps
Steps to reproduce the behavior:

  1. Configure Tyk gateway to support gRPC streaming (enable HTT/2, flush interval etc.)
  2. Add an API
  3. Connect a client to the API with a backend service that uses gRPC server-side streaming
  4. Gracefully shut down the server (it needs to be implemented in a way to send GOAWAY )
  5. Watch the client error & gateway logs

Actual behavior

When the upstream server sends a GOAWAY, Tyk gateway closes the connection to the client with INTERNAL-error, server closed the stream without sending trailers , but internally logs that it received a GOAWAY.

Expected behavior

The gateway should also send a GOAWAY to the client, so it can handle it properly.

Screenshots/Video

n/a

Logs (debug mode or log file):

gateway-tyk-gateway time="Jul 22 08:24:39" level=error msg="http: proxy error during body copy: http2: server sent GOAWAY and closed the connection; LastStreamID=5, ErrCode=NO_ERROR, debug=\"graceful_stop\"" api_id=my-api api_name="My API" mw=ReverseProxy

Configuration (tyk config file):

(no config file, but environment variables from Helm chart; only those added to the chart's defaults)

TYK_GW_HTTPSERVEROPTIONS_ENABLEHTTP2: true
TYK_GW_HTTPSERVEROPTIONS_FLUSHINTERVAL: 1
TYK_GW_PROXYENABLEHTTP2: true
TYK_GW_LOGLEVEL: info
TYK_GW_HTTPSERVEROPTIONS_READTIMEOUT: 660
TYK_GW_HTTPSERVEROPTIONS_WRITETIMEOUT: 660

Additional context

Looking at the source code, it seems to me that the issue is that the error received from the http2.Transport.RoundTrip() in func (rt *TykRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) (gateway/reverse_proxy.go) just bubbles up to func (p *ReverseProxy) WrappedServeHTTP(rw http.ResponseWriter, req *http.Request, withCache bool) ProxyResponse, where there is no distinction made between HTTP/1.1 and HTTP/2, and therefore no special handling for GOAWAY is possible.

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

No branches or pull requests

1 participant