R6(a): de-stage code, docs, READMEs; split stage6_test
Mechanical, behaviour-preserving removal of Stage N / TODO-N / phase (RN) references from comments, doc-comments, service READMEs, the current-state docs (ARCHITECTURE, FUNCTIONAL+_ru, TESTING, UI_DESIGN), config-file comments, and the .fbs/.proto schema comments. PLAN.md / PRERELEASE.md / CLAUDE.md keep the stage history. - Rename the only stage-named identifiers: registerStage8 -> registerSocialOps, registerStage11 -> registerLinkOps (gateway transcode). - Split stage6_test.go: TestEmailLoginFlow -> email_test.go, TestGuestAutoMatchLeavesNoStats (+ provisionGuest) -> account_test.go. - Regenerated proto bindings (push.pb.go, telegram_grpc.pb.go) from the de-staged .proto comments; FB Go/TS bindings unchanged (flatc strips schema comments). go build/vet/gofmt clean across modules; integration typecheck and pnpm check green.
This commit is contained in:
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
// TestPeerIP covers the client-IP extraction the chat-moderation IP and the per-IP rate
|
||||
// limiter both rely on: the first X-Forwarded-For hop (the real client, once Caddy is
|
||||
// configured to trust its upstream), falling back to the connection peer (Stage 17).
|
||||
// configured to trust its upstream), falling back to the connection peer.
|
||||
func TestPeerIP(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
@@ -35,7 +35,7 @@ import (
|
||||
const heartbeatKind = "heartbeat"
|
||||
|
||||
// Limiter classes, the `class` attribute of gateway_rate_limited_total and the
|
||||
// class field of the periodic rejection report (R3).
|
||||
// class field of the periodic rejection report.
|
||||
const (
|
||||
classUser = "user"
|
||||
classPublic = "public"
|
||||
@@ -43,13 +43,13 @@ const (
|
||||
classAdmin = "admin"
|
||||
)
|
||||
|
||||
// Explicit h2c server sizing (R3, after the R2 stress run questioned the
|
||||
// implicit defaults).
|
||||
// Explicit h2c server sizing, made explicit rather than relying on the
|
||||
// implicit defaults.
|
||||
const (
|
||||
// h2cMaxConcurrentStreams bounds the open streams per client connection — the
|
||||
// x/net default made explicit. A real client holds one Subscribe stream plus a
|
||||
// few unary calls; only a synthetic load multiplexing many players over one
|
||||
// transport approaches it. R7 revisits the sizing.
|
||||
// transport approaches it.
|
||||
h2cMaxConcurrentStreams = 250
|
||||
// h2cIdleTimeout closes a connection with no open streams. A live Subscribe
|
||||
// stream keeps its connection active, so long-lived clients are unaffected;
|
||||
@@ -151,7 +151,7 @@ func (s *Server) HTTPHandler() http.Handler {
|
||||
// working over h2c (docs/ARCHITECTURE.md §12). In the deployed contour the
|
||||
// front caddy owns the /_gm Basic-Auth and Grafana routing; this mount serves
|
||||
// a non-caddy (local) setup. The per-IP admin limiter class guards it —
|
||||
// notably a Basic-Auth brute force (R3).
|
||||
// notably a Basic-Auth brute force.
|
||||
mux.Handle("/_gm/", s.limitAdmin(s.adminProxy))
|
||||
} else {
|
||||
// With the console disabled here, keep /_gm a 404 so the SPA catch-all below
|
||||
@@ -162,14 +162,14 @@ func (s *Server) HTTPHandler() http.Handler {
|
||||
// Mini App) — the single-origin model (docs/ARCHITECTURE.md §13). Both sit below
|
||||
// the h2c wrap so the Connect edge (a more specific prefix) keeps priority, and
|
||||
// each mount falls back to the app shell (index.html) for the hash router. The
|
||||
// public landing moved to its own static container behind the contour caddy
|
||||
// (R3), so the catch-all redirects a stray root hit to the app shell — which
|
||||
// public landing lives in its own static container behind the contour caddy,
|
||||
// so the catch-all redirects a stray root hit to the app shell — which
|
||||
// keeps a local no-caddy run usable.
|
||||
mux.Handle("/telegram/", webui.Handler("/telegram/", "index.html"))
|
||||
mux.Handle("/app/", webui.Handler("/app/", "index.html"))
|
||||
mux.Handle("/", http.RedirectHandler("/app/", http.StatusPermanentRedirect))
|
||||
// Every request body on the public listener is capped (the admin proxy POSTs
|
||||
// included); the h2c server carries explicit stream/idle sizing (R3).
|
||||
// included); the h2c server carries explicit stream/idle sizing.
|
||||
return h2c.NewHandler(maxBodyHandler(s.maxBodyBytes, mux), &http2.Server{
|
||||
MaxConcurrentStreams: h2cMaxConcurrentStreams,
|
||||
IdleTimeout: h2cIdleTimeout,
|
||||
@@ -264,7 +264,7 @@ func (s *Server) Subscribe(ctx context.Context, req *connect.Request[edgev1.Subs
|
||||
// Send an immediate heartbeat so the stream's first byte flushes through the proxy chain
|
||||
// right away and resets edge/client idle timers, instead of the connection sitting silent
|
||||
// until the first tick — which otherwise raced a ~15 s idle timeout and forced a reconnect
|
||||
// every interval (Stage 17).
|
||||
// every interval.
|
||||
if err := stream.Send(&edgev1.Event{Kind: heartbeatKind}); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -294,7 +294,7 @@ func (s *Server) Subscribe(ctx context.Context, req *connect.Request[edgev1.Subs
|
||||
// noteRateLimited accounts one limiter rejection: the aggregate counter, the
|
||||
// per-rejection Debug line and the periodic-report tracker. The operational
|
||||
// signal is the reporter's Warn summary; per-rejection logging stays at Debug so
|
||||
// a rejection flood cannot flood the log (R3).
|
||||
// a rejection flood cannot flood the log.
|
||||
func (s *Server) noteRateLimited(ctx context.Context, class, key, msgType string) {
|
||||
s.metrics.recordRateLimited(ctx, class)
|
||||
s.tracker.Add(class, key)
|
||||
@@ -315,7 +315,7 @@ func (s *Server) rejectRateLimited(ctx context.Context, class, key, msgType stri
|
||||
// of its Basic-Auth check (a credential brute force is exactly what it bounds).
|
||||
// It covers the gateway-fronted /_gm mount; in the deployed contour /_gm reaches
|
||||
// the backend through caddy, whose Basic-Auth has no limiter (stock caddy) — see
|
||||
// docs/ARCHITECTURE.md §12 (R3).
|
||||
// docs/ARCHITECTURE.md §12.
|
||||
func (s *Server) limitAdmin(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ip := peerIP(r.RemoteAddr, r.Header)
|
||||
@@ -340,8 +340,8 @@ func (s *Server) resolve(ctx context.Context, h http.Header) (string, error) {
|
||||
// An unknown or expired token (a backend 4xx) is the client's problem and
|
||||
// stays silent; anything else — a resolve timeout, a refused connection, a
|
||||
// backend 5xx — is an infra failure misread as "unauthenticated" by the
|
||||
// client, so surface the cause (the transient resolves seen under load in
|
||||
// the R2 stress run). The token itself is never logged.
|
||||
// client, so surface the cause (the transient resolves seen under load).
|
||||
// The token itself is never logged.
|
||||
var apiErr *backendclient.APIError
|
||||
if !errors.As(err, &apiErr) || apiErr.Status >= http.StatusInternalServerError {
|
||||
s.log.Warn("session resolve failed", zap.Error(err))
|
||||
|
||||
@@ -85,7 +85,7 @@ func TestExecuteAuthedRequiresSession(t *testing.T) {
|
||||
|
||||
// TestExecuteRateLimitedTracked verifies a limiter rejection returns
|
||||
// ResourceExhausted and lands in the rejection tracker under the public class,
|
||||
// keyed by the client IP (R3).
|
||||
// keyed by the client IP.
|
||||
func TestExecuteRateLimitedTracked(t *testing.T) {
|
||||
backendSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
_, _ = w.Write([]byte(`{"token":"tok","user_id":"u-1","is_guest":true,"display_name":"Guest"}`))
|
||||
@@ -135,7 +135,7 @@ func TestExecuteRateLimitedTracked(t *testing.T) {
|
||||
}
|
||||
|
||||
// TestAdminMountRateLimited verifies the /_gm mount is guarded by the per-IP
|
||||
// admin limiter class ahead of the proxy's Basic-Auth (R3).
|
||||
// admin limiter class ahead of the proxy's Basic-Auth.
|
||||
func TestAdminMountRateLimited(t *testing.T) {
|
||||
backendSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
|
||||
defer backendSrv.Close()
|
||||
@@ -181,7 +181,7 @@ func TestAdminMountRateLimited(t *testing.T) {
|
||||
|
||||
// TestExecuteOversizedPayloadRejected verifies the request-body cap: an Execute
|
||||
// message above GATEWAY_MAX_BODY_BYTES is refused at the edge without reaching
|
||||
// the backend (R3).
|
||||
// the backend.
|
||||
func TestExecuteOversizedPayloadRejected(t *testing.T) {
|
||||
client, cleanup := newEdge(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Error("backend must not be called for an oversized payload")
|
||||
@@ -198,7 +198,7 @@ func TestExecuteOversizedPayloadRejected(t *testing.T) {
|
||||
}
|
||||
|
||||
// TestRootRedirectsToApp verifies the gateway no longer serves a landing at "/"
|
||||
// (it lives in the landing container since R3): a stray root hit is redirected
|
||||
// (it lives in the landing container): a stray root hit is redirected
|
||||
// to the app shell.
|
||||
func TestRootRedirectsToApp(t *testing.T) {
|
||||
front := httptest.NewServer(connectsrv.NewServer(connectsrv.Deps{}).HTTPHandler())
|
||||
|
||||
Reference in New Issue
Block a user