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
net/http: Response.Write does not write Content-Length when 0 #5381
Labels
Milestone
Comments
Comment 1 by PieterDroogendijk: The given example also does not write Content-Length when it is not 0. If the Response has no Body, it has no Content-Length (though perhaps it should.) http://play.golang.org/p/SiN2HojWb0 does provide a body, and indeed when ContentLength == 0 it is not present in the header. |
The given example also does not write Content-Length when it is not 0. If the Response has no Body, it has no Content-Length (though perhaps it should.) http://play.golang.org/p/SiN2HojWb0 does provide a body, and indeed when ContentLength == 0 it is not present in the header. |
FWIW, the HTTP server code does the right thing. I assume you're writing your own HTTP server? One way to fix this is: in Response.Write, see if the ContentLength is zero and the Body is non-nil. If zero, read a byte, checking for EOF. If it's EOF immediately, write out a "Content-Length: 0". If it's not EOF, don't send a Content-Length header. And re-write out the byte before copying the rest of resp.Body. That part isn't contentious. Where it gets trickier is what ResponseWrite should do if ContentLength is 0 (unset) and there's a body: chunked encoding or not? Function of which other headers are set? Set a "Transfer-Encoding: chunked"? But I think that's all getting outside the scope of what this method should do. Like I said, the http.Server code does all this correctly already, so you must be writing your own server, which means you are probably doing lots of this sort of stuff now, right? If not, what's the actual problem? Labels changed: added priority-later, suggested, removed priority-triage. Status changed to Accepted. |
Related: issue #5357 |
Yes, this bug came up while working on a server implementation. It's pretty easy to work around[1], and sort out the chunked encoding behavior, etc. I think it makes sense to have some basic logic in Response.Write to decide when to send the Content-Length, but nothing complex. As long as the behavior is documented and makes sense, then servers using it can easily implement the exact behavior they want. I propose this behavior: if res.ContentLength > 0 || res.ContentLength == 0 && res.Body != nil { // write Content-Length } This stays out of the way of server implementors and doesn't try to do anything magical or unexpected. No need for the heuristic here, Response.ContentLength is already explicitly specified as unknown (chunked) if -1. [1] https://github.com/fitstar/falcore/blob/a3c31f03fec11a62d3f49d016b041d1924cd997a/server.go#L297-L331 |
In the case res.ContentLength == 0 && res.Body != nil, you can't just "// write Content-Length" ... what would you write? You can't write "Content-Length: -1". We can't slurp it all in-memory, We _can_ read one byte to decide between "Content-Length: 0" and ????? where ????? is either no header (weird?) and "Transfer-Encoding: chunked" (which I don't want to get into). So which is it? |
> In the case res.ContentLength == 0 && res.Body != nil, you can't just "// write Content-Length" ... what would you write? Content-Length: 0 It should be an error to pass a body with length > 0 and Content-Length == 0. From the docs: // ContentLength records the length of the associated content. The // value -1 indicates that the length is unknown. Unless Request.Method // is "HEAD", values >= 0 indicate that the given number of bytes may // be read from Body. ContentLength int64 The Content-Length header should never be written when -1 (in most cases this indicates chunked encoding). |
No Content-Length. If Response.TransferEncoding is set, the value of it. Two options for handling nil: 1) "chunked" 2) No Transfer-Encoding header. I like #1, but the docs say otherwise: // Contains transfer encodings from outer-most to inner-most. Value is // nil, means that "identity" encoding is used. TransferEncoding []string |
Issue #6762 has been merged into this issue. |
CL https://golang.org/cl/85740046 mentions this issue. |
This issue was closed by revision a30eaa1. Status changed to Fixed. |
titanous
added
fixed
Suggested
Issues that may be good for new contributors looking for work to do.
labels
Apr 11, 2014
This issue was closed.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
The text was updated successfully, but these errors were encountered: