clone

a self-hosted multitenant nostr relay with sites, file storage, git hosting, and inbox and outbox delivery

feat/standalone-relay
tinyrelay / tinyclient / remote_proxy_test.go
remote_proxy_test.go 2.5K
1package tinyclient23import (4 "io"5 "net/http"6 "net/http/httptest"7 "strings"8 "testing"9)1011func TestRemoteProxiesRelayProtocolsWithoutChangingSignedRequest(t *testing.T) {12 const public = "http://client.example"13 upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {14 if r.URL.Path == BackendPath {15 http.Error(w, "unexpected renderer request", 500)16 return17 }18 body, _ := io.ReadAll(r.Body)19 if r.Host != "client.example" || r.Header.Get("Origin") != public || r.Header.Get("Cookie") != "tiny_session=token" {20 t.Errorf("request identity changed: host=%s headers=%v", r.Host, r.Header)21 }22 w.Header().Set("Set-Cookie", "tiny_session=updated; Path=/; HttpOnly; SameSite=Strict")23 w.Header().Set("Content-Type", "text/event-stream")24 w.WriteHeader(202)25 _, _ = io.WriteString(w, r.Method+" "+r.URL.RequestURI()+" "+r.Header.Get("Authorization")+" "+string(body))26 }))27 defer upstream.Close()28 remote, err := NewRemote(RemoteOptions{BackendURL: upstream.URL, PublicURL: public})29 if err != nil {30 t.Fatal(err)31 }32 for _, tc := range []struct{ method, path, auth, body string }{33 {"POST", "/session", "Nostr exact-proof", "signed body"},34 {"POST", "/manage/rpc", "Nostr exact-proof", "signed body"},35 {"POST", "/events", "Nostr exact-proof", "signed body"},36 {"POST", "/query", "Nostr exact-proof", "signed body"},37 {"POST", "/mcp", "Nostr exact-proof", "signed body"},38 {"GET", "/rooms/build/stream?cursor=a%2Fb", "", ""},39 {"GET", "/views/plot/hash.svg", "", ""},40 {"GET", "/repo/raw?ref=main&path=a%2Fb", "", ""},41 {"GET", "/files/raw?hash=123", "", ""},42 {"GET", "/npub1example/repo.git/info/refs?service=git-upload-pack", "", ""},43 {"GET", "/healthz", "", ""},44 {"GET", "/.well-known/nostr.json", "", ""},45 {"GET", "/" + strings.Repeat("a", 64) + ".png", "", ""},46 } {47 t.Run(tc.method+tc.path, func(t *testing.T) {48 request := httptest.NewRequest(tc.method, public+tc.path, strings.NewReader(tc.body))49 request.Header.Set("Authorization", tc.auth)50 request.Header.Set("Origin", public)51 request.Header.Set("Cookie", "tiny_session=token")52 response := httptest.NewRecorder()53 remote.ServeHTTP(response, request)54 want := tc.method + " " + tc.path + " " + tc.auth + " " + tc.body55 if response.Code != 202 || response.Body.String() != want || !strings.Contains(response.Header().Get("Set-Cookie"), "tiny_session=updated") {56 t.Fatalf("proxy changed request: status=%d body=%s", response.Code, response.Body.String())57 }58 })59 }60}