Skip to content

Commit 8b14e99

Browse files
dmitshurgopherbot
authored andcommitted
cmd/go/internal/modfetch: show real URL in response body read errors
CL 233437 added a redactedURL field to proxyRepo, a struct that already had a field named 'url'. Neither fields were documented, so the similar names suggest the most natural interpretation that proxyRepo.redactedURL is equivalent to proxyRepo.url.Redacted() rather than something else. That's possibly why it was joined with the module version in CL 406675. It turns out the two URLs differ in more than just redaction: one is the base proxy URL with (escaped) module path joined, the other is just the base proxy URL, in redacted form. Document and rename the fields to make the distinction more clear, and include all 3 of base module proxy URL + module path + module version in the reported URL, rather than just the first and third bits as seen in the errors at https://go.dev/issue/51323#issuecomment-1735812250. For #51323. Updates #38680. Updates #52727. Change-Id: Ib4b134b548adeec826ee88fe51a2cf580fde0516 Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest Reviewed-on: https://go-review.googlesource.com/c/go/+/532035 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Bryan Mills <[email protected]> Auto-Submit: Dmitri Shuralyov <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
1 parent e2d9574 commit 8b14e99

File tree

1 file changed

+26
-22
lines changed

1 file changed

+26
-22
lines changed

Diff for: src/cmd/go/internal/modfetch/proxy.go

+26-22
Original file line numberDiff line numberDiff line change
@@ -185,41 +185,45 @@ func TryProxies(f func(proxy string) error) error {
185185
}
186186

187187
type proxyRepo struct {
188-
url *url.URL
189-
path string
190-
redactedURL string
188+
url *url.URL // The combined module proxy URL joined with the module path.
189+
path string // The module path (unescaped).
190+
redactedBase string // The base module proxy URL in [url.URL.Redacted] form.
191191

192192
listLatestOnce sync.Once
193193
listLatest *RevInfo
194194
listLatestErr error
195195
}
196196

197197
func newProxyRepo(baseURL, path string) (Repo, error) {
198+
// Parse the base proxy URL.
198199
base, err := url.Parse(baseURL)
199200
if err != nil {
200201
return nil, err
201202
}
203+
redactedBase := base.Redacted()
202204
switch base.Scheme {
203205
case "http", "https":
204206
// ok
205207
case "file":
206208
if *base != (url.URL{Scheme: base.Scheme, Path: base.Path, RawPath: base.RawPath}) {
207-
return nil, fmt.Errorf("invalid file:// proxy URL with non-path elements: %s", base.Redacted())
209+
return nil, fmt.Errorf("invalid file:// proxy URL with non-path elements: %s", redactedBase)
208210
}
209211
case "":
210-
return nil, fmt.Errorf("invalid proxy URL missing scheme: %s", base.Redacted())
212+
return nil, fmt.Errorf("invalid proxy URL missing scheme: %s", redactedBase)
211213
default:
212-
return nil, fmt.Errorf("invalid proxy URL scheme (must be https, http, file): %s", base.Redacted())
214+
return nil, fmt.Errorf("invalid proxy URL scheme (must be https, http, file): %s", redactedBase)
213215
}
214216

217+
// Append the module path to the URL.
218+
url := base
215219
enc, err := module.EscapePath(path)
216220
if err != nil {
217221
return nil, err
218222
}
219-
redactedURL := base.Redacted()
220-
base.Path = strings.TrimSuffix(base.Path, "/") + "/" + enc
221-
base.RawPath = strings.TrimSuffix(base.RawPath, "/") + "/" + pathEscape(enc)
222-
return &proxyRepo{base, path, redactedURL, sync.Once{}, nil, nil}, nil
223+
url.Path = strings.TrimSuffix(base.Path, "/") + "/" + enc
224+
url.RawPath = strings.TrimSuffix(base.RawPath, "/") + "/" + pathEscape(enc)
225+
226+
return &proxyRepo{url, path, redactedBase, sync.Once{}, nil, nil}, nil
223227
}
224228

225229
func (p *proxyRepo) ModulePath() string {
@@ -253,22 +257,22 @@ func (p *proxyRepo) versionError(version string, err error) error {
253257
}
254258

255259
func (p *proxyRepo) getBytes(ctx context.Context, path string) ([]byte, error) {
256-
body, err := p.getBody(ctx, path)
260+
body, redactedURL, err := p.getBody(ctx, path)
257261
if err != nil {
258262
return nil, err
259263
}
260264
defer body.Close()
261265

262266
b, err := io.ReadAll(body)
263267
if err != nil {
264-
// net/http doesn't add context to Body errors, so add it here.
268+
// net/http doesn't add context to Body read errors, so add it here.
265269
// (See https://go.dev/issue/52727.)
266-
return b, &url.Error{Op: "read", URL: strings.TrimSuffix(p.redactedURL, "/") + "/" + path, Err: err}
270+
return b, &url.Error{Op: "read", URL: redactedURL, Err: err}
267271
}
268272
return b, nil
269273
}
270274

271-
func (p *proxyRepo) getBody(ctx context.Context, path string) (r io.ReadCloser, err error) {
275+
func (p *proxyRepo) getBody(ctx context.Context, path string) (r io.ReadCloser, redactedURL string, err error) {
272276
fullPath := pathpkg.Join(p.url.Path, path)
273277

274278
target := *p.url
@@ -277,13 +281,13 @@ func (p *proxyRepo) getBody(ctx context.Context, path string) (r io.ReadCloser,
277281

278282
resp, err := web.Get(web.DefaultSecurity, &target)
279283
if err != nil {
280-
return nil, err
284+
return nil, "", err
281285
}
282286
if err := resp.Err(); err != nil {
283287
resp.Body.Close()
284-
return nil, err
288+
return nil, "", err
285289
}
286-
return resp.Body, nil
290+
return resp.Body, resp.URL, nil
287291
}
288292

289293
func (p *proxyRepo) Versions(ctx context.Context, prefix string) (*Versions, error) {
@@ -370,7 +374,7 @@ func (p *proxyRepo) Stat(ctx context.Context, rev string) (*RevInfo, error) {
370374
}
371375
info := new(RevInfo)
372376
if err := json.Unmarshal(data, info); err != nil {
373-
return nil, p.versionError(rev, fmt.Errorf("invalid response from proxy %q: %w", p.redactedURL, err))
377+
return nil, p.versionError(rev, fmt.Errorf("invalid response from proxy %q: %w", p.redactedBase, err))
374378
}
375379
if info.Version != rev && rev == module.CanonicalVersion(rev) && module.Check(p.path, rev) == nil {
376380
// If we request a correct, appropriate version for the module path, the
@@ -391,7 +395,7 @@ func (p *proxyRepo) Latest(ctx context.Context) (*RevInfo, error) {
391395
}
392396
info := new(RevInfo)
393397
if err := json.Unmarshal(data, info); err != nil {
394-
return nil, p.versionError("", fmt.Errorf("invalid response from proxy %q: %w", p.redactedURL, err))
398+
return nil, p.versionError("", fmt.Errorf("invalid response from proxy %q: %w", p.redactedBase, err))
395399
}
396400
return info, nil
397401
}
@@ -422,17 +426,17 @@ func (p *proxyRepo) Zip(ctx context.Context, dst io.Writer, version string) erro
422426
return p.versionError(version, err)
423427
}
424428
path := "@v/" + encVer + ".zip"
425-
body, err := p.getBody(ctx, path)
429+
body, redactedURL, err := p.getBody(ctx, path)
426430
if err != nil {
427431
return p.versionError(version, err)
428432
}
429433
defer body.Close()
430434

431435
lr := &io.LimitedReader{R: body, N: codehost.MaxZipFile + 1}
432436
if _, err := io.Copy(dst, lr); err != nil {
433-
// net/http doesn't add context to Body errors, so add it here.
437+
// net/http doesn't add context to Body read errors, so add it here.
434438
// (See https://go.dev/issue/52727.)
435-
err = &url.Error{Op: "read", URL: strings.TrimSuffix(p.redactedURL, "/") + "/" + path, Err: err}
439+
err = &url.Error{Op: "read", URL: redactedURL, Err: err}
436440
return p.versionError(version, err)
437441
}
438442
if lr.N <= 0 {

0 commit comments

Comments
 (0)