@ 261101.7

261029.3 · 589e88fb89c93bd3a9996bc8d42a847172ba1f7a

A public tree's git errors hide the cache, and a cut lookup is not kept

git's errors name the paths it was given, so a failed log or show on a public tree could still print where the cache lies. gitErr now writes it as "cache", as the clone's steps already do.

reach returned neither options nor an error when its context ended after a lookup that worked. git then fails on the dead context anyway, but the pin should not rest on that. reach now returns what it found and skips its cache only for a lookup the end cut short.

TestWebPublic had loosened its check so the refused loopback listing passed. Loopback counts as the open internet there now, so the listing runs as it did and the check is whole again.

reading declarations

git.go

@@ -313,11 +313,15 @@ func (t *tree) warm() { 	logInfo("warmed git answers for %s in %d ms: %s", t.dir, time.Since(start).Milliseconds(), strings.Join(names, ", ")) } -// gitErr is err, or on a share errNoHistory.+// gitErr is err, or on a share errNoHistory. On a public tree it names+// the cache as "cache", since git's errors name the paths it was given. func (t *tree) gitErr(err error) error { 	if t.shared { 		return errNoHistory 	}+	if t.public && err != nil && cacheRoot != "" && strings.Contains(err.Error(), cacheRoot) {+		return errors.New(strings.ReplaceAll(err.Error(), cacheRoot, "cache"))+	} 	return err } 

reach.go

@@ -78,7 +78,8 @@ func reach(ctx context.Context, host string) ([]string, error) { 		return a.args, a.err 	} 	args, err := lookupReach(ctx, host)-	if ctx.Err() != nil {+	// A lookup cut short says nothing of the host, so it is not kept.+	if err != nil && ctx.Err() != nil { 		return nil, err 	} 	reachMu.Lock()

web_test.go

@@ -343,6 +343,11 @@ func TestWebPublic(t *testing.T) { 	f.repo(t, "acct/r", map[string]string{"README.md": "x\n"}) 	w := testWeb(t, defaultDisk) 	w.public, w.srv.public = true, true+	// The forge listens on loopback, which a public server's listings+	// refuse; here it stands for the open internet.+	open := reachable+	reachable = func(netip.Addr) bool { return true }+	t.Cleanup(func() { reachable = open }) 	get := func(path string) *httptest.ResponseRecorder { 		return get(w.srv.handler(), path, "Host", "visitor.example.org") 	}@@ -355,7 +360,7 @@ func TestWebPublic(t *testing.T) { 	if body := get("/").Body.String(); strings.Contains(body, "acct/r") || strings.Contains(body, "The cache") { 		t.Errorf("the root shows the cache:\n%s", body) 	}-	if rec := read(t, w, "/"+f.host+"/acct"); rec.Code != http.StatusNotFound || strings.Contains(rec.Body.String(), "acct/r/\"") {+	if rec := read(t, w, "/"+f.host+"/acct"); rec.Code != http.StatusNotFound || strings.Contains(rec.Body.String(), "acct/r") { 		t.Errorf("a listing falls back to the cache: %d\n%s", rec.Code, rec.Body) 	} 	if rec := get("/" + f.host + "/acct/r/README.md"); rec.Code != http.StatusOK {