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

Reconcile trailers-only and misc error behavior with grpc-go #690

Merged
merged 3 commits into from
Feb 16, 2024

Conversation

jhump
Copy link
Member

@jhump jhump commented Feb 16, 2024

This largely undoes a recent change to do more validation of trailers-only responses (#685), which disallows a body or trailers in what appeared to be a trailers-only response. In that change, a trailers-only response was identified by the presence of a "grpc-status" key in the headers.

In this PR, a trailers-only response is instead defined by the lack of body and trailers (not the presence of a "grpc-status" header). This PR also tweaks some other error scenarios:

  • If trailers (or an end-stream message) is completely missing from a response, it's considered an internal error. But if trailers are present, but the "grpc-status" key is missing, it's considered an issue determining the status, which is an unknown error.
  • Similarly, if a response content-type doesn't appear to be the right protocol (like it may have come from a non-RPC server), the error code is now unknown. But if it looks like the right protocol but uses the wrong sub-format/codec, it's an internal error.
    • Note that in grpc-go, this behavior is also seen in the client, but this PR doesn't attempt to address that in the connect-go client. Instead, that change can be made when ErrorWriter.IsSupported is overly strict #689 is addressed.

This PR also now makes connect-go more strict about the "compressed" flag in a streaming protocol when there was no compression algorithm negotiated. Previously, this library was lenient and did not consider it an error if the message in question was empty (zero bytes). But to correctly adhere to gRPC semantics, it MUST report this case as an internal error (see bullet 6 in the test cases section of the gRPC compression docs).

* This largely undoes a recent change to do more validation of trailers-only
  responses, which would disallow a body or trailers in what appeared to be
  a trailers-only response.
* Instead, a trailers-only response is now defined by the lack of body and
  trailers, not the presence of a "grpc-status" header.
* This also tweaks some other error scenarios. If trailers (or an end-stream
  message) is completely missing from a response, it's considered an internal
  error. But if trailers are present, but the "grpc-status" key is missing,
  it's considered an issue determining the status, which is an unknown error.
* Similarly, if a response content-type doesn't appear to be the right
  protocol (like it may have come from a non-RPC server), the error code is
  now unknown. But if it looks like the right protocol but uses the wrong
  sub-format/codec, it's an internal error.
* This is also now more strict about the "compressed" flag in a streaming
  protocol when there was no compression algorithm negotiated. This was
  previously not considered an error if the message in question was empty
  (zero bytes).
header_test.go Show resolved Hide resolved
@akshayjshah akshayjshah changed the title Reconcile trailers-only behavior (and some other error situations) with the behavior of grpc-go Reconcile trailers-only and misc error behavior with grpc-go Feb 16, 2024
envelope.go Outdated Show resolved Hide resolved
envelope.go Outdated Show resolved Hide resolved
@@ -2442,97 +2483,6 @@ func TestClientDisconnect(t *testing.T) {
})
}

func TestTrailersOnlyErrors(t *testing.T) {
Copy link
Member Author

Choose a reason for hiding this comment

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

These tests were for the old classification and no longer apply.

For example, they'd check that if we classify a response as trailers-only (due to presence of grpc-status key), then the client complains (in the form of an RPC error with "internal" code) if there is a non-empty body or non-empty HTTP trailers.

But since we now define trailers-only to be a request without body or HTTP trailers, they are moot. In these situations (where a response has a grpc-status key in headers and a non-empty body) we now just ignore the grpc-status key in headers (which is also what grpc-go does).

protocol_grpc.go Outdated Show resolved Hide resolved
Copy link
Member

@akshayjshah akshayjshah left a comment

Choose a reason for hiding this comment

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

Apart from my suggestions on comments, this looks great. I'm very glad that we've invested in a more thorough conformance testing suite!

jhump and others added 2 commits February 16, 2024 15:08
Co-authored-by: Akshay Shah <akshayjshah@users.noreply.github.com>
@jhump jhump merged commit 2f76b54 into main Feb 16, 2024
12 checks passed
@jhump jhump deleted the jh/revisit-trailers-only branch February 16, 2024 20:48
@jhump jhump added the bug Something isn't working label Feb 16, 2024
@jhump jhump mentioned this pull request Feb 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants