Comments (8)
Hm, thanks for your report, that is unfortunate. As I see it though, you could still work around this in your code with a http.ResponseWriter
wrapper that intercepts the setting of the Content-Type
header, which would allow you to set that header in your gzip middleware instead. As long as there is some workaround, I think I'd prefer not to introduce other options. Can you see if that fixes your issue?
from grpc-gateway.
Yes. I can intercept this on my side and fix the issue for my case.
Mostly wanted to point it out as more people may face the same breaking change by updating grpc-gateway package if they're using any on-the-fly modification. We could prevent others from facing the same issue in future by making Content-Length header as an opt-in option.
I'll fix my case in any case.
from grpc-gateway.
Thanks for your issue! I'd like to ask some clarifying questions:
- Could you elaborate on the behavior of the
net/http
handler in this case? If they choose to only do this for "small responses", why should we do anything differently? - Is this something that could be by a custom middleware instead? I'm thinking something that wraps the
http.ResponseWriter
and counts the bytes written, setting the header before writing it to the wire. That would mean we wouldn't have to add it as an option here. - Thanks for the PR, but please refrain from submitting anything until we've discussed the best way forward.
from grpc-gateway.
Hey @johanbrandhorst,
On question 1:
// If [ResponseWriter.WriteHeader] has not yet been called, Write calls
// WriteHeader(http.StatusOK) before writing the data. If the Header
// does not contain a Content-Type line, Write adds a Content-Type set
// to the result of passing the initial 512 bytes of written data to
// [DetectContentType]. Additionally, if the total size of all written
// data is under a few KB and there are no Flush calls, the
// Content-Length header is added automatically.
https://github.com/golang/go/blob/960fa9bf66139e535d89934f56ae20a0e679e203/src/net/http/server.go#L1582 also has some additional comments.
The library doesn't know if the calling code is going to call write once or multiple times. In this case, we know the Write method is only called once as long as doForwardTrailers isn't set.
On question 2:
I'm not sure of a way this can be done without writing the data to a buffer first, which adds additional allocations. This could be problematic for very large responses.
from grpc-gateway.
Thanks for your responses. I wonder if we can't just enable this behavior by default since we know the size of the buffer we want to write. Worst case it's going to add a content-length header where we didn't before, but that seems like a better experience. What do you think? Feel free to update the PR and remove the option if you agree.
from grpc-gateway.
I'm supportive of that, the only edge case I could think of is if a user already had some other middleware that was writing the header and maybe causing some trouble there. I'll update the PR now.
from grpc-gateway.
I recreated the PR with a cleaner history
from grpc-gateway.
Hi. This introduced a bug in my code after upgrading to the newer version.
In my code base, I apply an on-the-fly gzip compression of the response on a higher level where the gzip writer is passed as the response writer. I was relying on the Go's automatically added Content-Length
header for this.
With the following changes, Content-Length
is set by the gateway internally and when gzip response is being written, I often receive http: wrote more than the declared Content-Length
. This happens when the response is empty (i.e. {}
) and gateway adds the header Content-Length: 2
, but gzip compressed response is bigger as it needs to add at least 10 bytes for its header.
grpc-gateway/runtime/handler.go
Lines 193 to 195 in e99e853
May I know if we can plan anything to address that on the gateway level? Something like either enable or disable this new behavior using a feature flag?
Although in my case, it happened for an emptypb response, it still may happen for any type of on-the-fly response modification.
from grpc-gateway.
Related Issues (20)
- Grpc gateway project starter script HOT 1
- Support Service doc comments for OpenApi/Swagger generation HOT 4
- [Feature Request] Provide a legit way to override HTTP Response. HOT 7
- How to get HTTP headers in custom Marshaller? HOT 1
- streaming response does not return text/event-stream content-type HOT 14
- Define "CustomHttpPattern" under "google.api.http", using the plug-in protoc-gen-openapiv2 encountered no swagger documentation generated. HOT 1
- Support Protobuf Editions HOT 7
- Dealing with 304 response without printing errors HOT 5
- How to pass the error 400 in fieldmask if a unknow field is send? HOT 1
- google.protobuf.Empty as response serializes to not empty response on REST client depending on request headers HOT 4
- ERROR: Failed to extract ServerMetadata from context HOT 13
- Placement for unique items in array type is located in the wrong place HOT 1
- Support explicit omitempty annotation in proto HOT 1
- gateway to multiple grpc services defined in two different files HOT 3
- bug: URL Query parameter not bind to `Optional` proto message field HOT 5
- How can register multiple gRPC services in `main.go` at the same time? HOT 1
- Feature request: virtual oneof property HOT 3
- Unable to mark the body parameter as REQUIRED when part of the proto message is path param HOT 2
- google.protobuf.Any generated OpenAPI v2 yaml that is potentially incorrect HOT 1
- Incorrect google.protobuf.Empty representation with oneof in GET request HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from grpc-gateway.