From 2e78be8f1b88ea090fb762ff44926e9aa6090d3b Mon Sep 17 00:00:00 2001 From: Anirudh Oppiliappan Date: Tue, 3 Mar 2026 18:08:14 +0200 Subject: [PATCH] appview/oauth: set x-ratelimit-bypass for pds xrpc requests We're hitting 429s due to high load. This allows the appview to bypass otherwise normal rate limits on the PDS. Signed-off-by: Anirudh Oppiliappan --- appview/config/config.go | 1 + appview/oauth/handler.go | 20 ++++++++++++++------ appview/state/state.go | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/appview/config/config.go b/appview/config/config.go index 1c93b366..92b10219 100644 --- a/appview/config/config.go +++ b/appview/config/config.go @@ -17,6 +17,7 @@ type CoreConfig struct { AppviewName string `env:"APPVIEW_Name, default=Tangled"` Dev bool `env:"DEV, default=false"` DisallowedNicknamesFile string `env:"DISALLOWED_NICKNAMES_FILE"` + RateLimitBypass string `env:"PDS_RATE_LIMIT_BYPASS"` // temporarily, to add users to default knot and spindle AppPassword string `env:"APP_PASSWORD"` diff --git a/appview/oauth/handler.go b/appview/oauth/handler.go index 833e99e9..8d64cf24 100644 --- a/appview/oauth/handler.go +++ b/appview/oauth/handler.go @@ -130,7 +130,7 @@ func (o *OAuth) addToDefaultSpindle(did string) { } l.Debug("adding to default spindle") - session, err := CreateAppPasswordSession(o.IdResolver, o.Config.Core.AppPassword, consts.TangledDid) + session, err := CreateAppPasswordSession(o.IdResolver, o.Config.Core.AppPassword, consts.TangledDid, o.Config.Core.RateLimitBypass) if err != nil { l.Error("failed to create session", "err", err) return @@ -169,7 +169,7 @@ func (o *OAuth) addToDefaultKnot(did string) { } l.Debug("adding to default knot") - session, err := CreateAppPasswordSession(o.IdResolver, o.Config.Core.AppPassword, consts.TangledDid) + session, err := CreateAppPasswordSession(o.IdResolver, o.Config.Core.AppPassword, consts.TangledDid, o.Config.Core.RateLimitBypass) if err != nil { l.Error("failed to create session", "err", err) return @@ -244,12 +244,13 @@ func (o *OAuth) ensureTangledProfile(sessData *oauth.ClientSessionData) { // create a AppPasswordSession using apppasswords type AppPasswordSession struct { - AccessJwt string `json:"accessJwt"` - PdsEndpoint string - Did string + AccessJwt string `json:"accessJwt"` + PdsEndpoint string + Did string + RateLimitBypass string } -func CreateAppPasswordSession(res *idresolver.Resolver, appPassword, did string) (*AppPasswordSession, error) { +func CreateAppPasswordSession(res *idresolver.Resolver, appPassword, did, rateLimitBypass string) (*AppPasswordSession, error) { if appPassword == "" { return nil, fmt.Errorf("no app password configured") } @@ -279,6 +280,9 @@ func CreateAppPasswordSession(res *idresolver.Resolver, appPassword, did string) return nil, fmt.Errorf("failed to create session request: %v", err) } sessionReq.Header.Set("Content-Type", "application/json") + if rateLimitBypass != "" { + sessionReq.Header.Set("x-ratelimit-bypass", rateLimitBypass) + } client := &http.Client{Timeout: 30 * time.Second} sessionResp, err := client.Do(sessionReq) @@ -298,6 +302,7 @@ func CreateAppPasswordSession(res *idresolver.Resolver, appPassword, did string) session.PdsEndpoint = pdsEndpoint session.Did = did + session.RateLimitBypass = rateLimitBypass return &session, nil } @@ -328,6 +333,9 @@ func (s *AppPasswordSession) putRecord(record any, collection string) error { req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+s.AccessJwt) + if s.RateLimitBypass != "" { + req.Header.Set("x-ratelimit-bypass", s.RateLimitBypass) + } client := &http.Client{Timeout: 30 * time.Second} resp, err := client.Do(req) diff --git a/appview/state/state.go b/appview/state/state.go index cf604681..271bdc62 100644 --- a/appview/state/state.go +++ b/appview/state/state.go @@ -622,7 +622,7 @@ func fetchBskyPosts(ctx context.Context, res *idresolver.Resolver, config *confi return } - session, err := oauth.CreateAppPasswordSession(res, config.Core.AppPassword, consts.TangledDid) + session, err := oauth.CreateAppPasswordSession(res, config.Core.AppPassword, consts.TangledDid, config.Core.RateLimitBypass) if err != nil { logger.Error("failed to create appassword session... skipping fetch", "err", err) return -- 2.51.2