-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
feat: skip calling http Write method when response is of empty type #4902
Conversation
@johanbrandhorst can you please review this PR? Thank you |
There was a problem hiding this 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).
runtime/handler.go
Outdated
if _, ok := resp.(*emptypb.Empty); !ok { | ||
if _, err = w.Write(buf); err != nil { | ||
grpclog.Errorf("Failed to write response: %v", err) | ||
} |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
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) | |
} |
There was a problem hiding this comment.
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
runtime/handler.go
Outdated
if _, ok := resp.(*emptypb.Empty); !ok { | ||
if _, err = w.Write(buf); err != nil { | ||
grpclog.Errorf("Failed to write response: %v", err) | ||
} |
There was a problem hiding this comment.
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?
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) | |
} |
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.Other comments