Skip to content
quarry Artifact [4397dd66d3]
Login

Artifact [4397dd66d3]

Artifact 4397dd66d352ec5f30a9a2ef0a06d863d4f4b14a477f59711fc44e5baff16387:


package xfer

import (
	"bytes"
	"net/http"
	"net/http/httptest"
	"testing"
)

// A repository under a takedown answers a sync with the protocol's own
// error, carrying the gate's sentence, and never reaches the child; a
// repository the read gate hides is not asked about at all.
func TestATakedownRefusesASyncInWords(t *testing.T) {
	f := gated()
	defer f.Close()
	srv, _ := fakeChild(t, f, "alpha")
	reached := false
	srv.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		reached = true
		w.Header().Set("Content-Type", "application/x-fossil")
		w.Write([]byte("pragma ok\n"))
	})
	f.SetHoldGate(func(_ *http.Request, repo, _ string) string {
		return "this repository is unavailable for legal reasons"
	})
	w, _, _ := postRaw(t, f, encodeContainer([]byte("pull SRV PRJ\n")))
	if w.Code != http.StatusUnauthorized {
		t.Errorf("FAIL: a caller who offered nothing answered %d, want the 401 challenge", w.Code)
	}
	w = postAs(t, f, encodeContainer([]byte("pull SRV PRJ\n")))
	if reached {
		t.Error("FAIL: the child served a repository under a takedown")
	}
	if body := decodeContainer(w.Body.Bytes()); !bytes.Contains(body, []byte(`error this\srepository\sis\sunavailable\sfor\slegal\sreasons`)) {
		t.Errorf("FAIL: the reply carries no error card: %q", body)
	}

	asked := false
	f.SetReadGate(func(*http.Request, string, string) bool { return false })
	f.SetHoldGate(func(*http.Request, string, string) string { asked = true; return "held" })
	postRaw(t, f, encodeContainer([]byte("pull SRV PRJ\n")))
	if asked {
		t.Error("FAIL: the hold gate was asked about a repository the read gate hides")
	}
}

// postAs is postRaw with a Basic credential, the second round a stock
// client sends after a challenge.
func postAs(t *testing.T, f *Fronter, raw []byte) *httptest.ResponseRecorder {
	t.Helper()
	req := httptest.NewRequest(http.MethodPost, "/r/alpha", bytes.NewReader(raw))
	req.SetPathValue("repo", "alpha")
	req.Header.Set("Content-Type", "application/x-fossil")
	req.SetBasicAuth("someone", "pw")
	w := httptest.NewRecorder()
	f.ServeHTTP(w, req)
	return w
}