From: Bryan C. Mills Date: Mon, 16 May 2022 19:25:28 +0000 (-0400) Subject: cmd/go/internal/modfetch: wrap errors from HTTP response bodies X-Git-Tag: go1.19beta1~129 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=7ce38641564e5c0183bb09df8c523caf5e0ab8e1;p=gostls13.git cmd/go/internal/modfetch: wrap errors from HTTP response bodies The Read method on the Body returned from a net/http.Transport does not wrap errors returned by the underlying io.Reader and returns a bare io.ErrUnexpectedEOF if the body is shorter than the declared Content-Length. Since we can't feasibly add detail on the net/http side without breaking established users, we must instead add detail on the caller side. Since the net/http client uses url.Error for most of its own errors, we use that same error type here. I have not added a regression test for this change. (While it is theoretically possible to set up a GOPROXY that returns incorrect Content-Length headers, the change seems straightforward enough that it isn't worth the complex test setup.) Fixes #52727. Change-Id: Id00b04ae4fd518148106a49188fe169aadbcce2c Reviewed-on: https://go-review.googlesource.com/c/go/+/406675 Auto-Submit: Bryan Mills Run-TryBot: Bryan Mills Reviewed-by: Michael Matloob TryBot-Result: Gopher Robot --- diff --git a/src/cmd/go/internal/modfetch/proxy.go b/src/cmd/go/internal/modfetch/proxy.go index 31d453c807..4d63dd5648 100644 --- a/src/cmd/go/internal/modfetch/proxy.go +++ b/src/cmd/go/internal/modfetch/proxy.go @@ -247,10 +247,17 @@ func (p *proxyRepo) getBytes(path string) ([]byte, error) { return nil, err } defer body.Close() - return io.ReadAll(body) + + b, err := io.ReadAll(body) + if err != nil { + // net/http doesn't add context to Body errors, so add it here. + // (See https://go.dev/issue/52727.) + return b, &url.Error{Op: "read", URL: pathpkg.Join(p.redactedURL, path), Err: err} + } + return b, nil } -func (p *proxyRepo) getBody(path string) (io.ReadCloser, error) { +func (p *proxyRepo) getBody(path string) (r io.ReadCloser, err error) { fullPath := pathpkg.Join(p.url.Path, path) target := *p.url @@ -407,7 +414,8 @@ func (p *proxyRepo) Zip(dst io.Writer, version string) error { if err != nil { return p.versionError(version, err) } - body, err := p.getBody("@v/" + encVer + ".zip") + path := "@v/" + encVer + ".zip" + body, err := p.getBody(path) if err != nil { return p.versionError(version, err) } @@ -415,6 +423,9 @@ func (p *proxyRepo) Zip(dst io.Writer, version string) error { lr := &io.LimitedReader{R: body, N: codehost.MaxZipFile + 1} if _, err := io.Copy(dst, lr); err != nil { + // net/http doesn't add context to Body errors, so add it here. + // (See https://go.dev/issue/52727.) + err = &url.Error{Op: "read", URL: pathpkg.Join(p.redactedURL, path), Err: err} return p.versionError(version, err) } if lr.N <= 0 {