package main import ( "crypto/sha256" "net/http" "net/http/httptest" "net/url" "testing" ) func TestProxyForwardsResponseAndStripsClientIPHeaders(t *testing.T) { upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if got := r.Header.Get("X-Forwarded-For"); got != "" { t.Fatalf("forwarded client IP header leaked: %q", got) } w.Header().Set("Subscription-Userinfo", "upload=1; download=2; total=3") w.Header().Add("Set-Cookie", "a=b") w.WriteHeader(http.StatusAccepted) _, _ = w.Write([]byte("raw-subscription")) })) defer upstream.Close() p := &proxy{ tokenHash: sha256ForTest("secret"), client: upstream.Client(), } req := httptest.NewRequest(http.MethodGet, "/secret?url="+url.QueryEscape(upstream.URL+"/sub?token=abc"), nil) req.Header.Set("X-Forwarded-For", "1.2.3.4") rec := httptest.NewRecorder() p.ServeHTTP(rec, req) if rec.Code != http.StatusAccepted { t.Fatalf("status = %d", rec.Code) } if got := rec.Body.String(); got != "raw-subscription" { t.Fatalf("body = %q", got) } if got := rec.Header().Get("Subscription-Userinfo"); got == "" { t.Fatal("missing upstream response header") } if got := rec.Header().Values("Set-Cookie"); len(got) != 1 || got[0] != "a=b" { t.Fatalf("set-cookie = %#v", got) } } func TestRejectsBadToken(t *testing.T) { p := &proxy{tokenHash: sha256ForTest("secret")} req := httptest.NewRequest(http.MethodGet, "/bad?url=https://example.com", nil) rec := httptest.NewRecorder() p.ServeHTTP(rec, req) if rec.Code != http.StatusNotFound { t.Fatalf("status = %d", rec.Code) } } func sha256ForTest(s string) [32]byte { return sha256.Sum256([]byte(s)) }