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

feat: skip calling http Write method when response is of empty type #4902

Conversation

reversearrow
Copy link
Contributor

@reversearrow reversearrow commented Nov 4, 2024

References to other Issues or PRs

#4901
#240

Have you read the Contributing Guidelines?

Yes

Brief description of what is fixed or changed

Skip calling the Write() method on the HTTP response writer when the response is empty. This is to avoid code from keep printing the error message below.

2024/11/04 10:49:00 ERROR: Failed to write response: http: request method or response status code does not allow body

Other comments

@reversearrow reversearrow marked this pull request as ready for review November 4, 2024 16:06
@reversearrow
Copy link
Contributor Author

@johanbrandhorst can you please review this PR? Thank you

Copy link
Collaborator

@johanbrandhorst johanbrandhorst left a comment

Choose a reason for hiding this comment

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

Could you please add a test for this behavior? It might be possible to capture the log output in an integration test (https://github.com/grpc-ecosystem/grpc-gateway/blob/main/examples/internal/integration/integration_test.go).

Comment on lines 198 to 201
if _, ok := resp.(*emptypb.Empty); !ok {
if _, err = w.Write(buf); err != nil {
grpclog.Errorf("Failed to write response: %v", err)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I understand the problem, but I don't think this is the right conditional. The error is because we're trying to write a body when the request method doesn't allow it. Shouldn't we just check if req.Method == http.MethodGet or something like that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @johanbrandhorst for the review.

The error occurs because status codes 204 and 304 do not allow a response body.

Ideally, we should check if the response status is one of these codes before attempting to write a body. However, there isn’t a straightforward way to retrieve the status code from http.ResponseWriter after it has been written.

Also, req.Method == http.MethodGet alone is not sufficient, as a GET request can still return a non-empty response body. We could add a check for DELETE method calls, but again, there’s no guarantee that they will always have an empty response.

Copy link
Collaborator

Choose a reason for hiding this comment

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

OK, alternative idea. How about we intercept the error and just don't log it?

Suggested change
if _, ok := resp.(*emptypb.Empty); !ok {
if _, err = w.Write(buf); err != nil {
grpclog.Errorf("Failed to write response: %v", err)
}
if _, err = w.Write(buf); err != nil && !errors.Is(err, http.ErrBodyNotAllowed) {
grpclog.Errorf("Failed to write response: %v", err)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Works for me, thank you. Addressed it here ff571ca

Comment on lines 198 to 201
if _, ok := resp.(*emptypb.Empty); !ok {
if _, err = w.Write(buf); err != nil {
grpclog.Errorf("Failed to write response: %v", err)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

OK, alternative idea. How about we intercept the error and just don't log it?

Suggested change
if _, ok := resp.(*emptypb.Empty); !ok {
if _, err = w.Write(buf); err != nil {
grpclog.Errorf("Failed to write response: %v", err)
}
if _, err = w.Write(buf); err != nil && !errors.Is(err, http.ErrBodyNotAllowed) {
grpclog.Errorf("Failed to write response: %v", err)
}

@johanbrandhorst johanbrandhorst enabled auto-merge (squash) November 6, 2024 01:24
@johanbrandhorst johanbrandhorst merged commit 0b8a90a into grpc-ecosystem:main Nov 6, 2024
17 checks passed
@reversearrow reversearrow deleted the feat/skip_writing_empty_response branch November 6, 2024 15:19
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

Successfully merging this pull request may close these issues.

2 participants