Closed
Description
What version of Go are you using (go version
)?
$ go version go version go1.15 darwin/amd64
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GO111MODULE="on" GOARCH="amd64" GOBIN="" GOCACHE="/Users/gaojingyu/Library/Caches/go-build" GOENV="/Users/gaojingyu/Library/Application Support/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="darwin" GONOPROXY="*.byted.org" GONOSUMDB="*.byted.org" GOOS="darwin" GOPATH="/Users/gaojingyu/go" GOPRIVATE="*.byted.org" GOPROXY="https://go-mod-proxy.byted.org" GOROOT="/usr/local/Cellar/go/1.13.6/libexec" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/Cellar/go/1.13.6/libexec/pkg/tool/darwin_amd64" GCCGO="gccgo" AR="ar" CC="clang" CXX="clang++" CGO_ENABLED="1" GOMOD="/Users/gaojingyu/Tmp/go.mod" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/r1/fgd1nc4s32zcy8myvl17np8r0000gp/T/go-build991311603=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
Now in http.NewRequestWithContext
it check wether body type is a *bytes.Buffer
,*bytes.Reader
or *strings.Reader
, then call Len()
to get content-length.
What did you expect to see?
Check wether the body type implement interfae{Len()int}
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
rsc commentedon Sep 2, 2020
We know that Len is the right choice for those three types.
There's no widespread "Len-er" interface in Go, though, so I am skeptical of calling it always.
Maybe on some types Len might be a number of records?
jingyugao commentedon Sep 3, 2020
How about check
ContentLength
is zero?If
ContentLength
is zero andbody
implement interfae{Len()int},then assign Len() toContentLength
.[-]proposal:net/http:support get content-length from interface{Len() int}[/-][+]proposal: net/http: automatically set Content-Length from Len method on Body[/+]rsc commentedon Sep 3, 2020
@jingyugao I certainly agree that if the caller has explicitly set ContentLength then it should not be replaced.
But that doesn't really address my objection. Content-Length is not a hint. It is a promise, and the code should not make a promise unless it is sure it can be kept. The code is sure for the three special-case types (which are very common). The code cannot be anywhere near as sure about any type that happens to have a
Len() int
method. Len is measured in elements, which does not always mean bytes. (For example, suppose io.MultiReader returned a concrete implementation with a Len method that returned the number of underlying readers.)Is there some widespread body implementation you are concerned about handling?
rsc commentedon Sep 23, 2020
Adding to the proposal minutes.
Len() int
still seems like not enough signal for me.bcmills commentedon Sep 23, 2020
In #16474 (comment), @ianlancetaylor observed:
For this case I would share Russ's concern about
Len
indicating the length of some container in units other than bytes — perhaps runes, number of entries, or similar.rsc commentedon Sep 30, 2020
Based on the discussion above, this seems like a likely decline.
rsc commentedon Oct 7, 2020
No change in consensus, so declined.