···991010 appbsky "github.com/bluesky-social/indigo/api/bsky"
1111 lexutil "github.com/bluesky-social/indigo/lex/util"
1212- "github.com/bluesky-social/indigo/util"
13121413 "github.com/carlmjohnson/versioninfo"
1514)
···103102104103 var blobBytes []byte
105104106106- // TODO: better way to do this, eg a shared client?
107107- client := util.RobustHTTPClient()
105105+ // TODO: potential security issue here with malformed or "localhost" PDS endpoint
108106 pdsEndpoint := c.Account.Identity.PDSEndpoint()
109107 xrpcURL := fmt.Sprintf("%s/xrpc/com.atproto.sync.getBlob?did=%s&cid=%s", pdsEndpoint, c.Account.Identity.DID, blob.Ref)
110108···114112 }
115113116114 req.Header.Set("User-Agent", "indigo-automod/"+versioninfo.Short())
117117- // TODO: more robust PDS hostname check
115115+ // TODO: more robust PDS hostname check (eg, future trailing slash or partial path)
118116 if c.engine.BskyClient.Headers != nil && strings.HasSuffix(pdsEndpoint, ".bsky.network") {
119117 val, ok := c.engine.BskyClient.Headers["x-ratelimit-bypass"]
120118 if ok {
121119 req.Header.Set("x-ratelimit-bypass", val)
122120 }
121121+ }
122122+123123+ client := c.engine.BlobClient
124124+ if client == nil {
125125+ client = http.DefaultClient
123126 }
124127125128 resp, err := client.Do(req)
+3
automod/engine/engine.go
···44 "context"
55 "fmt"
66 "log/slog"
77+ "net/http"
78 "time"
89910 "github.com/bluesky-social/indigo/atproto/identity"
···3839 BskyClient *xrpc.Client
3940 // used to persist moderation actions in mod service (optional)
4041 AdminClient *xrpc.Client
4242+ // used to fetch blobs from upstream PDS instances
4343+ BlobClient *http.Client
4144}
42454346// Entrypoint for external code pushing arbitrary identity events in to the engine.